Wîkîferheng
kuwiktionary
https://ku.wiktionary.org/wiki/Destp%C3%AAk
MediaWiki 1.47.0-wmf.17
case-sensitive
Medya
Taybet
Gotûbêj
Bikarhêner
Gotûbêja bikarhêner
Wîkîferheng
Gotûbêja Wîkîferhengê
Wêne
Gotûbêja wêneyî
MediaWiki
Gotûbêja MediaWiki
Şablon
Gotûbêja şablonê
Alîkarî
Gotûbêja alîkariyê
Kategorî
Gotûbêja kategoriyê
Pêvek
Gotûbêja pêvekê
Nimînok
Gotûbêja nimînokê
Portal
Gotûbêja portalê
Tewandin
Gotûbêja tewandinê
Jinûvesazî
Gotûbêja jinûvesaziyê
TimedText
TimedText talk
Modul
Gotûbêja modulê
Event
Event talk
kî
0
3396
6347632
6339069
2026-09-01T11:48:00Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347632
wikitext
text/x-wiki
{{bnr-h|ki|-kî}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/kʰiː/}}
* {{deng|ku|Ku-kî.ogg|Deng|dever=Êlih}}
* {{deng|ku|LL-Q36163 (kmr)-Key Mîrza-kî.wav|dever=Bidlîs}}
* {{kîte|ku|kî}}
=== Cînav ===
[[Wêne:User Question Mark (1162770) - The Noun Project.svg|thumb|Ew '''kî''' ye?]]
{{cînav|ku}}, {{k-ya req}}
# [[çi]] [[kes]], [[kîj]] [[kes]], [[kîjan]] [[kes]]
#: {{nm|ku|Tu '''kî''' yî?|Navê te çi ye? Navê xwe bibêje.|rêz=1}}
#: {{nm|ku|Ew '''kî''' ye?|Navê wî çi ye? / Navê wê/wî bibêje.|rêz=1}}
#: {{nm|ku|'''Kî''' wisa dibêje?}}
#: {{nm|ku|Te '''kî''' dît?}}
==== Ji wêjeya klasîk ====
* {{J:Feqiyê Teyran|jêgirtin=Belgek heye sih lê nebî</br>'''Kî''' j'ni'metê dê dit xeber</br>Ya Reb derê feyzê vebî}}
==== Notên bikaranînê ====
* ''Kê'' forma çemandî ya ''kî'' ye. Eger bersiva ''kî'' "ez" be (- Ew kî ye? - Ez im.), hingê ya ''kê'' jî "min" e (- Kê got? - Min got).
* Berovajî ku hin kes carinan bi şaşî bi kar tînin, ''kê'' ne forma [[mê]] ya ''kî'' ye. Di ''kî'' û ''kê'' de [[zayend]] nîne.
==== Bi alfabeyên din ====
* {{ku-ar|كی}}
* {{ku-kr|ки}}
==== Têkildar ====
{{kol3|ku
|em
|ew
|ez
|hûn
}}
==== Etîmolojî ====
Forma çemandî/tewandî ''[[kê]]'', hevreha soranî {{g|ckb|کێ}}, zazakî ''[[kam]]'', talîşî {{g|fa|کی}} (kî), {{hv|fa|کی|tr=kî}}, tacikî [[кӣ]] (kî), avestayî [[𐬐𐬇]] (kə̄), [[𐬐𐬀]] (ke) û [[𐬐𐬋]] (ko), {{hv|sa|क}} (ká) û [[कः]] (káḥ), hindî [[कौन]] (kaun), latviyayî ''[[kas]]'', lîtwanî ''[[kàs]]'', albanî ''[[kush]]'', {{hv|ru|кто}} (kto), polonî/slovakî ''[[kto]]'', çekî ''[[kdo]]'', latînî ''[[quis]]'', fransî ''[[qui]]'', îtalî ''[[chi]]'' (bixwîne: kî), portugalî ''[[quem]]'', spanî ''[[quién]]'', danmarkî/norwecî ''[[hvem]]'', swêdî ''[[vem]]'', îzlendî ''[[hver]]'', almanî ''[[wer]]'', holendî ''[[wie]]'', îngilîzî ''[[who]]''... hemû ji {{ji|ine-pro|ku|-}} *''[[kʷis]]'' (kî; çi).
Peyvê di makezimanê [[proto-hindûewropî]] hem wateya "kî" û hem jî ya "[[çi]]" dida. Heta niha jî bo nimûne latviyayî ''[[kas]]'' û lîtwanî ''[[kàs]]'' hem [[wate]]ya "kî" û hem jî manaya "[[çi]]" didin.
Di zimanên [[germenî]] (bo nimûne almanî, îngilîzî û swêdî) de *k- ya proto-hindûewropî adeten dibe H (loma bo nimûne danmarkî/norwecî ''hvem''). Dûv re H ji swêdî, holendî û almanî ketiye. Di îngilîzî de HW bi [[metatez]]ê bûye WH.
Ji heman rehî herwiha peyvên kurdî: ''[[çi]], [[kîjan]]/[[kîşk]], [[ku]], [[kusa]], [[kû]]''...
Peyva hindûewropî herwiha pir dişibe [[hevwate]]yên xwe hem di zimanên [[altayî]] de û hem jî di zimanên [[ûralî]] de. Bo nimûne: tirkî (altayî) ''[[kim]]'' û macarî/hungarî (ûralî) ''[[ki]]''.
Lê ev peyvên van zimanan ne ji zimanên hindûewropî hatine wergirtin, ew peyvên xwemalî yên van zimanan in. Bi tesadifî wek peyva hindûewropî ne yan jî carinan wisa tê texmînkirin ku hindûewropî, altayî, ûralî û hinek malbatên din jî yên zimanan yên [[Ewrasya]]yê binemaleke zimanan ya kevn ya hevpar bi navê [[nostratîkî]] pêk tînin. Ji bilî vê peyvê, hinek cînavên din jî wek delîl tên pêşkêşkirin (bo nimûne kurdî "[[min]]", azerî "[[men]]" û fînlandî "[[minä]]"). Lê ev teorî ji aliyê piraniya zimannasan ve tê redkirin û wekheviyên wiha tenê wek tiştên tesadifî tên qebûlkirin.
==== Forma çemandî ====
{{kol3|ku
|kê
}}
==== Nêzîkî ====
{{kol3|ku
|çi
|[[kîjan]], [[kîj]], [[kîşk]]
|kû
}}
==== Werger ====
{{werger-ser}}
* {{Z|aa}}: {{W-|aa|iyya}}
* {{Z|af}}: {{W+|af|wie}}
* {{Z|akl}}: {{W-|akl|sin-o}}
* {{Z|sq}}: {{W+|sq|kush}}
* {{Z|de}}: {{W+|de|wer}}
* {{Z|alt}}: {{W-|alt|кем}}
* {{Z|arc}}: {{W-|arc|מַן|tr=man}}
* {{Z|rup}}: {{W-|rup|tsine}}
* {{Z|ast}}: {{W+|ast|quién}}, {{W+|ast|quiénes|p}}
* {{Z|az}}: {{W+|az|kim}}
* {{Z|ban}}: {{W-|ban|nyen}}
* {{Z|eu}}: {{W+|eu|nor}}
* {{Z|ba}}: {{W-|ba|кем|sc=Cyrl}}
* {{Z|be}}: {{W+|be|хто}}
* {{Z|bn}}: {{W+|bn|কে|sc=Beng}}
* {{Z|bcl}}: {{W-|bcl|siisay}}
* {{Z|bla}}: {{W-|bla|tahkaa}}
* {{Z|br}}: {{W+|br|piv}}
* {{Z|bg}}: {{W-|bg|кой}}
* {{Z|my}}: {{W-|my|ဘယ်သူ}}
* {{Z|ccc}}: {{W-|ccc|na'shanana}}
* {{Z|ce}}: {{W-|ce|мила}}
* {{Z|cs}}: {{W+|cs|kdo}}
* {{Z|chr}}: {{W-|chr|ᎦᎪ}}
* {{Z|ny}}: {{W-|ny|ndani}}
* {{Z|cic}}: {{W-|cic|kata}}
* {{Z|zh}}:
*: {{Z|yue}}: {{W-|yue|邊個|tr=bin1 go3}}, {{W-|yue|誰|tr=seoi4}}, {{W-|yue|邊位|tr=bin1 wai2}}, {{W-|yue|乜誰|tr=mat1 seoi4-2}}, {{W-|yue|何人|tr=ho4 jan4}}, {{W-|yue|誰人|tr=seoi4 jan4}}
*: {{Z|dng}}: {{W-|dng|сый}}
*: {{Z|hak}}: {{W-|hak|麼人|tr=má-ngìn, mán-ngìn}}, {{W-|hak|麼儕|tr=má-sà}}, {{W-|hak|何人|tr=hò-ngìn}}, {{W-|hak|哪儕|tr=nai-sà}}
*: {{Z|cmn}}: {{W+|cmn|誰|tr=shuí, shéi}}, {{W+|cmn|何人|tr=hérén}}, {{W-|cmn|誰人|tr=shéirén, shuírén}}, {{W+|cmn|阿誰|tr=āshéi, āshuí}}
*: {{Z|cdo}}: {{W-|cdo|底人|tr=diē-nè̤ng, dē̤-nè̤ng, dē̤-è̤ng}}
*: {{Z|nan}}: {{W+|nan|啥人|tr=siáⁿ-lâng}}, {{W+|nan|誰|tr=sûi, chûi, chūi, cho̍ah, chiâ, chôa, tiâng, siáng, siâng}}, {{W-|nan|啥物人|tr=siáⁿ-mih-lâng, siáⁿ-mí-lâng, sáng-n̂g, siàng-n̂g}}, {{W-|nan|甚物人|tr=sím-mih-lâng}}, {{W-|nan|是誰|tr=chī-chūi, sī-sûi}}, {{W-|nan|底人|tr=tī-lâng}}
*: {{Z|wuu}}: {{W-|wuu|啥人}}
* {{Z|ckt}}: {{W-|ckt|мэӈин|tr=mėṇin}}
* {{Z|cv}}: {{W-|cv|кам|sc=Cyrl}}
* {{Z|dlm}}: {{W-|dlm|ci}}
* {{Z|da}}: {{W+|da|hvem}}
* {{Z|dar}}: {{W-|dar|чи}}
* {{Z|dlg}}: {{W-|dlg|ким}}
* {{Z|id}}: {{W+|id|siapa}}
* {{Z|ar}}: {{W-|ar|مَن}}
*: {{Z|arz}}: {{W-|arz|مين|tr=mīn}}
*: {{Z|acw}}: {{W-|acw|مين|tr=mīn}}
*: {{Z|ary}}: {{W-|ary|شكون|tr=škūn}}, {{W-|ary|من|tr=man}}
*: {{Z|apc}}: {{W-|apc|مين|tr=mīn}}
* {{Z|hy}}: {{W+|hy|ով}}
*: {{Z|xcl}}: {{W-|xcl|ո}}, {{W-|xcl|ով}}
* {{Z|eo}}: {{W+|eo|kiu}}
* {{Z|et}}: {{W+|et|kes}}
* {{Z|evn}}: {{W-|evn|ңи}}
* {{Z|fa}}: {{W+|fa|کی|tr=ki}}
* {{Z|fo}}: {{W+|fo|hvør|n|m}}, {{W+|fo|hvat|nt}}
* {{Z|fi}}: {{W+|fi|kuka}}, {{W+|fi|ken}}
* {{Z|fr}}: {{W+|fr|qui}}
*: {{Z|fro}}: {{W-|fro|qui}}, {{W-|fro|ki}}, {{W-|fro|cui}}
* {{Z|ofs}}: {{W-|ofs|hwā}}
* {{Z|fy}}: {{W+|fy|wa}}
* {{Z|gd}}: {{W-|gd|cò}}
* {{Z|gl}}: {{W-|gl|quen|n|m-p|m|f-p}}
* {{Z|got}}: {{W-|got|𐍈𐌰𐍃}}
* {{Z|gu}}: {{W-|gu|કોણ}}
* {{Z|ka}}: {{W+|ka|ვინ|sc=Geor}}
* {{Z|gn}}: {{W+|gn|máva}}
* {{Z|mba}}: {{W-|mba|sin-o}}
* {{Z|hi}}: {{W+|hi|कौन|sc=Deva}}
* {{Z|hil}}: {{W-|hil|sin-o}}
* {{Z|mww}}: {{W-|mww|leej twg}}
* {{Z|odt}}: {{W-|odt|wie}}, {{W-|odt|wē}}
* {{Z|odt}}: {{W-|odt|hwē}}
* {{Z|nl}}: {{W+|nl|wie}}
* {{Z|ibg}}: {{W-|ibg|sinni}}
* {{Z|he}}: {{W-|he|מִי|tr=mi}}
* {{Z|io}}: {{W+|io|qua}}, {{W+|io|qui|p}}
* {{Z|ilo}}: {{W-|ilo|sino}}, {{W-|ilo|siasino}}, {{W-|ilo|asino}}
* {{Z|ang}}: {{W-|ang|hwā}}
* {{Z|enm}}: {{W-|enm|who}}
* {{Z|en}}: {{W+|en|who}}, {{W+|en|whom}}
* {{Z|izh}}: {{W-|izh|ken}}
* {{Z|inh}}: {{W-|inh|мала}}
* {{Z|ia}}: {{W+|ia|qui}}
* {{Z|ga}}: {{W-|ga|cé}}
*: {{Z|sga}}: {{W-|sga|cía}}
* {{Z|it}}: {{W+|it|chi}}
* {{Z|is}}: {{W+|is|hver|n|m}}, {{W+|is|hvert}}, {{W+|is|hvað|nt}}
* {{Z|ja}}: {{W+|ja|誰|tr=だれ, dare}}, {{W+|ja|だれ|tr=dare}}, {{W+|ja|どなた|tr=donata}}, {{W-|ja|どちらさま|tr=dochirasama}}
* {{Z|kaw}}: {{W-|kaw|syapa}}
* {{Z|jv}}: {{W+|jv|sapa}}, {{W-|jv|sinten}} (kromo-level)
* {{Z|xal}}: {{W-|xal|кен|sc=Cyrl}}
* {{Z|pam}}: {{W-|pam|ninu}}
* {{Z|krc}}: {{W-|krc|ким|tr=kim}}
* {{Z|kdr}}: {{W-|kdr|kim}}
* {{Z|kaa}}: {{W-|kaa|kim}}
* {{Z|xqa}}: {{W-|xqa|كِمْ|tr=kim}}
* {{Z|csb}}: {{W-|csb|chto}}
* {{Z|ca}}: {{W+|ca|qui}}
* {{Z|krj}}: {{W-|krj|sin-o}}
* {{Z|ky}}: {{W+|ky|ким|sc=Cyrl}}
* {{Z|ki}}: {{W-|ki|nũũ}}
* {{Z|si}}: {{W-|si|කවුද|sc=Sinh}}
* {{Z|ko}}: {{W+|ko|누구}}
* {{Z|rop}}: {{W-|rop|hu}}
* {{Z|kri}}: {{W-|kri|udat}}
* {{Z|cr}}: {{W-|cr|awina|sc=Cans}}
* {{Z|kum}}: {{W-|kum|ким|tr=kim}}
* {{Z|ltg}}: {{W-|ltg|kas}}
* {{Z|la}}: {{W+|la|quis|n|m}}
* {{Z|lv}}: {{W+|lv|kas}}
* {{Z|lo}}: {{W-|lo|ໃຜ}}
* {{Z|li}}: {{W+|li|wae}}
* {{Z|lt}}: {{W+|lt|kas|p}}
* {{Z|lmo}}: {{W-|lmo|chi}}
* {{Z|mk}}: {{W+|mk|кој}}
* {{Z|ml}}: {{W+|ml|ആര്}}
* {{Z|ms}}: {{W+|ms|siapa}}
* {{Z|mt}}: {{W-|mt|min}}
* {{Z|mns-nor}}: {{W-|mns-nor|хотьют}}
* {{Z|mi}}: {{W+|mi|wai}}
* {{Z|hu}}: {{W+|hu|ki}}, {{W-|hu|kik|p}}
* {{Z|mn}}: {{W+|mn|хэн|sc=Cyrl}}
* {{Z|wmw}}: {{W-|wmw|nani}}
* {{Z|nci}}: {{W-|nci|āc}}, {{W-|nci|āquihqueh}}, {{W-|nci|āquin}}
* {{Z|nap}}: {{W-|nap|chi}}
* {{Z|nog}}: {{W-|nog|ким}}
* {{Z|no}}:
*: {{Z|no}}: {{W+|no|hvem}}
*: {{Z|nn}}: {{W+|nn|kven}}
* {{Z|oj}}: {{W-|oj|awenen|sc=Cans}}
* {{Z|os}}: {{W-|os|чи}}
* {{Z|ota}}: {{W-|ota|كیم|tr=kim}}
* {{Z|ug}}: {{W-|ug|كىم}}
* {{Z|uz}}: {{W+|uz|kim}}
* {{Z|pag}}: {{W-|pag|siopa}}
* {{Z|pap}}: {{W-|pap|ken}}
* {{Z|pl}}: {{W+|pl|kto}}
* {{Z|pt}}: {{W+|pt|quem}}
* {{Z|pa}}: {{W-|pa|ਕੌਣ|tr=kauṇă}}
* {{Z|pua}}: {{W-|pua|ne}}
* {{Z|kk}}: {{W+|kk|кім|sc=Cyrl}}
* {{Z|rap}}: {{W-|rap|aai}}
* {{Z|rhg}}: {{W-|rhg|hon}}
* {{Z|rm}}: {{W-|rm|tgi}}
* {{Z|rom}}: {{W-|rom|kon}}
* {{Z|ro}}: {{W+|ro|cine}}
* {{Z|ru}}: {{W+|ru|кто}}
* {{Z|rue}}: {{W-|rue|хто}}
* {{Z|ssy}}: {{W-|ssy|iyya}}
* {{Z|sa}}: {{W+|sa|क|cuda=कः|n}}
* {{Z|ceb}}: {{W-|ceb|kinsa}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|ко̏}}, {{W-|sh|тко̏}}
*: Latînî: {{W-|sh|kȍ}}, {{W-|sh|tkȍ}}
* {{Z|sco}}: {{W-|sco|wha}}
* {{Z|cu}}:
*: Kirîlî: {{W-|cu|къто}}
*: Glagolîtîk: {{W-|cu|ⰽⱏⱅⱁ}}
* {{Z|orv}}: {{W-|orv|къто}}, {{W-|orv|хто}}
* {{Z|sk}}: {{W+|sk|kto}}
* {{Z|sl}}: {{W+|sl|kdó}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|chto}}
*: {{Z|hsb}}: {{W-|hsb|chto}}, {{W-|hsb|štó}}
* {{Z|es}}: {{W+|es|quién}}, {{W+|es|quiénes|p}}
* {{Z|su}}: {{W-|su|saha}}
* {{Z|sv}}: {{W+|sv|vem}} (singular), {{W+|sv|vilka}} (plural)
* {{Z|zdj}}: {{W-|zdj|nɗopvi}}
* {{Z|cjs}}: {{W-|cjs|кем|tr=kem}}
* {{Z|tg}}: {{W+|tg|кӣ|sc=Cyrl}}
* {{Z|tl}}: {{W+|tl|sino}}
* {{Z|tly}}: {{W-|tly|کی|tr=ki}}
* {{Z|ta}}: {{W+|ta|யார்}}, {{W+|ta|எவர்}}, {{W+|ta|எவன்}}
* {{Z|twf}}: {{W-|twf|p’ų́}}
* {{Z|tsg}}: {{W-|tsg|hisiyu}}
* {{Z|th}}: {{W+|th|ใคร}}
* {{Z|te}}: {{W+|te|ఎవరు}}
* {{Z|crh}}: {{W-|crh|kim}}
* {{Z|tt}}: {{W-|tt|кем|sc=Cyrl}}
* {{Z|tet}}: {{W-|tet|sé}}
* {{Z|otk}}: {{W-|otk|𐰚𐰢|tr=kem}}
* {{Z|tr}}: {{W+|tr|kim}}
* {{Z|tk}}: {{W-|tk|kim}}
* {{Z|bo}}: {{W-|bo|སུ}}
* {{Z|kim}}: {{W-|kim|ӄум|tr=qum}}
* {{Z|tpi}}: {{W-|tpi|husat}}
* {{Z|xto}}: {{W-|xto|kus}}
* {{Z|txb}}: {{W-|txb|kᵤse}}
* {{Z|tyv}}: {{W-|tyv|кым}}
* {{Z|uga}}: {{W-|uga|𐎎𐎊|tr=my}}
* {{Z|ur}}: {{W-|ur|کون|tr=kaun|sc=ur-Arab}}
* {{Z|uk}}: {{W+|uk|хто}}
* {{Z|uum}}: {{W-|uum|ким|tr=kim}}
* {{Z|vi}}: {{W+|vi|ai}}
* {{Z|vo}}: {{W+|vo|kim}}
* {{Z|wa}}: {{W+|wa|kî|n|m}}
* {{Z|war}}: {{W-|war|hin-o}}, {{W-|war|hin-o}}
* {{Z|wbl}}: {{W-|wbl|ku}}
* {{Z|cy}}: {{W-|cy|pwy}}
* {{Z|win}}: {{W-|win|peežega}}
* {{Z|kjh}}: {{W-|kjh|кем}}
* {{Z|km}}: {{W-|km|អ្នកណា}}, {{W+|km|នរណា}}, {{W+|km|ដែល}}
* {{Z|yai}}: {{W-|yai|ках}}
* {{Z|sah}}: {{W-|sah|ким}}
* {{Z|yi}}: {{W-|yi|ווער|sc=Hebr}}
* {{Z|yol}}: {{W-|yol|fho}}
* {{Z|el}}: {{W+|el|ποιος}}
*: {{Z|grc}}: {{W-|grc|τίς|n|m}}
* {{Z|zea}}: {{W-|zea|wie}}, {{W-|zea|wien}}
* {{Z|za}}: {{W-|za|bouxlawz}}
* {{Z|ase}}: {{W-|ase|L@Chin-ThumbBack Squeeze}}
* {{Z|zu}}: {{W-|zu|ubani|c1a|c2a}}
{{werger-bin}}
=== Girêdek ===
{{girêdek|ku}}
# ''Binêre'' '''[[ku]]''' (1)
=== Formeke lêkerê ===
{{lêker|ku|form=erê}}
# {{guherto|bikî}} ([[form]]a [[bilanî]]): <br>''Tu ê çi kî?'' (Tu dê çi bikî?)
==== Formên alternatîv ====
{{kol3|ku
|bikî<q:standard>
|[[kê]], [[key]]<qq:devokî, devkî>
}}
==== Têkildar ====
{{kol3|ku
|kim
|ke
|kin
}}
==== Etîmolojî ====
[[-k-]] (rehê dema niha yê lêkera '''[[kirin]]''') + [[-î]] ([[paşgir]]a kesê duyem yê yekhejmar anku "[[tu]]")
== {{ziman|zza}} ==
=== Cînav ===
{{cînav|zza}}
# {{guherto|zî}}
== {{ziman|wa}} ==
=== Cînav ===
{{cînav|wa}}
# [[kî#ku|kî]]
8nbcqylpth2ntu9449jyqt0c6ynuigg
fihêt
0
3417
6347633
6325868
2026-09-01T11:48:53Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347633
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# Tişta/ê ku kirina wê ji alî [[civak]]î ve wek [[rûreşî|rûreşiyekê]] tê [[hesibandin]].
#: {{hevmane|ku|eyb|şerm|fedî|ar|erz|şermezarî|rûreşî}}
#: {{nm|ku|'''Fihêt''' e ku mirov bêcil li derve bigerre.}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Formên alternatîv ====
{{kol3|ku
|fehêt
|fehît
|fêt
|fihêt
}}
==== Jê ====
{{kol3|ku
|bêfêt
|bêfêtî
|fêtî
|fihêt û şermizar kirin<ee:Dihok>
}}
==== Etîmolojî ====
Ji {{ji|arc|ku|tr=pehyûta|w=xeletî}} ji rehê ''p-h-y-'' ([[xelet]] bûn, riya xwe winda kirin).
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|Scham}} {{mê}}
* {{Z|cs}}: {{W|cs|stud}} {{mê}}
* {{Z|zh}}: {{W-|zh|羞辱|tr=xiūrǔ}}
* {{Z|ar}}: {{W|ar|خجل}} (xecel)
* {{Z|et}}: {{W|et|häbi}}
* {{Z|fa}}: {{W|fa|خجل|guman=erê}}
* {{Z|fi}}: [[häpeä]]; [[ujous]]
* {{Z|fr}}: {{W|fr|honte}} {{mê}}
* {{Z|nl}}: {{W|nl|schaamte}} {{mê}}
* {{Z|en}}: [[shyness]]; [[shame]], {{W|en|stirring}}, {{W|en|disgrace}}, {{W|en|arousing|guman=erê}}, {{W|en|instigation|guman=erê}}, {{W|en|tempting|guman=erê}}, {{W|en|insidious|guman=erê}}, {{W|en|incitement|guman=erê}}
* {{Z|it}}: {{W|it|vergogna}} {{mê}}
* {{Z|ja}}: {{W|ja|恥|tr=[[はじ]], haji}}, {{W-|ja|羞恥心|tr=しゅうちしん}}, {{W|ja|面汚し|tr=つらよごし, tsurayogoshi}}
* {{Z|ca}}: {{W|ca|vergonya}} {{mê}}
* {{Z|ko}}: {{W-|ko|수치|tr=suchi}}
* {{Z|hu}}: {{W|hu|szégyen}}
* {{Z|pt}}: {{W|pt|vergonha}} {{mê}}
* {{Z|ru}}: {{W-|ru|стыд|tr=styd}}
* {{Z|es}}: {{W|es|vergüenza}} {{mê}}
* {{Z|sv}}: {{W|sv|skam|c}}
* {{Z|te}}: {{W-|te|సిగ్గు|tr=siggu}}
* {{Z|tr}}: {{W|tr|utanç}}, {{W|tr|hicap}}, {{W|tr|utanma}}, {{W|tr|ayıp|guman=erê}}
* {{Z|el}}: {{W-|el|ντροπή|tr=dropí}}
{{werger-bin}}
7eu0wiyx3tegcfqzypefv16f5o2xz4u
zanîn
0
3795
6347435
6341187
2026-08-31T19:06:32Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347435
wikitext
text/x-wiki
{{bnr-h|zanin}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/zˤɑ'niːn/}}
* {{ku-kîte}}
=== Lêker ===
{{ku-tewîn-lk|zanîn|form=gerguhêz|niha=zan|borî=zanî}}
{{lêker|ku|c=x-gh}}
# [[hay]] jê hebûn, [[agah]] jê hebûn, [[agahdar]] bûn, [[haydar bûn]] (ji tiştekê);
#: {{mk|ku|Ez '''dizanim''' ew li kû ye.|Min agadarî heye ka ew li kû ye. Min hay jê heye ew li kû derê ye.|rêz=1}}
#* {{J:Yaşar Kemal:Çiyayê Agirî|jêgirtin=Mahmût Xan '''nizane''' maf û diyarî çi ye. Ew bûye Osmanî.}}
#* {{jêder-kovar|ku|jêgirtin=Herwiha Philippe Ariès îdia dike ku di çaxa navîn de jî derbarê zarokatîyê de tiştek nedihat '''zanîn''' û zarok weku kesên kêm yanî yên ku hêj mezin nebûne, dihatin zanîn|nivîskar=Kenan Subaşı|sernav=Peywendîya Çîrokên Gelêrî û Zarokan di gel Pêşnîyazeke Rêbazên Xwendinê yên Çîrokan|kovar=International Journal of Kurdish Studies|cild=11|hejmar=1|sal=2025|rûpel=23|url=https://dergipark.org.tr/en/pub/ijoks/article/1605278}}
# [[karîn]] tiştekî bike
#: {{mk|ku|Ez [[dirûn]]ê '''nizanim'''.}}
# [[karîn]] bi [[ziman]]ekî [[axiftin|biaxive]] û [[fam]] bike
#: {{mk|ku|Ew baş bi kurdî dizane.}}
# [[piştrast]] bûn
#: {{mk|ku|Ez '''dizanim''' ew dîsan jî nayê.}}
==== Ji wêjeya klasîk ====
* {{J:Melayê Cizîrî:Dîwana Melayê Cizîrî|jêgirtin=Şêweyê dilberê '''bizan''' sunnet e şêwe 'işwe ferd</br>Şêweyê dilberê '''bizan''' sunnet e şêwe 'işwe ferd}}
==== Notên bikaranînê ====
{{veşêre-ser}}
Lêkerên ''karîn/kanîn'' û ''zanîn'' bi hin awayan ji lêkerên din yên kurmancî cuda tên tewandin. Bo mînak: di dema niha de di hin devokan de pêşqertafa ''di-'' nakeve pêşiya wan. Anku lêkeran bi awayê "ez '''di'''kim, tu '''di'''bêjî, ew '''di'''xwe" tên tewandin lê ''karîn/kanîn'' û ''zanîn'' di hin devokan de wek "ez karim, tu zanî, ew kane" tên tewandin (li cihê "ez dikarim, tu dizanî, ew dikane").
Herwiha neyînîkirina wan ne bi ''na-'' ye lê bi ''ni-'' ye. Anku di kurmancî de lêker bi awayê "ez '''na'''kim, tu '''na'''çî, ew '''na'''bêje" û hwd. tên neyînîkirin lê ji bilî van lêkeran ''karîn/kanîn'' û ''zanîn'' - ku bi awayê "ez '''ni'''zanim, tu '''ni'''karî, ew '''ni'''kane" tên neyînîkirin.
Herwiha di rewşên din de jî hin cudahî hene. Ji hemû lêkerên din re di raweya şertî de (''kondîsyonal'' yan ''subjunktîv'') bi giştî lêker bi formûlaya "bi- + reha dema niha + qertafa kesane''"'' ne: "ez bi-ç-im, tu bi-k-î, ew bi-bêj-e". Ev qaydeya giştî di hin devokan de li gel lêkerên ''karîn/kanîn'' û ''zanîn'' dîsa jî li kar e: "ez bi-zan-im, tu bi-kar-î, ew bi-kan-e". Lê di hin devokan de jî ew bi formûlaya "rehê dema niha + -i- + -b- + qertafa kesane" tên çêkirin: "ez kar-i-b-im, tu zan-i-b-î, ew kan-i-b-e". Di hin devokan de jî îcar ev herdu qayde di heman demê de tên bikaranîn: "ez bi-zan-i-b-im, tu bi-kar-i-b-î, ew bi-kan-i-b-e".
Herwiha ev ''zanibû'' bi teşeya raboriya dûr ''zanîbû'' hemanî nayê lêvandin.
{{veşêre-bin}}
==== Bi alfabeyên din ====
* {{ku-ar|زانين}} (dengnasî: ظانین)
* {{ku-kr|занин}}
==== Jê ====
{{kol3|ku
|nezan
|nezanî
|zana
|zanatî
|zane
|zanetî
|zanist
|zanistî
|zanistavan
|zanyar
|zanyarî
}}
==== Etîmolojî ====
Ji {{ji|ine-pro|ku|*ǵenh₃-}} / {{q|ine-pro|*ǵenə-}} / {{q|ine-pro|*ǵnō-}}, têkildarî ''zan-'' ya avestayî, {{hv|pal||dan-|sc=Latn}}, farisî ''dan-'', zazakî {{q|zza|zanayene}}, sanskrîtî ''jānāmi'', {{hv|ru|знать}} (znat'), almanî {{q|de|kann}}, {{hv|sv|kan}} ([[karîn|dikare]]) û [[känna]] ([[nasîn]]), îngilîzî [[can]] (bixwîne: ''ken'', "karîn") û [[know]] (bixwîne: ''now'' "zanîn" ji îngilîziya kevn [[cunnan]], bixwîne: ''kunnan'' "zanîn").
Ji {{ji|ine-pro|ku|-}}: *'''gne'''- ("zanîn"),
{{ji|ira-pro||-}}: *'''zan'''- ("zanîn"),
{{ae}}: '''zān'''- ("zanîn"),
{{xpr}}: '''z'n'''- ("zanîn"),
{{pal}}: '''d'n'''- ("zanîn"),
{{sog}}: '''z'n'''- ("zanîn"),
{{fa}}: '''dān'''- ("zanîn"),
{{os}}: '''zynd'''- ("zanîn"),
{{bal}}: '''zan'''- ("zanîn"),
[[semnanî]]: '''zūn'''- ("zanîn"),
[[sengîserî]]: '''zun'''- ("zanîn") ... {{ir}},
{{kmr}}: '''zanîn'''- ("zanîn"),
{{ckb}}: '''zanîn'''- ("zanîn"),
{{hac}}: '''zanay''' ("zanîn"),
{{zza}}: '''[[zanayene]]''',
{{sa}}: '''jna'''- ("zanîn"),
{{la}}: '''gno'''- ("zanîn"),
{{el}}: '''gno'''- ("zanîn"),
{{en}}: '''know''' ("zanîn") ...,
{{de}}: '''[[kann]]''' ([[karîn|dikare]]),
{{sv}}: '''[[kan]]''' ([[karîn|dikare]]), '''[[känna]]''' ([[nasîn]])
;{{biçûk|Çavkanî:
* {{Cheung|r=467}}
* {{Watkins|r=33}}
* {{Etymonline}}
}}
<font style="font-size:10px">Binere herwiha: [[nasîn]]</font>
==== Bide ber ====
* {{g|ku|agah}} jê hebûn
* {{g|ku|aşna}} bûn
* {{g|ku|hay}} jê hebûn
* {{g|ku|nasîn}}
* {{g|ku|nas}} kirin
* {{g|ku|şareza}} bûn
==== kurtebêj ====
#: {{mk|ku|'''tu same lo''' .|Ma ez çi dizanime bavo. Min hay jê nîne, ez pê nizanim.|rêz=1}}
==== Werger ====
{{werger-ser}}
* {{Z|ab}}: {{W-|ab|адырра}}
* {{Z|aa}}: {{W-|aa|eexege}}
* {{Z|af}}: {{W+|af|weet}}
* {{Z|ak}}: {{W-|ak|nim}}
* {{Z|sq}}: {{W+|sq|di}}
* {{Z|de}}: {{W+|de|wissen}}
*: {{Z|gsw}}: {{W-|gsw|wüsse}}
* {{Z|alt}}: {{W-|alt|билер}}
* {{Z|am}}: {{W+|am|ማወቅ}}, {{W-|am|ማዎቅ}}
* {{Z|am}}: {{W+|am|ማወቅ}}
* {{Z|arc}}: {{W-|arc|יְדַע}}
* {{Z|rup}}: {{W-|rup|shciu}}
* {{Z|ast}}: {{W+|ast|saber}}
* {{Z|az}}: {{W+|az|bilmək}}
* {{Z|eu}}: {{W-|eu|jakin}}, {{W-|eu|jakina izan}}
* {{Z|ba}}: {{W-|ba|белеү}}
* {{Z|bar}}: {{W-|bar|wissn}}
* {{Z|be}}: {{W-|be|ве́даць|impf}}, {{W-|be|знаць|impf}}
* {{Z|bn}}: {{W+|bn|জানা}}, {{W+|bn|চেনা}}
* {{Z|bqi}}: {{W-|bqi|دونستن|tr=dõwesten|sc=fa-Arab}}
* {{Z|bi}}: {{W-|bi|save}}
* {{Z|ebk}}: {{W-|ebk|ammo}}, {{W-|ebk|inila}}
* {{Z|br}}: {{W+|br|gouzout}}
* {{Z|bug}}: {{W-|bug|ito}}
* {{Z|mbb}}: {{W-|mbb|savut}}
* {{Z|bg}}: {{W+|bg|зна́я|impf}}
* {{Z|my}}: {{W+|my|သိရှိ}}, {{W+|my|သိ}}
* {{Z|dz}}: {{W-|dz|ཤེས}}
* {{Z|cs}}: {{W+|cs|vědět}}
* {{Z|chn}}: {{W-|chn|kəmtəks}}
* {{Z|zh}}:
*: {{Z|yue}}: {{W-|yue|知|tr=zi1}}
*: {{Z|dng}}: {{W-|dng|җыдо}}
*: {{Z|hak}}: {{W-|hak|知|tr=tî}}
*: {{Z|cmn}}: {{W+|cmn|知道|tr=zhīdao}}, {{W+|cmn|曉得|tr=xiǎode}}
*: {{Z|cdo}}: {{W-|cdo|捌|tr=báik}}
*: {{Z|nan}}: {{W+|nan|知影|tr=chai-iáⁿ}}, {{W+|nan|會曉|tr=ē-hiáu}}, {{W+|nan|明白|tr=bîng-pi̍k}}
*: {{Z|wuu}}: {{W-|wuu|曉得}}
* {{Z|cv}}: {{W-|cv|пӗл|cuda=пĕл}}
* {{Z|dlm}}: {{W-|dlm|sapar}}
* {{Z|da}}: {{W+|da|vide}}
* {{Z|dlg}}: {{W-|dlg|бил}}
* {{Z|sce}}: {{W-|sce|mejie}}
* {{Z|egl}}: {{W-|egl|savêr}}
* {{Z|id}}: {{W+|id|tahu}}
* {{Z|ar}}: {{W+|ar|عَلِمَ}}, {{W+|ar|عَرَفَ}}
*: {{Z|arz}}: {{W-|arz|عرف|tr=ʿeref|sc=Arab}}
*: {{Z|acw}}: {{W-|acw|عرف|tr=ʕirif}}
* {{Z|hy}}: {{W+|hy|գիտենալ}}, {{W+|hy|իմանալ}}
* {{Z|eo}}: {{W+|eo|scii}}
* {{Z|et}}: {{W+|et|teadma}}
* {{Z|eve}}: {{W-|eve|хадай}}
* {{Z|evn}}: {{W-|evn|сами}}
* {{Z|fan}}: {{W-|fan|-yem}}
* {{Z|fa}}: {{W+|fa|دانستن|tr=dânestan}}, {{W-|fa|دونستن|tr=dunestan}}
* {{Z|fo}}: {{W+|fo|vita}}
* {{Z|fi}}: {{W+|fi|tietää}}
* {{Z|fro}}: {{W-|fro|savoir}}, {{W-|fro|saveir}}
* {{Z|fr}}: {{W+|fr|savoir}}
* {{Z|fur}}: {{W-|fur|savê}}
* {{Z|frr}}: {{W-|frr|waase}}, {{W-|frr|witj}}
* {{Z|fy}}: {{W+|fy|wite}}, {{W+|fy|witte}}
* {{Z|gd}}: {{W-|gd|bi fhios aig}}
* {{Z|gl}}: {{W+|gl|saber}}
* {{Z|got}}: {{W-|got|𐍅𐌹𐍄𐌰𐌽}}
* {{Z|gu}}: {{W-|gu|જાણવું}}
* {{Z|ka}}: {{W-|ka|ცოდნა}}
* {{Z|gn}}: {{W-|gn|kuaa}}
* {{Z|ht}}: {{W-|ht|konnen}}
* {{Z|haw}}: {{W-|haw|ʻike}}
* {{Z|ha}}: {{W-|ha|sanī̀}}
* {{Z|hi}}: {{W+|hi|जानना}}
* {{Z|nl}}: {{W+|nl|weten}}
* {{Z|he}}: {{W+|he|יָדַע|tr=yadá}}
* {{Z|io}}: {{W+|io|savar}}
* {{Z|ilo}}: {{W-|ilo|ammo}}
* {{Z|ang}}: {{W-|ang|witan}}
* {{Z|en}}: {{W+|en|know}}
* {{Z|ga}}: {{W-|ga|a fhios a bheith agat}}, {{W-|ga|is eol do}}, {{W-|ga|[[eolas]] a bheith ag}}
* {{Z|ist}}: {{W-|ist|savì}}
* {{Z|it}}: {{W+|it|sapere}}
* {{Z|is}}: {{W+|is|vita}}
* {{Z|ja}}: {{W+|ja|知る|tr=しる, shiru}}, {{W-|ja|[[確信]]している|tr=かくしんしている, kakushin shite iru}}, {{W-|ja|[[ご存知]]である|tr=ごぞんじである, go-zonji de aru}}, {{W-|ja|存じ上げる|tr=ぞんじあげる, zonjiageru}}
* {{Z|kaw}}: {{W-|kaw|wruh}}
* {{Z|jv}}: {{W+|jv|weruh}}
* {{Z|kab}}: {{W-|kab|ẓer}}
* {{Z|ksc}}: {{W-|ksc|akammu}}
* {{Z|xnn}}: {{W-|xnn|gekken}}
* {{Z|xqa}}: {{W-|xqa|بِلْماكْ|tr=bilmēk}}
* {{Z|ca}}: {{W+|ca|saber}}
* {{Z|qu}}: {{W-|qu|riqsiy}}
* {{Z|ky}}: {{W+|ky|билүү}}
* {{Z|ki}}: {{W-|ki|ũĩ}}
* {{Z|kij}}: {{W-|kij|-[[nukwali]]-}}
* {{Z|si}}: {{W-|si|දන්නවා|sc=Sinh}}
* {{Z|ko}}: {{W+|ko|알다}}
* {{Z|kw}}: {{W-|kw|godhvos}}
* {{Z|kri}}: {{W-|kri|sabi}}
* {{Z|la}}: {{W+|la|sciō}}
* {{Z|lv}}: {{W+|lv|zināt}}
* {{Z|lo}}: {{W+|lo|ຮູ້}}, {{W-|lo|ຊາບ}}
* {{Z|ln}}: {{W-|ln|yeba}}
* {{Z|lt}}: {{W+|lt|žinoti}}
* {{Z|lmo}}: {{W-|lmo|savè}}
* {{Z|khb}}: {{W-|khb|ᦣᦴᧉ}}
* {{Z|mak}}: {{W-|mak|ito}}
* {{Z|mk}}: {{W-|mk|зна́е|impf}}
* {{Z|ml}}: {{W+|ml|അറിയുക}}
* {{Z|ms}}: {{W+|ms|tahu}}
* {{Z|mt}}: {{W-|mt|għaf}}
* {{Z|mnc}}: {{W-|mnc|ᠰᠠᠮᠪᡳ}}
* {{Z|mr}}: {{W+|mr|जाणणे|tr=j̈āṇṇe}}
* {{Z|gun}}: {{W-|gun|kuaa}}
* {{Z|hu}}: {{W+|hu|tud}}
* {{Z|min}}: {{W-|min|tahu}}
* {{Z|mwl}}: {{W-|mwl|saber}}
* {{Z|mn}}: {{W+|mn|мэдэх|sc=Cyrl}}
* {{Z|nah}}: {{W-|nah|mati}}
* {{Z|gld}}: {{W-|gld|саори}}, {{W-|gld|отоли-}}
* {{Z|nds}}: {{W-|nds|weten}}
* {{Z|ne}}: {{W-|ne|चिन्नु}}
* {{Z|nrf}}: {{W-|nrf|saver}}
* {{Z|no}}: {{W+|no|vite}}
* {{Z|oc}}: {{W+|oc|saber}}, {{W+|oc|saupre}}
* {{Z|or}}: {{W+|or|ଜାଣିବା}}
* {{Z|om}}: {{W-|om|baruu}}
* {{Z|os}}: {{W-|os|зонын}}
* {{Z|ota}}: {{W-|ota|بیلمك|tr=bilmek|sc=ota-Arab}}
* {{Z|ug}}: {{W-|ug|بىلمەك|sc=ug-Arab}}
* {{Z|uz}}: {{W+|uz|bilmoq}}
* {{Z|ps}}: {{W+|ps|پوهېدل|tr=pohedᶕl}}, {{W-|ps|پيېدل|tr=pǝyedǝ́l}}
* {{Z|pms}}: {{W-|pms|savej}}
* {{Z|pl}}: {{W+|pl|wiedzieć|impf}}, {{W+|pl|znać|impf}}
* {{Z|pt}}: {{W+|pt|saber}}
* {{Z|kk}}: {{W+|kk|білу|sc=Cyrl}}
* {{Z|rth}}: {{W-|rth|mataton}}
* {{Z|rm}}: {{W-|rm|savair}}, {{W-|rm|saveir}}, {{W-|rm|saver}}
* {{Z|ro}}: {{W+|ro|ști}}
* {{Z|ru}}: {{W+|ru|знать|impf}}, {{W+|ru|ве́дать|impf}}
* {{Z|ssy}}: {{W-|ssy|eerhege}}
* {{Z|osx}}: {{W-|osx|witan}}
* {{Z|sgs}}: {{W-|sgs|žėnuotė}}
* {{Z|sa}}: {{W+|sa|जानाति}}
* {{Z|sc}}: {{W-|sc|ischire}}, {{W-|sc|ischiri}}
* {{Z|ceb}}: {{W-|ceb|kahibalo}}
* {{Z|scn}}: {{W+|scn|sapiri}}
* {{Z|sd}}: {{W-|sd|ڄاڻڻ}}
* {{Z|srn}}: {{W-|srn|sabi}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|знати|impf|sc=Cyrl}}
*: Latînî: {{W+|sh|znati|impf}}
* {{Z|cu}}:
*: Kirîlî: {{W-|cu|знати|sc=Cyrs}}, {{W-|cu|вѣдѣти|sc=Cyrs}}
* {{Z|orv}}: {{W-|orv|знати}}, {{W-|orv|вѣдѣти}}
* {{Z|sk}}: {{W+|sk|vedieť|impf}}
* {{Z|sl}}: {{W+|sl|vedeti|impf}}
* {{Z|so}}: {{W-|so|ogaasho}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|wěźeś}}
*: {{Z|hsb}}: {{W-|hsb|wědźeć}}
* {{Z|es}}: {{W+|es|saber}}
* {{Z|su}}: {{W-|su|uninga}}
* {{Z|sw}}: {{W-|sw|kujua}}
* {{Z|sv}}: {{W+|sv|veta}}
* {{Z|xsr}}: {{W-|xsr|ཤེའ|tr=shee}}
* {{Z|tg}}: {{W+|tg|донистан|sc=Cyrl}}
* {{Z|tl}}: {{W+|tl|alam}}
* {{Z|roa-tar}}: {{W-|roa-tar|sapè}}
* {{Z|nod}}: {{W-|nod|ᩁᩪ᩶|tr=hu|sc=Lana}}
* {{Z|th}}: {{W+|th|รู้}}, {{W+|th|ทราบ}}
* {{Z|tft}}: {{W-|tft|waro}}
* {{Z|tt}}: {{W+|tt|белергә}}
* {{Z|tet}}: {{W-|tet|hatene}}
* {{Z|xct}}: {{W-|xct|ཤེས་|tr=shes}}
* {{Z|otk}}: {{W-|otk|𐰋𐰃𐰠|ts=bil-}}
* {{Z|tr}}: {{W+|tr|bilmek}}
* {{Z|tk}}: {{W+|tk|bilmek}}
* {{Z|bo}}: {{W-|bo|ཤེས}}, {{W-|bo|མཁྱེན}}
* {{Z|kim}}: {{W-|kim|билир|tr=bilir}}, {{W-|kim|биир|tr=biir}}
* {{Z|tpi}}: {{W-|tpi|save}}
* {{Z|roa-tou}}: {{W-|roa-tou|sçaveirĕ}}
* {{Z|txb}}: {{W-|txb|kärs-}}
* {{Z|tyv}}: {{W-|tyv|билир}}
* {{Z|uga}}: {{W-|uga|𐎊𐎄𐎓}}
* {{Z|ur}}: {{W-|ur|جاننا|tr=jānnā}}
* {{Z|uk}}: {{W+|uk|зна́ти|impf}}, {{W+|uk|ві́дати|impf|sc=Cyrl}}
* {{Z|vec}}: {{W-|vec|saver}}
* {{Z|vi}}: {{W+|vi|biết}}
* {{Z|vo}}: {{W+|vo|nolön}}
* {{Z|cy}}: {{W+|cy|medru}}, {{W+|cy|gwybod}}
* {{Z|kjh}}: {{W-|kjh|пілерге}}
* {{Z|km}}: {{W+|km|ចេរ}}
* {{Z|sah}}: {{W-|sah|бил}}
* {{Z|yi}}: {{W-|yi|וויסן}}
* {{Z|el}}: {{W+|el|ξέρω}}
*: {{Z|grc}}: {{W-|grc|γιγνώσκω}}, {{W-|grc|γινώσκω}}, {{W-|grc|οἶδα}}
* {{Z|zea}}: {{W-|zea|weête}}
* {{Z|za}}: {{W-|za|rox}}
* {{Z|ase}}: {{W-|ase|BentB@Sfhead}}
{{werger-bin}}
==== Anagram ====
* {{anagram|ku|a=aînnz|nazîn}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[haydarî]], [[agahî]], [[hay]], [[esehî]], [[piştrastî]]
#: {{mk|ku|'''Zanîna''' zimanê kurdî.}}
#: {{mk|ku|'''Zanîna''' rastiyê.}}
#* {{J:Kurdistan:1898|sernav=Bîsmîllahîrrehmanîrrehîm|nivîskar=Mîqdad Mîdhet Bedirxan|sal=1898|hj=1|r=1||cild=1|jg=Sed hezar şikir û hemd ji Xwedê teala re, em Musulman xelq kirin û '''zanîna''' ilm û marîfetê re hiş û zeka da me.}}
# [[zanyarî]], [[zanist]], [[ilm]]
#: {{mk|ku|Divê em welatê xwe bi '''zanînê''' ava bikin.}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Dijmane ====
{{kol3|ku
|nezanîn
|nezanî
}}
==== Jê ====
{{kol3|ku
|zanînî
}}
==== Bide ber ====
{{kol3|ku
|nasîn
|karîn
}}
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W+|af|kennis}}
* {{Z|sq}}: {{W+|sq|dituri|m}}, {{W+|sq|dije|m}}, {{W+|sq|dijeni|m}}
* {{Z|de}}: {{W+|de|Wissen|nt}}, {{W+|de|Kenntnis|m}}
* {{Z|am}}: {{W-|am|እውቀት}}
* {{Z|as}}: {{W-|as|জ্ঞান}}
* {{Z|ast}}: {{W-|ast|conocimientu|n}}, {{W-|ast|conocencia|m}}
* {{Z|az}}: {{W+|az|bilik}}
* {{Z|ba}}: {{W-|ba|белем|sc=Cyrl}}
* {{Z|be}}: {{W-|be|ве́данне|nt|sc=Cyrl}}
* {{Z|bn}}: {{W+|bn|জ্ঞান}}, {{W+|bn|এলেম|tr=elem}}
* {{Z|bcl}}: {{W-|bcl|kaaraman}}
* {{Z|br}}: {{W-|br|anaoudegez|m}}
* {{Z|bg}}: {{W+|bg|зна́ние|nt|sc=Cyrl}}
* {{Z|my}}: {{W+|my|အသိပညာ}}, {{W+|my|ဝိဇ္ဇာ}}
* {{Z|chl}}: {{W-|chl|'e'nanill}}
* {{Z|cs}}: {{W+|cs|znalost|m}}, {{W-|cs|vědění|nt}}
* {{Z|zh}}:
*: {{Z|yue}}: {{W-|yue|知識|tr=zi1 sik1, zi3 sik1}}, {{W-|yue|見識|tr=gin3 sik1}}
*: {{Z|dng}}: {{W-|dng|җышы}}, {{W-|dng|җяншы}}, {{W-|dng|эрлин}}
*: {{Z|cmn}}: {{W+|cmn|知識|tr=zhīshi}}, {{W+|cmn|見識|tr=jiànshí, jiànshì}}
* {{Z|da}}: {{W+|da|viden}}, {{W-|da|kundskab}}, {{W+|da|kendskab}}
* {{Z|id}}: {{W+|id|pengetahuan}}
* {{Z|ar}}: {{W+|ar|عِلْم|n}}, {{W+|ar|مَعْرِفَة|m}}
* {{Z|hy}}: {{W+|hy|իմացություն|sc=Armn}}, {{W+|hy|գիտելիք|sc=Armn}}
* {{Z|eo}}: {{W-|eo|scio}}
* {{Z|et}}: {{W-|et|teadmine}}, {{W-|et|teadmised|p}}
* {{Z|fa}}: {{W+|fa|دانش|tr=dâneš}}, {{W+|fa|شناخت|tr=šenâxt}}, {{W+|fa|علم|tr='elm}}, {{W+|fa|معرفت|tr=ma'refat}}
* {{Z|fo}}: {{W-|fo|vitan|m}}
* {{Z|fi}}: {{W+|fi|tieto}}, {{W+|fi|tiedot|p}}
* {{Z|fro}}: {{W-|fro|saveir}}
* {{Z|fr}}: {{W+|fr|connaissance|m}}, {{W+|fr|science|m}}
*: {{Z|frm}}: {{W-|frm|sçavoir|n}}
*: {{Z|fro}}: {{W-|fro|savoir|n}}, {{W-|fro|conoissance|m}}, {{W-|fro|escient|n}}
* {{Z|fur}}: {{W-|fur|cognossince|m}}
* {{Z|fy}}: {{W+|fy|witten}}
* {{Z|gd}}: {{W-|gd|fios|n}}
* {{Z|gl}}: {{W+|gl|coñecemento|n}}, {{W-|gl|sabenza|m}}, {{W-|gl|sabedoría|m}}
* {{Z|ka}}: {{W-|ka|ცოდნა}}
* {{Z|ht}}: {{W-|ht|konesans}}
* {{Z|haw}}: {{W-|haw|ʻike}}
* {{Z|hi}}: {{W+|hi|जान|m|sc=Deva}}, {{W+|hi|ज्ञान|n|sc=Deva}}, {{W+|hi|बुद्धि|m|sc=Deva}}, {{W+|hi|इल्म|n}}
* {{Z|nl}}: {{W+|nl|kennis}}, {{W+|nl|weten}}, {{W+|nl|wetenschap}}
* {{Z|he}}: {{W+|he|יֶדַע|tr=yéda|sc=Hebr}}, {{W+|he|ידיעה|m|tr=yediá}}
* {{Z|en}}: {{W+|en|knowledge}}
* {{Z|ia}}: {{W-|ia|cognoscentia}}
* {{Z|ga}}: {{W-|ga|fios|n}}
* {{Z|it}}: {{W+|it|conoscenza|m}}
* {{Z|is}}: {{W+|is|þekking|m}}
* {{Z|ja}}: {{W+|ja|知識|tr=ちしき, chishiki}}
* {{Z|pam}}: {{W-|pam|pamibaluan}}, {{W-|pam|pangabalu}}
* {{Z|ca}}: {{W+|ca|coneixement|n}}
* {{Z|qu}}: {{W-|qu|riqsiy}}
* {{Z|ky}}: {{W+|ky|билим}}
* {{Z|ko}}: {{W+|ko|지식}}, {{W+|ko|앎}}
* {{Z|la}}: {{W-|la|notitia|m}}, {{W+|la|notio|m}}, {{W-|la|agnitio|m}}, {{W-|la|cognitio|m}}, {{W-|la|intelligentia|m}}
* {{Z|lv}}: {{W-|lv|zināšana|m}}
* {{Z|lo}}: {{W+|lo|ຄວາມຮູ້}}, {{W-|lo|ວິຊາ}}
* {{Z|lt}}: {{W-|lt|žinojimas|n}}, {{W+|lt|mokėjimas|n}}, {{W-|lt|išmanymas|n}}
* {{Z|mk}}: {{W-|mk|знаење|m|sc=Cyrl}}
* {{Z|ms}}: {{W+|ms|pengetahuan}}, {{W+|ms|ilmu}}
* {{Z|mt}}: {{W-|mt|konoxxenza|m}}
* {{Z|mi}}: {{W+|mi|mātauranga}}, {{W-|mi|mōhio ngutu}}
* {{Z|hu}}: {{W+|hu|tudás}}, {{W+|hu|ismeret}}
* {{Z|mn}}: {{W+|mn|эрдэм}}, {{W+|mn|мэдлэг}}
* {{Z|ne}}: {{W-|ne|ज्ञान}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|kunnskap|n}}, {{W-|nb|viten|n}}
*: {{Z|nn}}: {{W-|nn|kunnskap|n}}
* {{Z|oc}}: {{W+|oc|coneissença|m}}
* {{Z|or}}: {{W+|or|ଜ୍ଞାନ}}
* {{Z|ota}}: {{W-|ota|بیلك|tr=bilik}}
* {{Z|ug}}: {{W+|ug|بىلىم}}
* {{Z|uz}}: {{W+|uz|bilim}}, {{W+|uz|bilish}}
* {{Z|pi}}: {{W-|pi|ñāṇa}}, {{W-|pi|vijjā}}
* {{Z|pdt}}: {{W-|pdt|Wissenschoft|m}}
* {{Z|pl}}: {{W+|pl|wiedza|m}}
* {{Z|pt}}: {{W+|pt|conhecimento|n}}
* {{Z|kk}}: {{W-|kk|білім|sc=Cyrl}}, {{W+|kk|ғылым}}
* {{Z|ro}}: {{W+|ro|cunoaștere|m}}, {{W+|ro|știre|m}}
* {{Z|ru}}: {{W+|ru|зна́ние|nt}}, {{W+|ru|осведомлённость|m}}
* {{Z|sa}}: {{W+|sa|ज्ञान}}, {{W+|sa|बुद्धि}}, {{W+|sa|विद्या}}, {{W+|sa|बोध}}
* {{Z|scn}}: {{W-|scn|canuscenza|m}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|знáње|nt}}
*: Latînî: {{W+|sh|znánje|nt}}
* {{Z|syl}}: {{W-|syl|ꠉꠣꠀꠘ|tr=gian}}
* {{Z|sco}}: {{W-|sco|kennin}}
* {{Z|sk}}: {{W-|sk|znalosť|m}}
* {{Z|sl}}: {{W+|sl|znanje}}
* {{Z|es}}: {{W+|es|conocimiento|n}}
* {{Z|su}}: {{W-|su|ᮕᮍᮝᮨᮛᮥᮂ}}
* {{Z|sw}}: {{W+|sw|maarifa}}
* {{Z|sv}}: {{W+|sv|kunskap|g}}
* {{Z|zdj}}: {{W-|zdj|udjuzi|c11}}
* {{Z|tg}}: {{W+|tg|дониш|sc=Cyrl}}, {{W+|tg|маърифат|sc=Cyrl}}
* {{Z|tl}}: {{W-|tl|karunungan|nt}}
* {{Z|ta}}: {{W+|ta|அறிவு|sc=Taml}}, {{W+|ta|ஞானம்}}
* {{Z|th}}: {{W+|th|ความรู้}}, {{W+|th|วิชา}}, {{W+|th|วิทยา}}
* {{Z|te}}: {{W+|te|జ్ఞానము}}, {{W+|te|బోధ}}
* {{Z|tzm}}: {{W-|tzm|ⵜⵓⵙⵙⵏⴰ|m}}
* {{Z|crh}}: {{W-|crh|bilgi}}, {{W-|crh|bilme}}
* {{Z|tt}}: {{W+|tt|белем}}
* {{Z|tr}}: {{W+|tr|bilim}}, {{W+|tr|marifet}}, {{W+|tr|bilgi}}
* {{Z|tk}}: {{W+|tk|bilim}}, {{W-|tk|maglumat}}
* {{Z|bo}}: {{W-|bo|ཤེས་བྱ}}, {{W-|bo|ཡོན་ཏན}}
* {{Z|tpi}}: {{W-|tpi|save}}
* {{Z|txb}}: {{W-|txb|karsalñe}}, {{W-|txb|kärsor}}
* {{Z|uga}}: {{W-|uga|𐎄𐎓𐎚}}
* {{Z|ur}}: {{W-|ur|گیان|tr=gyān|sc=ur-Arab}}, {{W+|ur|علم|tr=ilm|sc=ur-Arab}}
* {{Z|uk}}: {{W+|uk|знання́|nt}}
* {{Z|vi}}: {{W+|vi|tri thức}}
* {{Z|war}}: {{W-|war|kaaram}}
* {{Z|cy}}: {{W+|cy|adnabyddiaeth}}, {{W+|cy|gwybodaeth|m}}
* {{Z|km}}: {{W+|km|ចំណេះ}}, {{W+|km|ញាណ}}, {{W+|km|វិជ្ជា}}
* {{Z|yi}}: {{W-|yi|וויסן|nt}}
* {{Z|el}}: {{W+|el|γνώση|m}}, {{W+|el|αγωγή|m}}
*: {{Z|grc}}: {{W-|grc|γνῶσις|m}}
{{werger-bin}}
{{kontrolWerger}}
6xsb2zas4ia5frhe8tf00ojwhwywnol
karîn
0
3979
6347437
6337904
2026-08-31T19:09:21Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347437
wikitext
text/x-wiki
{{bnr-h|Karîn}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{deng|ku|LL-Q36368 (kur)-Dildadil-karîn.wav|dever=Amed}}
* {{ku-kîte}}
=== Lêker ===
{{ku-tewîn-lk|karîn|form=gerguhêz|niha=kar|borî=karî}}
[[Wêne:Olympic-style weight lifting training.JPG|thumb|Ev kes '''dikarin''' tiştên [[giran]] [[hilgirtin|hilgirin]].]]
{{lêker|ku|c=x-gh}}, {{k-ya nerm}}
# [[hêz|Hêz]] / [[taqet]] yan [[hinêr]] yan [[derfet]] / [[delîv]] yan [[zanîn]] hebûn bo kirina tiştekî.
#: {{hevmane|ku|şiyan}}
#* {{J:Melayê Cizîrî:Dîwana Melayê Cizîrî|jêgirtin=Tu narê firqetê zanî</br>'''Dikarim''' ez tehemmul kim</br>Diyarê kohê Qendîl im}}
# [[qezenc kirin]], [[jê birin]], [[bi ser ketin]]:
#: {{mk|ku|Di avjenîyê de min '''karî''' te.}}
==== Notên bikaranînê ====
{{veşêre-ser|Notên bikaranînê}}
Lêkerên "karîn/kanîn" (anku "şiyan", "hêz hebûn") û "zanîn" bi hin awayan ji lêkerên din yên kurmancî cuda ditewin. Bo nimûne di dema niha de di hin devokan de pêşqertafa "di-" nakeve pêşiya wan. Loma "ez di-kim, tu di-bêjî, ew di-xwe" lê "ez karim, tu zanî, ew kane" (li cihê "ez dikarim, tu dizanî, ew dikane").
Herwiha neyînîkirina wan ne bi "na-" ya giştî lê bi "ni-" ye: Loma "ez na-kim, tu na-çî, ew na-bêje" lê "ez ni-zanim, tu ni-karî, ew nikane".
Herwiha di rewşên din de jî hin cudahî hene. Ji hemû lêkerên din re di raweya şertî de (kondîsyonal yan subjunktîv) bi giştî lêker bi formûlaya "bi- + rehê dema niha + qertafa kesandinê ne": "ez bi-ç-im, tu bi-k-î, ew bi-bêj-e". Ev qaydeya giştî di hin devokan de dîsa li gel lêkerên "karîn/kanîn" û "zanîn" jî li kar e: "ez bi-zan-im, tu bi-kar-î, ew bi-kan-e". Lê di hin devokan de jî ew bi formûlaya "rehê dema niha + -i- + -b- + qertafa kesandinê" tê çêkirin: "ez kar-i-b-im, tu zan-i-bî, ew kan-i-b-e". Di hin devokan de jî îcar ev herdu qayde di heman demê de tên bikaranîn: "ez bi-zan-i-b-im, tu bi-kar-i-bî".
Lê ji van awarteyiyan tenê "ni-" ya neyînîkirinê di kurmancî de di hemû devokan de awrte ye. Lê awarteyiyên din tenê di hin devokan de hene. Devokên din qeydeyên giştî bi kar tînin. Loma divê em di mesela "di-" de li gor qaydeya giştî biçin: "ez dikarim" ne "ez karim". Herwiha ji ber ku "ez bi-zan-im, tu bi-kar-î, ew bi-kan-e" li gor qaydeya giştî ne û formên wek "ez zan-i-bim, tu kar-i-bî, ew kan-i-be" yan jî "ez bi-zan-i-bim, tu bi-kar-i-bî, ew bi-kar-i-be" awarte ne, divê em wek "bizanim, bikarî, bikane" tercih bikin.
Herwiha ev ''karibû'' bi teşeya raboriya dûr ''karîbû'' hemanî nayê lêvandin.
{{veşêre-bin}}
==== Bi alfabeyên din ====
* {{ku-ar|کارین}}
* {{ku-kr|карин}}
==== Formên alternatîv ====
* {{g|ku|kanîn}}
* {{hw|ku|kaynîn||kurmanciya Xorasanê}}
==== Jê ====
{{kol3|ku
|kara
}}
==== Etîmolojî ====
Ji {{ji|hy|ku|-}}{{çp}}, bi ermeniya rojava {{g|hy|կարնալ|tr=arenal/garenal}}, ermeniya rojhilat {{g|hy|կարողանալ|tr=karoġanal}}, têkilî ermeniya kevn {{g|xcl|կարող|tr=karoł|w=[[xurt]], [[bihêz]]}} ji {{g|xcl|կար|tr=kar|w=[[hêz]], [[îmkan]]}}.
{{veşêre-ser}}
Di lêkera ermenî de di nava peyvê de hem "r" û hem jî "n" heye loma di hin devokên kurmancî de "karîn" û di hinan de jî "kanîn" e. Di devokên kurmancî yên dûrî ermenî de û di zaravayên din yên kurdî û di zimanên din yên îranî de peyda nabe loma ihtimala ku ji ermenî be gelekî mezin e. Bi hin devokên kurmancî [[şiyan]] e ku [[hevreh]]a [[şiyan]] ([[mimkin]] bûn) ya soranî, [[şayed]] ya ji farisî û [[şikayene, eşkayene, şayene]] ya zazakî ye. Di soranî de [[tiwanîn]] (rehê dema niha "-tiwan-") e ku hevreha {{g|fa|توانستن|tr=tevanesten}} ya farisî ye ku rehê wê yê dema niha "-tevan-" e. Ne têkilî [[can]] (bixwîne: ken yan kan) ya îngilîzî û hevrehên wê yên zimanên cermenî ye ji ber ku eger ew hevreh bûna, "k" ya proto-hindûewropî divê di kurdî de bûbûya "s" û di zimanên cermenî de jî "h". Idiaya [[Şablon:Beghyani|Beghyani]], ku dibêje ji [[kirin]] e, bi ti [[belge]]yan nehatiye [[peyitandin]]. [[Şablon:Hesendost|Hesendost]] bi xeletî li ber peyva "tevanisten" ya farisî nivîsiye: "kirmaşanî: twanîn, karîn, û: karîn, kan, kanî". Di rastiyê de li ber "karîn, -kan-, kanî" diviyabû ku "kurmancî" hatibûya nivîsîn. Bi Kirmaşanî û lekî [[tüenîn]] / [[tüenisin]] e.
Peyva ermenî jî ji zimanekî gurcî-zanî wergirtiye<ref>Ačaṙean, Hračʿeay (1973), “կռիւ”, in Hayerēn armatakan baṙaran [Armenian Etymological Dictionary] (in Armenian), volume II, 2nd edition, a reprint of the original 1926–1935 seven-volume edition, Yerevan: University Press, rûpel 671b http://www.nayiri.com/imagedDictionaryBrowser.jsp?dictionaryId=7&printPage=671&volume=2</ref>, ji proto-gurcî-zanî {{q|ccs-gzn-pro|*ḳar-|w=[[bestin]]}}, ji proto-kartvelî ''[[*ḳar-]]'' ku bûye [[lazî]] {{g|lzz|ო-კორ-უ|tr=o-ǩor-u|w=bestin}}, mingrelî {{g|xmf|კჷრ-უ-ა|w=bestin}}, gurcî {{g|ka|კრვა|tr=ḳrva}}<ref>Klimov, G. A. (1998) Etymological Dictionary of the Kartvelian Languages (Trends in linguistics. Documentation; 16), New York, Berlin: Mouton de Gruyter, rûpel 86 https://archive.org/details/KlimovEtymological/Klimov?view=theater#page/n102/mode/1up</ref><ref>Fähnrich, Heinz (2007) Kartwelisches Etymologisches Wörterbuch [Kartvelian Etymological Dictionary] (Handbuch der Orientalistik; VIII.18) (in German), Leiden, Boston: Brill, rûpel 222 https://archive.org/details/Fahnrich_2007/page/n221/mode/1up?view=theater</ref>... Ev dikare bê maneya ku ew peyveke substrat a hevpar e ku ketiye ermenî û hin zaravayên kurdî ji zimanên [[Qefqaz]]î, lê ew ne[[vebirî]] ye.
Herwiha bi zimanê [[partî]] hatiye qeydkirin ku lêkera {{q|ku|kirin}} bo diyarkirina [[pêkanî|pêkaniya]] tiştek jî li kar bûye.<ref>Dictionary Of Manichean Middle Persian & Parthian by Durkin-Meisterernst, Desmond, rûpel 206, '''kr-, qr- Pa lkar-1 vtr. "to do, make'. Used as an auxiliary verb following a pp. in the 'potentialis', to indicate a possibility, eg MKG(726i fr'm](r)g kyrd kr'n "if- I could make (her) forgetful"''', https://archive.org/details/DictionaryOfMMP/page/n236/mode/1up?q=could</ref>mînak: "''framereg kird keran''" = (ku min wê) bikariya [[bîroke]] bikim (framereg: [[bîroke]] - ji reha fremûşten/ji bîr kirin / kird: kir - dema bihûrî a sade / keran: bikim - kesê yekjimar ê 1. dema niha a bilanî). Di soranî de jî rrewşa pasîf a lêkera "{{g|ckb|کردن}}" wek hevwateya {{g|ckb|شیان|w=mimkin bûn}} tê bikaranîn (wek "dekirêt rû bidat" = "tê kirin ku rû de" anku [[pêkan]] e ku rû de) an jî "deyekat" = ew wî dike/ew dikare... lê ne wek hevmaneya {{g|ckb|tiwanîn|sc=Latn|w=karîn}}. Anku ne ku di zimanên îranî ên din de peyda nabe, [[nexasma]] di zimanên kurdî de.
{{veşêre-bin}}
==== Werger ====
{{werger-ser}}
* {{Z|sq}}: {{W-|sq|mund}}, {{W+|sq|mundem}}
* {{Z|de}}: {{W+|de|können}}
*: {{Z|gsw}}: {{W-|gsw|chöne}}
* {{Z|an}}: {{W-|an|poder}}
* {{Z|rup}}: {{W-|rup|pot}}
* Assamese:
*: {{Z|as}}: {{W-|as|পাৰা}}
*: {{Z|as}}: {{W-|as|পৰা}}
* {{Z|ast}}: {{W+|ast|poder}}
* {{Z|az}}: {{W+|az|bilmək}}, {{W+|az|bacarmaq}}
* {{Z|eu}}: {{W-|eu|ahal izan}}
* {{Z|be}}: {{W-|be|магчы́|impf}}, {{W-|be|змагчы́|pf}}; {{W-|be|уме́ць|impf}}, {{W-|be|ўмець|impf}}, {{W-|be|суме́ць|pf}}
* {{Z|br}}: {{W-|br|gallout}}
* {{Z|bg}}: {{W-|bg|мо́га|impf}}, {{W-|bg|уме́я|impf}}
* {{Z|my}}: {{W+|my|နိုင်|sc=Mymr}}
* {{Z|cs}}: {{W-|cs|moci}}, {{W-|cs|umět}}
* {{Z|zh}}:
*: {{Z|yue}}: {{W-|yue|識得|tr=sik1 dak1}}
*: {{Z|cmn}}: {{W+|cmn|會|tr=huì}}, {{W+|cmn|能|tr=néng}}, /{{W+|cmn|不了|tr=-buliǎo}}}}, {{W+|cmn|能夠|tr=nénggòu}}
*: {{Z|nan}}: {{W+|nan|會得|tr=ē-tit}}, {{W+|nan|會當|tr=ē-tàng}}, {{W-|nan|會凍|tr=ē-tàng}}
* {{Z|dlm}}: {{W-|dlm|potar}}
* {{Z|da}}: {{W-|da|kunne}}
* {{Z|id}}: {{W+|id|boleh}}, {{W+|id|bisa}}
* {{Z|ar}}: {{W-|ar|قَدَرَ}}, {{W-|ar|اِسْتَطَاعَ}}, {{W-|ar|أَمْكَنَ}}
*: {{Z|arz}}: {{W-|arz|قدر|tr=ʾadar|sc=Arab}}
* {{Z|hy}}: {{W+|hy|կարողանալ}}, {{W+|hy|կրնալ}}
* {{Z|eo}}: {{W+|eo|povi}}
* {{Z|et}}: {{W-|et|osata}}, {{W-|et|võima}}
* {{Z|fa}}: {{W-|fa|توانستن|tr=tavânestan}}, {{W-|fa|قادر بودن}}
* {{Z|fo}}: {{W+|fo|kunna}}
* {{Z|fi}}: {{W+|fi|osata}}, {{W+|fi|voida}}, {{W+|fi|pystyä}}
* {{Z|frp}}: {{W-|frp|povêr}}, {{W-|frp|possêr}}
* {{Z|fr}}: {{W+|fr|pouvoir}}
* {{Z|fur}}: {{W-|fur|podê}}
* {{Z|frr}}: {{W-|frr|koone}}, {{W-|frr|kön}}, {{W-|frr|kan}}
* {{Z|ofs}}: {{W-|ofs|kunna}}
* {{Z|stq}}: {{W-|stq|konne}}
* {{Z|gd}}: {{W-|gd|'s urrainn do}}, {{W-|gd|faod}}
* {{Z|gl}}: {{W+|gl|poder}}
* {{Z|roa-gal}}: {{W-|roa-gal|póeir}}
* {{Z|got}}: {{W-|got|𐌼𐌰𐌲𐌰𐌽}}, {{W-|got|𐌺𐌿𐌽𐌽𐌰𐌽}}
* {{Z|ka}}: {{W-|ka|შეუძლია}}
* {{Z|ht}}: {{W-|ht|ka}}, {{W-|ht|kapab}}, {{W-|ht|kab}}
* {{Z|hi}}: {{W-|hi|सकना}}, {{W-|hi|समर्थ होना}}
* {{Z|nl}}: {{W+|nl|kunnen}}, {{W+|nl|vermogen}}
* {{Z|he}}: {{W+|he|יכול|n|tr=yakhól|cuda=יכול / יָכֹל}}, {{W-|he|מסוגל|n|tr=m'sugál|cuda=מסוגל / מְסֻגָּל}}
* {{Z|ang}}: {{W-|ang|magan}}, {{W-|ang|cunnan}}
* {{Z|ga}}: {{W-|ga|is féidir le}}, {{W-|ga|tig le}}, {{W-|ga|féad}}, {{W-|ga|bí}} {{W-|ga|in ann}}
*: {{Z|sga}}: {{W-|sga|con·icc}}
* {{Z|it}}: {{W+|it|potere}}, {{W+|it|riuscire}}, {{W+|it|sapere}}
* {{Z|is}}: {{W+|is|geta}}
* {{Z|ja}}: {{W+|ja|できる|tr=dekiru|sc=Jpan}}, {{W+|ja|れる|cuda=-れる|tr=-reru|sc=Jpan}}, {{W+|ja|られる|cuda=-られる|tr=-rareru|sc=Jpan}}
* {{Z|kn}}: {{W+|kn|ಬಹುದು}}
* {{Z|ca}}: {{W-|ca|poder}}, {{W-|ca|poguer}}
* {{Z|qu}}: {{W+|qu|atiy}}
* {{Z|gil}}: {{W-|gil|kona}}
* {{Z|ko}}: {{W-|ko|수|cuda=...을/ᄅ 수 있다|tr=...-l su itda}}, {{W+|ko|eu}}
* {{Z|kw}}: {{W-|kw|gallos}}
* {{Z|la}}: {{W+|la|possum}}, {{W-|la|queo}}, {{W+|la|scio}}
* {{Z|lv}}: {{W+|lv|prast}}, {{W+|lv|spēt}}, {{W+|lv|varēt}}
* {{Z|lo}}: {{W-|lo|ໄດ້}}
* {{Z|lt}}: {{W+|lt|galėti}}
* {{Z|liv}}: {{W-|liv|mȯistõ}}, {{W-|liv|võidõ}}
* {{Z|khb}}: {{W-|khb|ᦺᦡᧉ}}
* {{Z|lb}}: {{W+|lb|kënnen}}
* {{Z|mk}}: {{W-|mk|може}}
* {{Z|ml}}: {{W-|ml|കഴിയും}}
* {{Z|ms}}: {{W-|ms|dapat}}, {{W-|ms|boleh}}, {{W+|ms|bisa}}
* {{Z|mt}}: {{W-|mt|seta'}}
* {{Z|gv}}: {{W-|gv|jarg}}
* {{Z|hu}}: {{W+|hu|tud}}, {{W+|hu|képes}}
* {{Z|mn}}: {{W+|mn|чадах}}, {{W-|mn|ᠴᠢᠳᠠᠬᠤ}}
* {{Z|nah}}: {{W-|nah|huelīti}}
* {{Z|nap}}: {{W-|nap|putè}}
* {{Z|nds}}: {{W-|nds|könen}}
* {{Z|no}}: {{W+|no|kunne}}
* {{Z|oc}}: {{W-|oc|pòder}}, {{W-|oc|podre}}
* {{Z|ppl}}: {{W-|ppl|weli}}, {{W-|ppl|hueli}}
* {{Z|pl}}: {{W+|pl|móc}}, {{W+|pl|umieć}}, {{W+|pl|potrafić}}
* {{Z|pt}}: {{W+|pt|conseguir}}, {{W+|pt|saber}}
* {{Z|rm}}: {{W-|rm|pudair}}, {{W-|rm|puder}}, {{W-|rm|pudeir}}
* {{Z|ro}}: {{W+|ro|putea}}
* {{Z|ru}}: {{W+|ru|мочь|impf}}, {{W+|ru|смочь|pf}}, {{W-|ru|уме́ть|impf}}, {{W-|ru|быть в состоя́нии}}
* {{Z|osx}}: {{W-|osx|kunnan}}
* {{Z|sc}}: {{W-|sc|podere}}, {{W-|sc|podi}}, {{W-|sc|podiri}}, {{W-|sc|pori}}, {{W-|sc|porrere}}, {{W-|sc|potere}}
* {{Z|scn}}: {{W+|scn|putiri}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|моћи}}, {{W-|sh|умети}}, {{W-|sh|умјети}}
*: Latînî: {{W+|sh|moći}}, {{W+|sh|umeti}}, {{W+|sh|umjeti}}
* {{Z|syl}}: {{W-|syl|ꠙꠣꠞꠣ}}
* {{Z|sk}}: {{W-|sk|môcť}}
* {{Z|sl}}: {{W+|sl|moči}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|móc}}
* {{Z|es}}: {{W+|es|poder}}, {{W+|es|saber}}
* {{Z|sv}}: {{W+|sv|kunna}}
* {{Z|zdj}}: {{W-|zdj|djua|cuda=udjua}}
* {{Z|ta}}: {{W-|ta|செய்யக்கூடிய}}
* {{Z|th}}: {{W+|th|ได้}}, {{W+|th|ย่อม}}, {{W+|th|สามารถ}}
* {{Z|otk}}: {{W-|otk|𐰆|ts=u-}}
* {{Z|tr}}: {{W+|tr|-ebilmek}}, {{W+|tr|-abilmek}} {{W+|tr|yenmek}}
* {{Z|txb}}: {{W-|txb|yāt-}}
* {{Z|ur}}: {{W-|ur|سکنا|tr=saknā|sc=ur-Arab}}
* {{Z|uk}}: {{W-|uk|могти́|impf}}, {{W-|uk|змогти́|pf}}; {{W-|uk|вмі́ти|impf}}, {{W-|uk|умі́ти|impf}}, {{W-|uk|зумі́ти|pf}}
* {{Z|vec}}: {{W-|vec|poder}}
* {{Z|vi}}: {{W+|vi|có thể}}, {{W+|vi|được}}
* {{Z|wa}}: {{W+|wa|poleur}}, {{W+|wa|saveur}}, {{W+|wa|sawè}}
* {{Z|cy}}: {{W+|cy|gallu}}, {{W+|cy|medru}}
* {{Z|km}}: {{W+|km|បាន|tr=baan}}
* {{Z|yi}}: {{W-|yi|קענען}}
* {{Z|esu}}: {{W-|esu|-yugnga}}
* {{Z|el}}: {{W+|el|μπορώ}}, {{W+|el|δύναμαι}}
*: {{Z|grc}}: {{W-|grc|δύναμαι}}
* {{Z|za}}: {{W-|za|maenz}}
* {{Z|ase}}: {{W-|ase|S@Sternumhigh-PalmDown-S@Sternumhigh-PalmDown S@Chesthigh-PalmDown-S@Chesthigh-PalmDown}}
{{werger-bin}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[şiyan]], [[taqet]], [[hêz]], [[qudret]]
#* {{mk|ku|Bi serketinê wî '''karîna''' xwe nîşan da.}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Werger ====
{{werger-ser}}
* {{Z|tr}}: {{W|tr|edebilme}}, {{W|tr|yapabilme}}, {{W|tr|güç}}, {{W|tr|kudret}}, {{W|tr|erk}}, {{W|tr|yapabilme}}, {{W|tr|nüfuz}}
{{werger-bin}}
{{bend}}
=== Lêker 2 ===
{{lêker|ku|c=x-ngh}}
# [[girîn]]
#: {{mk|ku|Çêla zer ji birsan '''karî'''.}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|en}}: {{W|en|cry}}
* {{Z|tr}}: {{W|tr|ağlamak}}
{{werger-bin}}
=== Çavkanî ===
{{çavkanî}}
ga3nsuggqx79kjllw654k09c06l3hph
meh
0
4030
6347436
6337910
2026-08-31T19:08:45Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347436
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# 30 [[roj]], 1/12 ji [[sal]]ê, <br>[[heyam]]ek anku [[dem]]ek ji 30 yan 31 rojan pêkhatî (lê meha 2yem ji [[salname]]ya romî 28 yan 29 roj e.)
#: {{nm|ku|12 '''meh''' dibin salek.}}
#: {{nm|ku|Her demsalek ji sê '''meh'''an pêk tê.}}
#* {{J:Melayê Cizîrî:Dîwana Melayê Cizîrî|jêgirtin=Ta çend-i bi hecra xwe tu min tecribe înî</br>Zêrê ji xwe xalis '''meh'''ek û gaz-i çi hacet}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Notên bikaranînê ====
Di hin devokên kurmancî de peyva "meh" nayê bikaranîn. Bi mebesta "30 roj" jî peyva "heyv/hîv" di wan devokan de tê xebitandin.
==== Formên alternatîv ====
{{kol3|ku
|ma
|mah
|mehe
}}
==== Hevmane ====
{{kol3|ku
|heyv
|hîv
|mang
}}
==== Jê ====
{{kol3|ku
|mehane
|mehik
|mehî
|mehname
}}
==== Etîmolojî ====
{{ji|ine-pro|ku|-}}: *'''mē'''- ("[[pîvan]]") > *'''me(n)ses'''- ("heyv")
* {{ji|ine-pro|ku|-}}: *'''mē'''- ("[[pîvan]]") > *'''me(n)ses'''- ("heyv")
::{{ae}}: '''māh'''- ("heyv, meh")
::{{peo}}: '''māh'''- ("heyv, meh")
::{{fa}}: '''māh''' ("heyv, meh")
::{{bal}}: '''māh''' ("heyv, meh")
::{{os}}: '''māyā''' ("heyv, meh") ... {{ir}}
::{{kmr}}: '''meh''' ("meh")
::{{ckb}}: '''mang''' ("heyv, meh")
::{{hac}}: '''mānga''' ("heyv, meh")
::{{zza}}: '''[[mang]]''' ("heyv, meh")
:{{sa}}: '''mas'''- ("heyv, meh")
:{{el}}: '''mene''' ("heyv, meh")
:{{la}}: '''mensis''' ("heyv, meh")
:{{hy}}: '''mis''' ("heyv")
:{{de}}: '''Mond''' ("heyv")
:{{en}}: '''moon''' ("heyv") '''[[month]]''' ("meh") ...
Di kurmancî de āh -> eh berbelav e, bide ber [[-geh]], [[xweh]], [[şeh]] ...
Hevreha ''[[heyv]], [[pîvan]]''.
;{{biçûk|Çavkanî:
* {{Horn|r=216}}
* {{Watkins|r=51}}
* {{MacKenzie|r=129}},
* {{Etymonline|Etymonline}}
}}
==== Bi zaravayên din ====
* {{Z|ckb}}: [[mang]]
==== Werger ====
{{werger-ser}}
* {{Z|ab}}: {{W-|ab|амза}}
* {{Z|ady}}: {{W-|ady|мазэ}}
* {{Z|af}}: {{W+|af|maand}}
* {{Z|ak}}: {{W-|ak|abosome}}
* {{Z|sq}}: {{W+|sq|muaj|n}}
* {{Z|de}}: {{W-|de|Monat|n}}
* {{Z|alt}}: {{W-|alt|ай}}
* {{Z|am}}: {{W-|am|ወር}}
* {{Z|amu}}: {{W-|amu|chi'}}
* {{Z|arc}}:
*: {{Z|aii}}: {{W-|aii|ܝܲܪܚܵܐ|n|tr=yārḳa}}
*: {{Z|syc}}: {{W-|syc|ܝܪܚܐ|n|tr=yarḥā}}
*: Aramiya cihû: {{W-|arc|יַרְחָא|n|tr=yarḥā|sc=Hebr}}
* {{Z|rup}}: {{W+|rup|mes|n}}, {{W-|rup|lunã|m}}
* {{Z|as}}: {{W-|as|মাহ}}
* {{Z|ast}}: {{W+|ast|mes|n}}
* {{Z|av}}: {{W-|av|моцӏ}}
* {{Z|az}}: {{W+|az|ay}}
* {{Z|ban}}: {{W-|ban|bulan}}, {{W-|ban|sasi}}
* {{Z|eu}}: {{W-|eu|hil}}, {{W-|eu|hilabete}}
* {{Z|ba}}: {{W-|ba|ай}}
* {{Z|be}}: {{W-|be|ме́сяц|n}}
* {{Z|bal}}: {{W-|bal|ماہ|tr=máh}}
* {{Z|bn}}: {{W+|bn|মাস}}, {{W+|bn|মাহ}}
* {{Z|br}}: {{W+|br|miz|n}}, {{W+|br|mizvezh|n}}
* {{Z|kxd}}: {{W-|kxd|bulan}}
* {{Z|bg}}: {{W-|bg|ме́сец|n}}
* {{Z|my}}: {{W-|my|လ}}
* {{Z|bua}}: {{W-|bua|һара}}
* {{Z|pcc}}: {{W-|pcc|ndianl}}
* {{Z|ch}}: {{W-|ch|pulan}}
* {{Z|ce}}: {{W-|ce|бутт}}
* {{Z|cs}}: {{W-|cs|měsíc|n}}
* {{Z|chr}}: {{W-|chr|ᏏᏅᏙ|sc=Cher}}, {{W-|chr|ᎧᎸᎢ}}
* {{Z|ny}}: {{W-|ny|mwezi}}
* {{Z|zh}}:
*: {{Z|yue}}: {{W-|yue|月|tr=jyut6}}
*: {{Z|dng}}: {{W-|dng|йүә}}
*: {{Z|cmn}}: {{W-|cmn|月|tr=yuè}}, {{W-|cmn|月份|tr=yuèfèn}}
*: {{Z|nan}}: {{W+|nan|月|tr=ge̍h / goe̍h}}
* {{Z|cv}}: {{W-|cv|уйӑх}}
* {{Z|dlm}}: {{W-|dlm|mais|n}}
* {{Z|da}}: {{W-|da|måned|g}}
* {{Z|dtp}}: {{W-|dtp|wulan}}
* {{Z|id}}: {{W+|id|bulan}}
* {{Z|ar}}: {{W-|ar|شَهْر|n}}
*: {{Z|arz}}: {{W-|arz|شهر|n|tr=šahr}}
*: {{Z|afb}}: {{W-|afb|شهر|n|tr=šahar}}
*: {{Z|acw}}: {{W-|acw|شهر|n|tr=šahar}}
*: {{Z|ary}}: {{W-|ary|شهر|n|tr=šhar}}
*: {{Z|ajp}}: {{W-|ajp|شهر|n|tr=šáher}}
* {{Z|hy}}: {{W-|hy|ամիս}}
*: {{Z|xcl}}: {{W-|xcl|ամիս}}
* {{Z|myv}}: {{W-|myv|ков}}
* {{Z|eo}}: {{W-|eo|monato}}
* {{Z|et}}: {{W-|et|kuu}}
* {{Z|ee}}: {{W-|ee|dzinu}}, {{W-|ee|ɣleti}}
* {{Z|fa}}: {{W-|fa|ماه|tr=mâh}}
* {{Z|fo}}: {{W-|fo|mánaður|n}}
* {{Z|fi}}: {{W-|fi|kuukausi}}, {{W+|fi|kuu}}
* {{Z|fr}}: {{W-|fr|mois|n}}
* {{Z|fur}}: {{W-|fur|mês|n}}
* {{Z|frr}}: {{W-|frr|moune}}; {{W-|frr|muun|n}}
* {{Z|stq}}: {{W-|stq|Mound}}
* {{Z|fy}}: {{W-|fy|moanne|g}}
* {{Z|gd}}: {{W-|gd|mìos|n}}
* {{Z|gl}}: {{W+|gl|mes|n}}
* {{Z|gdo}}: {{W-|gdo|пурццу}}
* {{Z|got}}: {{W-|got|𐌼𐌴𐌽𐍉𐌸𐍃|n}}
* {{Z|gu}}: {{W+|gu|મહિનો|n}}
* {{Z|ka}}: {{W-|ka|თვე}}
* {{Z|ht}}: {{W-|ht|mwa}}
* {{Z|haw}}: {{W-|haw|mahina}}
* {{Z|ha}}: {{W+|ha|wata}}
* {{Z|hi}}: {{W+|hi|महीना|n}}, {{W+|hi|मास|n}}, {{W+|hi|माह|n}}
* {{Z|hil}}: {{W-|hil|bulan}}
* {{Z|mww}}: {{W-|mww|hli}}
* {{Z|nl}}: {{W+|nl|maand|m}}
* {{Z|he}}: {{W+|he|חודש|n|cuda=חודש \ חֹדֶשׁ|tr=khódesh}}
* {{Z|io}}: {{W+|io|monato}}
* {{Z|ilo}}: {{W-|ilo|bulan}}
* {{Z|ang}}: {{W-|ang|mōnaþ|n}}
* {{Z|enm}}: {{W-|enm|moneth}}
* {{Z|en}}: {{W+|en|month}}
* {{Z|inh}}: {{W-|inh|бутт}}
* {{Z|ia}}: {{W-|ia|mense}}
* {{Z|iu}}: {{W-|iu|ᑕᖅᕿᖅ}}
* {{Z|ga}}: {{W-|ga|mí|m}}
* {{Z|ist}}: {{W-|ist|miz}}
* {{Z|it}}: {{W+|it|mese|n}}
* {{Z|is}}: {{W+|is|mánuður}}
* {{Z|ja}}: {{W+|ja|月|tr=つき, tsuki|sc=Jpan}}, {{W+|ja|月間|tr=げっかん, gekkan|sc=Jpan}}
* {{Z|jv}}: {{W+|jv|sasi}}
* {{Z|kbd}}: {{W-|kbd|мазэ}}
* {{Z|kab}}: {{W-|kab|ayyur|n}}
* {{Z|xal}}: {{W-|xal|сар}}
* {{Z|kn}}: {{W+|kn|ಮಾಸ}}, {{W+|kn|ತಿಂಗಳು}}
* {{Z|cak}}: {{W-|cak|ik’}}
* {{Z|krl}}: {{W-|krl|kuu}}
* {{Z|csb}}: {{W-|csb|miesąc|n}}
* {{Z|ca}}: {{W+|ca|mes|n}}
* {{Z|ks}}: {{W-|ks|رؠتھ}}
* {{Z|kjg}}: {{W-|kjg|ເນື່ອນ}}
* {{Z|ky}}: {{W+|ky|ай}}
* {{Z|ki}}: {{W-|ki|mweri|c3}}
* {{Z|si}}: {{W+|si|මාසය|sc=Sinh}}
* {{Z|ko}}: {{W+|ko|달}}, {{W+|ko|월}}
* {{Z|kw}}: {{W-|kw|mis|n}}
* {{Z|co}}: {{W-|co|mese|n}}
* {{Z|lld}}: {{W-|lld|meis}}, {{W-|lld|mens}}, {{W-|lld|mëns}}
* {{Z|la}}: {{W+|la|mensis|n}}
* {{Z|lv}}: {{W-|lv|mēnesis|n}}
* {{Z|lo}}: {{W+|lo|ເດືອນ}}
* {{Z|lez}}: {{W-|lez|варз|sc=Cyrl}}
* {{Z|lij}}: {{W-|lij|méize|n}}
* {{Z|lt}}: {{W+|lt|mėnuo|n}}
* {{Z|liv}}: {{W-|liv|kū}}
* {{Z|lmo}}: {{W-|lmo|mes|n}}
* {{Z|mk}}: {{W-|mk|месец|n|sc=Cyrl}}
* {{Z|ml}}: {{W+|ml|മാസം}}
* {{Z|ms}}: {{W+|ms|bulan}}, {{W-|ms|purnama}}
* {{Z|mt}}: {{W+|mt|xahar|n}}
* {{Z|mnc}}: {{W-|mnc|ᠪᡳᠶᠠ}}
* {{Z|mni}}: {{W-|mni|ꯊꯥ}}
* {{Z|mi}}: {{W-|mi|marama}}
* {{Z|mrw}}: {{W-|mrw|bolan}}
* {{Z|mr}}: {{W+|mr|महिना}}
* Marî:
*: {{Z|mrj}}: {{W-|mrj|тӹлзӹ}}
* {{Z|hu}}: {{W+|hu|hónap}}
* {{Z|mn}}: {{W+|mn|сар|sc=Cyrl}}
* {{Z|wmw}}: {{W-|wmw|mwezi}}
* {{Z|nci}}: {{W-|nci|mētztli}}
* {{Z|niq}}: {{W-|niq|arawa}}
* {{Z|nv}}: {{W-|nv|náhidizídígíí}}, {{W-|nv|náhidizííd}}, {{W-|nv|yiził}}
* {{Z|nds}}:
*: {{Z|nds-nl}}: {{W-|nds-nl|maond}}
*: {{Z|nds-de}}: {{W-|nds-de|Maand|n}}, {{W-|nds-de|Monat|n}}
* {{Z|ne}}: {{W-|ne|महिना}}
* {{Z|nrf}}: {{W-|nrf|mais|n}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|måned|n}}
*: {{Z|nn}}: {{W+|nn|månad|n}}
* {{Z|css}}: {{W-|css|hemetscha char}}
* {{Z|oj}}: {{W-|oj|giizis}}
* {{Z|oc}}: {{W+|oc|mes}}
* {{Z|or}}: {{W+|or|ମାସ}}
* {{Z|om}}: {{W-|om|baatii}}
* {{Z|os}}: {{W-|os|мӕй|sc=Cyrl}}
* {{Z|ug}}: {{W+|ug|ئاي}}
* {{Z|uz}}: {{W+|uz|oy}}
* {{Z|blk}}: {{W-|blk|လာ}}
* {{Z|pap}}: {{W-|pap|luna}}
* {{Z|bxd}}: {{W-|bxd|la̠³⁵}}, {{W-|bxd|lɛ̠̃³⁵ma³¹}}
* {{Z|ps}}: {{W+|ps|مياشت|n|tr=myāšt}}
* {{Z|ppl}}: {{W-|ppl|metzti}}
* {{Z|pdt}}: {{W-|pdt|Moonat|m}}
* {{Z|pl}}: {{W+|pl|miesiąc|m-in}}
* {{Z|pt}}: {{W+|pt|mês|n}}
* {{Z|pa}}: {{W-|pa|ਮਹੀਨਾ}}
* {{Z|kk}}: {{W-|kk|ай|sc=Cyrl}}
* {{Z|cop}}: {{W-|cop|ⲁⲃⲟⲧ|n|tr=ɑouːt}}, {{W-|cop|ⲉⲃⲟⲧ|n|tr=aouːt}}, {{W-|cop|ⲁⲃⲏⲧ|p|tr=ɑouat}}, {{W-|cop|ⲉⲃⲁⲧⲉ|p|tr=aouɑda}}
* {{Z|rm}}: {{W-|rm|mais|n}}
* {{Z|rom}}: {{W-|rom|masek|n}}, {{W-|rom|ćhon|n}}
* {{Z|ro}}: {{W+|ro|lună|m}}
* {{Z|ru}}: {{W-|ru|ме́сяц|n}}
* {{Z|rue}}: {{W-|rue|мі́сяць|n}}
* {{Z|ksw}}: {{W-|ksw|လါ}}
* {{Z|se}}: {{W-|se|mánotbadji}}
* {{Z|smn}}: {{W-|smn|mánuppaje}}
* {{Z|sms}}: {{W-|sms|mään}}, {{W-|sms|määnpââ´jj}}
* {{Z|sa}}: {{W+|sa|मास}}
* {{Z|sc}}: {{W-|sc|mese}}, {{W-|sc|mesi}}
* {{Z|scn}}: {{W+|scn|misi|n}}
* {{Z|szl}}: {{W-|szl|mjeśůnc|n}}
* {{Z|sd}}: {{W-|sd|مهنو}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|ме̏се̄ц|n|sc=Cyrl}}, {{W-|sh|мје̏се̄ц|n|sc=Cyrl}}
*: Latînî: {{W+|sh|mȅsēc|n}}, {{W+|sh|mjȅsēc|n}}
* {{Z|cu}}:
*: Kirîlî: {{W-|cu|мѣсѧць|n}}
* {{Z|orv}}: {{W-|orv|мѣсѧць|n}}
* {{Z|sk}}: {{W+|sk|mesiac|n}}
* {{Z|sl}}: {{W+|sl|mésec|n}}
* {{Z|so}}: {{W+|so|bil}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|mjasec|n}}
*: {{Z|hsb}}: {{W+|hsb|měsac|n}}
* {{Z|st}}: {{W+|st|kgwedi}}
* {{Z|es}}: {{W-|es|mes|n}}
* {{Z|su}}: {{W-|su|sasih}}
* {{Z|sw}}: {{W+|sw|mwezi|c3|c4}}
* {{Z|sv}}: {{W+|sv|månad|g}}
* {{Z|xsr}}: {{W-|xsr|ལའ|tr=laa}}
* {{Z|tab}}: {{W-|tab|ваз}}
* {{Z|tg}}: {{W+|tg|моҳ|sc=Cyrl}}
* {{Z|tl}}: {{W+|tl|buwan}}
* {{Z|ta}}: {{W+|ta|மாதம்}}, {{W+|ta|மாசம்}}, {{W+|ta|திங்கள்}}
* {{Z|th}}: {{W+|th|เดือน}}, {{W+|th|มาส}}
* {{Z|te}}: {{W+|te|నెల}}, {{W+|te|మాసము}}
* {{Z|tzm}}: {{W-|tzm|ⵢⵓⵔ}}
* {{Z|crh}}: {{W-|crh|ay}}
* {{Z|tt}}: {{W+|tt|ай|sc=Cyrl}}
* {{Z|ti}}: {{W-|ti|ወርሒ}}
* {{Z|tr}}: {{W+|tr|ay}}
* {{Z|tk}}: {{W+|tk|aý}}
* {{Z|bo}}: {{W-|bo|ཟླ}}
* {{Z|tpi}}: {{W-|tpi|mun}}
* {{Z|xto}}: {{W-|xto|mañ}}
* {{Z|txb}}: {{W-|txb|meñe}}
* {{Z|tyv}}: {{W-|tyv|ай}}
* {{Z|uga}}: {{W-|uga|𐎊𐎗𐎃}}
* {{Z|ur}}: {{W-|ur|مہینا|n|tr=mahīnā|sc=ur-Arab}}, {{W-|ur|مہینہ|n|tr=mahīnah|sc=ur-Arab}}, {{W-|ur|ماہ|n|tr=māh|sc=ur-Arab}}, {{W-|ur|ماس|n|tr=mās|sc=ur-Arab}}
* {{Z|uk}}: {{W-|uk|мі́сяць|n}}
* {{Z|vec}}: {{W-|vec|méxe}}
* {{Z|vep}}: {{W-|vep|ku}}
* {{Z|vi}}: {{W+|vi|tháng}} ({{W-|vi|𣎃|sc=Hani}})
* {{Z|vo}}: {{W+|vo|mul}}
* {{Z|cy}}: {{W+|cy|mis}}
* {{Z|km}}: {{W+|km|ខែ}}
* {{Z|yai}}: {{W-|yai|моҳ}}
* {{Z|sah}}: {{W-|sah|ый}}
* {{Z|yi}}: {{W+|yi|חודש|tr=khóydesh|n}}, {{W-|yi|מאָנאַט|n|sc=Hebr}}
* {{Z|el}}: {{W+|el|μήνας|n}}
*: {{Z|grc}}: {{W-|grc|μήν|n}}
*: {{Z|gmy}}: {{W-|gmy|𐂵}}
* {{Z|za}}: {{W-|za|ndwen}}
* {{Z|ase}}: {{W-|ase|1@TipFinger-PalmBack-1@CenterChesthigh-FingerUp 1@BaseThumb-PalmBack-1@CenterChesthigh-FingerUp}}
* {{Z|zu}}: {{W+|zu|inyanga|c9|c10}}
{{werger-bin}}
=== Navdêr 2 ===
{{navdêr|ku|z=m}}
# {{f|ku|Ûrmîye}} [[mey]], [[bade]], [[şerab]]
#* {{bêmînak|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|fa}}: {{W|fa|می}}, {{W|fa|باده}}, {{W|fa|شراب}}
* {{Z|en}}: {{W|en|wine}}
* {{Z|tr}}: {{W|tr|şarap}}
{{werger-bin}}
== {{ziman|en}} ==
=== Bilêvkirin ===
* {{deng|en|en-us-meh.ogg|dever=DYA}}
* {{deng|en|en-au-meh.ogg|dever=Awistralya}}
=== Rengdêr ===
{{rengdêr|en}}
# [[bêkeyf]], [[bêcoş]]
#* {{bêmînak|en}}
== {{ziman|za}} ==
=== Navdêr ===
{{navdêr|za}}
# {{f|za|malbat}} [[dayik#ku|dayik]], [[dê#ku|dê]]
#* {{bêmînak|za}}
lb6246yj6mmlmo8ziy85daonyl6m16i
zeman
0
4107
6347615
6337919
2026-09-01T11:30:41Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347615
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/zɛˈmɑːn/}}
* {{kîte|ku|ze|man}}
=== Navdêr ===
{{navdêr|ku|z=n}}
# [[dem]], [[çax]], [[heyam]], [[serdem]], [[wext]]
#* {{bêmînak|ku}}
==== Ji wêjeya klasîk ====
* {{J:Feqiyê Teyran|jêgirtin=87. Dibarît ar ji asmana</br>'''Zeman'''ê çerx û dewrana (X.)</br>88. a- Ne bixur e ne Bulxar e (X.)}}
==== Notên bikaranînê ====
* '''çi zemanî''': [[kengî]]
* '''wî zemanî''': [[hingê]]
* '''zemanê berê''':
==== Bi alfabeyên din ====
* {{ku-ar|زهمان}}
==== Formên alternatîv ====
{{kol3|ku
|zaman
|deman<crz:2>
}}
==== Etîmolojî ====
Ji {{ji|fa|ku|زمان|tr=zeman}}, hevreha {{q|ku|jem}} û {{hv|ckb|ژەمەن|tr=jemen|w=dana xwarinê, [[jiyar]], [[rizq]]}}, {{hv|xpr|tr=jeman}}, {{q|xpr|tr=çemen|w=saet}}, {{hv|peo|tr=cemana}} (>[[akadî]] {{q|akk|𒋛𒈠𒉡|tr=si-ma-nu}}, >>[[aramî]] {{q|arc-imp|𐡆𐡌𐡍}}), ji {{ji|ira-pro|ku|*ǰámaHnaH|tr=cemehneh}}, ji {{ji|iir-pro|ira-pro|*ǰámaHnas}}, ji {{q|iir-pro|*ǰámati|w=hatin}} ku forma han e ku guherîna /g/>/c/ pêkhatiye û hevreha {{q|ku|hatin}} e. Bo guherîna ji wateya ''hatin'' bi ''dem'' bide ber {{q|ku|gav}}.
==== Bi zaravayên din ====
* {{Z|ckb}}: [[kat]]
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W+|af|tyd}}
* {{Z|de}}: {{W+|de|Zeit}} {{mê}}, {{W+|de|Ära|f|guman=erê}}
* {{Z|be}}: {{W-|be|час}}
* {{Z|br}}: {{W+|br|amzer}}
* {{Z|bg}}: {{W+|bg|време}}
* {{Z|cs}}: {{W+|cs|čas}}
* {{Z|zh}}: {{W+|zh|時間|sc=Hani}}, {{W+|zh|时间|tr=shíjiān}}, {{W+|zh|時光|sc=Hani}}, {{W+|zh|时光|tr=shíguāng}}
* {{Z|da}}: {{W+|da|tid}}
* {{Z|ar}}: {{W+|ar|وقت}}, {{W+|ar|زمن|tr=zeman}} {{n}}, {{W+|ar|عصر|guman=erê}}, {{W-|ar|عهد|guman=erê}}, {{W-|ar|الأوجس|guman=erê}}, {{W-|ar|الحرس|guman=erê}}, {{W-|ar|العجاف|guman=erê}}, {{W-|ar|الملا|guman=erê}}, {{W-|ar|المنون|guman=erê}}, {{W-|ar|نفس الساعة|guman=erê}}
* {{Z|hy}}: {{W+|hy|ժամանակ|tr=žamanak}}
* {{Z|eo}}: {{W+|eo|tempo}}
* {{Z|et}}: {{W+|et|aeg}}
* {{Z|ee}}: {{W-|ee|ɣeyiɣi}}
* {{Z|fa}}: {{W+|fa|زمان}}, {{W+|fa|وقت}}
* {{Z|fi}}: {{W+|fi|aika}}
* {{Z|fro}}: {{W-|fro|tans}} {{n}}
* {{Z|fr}}: {{W+|fr|temps}} {{n}}
* {{Z|fy}}: {{W+|fy|tiid}}
* {{Z|gd}}: {{W-|gd|àm}} {{n}}
* {{Z|gl}}: {{W+|gl|vez}}
* {{Z|ka}}: {{W+|ka|დრო}}
* {{Z|hi}}: {{W+|hi|समय}}
* {{Z|nl}}: {{W+|nl|tijd}} {{n}}
* {{Z|he}}: {{W+|he|זמן}}
* {{Z|en}}: {{W+|en|time}}, {{W+|en|epoch}}, {{W+|en|era}}, {{W+|en|age|guman=erê}}
* {{Z|it}}: {{W+|it|tempo}} {{n}}
* {{Z|is}}: {{W+|is|tími}}, {{W+|is|tíð}} {{mê}}
* {{Z|ja}}: {{W+|ja|時間|tr=jikan}}, {{W+|ja|じかん|tr=jikan}}, {{W+|ja|時|tr=toki}}, {{W+|ja|とき|tr=toki}}
* {{Z|ca}}: {{W+|ca|temps}} {{n}}
* {{Z|ko}}: {{W+|ko|시간|tr=sigan}}
* {{Z|la}}: {{W+|la|tempus}} {{nt}}
*: {{Z|lv}}: {{W+|lv|laiks}} {{n}}
* {{Z|mk}}: {{W-|mk|време|tr=vréme}} {{nt}}
* {{Z|ml}}: {{W+|ml|സമയം|tr=samayam}}
* {{Z|mt}}: {{W-|mt|darba}}
* {{Z|mi}}: {{W+|mi|tāima}}, {{W-|mi|wā}}
* {{Z|hu}}: {{W+|hu|idő}}
* {{Z|nan}}: {{W+|nan|時間|tr=sî-kan}}, {{W-|nan|时间|tr=sî-kan}}
* {{Z|nah}}: {{W-|nah|cāhuitl}}
* {{Z|nv}}: {{W-|nv|ookił}}
* {{Z|non}}: {{W-|non|tíð}} {{mê}}
* {{Z|no}}: {{W+|no|tid}} {{n}}
* {{Z|pl}}: {{W+|pl|czas}} {{n}}
* {{Z|pt}}: {{W+|pt|tempo}} {{n}}
* {{Z|ru}}: {{W+|ru|время|tr=vrémja}} {{nt}}
* {{Z|sh}}: {{W+|sh|vrijeme}} {{nt}}
* {{Z|sh}}: {{W+|sh|vreme}} {{nt}}
* {{Z|cu}}: {{W-|cu|врѣмѧ|tr=vrěmę}} {{nt}}
* {{Z|sl}}: {{W+|sl|čas}} {{n}}
* {{Z|es}}: {{W+|es|tiempo}}
* {{Z|sv}}: {{W+|sv|tid|c}}
* {{Z|tg}}: {{W+|tg|замон|sc=Cyrl}}, {{W+|tg|вақт|sc=Cyrl}}
* {{Z|th}}: {{W+|th|เวลา|tr=waylaa}}
* {{Z|crh}}: {{W-|crh|vaqıt}}
* {{Z|tr}}: {{W+|tr|zaman}}, {{W+|tr|hin}}
* {{Z|bo}}: {{W-|bo|དུས་ཚོད།|tr=dus tshod}}
* {{Z|uk}}: {{W+|uk|час|tr=čas}} {{n}}
* {{Z|vi}}: {{W+|vi|thời gian}}
* {{Z|cy}}: {{W+|cy|amser}}
* {{Z|grc}}: {{W-|grc|χρόνος|tr=khronos}} {{n}}
* {{Z|el}}: {{W+|el|χρόνος}}, {{W+|el|καιρός}}
{{werger-bin}}
blup9ezn1znyqm7gmkgoitoya4n6ti9
bi
0
4131
6347431
6328085
2026-08-31T19:04:00Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347431
wikitext
text/x-wiki
{{binêre herwiha/bi}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{deng|ku|LL-Q36163_(kmr)-Key Mîrza-bi.wav|dever=Wan}}
* {{ku-kîte}}
=== Pêşdaçek ===
{{pêşdaçek|ku}}
# {{înm|Bo diyarkirina [[alav]]ekê / [[amûr]]ekê / [[hacet]]ekê tê bikaranîn.}}
#: {{mk|ku|'''Bi''' kêrê; '''bi''' [[tirimpêl]]ê; '''bi''' destan.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[alîkarî|alîkariyê]] tê bikaranîn.}}
#: {{mk|ku|Hemî karê xwe '''bi''' min dide kirin.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[nêzîkahî|nêzîkahiyê]] tê bikaranîn.}}
#: {{mk|ku|'''Bi''' rex min ve.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[dem]]ê tê bikaranîn.}}
#: {{mk|ku|'''Bi''' roj; '''bi''' şev; '''bi''' salan.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[pîvan]]ê tê bikaranîn.}}
#: {{mk|ku|'''Bi''' koman; '''bi''' kîloyan; '''bi''' salan.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[peydabûn]]a [[hêdî]]-hêdî tê bikaranîn.}}
#: {{mk|ku|yek '''bi''' yek.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[peydabûn]]a [[berdewam]] tê bikaranîn.}}
#: {{mk|ku|Roj '''bi''' roj.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[sedem]]ê tê bikaranîn.}}
#: {{mk|ku|'''Bi''' nexweşiya [[şêrpence]]yê mir.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[rê]] yan [[rêbaz]]ê tê bikaranîn.}}
#: {{mk|ku|'''Bi''' xwendinê xwe rehet dike.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[awa]]yî yan [[şêwe]]yî tê bikaranîn.}}
#: {{mk|ku|'''Bi''' destûra wan.}}
# Li gor ([[gotin]]a / [[bawerî|baweriya]] kesekê/î).
#: {{mk|ku|'''Bi''' te, divê em çi bikin?}}
#* {{nimûne?|ku}}
# [[sondxwarin|Sondxwarin]]
#: {{mk|ku|'''Bi''' Xwedê.}}
#: {{mk|ku|'''Bi''' serê te.}}
#* {{nimûne?|ku}}
# {{f|ku|devokî}} {{înm|[[bo|Bo]] [[pêkanîn]]a [[negerguhêz]]ên [[lêker]]ên [[gerguhêz]] ên [[pêkhatî]] [[ji]] ''[[kirin]]'' [[bi kar hatin|bi kar tê]].}}
#: {{mk|ku|deng kirin → '''bi''' deng bû (herwiha {{q|ku|bideng}} bû) <br>ageh kirin → '''bi'''( )ageh bû <br>agir kirin → '''bi''' agir bû}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[ziman]]î tê bikaranîn.}}
#: {{mk|ku|'''Bi''' îngilîzî.}}
#* {{jêder-kitêb|ku|jêgirtin=Baş e, xezetedê '''bi''' çi ezmanî derkevit?|nivîskar=E. Rehmî Ji Mala Hekarîyan|amadekar=M. E. Bozarslan|sernav=Jîn: kovara Kurdî-Tirkî. Cild 1|weşanxane=Weşanxana Deng|cih=Uppsala|sala weşandinê=1985|sal=1918|rûpel=310|isbn=978-91-970702-0-1}}
==== Formên alternatîv ====
* {{g|ku|b'}}
* {{alt|ku|f'|fi||hin deverên [[kurmanciya rojhilatî]], bo nimûne li Amêdiyê}}
* {{g|ku|p'}}
==== Bi alfabeyên din ====
* {{ku-ar|ب}}
* {{ku-kr|бь}}
==== Notên bikaranînê ====
Dema daçeka '''bi''' serbixwe (anku bêyî [[nomîn]]an) tê bikaranîn, ew '''pê''' ye:
* pê çûn: ''bi wê çûn''
==== Dijmane ====
{{kol3|ku
|bê
}}
==== Jê ====
{{col3|ku
|bi ... de
|bi ... re
|bi ... ve
|pê<crz:daçek>
}}
==== Bide ber ====
{{kol3|ku
|bi-
|bî-
|be
}}
==== Herwiha binêre ====
{{col3|ku|sernav=Daçekên kurdî yên sade
|bi
|bo
|di
|ji
|li
}}
==== Etîmolojî ====
Ji {{ji|ira}}, hevreha soranî {{g|ckb|به|tr=be}}, farisî {{g|fa|به|tr=be}}, {{hv|pal||ped|sc=Latn}}, farisiya kevn ''peti'', {{hv|ae||peyti-|sc=Latn}}.
==== Bi zaravayên kurdî ====
* {{Z|ckb}}: {{W-|ckb|be|sc=Latn}}, {{W-|ckb|we|sc=Latn}}
* {{Z|sdh}}: {{W-|sdh|we|sc=Latn}}
* {{Z|zza}}: {{W-|zza|bi}}
==== Werger ====
{{werger-ser|bi amûrekê}}
* {{Z|de}}: {{W+|de|mit}}, {{W+|de|mittels}}, {{W+|de|durch}}, {{W+|de|indem}}
* {{Z|az}}: {{W-|az|vasitəsilə}}
* {{Z|cs}}: {{W+|cs|pomocí}}, {{W+|cs|prostřednictvím}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|用|cuda=用…|tr=yòng}}, {{W+|cmn|由|cuda=由…|tr=yóu}}
* {{Z|da}}: {{W+|da|ved}}, {{W-|da|ved at}}
* {{Z|id}}: {{W+|id|kena}}
* {{Z|ar}}: {{W+|ar|بِـ}}
* {{Z|eo}}: {{W+|eo|per}}
* Finnish: ''adessive of the means''
* {{Z|fr}}: {{W+|fr|par}}, {{W+|fr|en}}, au {{W+|fr|moyen}} de
* {{Z|nl}}: {{W+|nl|door}}, {{W+|nl|op}}, {{W+|nl|per}}
* {{Z|he}}: {{W-|he|על ידי|tr=al yedey}}
* {{Z|io}}: {{W+|io|per}}
* {{Z|ang}}: {{W-|ang|þurh}}
* Polish:
* {{Z|en}}: {{W+|en|by}}
* {{Z|it}}: {{W+|it|con}}
* {{Z|ja}}: {{W+|ja|で|cuda=…で|sc=Jpan}}, {{W-|ja|により|cuda=…により|sc=Jpan}}, {{W+|ja|によって|cuda=…によって|tr=…niyotte|sc=Jpan}}
* {{Z|pam}}: {{W-|pam|gamit ing}}, {{W-|pam|gamit naning...}}, {{W-|pam|gamit ning...}}, {{W-|pam|ibat king...}}, {{W-|pam|...ken}}, {{W-|pam|bilang}}
* {{Z|ko}}: {{W+|ko|로써|cuda=...로써}}, {{W+|ko|로|cuda=...로}}
* {{Z|la}}: {{W+|la|per}}, {{W+|la|ab}}
* {{Z|lv}}: {{W+|lv|pa}}
* {{Z|ms}}: {{W+|ms|dengan}}
* {{Z|mt}}: {{W+|mt|bi}}
* {{Z|mi}}: {{W-|mi|nā}}, {{W-|mi|ki}}
* {{Z|hu}}: {{W+|hu|[[-val]]/[[-vel]]}}, {{W+|hu|által}}, {{W+|hu|útján}}, {{W+|hu|révén}}
* {{Z|no}}: {{W+|no|med}}
* {{Z|pt}}: {{W+|pt|por}}, {{W+|pt|a}}
* {{Z|ro}}: {{W+|ro|cu}}
* Russian: }}
* Slovak:, {{W-|sk|so}}, {{W-|sk|pomocou}}}}
* {{Z|sl}}: {{W+|sl|y}}, {{W+|sl|z}}
* {{Z|es}}: {{W+|es|por}}
* {{Z|sv}}: {{W-|sv|genom att}}
* {{Z|zdj}}: {{W-|zdj|ha}}
* {{Z|th}}: {{W+|th|โดย|tr=doy}}
* {{Z|tr}}: {{W+|tr|-la}}, {{W+|tr|-le}}, {{W+|tr|vasıtasıyla}}
* {{Z|uk}}: {{W-|uk|за допомогою}}
* {{Z|vi}}: {{W-|vi|bằng cách}}, {{W-|vi|theo cách}}
* {{Z|cy}}: {{W-|cy|â}}
* {{Z|el}}: {{W+|el|διά}}, {{W+|el|από}}
{{werger-bin}}
:{{werger çavkanî|en|by|beş=Ev qismê Wergerê|oldid=75765074}}
{{werger-ser|bi zimanekî, bi awayekî}}
* {{Z|de}}: {{W+|de|auf}}
* {{Z|my}}: {{W+|my|လို|sc=Mymr}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|用|tr=yòng}}
* {{Z|da}}: {{W+|da|på}}, {{W+|da|med}}
* {{Z|fi}}: {{W+|fi|-ksi}}, {{W-|fi|[[-lla]]/[[-llä]]}}
* {{Z|fr}}: {{W+|fr|en}}
* {{Z|hi}}: {{W+|hi|में}}
* {{Z|nl}}: {{W+|nl|in}}
* {{Z|ang}}: {{W-|ang|on}}
* {{Z|en}}: {{W+|en|in}}
* {{Z|ga}}: {{W+|ga|as}}
* {{Z|it}}: {{W+|it|in}}
* {{Z|ja}}: {{W+|ja|で|sc=Jpan|cuda=...で|tr=...de}}
* {{Z|ko}}: {{W+|ko|로|cuda=...로}}
* {{Z|hu}}: {{W+|hu|-ban}}, {{W+|hu|-ben}}, {{W+|hu|-ul}}, {{W+|hu|-ül}}, {{W+|hu|-val}}, {{W+|hu|-vel}}
* {{Z|nrf}}: {{W-|nrf|en}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|på}}
*: {{Z|nn}}: {{W-|nn|på}}
* {{Z|pl}}: {{W+|pl|po}}, {{W+|pl|w}}
* {{Z|pt}}: {{W+|pt|em}}
* {{Z|ro}}: {{W+|ro|în}}
* {{Z|ru}}: {{W+|ru|по-}}
* {{Z|es}}: {{W+|es|en}}
* {{Z|sv}}: {{W+|sv|på}}, {{W+|sv|i}}
* {{Z|vi}}: {{W+|vi|bằng}}
* {{Z|wa}}: {{W+|wa|e}}
* {{Z|cy}}: {{W+|cy|yn}}
{{werger-bin}}
:{{werger çavkanî|en|in|beş=Ev qismê Wergerê|oldid=75769288}}
== {{ziman|zza}} ==
=== Daçek ===
{{daçek|zza}}
# [[bi]], Daçek (amraz) e. Mana bi hev ra bûnê, [[dide]]: ''Bi dilê xwe, Were pêşiya lêkeran şeklê fermaniyê didê.: ''Bifiroşe, [[bibe]], [[bigre]], [[bide]], Di raweya bilanî û gerane de dibe alîkar.: ''Ez bi gorî, Di Tirkî da lêkerên ku''Bi zuran roj nêşono awan:Bi derewan roj naçe ava<ref>http://www.kovarabir.com/wp-content/uploads/Ferheng%C3%AA-Dimil%C3%AE-%C3%BB-Kurmanc%C3%AE-B-b.pdf</ref>
#* {{bêmînak|zza}}
=== Çavkanî ===
{{çavkanî}}
== {{ziman|duu}} ==
=== Lêker ===
{{lêker|duu}}
# [[dan#ku|dan]], [[dayîn#ku|dayîn]]
#* {{bêmînak|duu}}
== {{ziman|bor}} ==
=== Lêker ===
{{lêker|bor}}
# {{g|ku|mirin}}
#* {{bêmînak|bor}}
== {{ziman|evn}} ==
=== Lêker ===
{{lêker|evn}}
# (kesek/tiştek) {{g|ku|bûn}}
#* {{bêmînak|evn}}
=== Çavkanî ===
{{rûpela wergerê|evn|bûn}}
== {{ziman|gd}} ==
=== Lêker ===
{{lêker|gd}}
# {{g|ku|jîn}}, {{g|ku|sax}} bûn, li {{g|ku|jiyan}}ê bûn
#* {{bêmînak|gd}}
== {{ziman|en}} ==
=== Bilêvkirin ===
* {{IPA|en|/baɪ/}}
* {{deng|en|en-us-bi.ogg|dever=DYA}}
* {{hevdeng|en|bye|buy|by}}
* {{deng|en|LL-Q1860 (eng)-Scelultrix-bi.wav|Deng|dever=Îngilistan, QY}}
=== Rengdêr ===
{{en-rengdêr|-}}
# {{f|en|LGBT|argo}} [[bîseksuel|Bîseksuel]].<ref name="Niemoeller"/>
#: {{hevmaneyên peyvê|en|bisexual}}
#: {{ux|en|I'm straight, but my oldest sister is '''bi'''.|Ez heteroseksuel im lê, xwişka min a herî mezin bîseksuel e.}}
# {{f|en|LGBT|argo|neberbelav}} [[duzayend|Duzayend]], [[ducinsiyet]].
#* {{bêmînak|en}}
=== Navdêr ===
{{en-navdêr}}
# {{f|en|LGBT|argo}} Kesekî [[bîseksuel]].<ref name="Niemoeller"/>
#: {{hevmaneyên peyvê|en|bisexual|bisexual person}}
# {{f|en|wicûdçêkirin|zimanê rojane|neberbelav}} [[masûlke|Masûlkeyekî]] duserî.
#* {{bêmînak|en}}
==== Jê ====
{{kol3|en
|forced bi
}}
==== Etîmolojî ====
{{qusandin|en|bisexual}} û {{g|en|biceps}}.
==== Herwiha binêre ====
{{kol3|en
|bi-
}}
=== Bilêvkirin ===
* {{mj|KY|DYA}}, {{IPA|en|/biː/}}
* {{deng|en|en-us-bee.ogg|dever=DYA}}
* {{hevdeng|en|b|be|Bea|bee}}
=== Navdêr ===
{{en-navdêr|bi}}
# Cureyekî [[dîsk]]a [[yeşim]] ku li [[Çîn]]a kevnar hatiye çêkirin.
#* {{bêmînak|en}}
==== Formên alternatîv ====
{{kol3|en
|pi<q:ji [[Wade-giles]]>
}}
==== Etîmolojî ====
Ji {{ji|cmn|en|sc=Hani|璧|tr=bì}}
==== Bêhtir bixwîne ====
* {{pedia|ziman=en|Bi (jade)}}
=== Anagram ===
* {{anagram|en|a=bi|IB|ib.}}
=== Çavkanî ===
<references>
<ref name="Niemoeller">A. F. Niemoeller, "A Glossary of Homosexual Slang," '''Fact''' 2, no. 1 (Jan-Feb 1965): 25</ref>
</references>
== {{ziman|juc}} ==
=== Cînav ===
{{cînav|juc}}
# [[ez#ku|ez]] (wek [[biker]])
#* {{bêmînak|juc}}
== {{ziman|zai}} ==
=== Navdêr ===
{{navdêr|zai}}
# {{f|zai|hewa}} [[ba#ku|ba]]
#* {{bêmînak|zai}}
== {{ziman|za}} ==
=== Navdêr ===
{{navdêr|za}}
# {{f|za|dem}} [[sal#ku|sal]]
#* {{bêmînak|za}}
== {{ziman|zom}} ==
=== Navdêr ===
{{navdêr|zom}}
# {{g|ku|hêlîn}}
#* {{bêmînak|zom}}
=== Çavkanî ===
{{rûpela wergerê|zom|hêlîn}}
bncof49bonb7ax5qxygk0saglqy85ct
6347452
6347431
2026-08-31T19:41:06Z
Balyozbot
7867
[[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan
6347452
wikitext
text/x-wiki
{{binêre herwiha/bi}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{deng|ku|LL-Q36163_(kmr)-Key Mîrza-bi.wav|dever=Wan}}
* {{ku-kîte}}
=== Pêşdaçek ===
{{pêşdaçek|ku}}
# {{înm|Bo diyarkirina [[alav]]ekê / [[amûr]]ekê / [[hacet]]ekê tê bikaranîn.}}
#: {{mk|ku|'''Bi''' kêrê; '''bi''' [[tirimpêl]]ê; '''bi''' destan.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[alîkarî|alîkariyê]] tê bikaranîn.}}
#: {{mk|ku|Hemî karê xwe '''bi''' min dide kirin.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[nêzîkahî|nêzîkahiyê]] tê bikaranîn.}}
#: {{mk|ku|'''Bi''' rex min ve.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[dem]]ê tê bikaranîn.}}
#: {{mk|ku|'''Bi''' roj; '''bi''' şev; '''bi''' salan.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[pîvan]]ê tê bikaranîn.}}
#: {{mk|ku|'''Bi''' koman; '''bi''' kîloyan; '''bi''' salan.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[peydabûn]]a [[hêdî]]-hêdî tê bikaranîn.}}
#: {{mk|ku|yek '''bi''' yek.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[peydabûn]]a [[berdewam]] tê bikaranîn.}}
#: {{mk|ku|Roj '''bi''' roj.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[sedem]]ê tê bikaranîn.}}
#: {{mk|ku|'''Bi''' nexweşiya [[şêrpence]]yê mir.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[rê]] yan [[rêbaz]]ê tê bikaranîn.}}
#: {{mk|ku|'''Bi''' xwendinê xwe rehet dike.}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[awa]]yî yan [[şêwe]]yî tê bikaranîn.}}
#: {{mk|ku|'''Bi''' destûra wan.}}
# Li gor ([[gotin]]a / [[bawerî|baweriya]] kesekê/î).
#: {{mk|ku|'''Bi''' te, divê em çi bikin?}}
#* {{nimûne?|ku}}
# [[sondxwarin|Sondxwarin]]
#: {{mk|ku|'''Bi''' Xwedê.}}
#: {{mk|ku|'''Bi''' serê te.}}
#* {{nimûne?|ku}}
# {{f|ku|devokî}} {{înm|[[bo|Bo]] [[pêkanîn]]a [[negerguhêz]]ên [[lêker]]ên [[gerguhêz]] ên [[pêkhatî]] [[ji]] ''[[kirin]]'' [[bi kar hatin|bi kar tê]].}}
#: {{mk|ku|deng kirin → '''bi''' deng bû (herwiha {{q|ku|bideng}} bû) <br>ageh kirin → '''bi'''( )ageh bû <br>agir kirin → '''bi''' agir bû}}
#* {{nimûne?|ku}}
# {{înm|Bo diyarkirina [[ziman]]î tê bikaranîn.}}
#: {{mk|ku|'''Bi''' îngilîzî.}}
#* {{jêder-kitêb|ku|jêgirtin=Baş e, xezetedê '''bi''' çi ezmanî derkevit?|nivîskar=E. Rehmî Ji Mala Hekarîyan|amadekar=M. E. Bozarslan|sernav=Jîn: kovara Kurdî-Tirkî. Cild 1|weşanxane=Weşanxana Deng|cih=Uppsala|sala weşandinê=1985|sal=1918|rûpel=310|isbn=978-91-970702-0-1}}
==== Notên bikaranînê ====
Dema daçeka '''bi''' serbixwe (anku bêyî [[nomîn]]an) tê bikaranîn, ew '''pê''' ye:
* pê çûn: ''bi wê çûn''
==== Bi alfabeyên din ====
* {{ku-ar|ب}}
* {{ku-kr|бь}}
==== Formên alternatîv ====
* {{g|ku|b'}}
* {{alt|ku|f'|fi||hin deverên [[kurmanciya rojhilatî]], bo nimûne li Amêdiyê}}
* {{g|ku|p'}}
==== Dijmane ====
{{kol3|ku
|bê
}}
==== Jê ====
{{col3|ku
|bi ... de
|bi ... re
|bi ... ve
|pê<crz:daçek>
}}
==== Etîmolojî ====
Ji {{ji|ira}}, hevreha soranî {{g|ckb|به|tr=be}}, farisî {{g|fa|به|tr=be}}, {{hv|pal||ped|sc=Latn}}, farisiya kevn ''peti'', {{hv|ae||peyti-|sc=Latn}}.
==== Bide ber ====
{{kol3|ku
|bi-
|bî-
|be
}}
==== Herwiha binêre ====
{{col3|ku|sernav=Daçekên kurdî yên sade
|bi
|bo
|di
|ji
|li
}}
==== Bi zaravayên din ====
* {{Z|ckb}}: {{W-|ckb|be|sc=Latn}}, {{W-|ckb|we|sc=Latn}}
* {{Z|sdh}}: {{W-|sdh|we|sc=Latn}}
* {{Z|zza}}: {{W-|zza|bi}}
==== Werger ====
{{werger-ser|bi amûrekê}}
* {{Z|de}}: {{W+|de|mit}}, {{W+|de|mittels}}, {{W+|de|durch}}, {{W+|de|indem}}
* {{Z|az}}: {{W-|az|vasitəsilə}}
* {{Z|cs}}: {{W+|cs|pomocí}}, {{W+|cs|prostřednictvím}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|用|cuda=用…|tr=yòng}}, {{W+|cmn|由|cuda=由…|tr=yóu}}
* {{Z|da}}: {{W+|da|ved}}, {{W-|da|ved at}}
* {{Z|id}}: {{W+|id|kena}}
* {{Z|ar}}: {{W+|ar|بِـ}}
* {{Z|eo}}: {{W+|eo|per}}
* Finnish: ''adessive of the means''
* {{Z|fr}}: {{W+|fr|par}}, {{W+|fr|en}}, au {{W+|fr|moyen}} de
* {{Z|nl}}: {{W+|nl|door}}, {{W+|nl|op}}, {{W+|nl|per}}
* {{Z|he}}: {{W-|he|על ידי|tr=al yedey}}
* {{Z|io}}: {{W+|io|per}}
* {{Z|ang}}: {{W-|ang|þurh}}
* Polish:
* {{Z|en}}: {{W+|en|by}}
* {{Z|it}}: {{W+|it|con}}
* {{Z|ja}}: {{W+|ja|で|cuda=…で|sc=Jpan}}, {{W-|ja|により|cuda=…により|sc=Jpan}}, {{W+|ja|によって|cuda=…によって|tr=…niyotte|sc=Jpan}}
* {{Z|pam}}: {{W-|pam|gamit ing}}, {{W-|pam|gamit naning...}}, {{W-|pam|gamit ning...}}, {{W-|pam|ibat king...}}, {{W-|pam|...ken}}, {{W-|pam|bilang}}
* {{Z|ko}}: {{W+|ko|로써|cuda=...로써}}, {{W+|ko|로|cuda=...로}}
* {{Z|la}}: {{W+|la|per}}, {{W+|la|ab}}
* {{Z|lv}}: {{W+|lv|pa}}
* {{Z|ms}}: {{W+|ms|dengan}}
* {{Z|mt}}: {{W+|mt|bi}}
* {{Z|mi}}: {{W-|mi|nā}}, {{W-|mi|ki}}
* {{Z|hu}}: {{W+|hu|[[-val]]/[[-vel]]}}, {{W+|hu|által}}, {{W+|hu|útján}}, {{W+|hu|révén}}
* {{Z|no}}: {{W+|no|med}}
* {{Z|pt}}: {{W+|pt|por}}, {{W+|pt|a}}
* {{Z|ro}}: {{W+|ro|cu}}
* Russian: }}
* Slovak:, {{W-|sk|so}}, {{W-|sk|pomocou}}}}
* {{Z|sl}}: {{W+|sl|y}}, {{W+|sl|z}}
* {{Z|es}}: {{W+|es|por}}
* {{Z|sv}}: {{W-|sv|genom att}}
* {{Z|zdj}}: {{W-|zdj|ha}}
* {{Z|th}}: {{W+|th|โดย|tr=doy}}
* {{Z|tr}}: {{W+|tr|-la}}, {{W+|tr|-le}}, {{W+|tr|vasıtasıyla}}
* {{Z|uk}}: {{W-|uk|за допомогою}}
* {{Z|vi}}: {{W-|vi|bằng cách}}, {{W-|vi|theo cách}}
* {{Z|cy}}: {{W-|cy|â}}
* {{Z|el}}: {{W+|el|διά}}, {{W+|el|από}}
{{werger-bin}}
:{{werger çavkanî|en|by|beş=Ev qismê Wergerê|oldid=75765074}}
{{werger-ser|bi zimanekî, bi awayekî}}
* {{Z|de}}: {{W+|de|auf}}
* {{Z|my}}: {{W+|my|လို|sc=Mymr}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|用|tr=yòng}}
* {{Z|da}}: {{W+|da|på}}, {{W+|da|med}}
* {{Z|fi}}: {{W+|fi|-ksi}}, {{W-|fi|[[-lla]]/[[-llä]]}}
* {{Z|fr}}: {{W+|fr|en}}
* {{Z|hi}}: {{W+|hi|में}}
* {{Z|nl}}: {{W+|nl|in}}
* {{Z|ang}}: {{W-|ang|on}}
* {{Z|en}}: {{W+|en|in}}
* {{Z|ga}}: {{W+|ga|as}}
* {{Z|it}}: {{W+|it|in}}
* {{Z|ja}}: {{W+|ja|で|sc=Jpan|cuda=...で|tr=...de}}
* {{Z|ko}}: {{W+|ko|로|cuda=...로}}
* {{Z|hu}}: {{W+|hu|-ban}}, {{W+|hu|-ben}}, {{W+|hu|-ul}}, {{W+|hu|-ül}}, {{W+|hu|-val}}, {{W+|hu|-vel}}
* {{Z|nrf}}: {{W-|nrf|en}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|på}}
*: {{Z|nn}}: {{W-|nn|på}}
* {{Z|pl}}: {{W+|pl|po}}, {{W+|pl|w}}
* {{Z|pt}}: {{W+|pt|em}}
* {{Z|ro}}: {{W+|ro|în}}
* {{Z|ru}}: {{W+|ru|по-}}
* {{Z|es}}: {{W+|es|en}}
* {{Z|sv}}: {{W+|sv|på}}, {{W+|sv|i}}
* {{Z|vi}}: {{W+|vi|bằng}}
* {{Z|wa}}: {{W+|wa|e}}
* {{Z|cy}}: {{W+|cy|yn}}
{{werger-bin}}
:{{werger çavkanî|en|in|beş=Ev qismê Wergerê|oldid=75769288}}
== {{ziman|zza}} ==
=== Daçek ===
{{daçek|zza}}
# [[bi]], Daçek (amraz) e. Mana bi hev ra bûnê, [[dide]]: ''Bi dilê xwe, Were pêşiya lêkeran şeklê fermaniyê didê.: ''Bifiroşe, [[bibe]], [[bigre]], [[bide]], Di raweya bilanî û gerane de dibe alîkar.: ''Ez bi gorî, Di Tirkî da lêkerên ku''Bi zuran roj nêşono awan:Bi derewan roj naçe ava<ref>http://www.kovarabir.com/wp-content/uploads/Ferheng%C3%AA-Dimil%C3%AE-%C3%BB-Kurmanc%C3%AE-B-b.pdf</ref>
#* {{bêmînak|zza}}
=== Çavkanî ===
{{çavkanî}}
== {{ziman|duu}} ==
=== Lêker ===
{{lêker|duu}}
# [[dan#ku|dan]], [[dayîn#ku|dayîn]]
#* {{bêmînak|duu}}
== {{ziman|bor}} ==
=== Lêker ===
{{lêker|bor}}
# {{g|ku|mirin}}
#* {{bêmînak|bor}}
== {{ziman|evn}} ==
=== Lêker ===
{{lêker|evn}}
# (kesek/tiştek) {{g|ku|bûn}}
#* {{bêmînak|evn}}
=== Çavkanî ===
{{rûpela wergerê|evn|bûn}}
== {{ziman|gd}} ==
=== Lêker ===
{{lêker|gd}}
# {{g|ku|jîn}}, {{g|ku|sax}} bûn, li {{g|ku|jiyan}}ê bûn
#* {{bêmînak|gd}}
== {{ziman|en}} ==
=== Bilêvkirin ===
* {{IPA|en|/baɪ/}}
* {{deng|en|en-us-bi.ogg|dever=DYA}}
* {{hevdeng|en|bye|buy|by}}
* {{deng|en|LL-Q1860 (eng)-Scelultrix-bi.wav|Deng|dever=Îngilistan, QY}}
=== Rengdêr ===
{{en-rengdêr|-}}
# {{f|en|LGBT|argo}} [[bîseksuel|Bîseksuel]].<ref name="Niemoeller"/>
#: {{hevmaneyên peyvê|en|bisexual}}
#: {{ux|en|I'm straight, but my oldest sister is '''bi'''.|Ez heteroseksuel im lê, xwişka min a herî mezin bîseksuel e.}}
# {{f|en|LGBT|argo|neberbelav}} [[duzayend|Duzayend]], [[ducinsiyet]].
#* {{bêmînak|en}}
=== Navdêr ===
{{en-navdêr}}
# {{f|en|LGBT|argo}} Kesekî [[bîseksuel]].<ref name="Niemoeller"/>
#: {{hevmaneyên peyvê|en|bisexual|bisexual person}}
# {{f|en|wicûdçêkirin|zimanê rojane|neberbelav}} [[masûlke|Masûlkeyekî]] duserî.
#* {{bêmînak|en}}
==== Jê ====
{{kol3|en
|forced bi
}}
==== Etîmolojî ====
{{qusandin|en|bisexual}} û {{g|en|biceps}}.
==== Herwiha binêre ====
{{kol3|en
|bi-
}}
=== Bilêvkirin ===
* {{mj|KY|DYA}}, {{IPA|en|/biː/}}
* {{deng|en|en-us-bee.ogg|dever=DYA}}
* {{hevdeng|en|b|be|Bea|bee}}
=== Navdêr ===
{{en-navdêr|bi}}
# Cureyekî [[dîsk]]a [[yeşim]] ku li [[Çîn]]a kevnar hatiye çêkirin.
#* {{bêmînak|en}}
==== Formên alternatîv ====
{{kol3|en
|pi<q:ji [[Wade-giles]]>
}}
==== Etîmolojî ====
Ji {{ji|cmn|en|sc=Hani|璧|tr=bì}}
==== Bêhtir bixwîne ====
* {{pedia|ziman=en|Bi (jade)}}
=== Anagram ===
* {{anagram|en|a=bi|IB|ib.}}
=== Çavkanî ===
<references>
<ref name="Niemoeller">A. F. Niemoeller, "A Glossary of Homosexual Slang," '''Fact''' 2, no. 1 (Jan-Feb 1965): 25</ref>
</references>
== {{ziman|juc}} ==
=== Cînav ===
{{cînav|juc}}
# [[ez#ku|ez]] (wek [[biker]])
#* {{bêmînak|juc}}
== {{ziman|zai}} ==
=== Navdêr ===
{{navdêr|zai}}
# {{f|zai|hewa}} [[ba#ku|ba]]
#* {{bêmînak|zai}}
== {{ziman|za}} ==
=== Navdêr ===
{{navdêr|za}}
# {{f|za|dem}} [[sal#ku|sal]]
#* {{bêmînak|za}}
== {{ziman|zom}} ==
=== Navdêr ===
{{navdêr|zom}}
# {{g|ku|hêlîn}}
#* {{bêmînak|zom}}
=== Çavkanî ===
{{rûpela wergerê|zom|hêlîn}}
0a6i803gbs4e20eefeztyn7j0t8lc2t
pê
0
4323
6347432
6339025
2026-08-31T19:04:37Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347432
wikitext
text/x-wiki
{{bnr-h|pe|pé|pe-|pê-}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{deng|ku|LL-Q36163_(kmr)-Key Mîrza-pê.wav|dever=Wan}}
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Male Right Foot 1.jpg|rast|thumb|pê (1)]]
{{navdêr|ku|z=n}}, {{p-ya nerm}}
# {{f|ku|anatomî}} [[herdu]] [[parçe]]yên [[leş]]î yên ku [[mirov]] pê [[meşîn|dimeşin]] anku [[bi rê ve çûn|bi rê ve diçin]] bi taybetî beşa mirov dikin di [[pêlav]]ê anku [[sol]]ê de.
# [[beş|Beşên]] [[leş]]ê [[heywan]]an yên bi wî [[awa]]yî.
==== Tewandin ====
{{ku-tewîn-nav|nêr}}
==== Bi alfabeyên din ====
* {{ku-ar|پێ}}
* {{ku-kr|пе}}
==== Formên alternatîv ====
{{kol3|ku
|pî
|pa-
|pay-
}}
==== Hevmane ====
{{kol3|ku
|ling
|nig
}}
==== Jê ====
{{kol3|ku
|berpê
|derpê
|derpêkurtk
|pêlav
|peya
}}
==== Etîmolojî ====
Herwiha [[pî]], hevreha {{hv|ckb|پێ}}, kelhûrî ''[[pa]]'', zazakî ''[[pay]]'', farisiya niha {{g|fa|پا}} (pa) û farisiya kevntir {{g|fa|پای}} (pay), tacikî ''[[пой]] (poy)'', belûçî {{g|bal|پاد}} (pad), {{hv|pal|𐫛𐫀𐫅|tr=pʾd, /pay/}}, pertî [[𐫛𐫀𐫅]] (pʾd /pāδ/), {{hv|ae|𐬞𐬀𐬜𐬀|tr=paδa}} û [[𐬞𐬁𐬜𐬀]] (pāδa), hexamenişî [[𐎱𐎠𐎭]] (p-a-d /pādaʰ/), {{hv|sa|पद्|tr=pád}}, ûrdûyî [[پاؤں]] (pā̃v), hindî [[पांव]] (pā̃v), {{hv|hit|𒉺𒋫|tr=pa-ta; bi sûmerografî [[𒄊𒀸]]}}, toxarî A ''pe'', toxarî B ''paiyye'', {{hv|grc|πούς|tr=poús}}, {{hv|lv|pēda}}, {{hv|lt|pėda}}, {{hv|la|pēs}}, {{hv|it|piede}}, {{hv|fr|pied}}, {{hv|es|pie}}, {{hv|pt|pé}}, oksîtanî ''[[pè]]'', {{hv|en|foot}} (pirhejmar: ''[[feet]]''), norwecî/{{hv|sv|fot}}, {{hv|da|fod}}, {{hv|de|Fuß}}, {{hv|nl|voet}}... hemû ji {{ji|ine-pro|ku|-}} *''[[póds]]'' (pê) ji *''[[ped-]]'' ([[meşîn]], [[bi rê ve çûn]], [[gav]] [[avêtin]]) + *''[[-s]]'' ([[paşgir]]eke [[navdêrsaz]])
;{{biçûk|Çavkanî:
* {{Horn|r=63}}
* {{Cheung|r=305}}
* {{Watkins|r=62}}
* {{Etymonline}}
* {{Pokorny|r=790 - 792}}
}}
==== Bi zaravayên din ====
* {{Z|ckb}}: {{W-|ckb|پێ|tr=pê}}, {{W-|ckb|sc=Latn|pa|sc=Latn}}
* Kelhûrî: {{W-|sdh|sc=Latn|pa|sc=Latn}}
* {{Z|zza}}: {{W+|zza|pa|n}}, {{W-|zza|linge|m}}, {{W-|zza|ling|m}}
==== Werger ====
{{werger-ser}}
* {{Z|ab}}: {{W-|ab|ашьапы}}
* {{Z|aa}}: {{W-|aa|iba}}
* {{Z|af}}: {{W+|af|voet}}
* {{Z|akl}}: {{W-|akl|siki}}
* {{Z|sq}}: {{W+|sq|këmbë|m}}
* {{Z|pdc}}: {{W-|pdc|Fuuss|n}}
* {{Z|de}}: {{W+|de|Fuß|n}}, {{W+|de|Fuss|n}}
* {{Z|am}}: {{W-|am|እግር|tr=ǝgǝr}}
* Apaçî:
*: {{Z|apw}}: {{W-|apw|bikee’}}
* {{Z|an}}: {{W+|an|piet}}
* {{Z|agj}}: {{W-|agj|እግር|tr=ǝgǝr}}
* {{Z|rup}}: {{W-|rup|cicior}}
* {{Z|aer}}: {{W-|aer|ingke}}
* {{Z|ast}}: {{W+|ast|pie|n}}, {{W+|ast|pie|n}}
* {{Z|ay}}: {{W-|ay|kayu}}
* {{Z|az}}: {{W+|az|ayaq}}
* {{Z|ban}}: {{W-|ban|cokor}}
* {{Z|eu}}: {{W-|eu|oin}}
* {{Z|ba}}: {{W-|ba|аяҡ}}
* {{Z|bar}}: {{W-|bar|Fuaß}}
* {{Z|be}}: {{W-|be|нага́|m}}
* {{Z|bcl}}: {{W-|bcl|bitis}}
* {{Z|br}}: {{W+|br|troad|n}}
* {{Z|kxd}}: {{W-|kxd|batis}}, {{W-|kxd|kaki}}
* {{Z|bg}}: {{W+|bg|стъпа́ло|n}}
* {{Z|my}}: {{W+|my|ခြေ}}
* {{Z|bua}}: {{W-|bua|хүл}}
* {{Z|ccc}}: {{W-|ccc|kujtu}}
* {{Z|cs}}: {{W+|cs|noha|m}}
* {{Z|ny}}: {{W-|ny|phazi}}
* {{Z|zh}}:
*: {{Z|yue}}: {{W-|yue|腳|tr=goek3}}, {{W-|yue|足|tr=zuk1}}
*: {{Z|lzh}}: {{W-|lzh|足}}
*: {{Z|cmn}}: {{W+|cmn|腳|tr=jiǎo}}, {{W+|cmn|足|tr=zú}}, {{W-|cmn|腳丫|tr=jiǎoyā}}
*: {{Z|wuu}}: {{W-|wuu|腳}}
*: {{Z|nan}}: {{W+|nan|跤|tr=kha}}
* {{Z|dlm}}: {{W-|dlm|pi|n}}
* {{Z|da}}: {{W+|da|fod|g}}, {{W-|da|fødder|p}}
* {{Z|xda}}: {{W-|xda|dhunna}}
* {{Z|dlg}}: {{W-|dlg|атак}}
* {{Z|dbp}}: {{W-|dbp|ə̀zgər}}
* {{Z|id}}: {{W+|id|kaki}}
* {{Z|ar}}: {{W+|ar|رِجْل|m}}, {{W+|ar|قَدَم|m}}
*: {{Z|arz}}: {{W-|arz|قدم|m|n|tr=ʿadam, qadam|sc=Arab}}, {{W-|arz|رجل|m|tr=regl|sc=Arab}}
*: {{Z|afb}}: {{W-|afb|ريل|m|tr=rīl}}
*: {{Z|acw}}: {{W-|acw|رجل|m|tr=rijil}}
*: {{Z|apc}}: {{W-|apc|إجر|tr=ʾijir}}
* {{Z|hy}}: {{W+|hy|ոտք}}
* {{Z|myv}}: {{W-|myv|пильге}}
* {{Z|eo}}: {{W+|eo|piedo}}
* {{Z|et}}: {{W+|et|jalg}}, {{W-|et|jalalaba}}
* {{Z|gez}}: {{W-|gez|እግር}}
* {{Z|eve}}: {{W-|eve|бөдэл}}
* {{Z|evn}}: {{W-|evn|халган}}
* {{Z|ee}}: {{W-|ee|afɔ}}
* {{Z|fa}}: {{W+|fa|پا|tr=pâ}}
* {{Z|ddg}}: {{W-|ddg|ia}}
* {{Z|fo}}: {{W+|fo|fótur|n}}
* {{Z|fj}}: {{W+|fj|yava}}
* {{Z|fi}}: {{W+|fi|jalka}}, {{W+|fi|jalkaterä}}
* {{Z|frp}}: {{W-|frp|pied|n}}
* {{Z|fro}}: {{W-|fro|pié}}
* {{Z|fr}}: {{W+|fr|pied|n}}
* {{Z|fur}}: {{W-|fur|pît}}, {{W-|fur|pîd|m}}
* {{Z|frr}}: {{W-|frr|fötj|n}}, {{W-|frr|fut|n}}, {{W-|frr|Fut|n}}
* {{Z|fy}}: {{W-|fy|poat|n}}, {{W-|fy|foet}}
* {{Z|gd}}: {{W-|gd|cas|m}}
* {{Z|gl}}: {{W+|gl|pé|n}}
* {{Z|kld}}: {{W-|kld|thina}}
* {{Z|got}}: {{W-|got|𐍆𐍉𐍄𐌿𐍃|n}}
* {{Z|ka}}: {{W+|ka|ფეხი|sc=Geor}}, {{W+|ka|ტერფი}}
* {{Z|gn}}: {{W-|gn|py}}
* {{Z|ht}}: {{W-|ht|pye}}
* {{Z|haw}}: {{W-|haw|wāwae}}
* {{Z|mba}}: {{W-|mba|paa}}
* {{Z|hi}}: {{W+|hi|पैर|n|sc=Deva}}, {{W-|hi|पांव|sc=Deva}}
* {{Z|mww}}: {{W-|mww|ko taw}}
* {{Z|nl}}: {{W+|nl|voet|n}}
* {{Z|he}}: {{W+|he|רגל|m|tr=regel|sc=Hebr}}
* {{Z|io}}: {{W+|io|pedo}}
* {{Z|ilo}}: {{W-|ilo|betis}}
* {{Z|ang}}: {{W-|ang|fōt|n}}
* {{Z|en}}: {{W+|en|foot}}
* {{Z|ia}}: {{W-|ia|pede}}
* {{Z|ill}}: {{W-|ill|ai}}
* {{Z|ga}}: {{W+|ga|cos|m}}, {{W-|ga|troigh|m}}
* {{Z|zai}}: {{W-|zai|batañee}}, {{W-|zai|ñee}}
* {{Z|it}}: {{W+|it|piede|n}}
* {{Z|ja}}: {{W+|ja|足|tr=あし, ashi|sc=Jpan}}
* {{Z|jv}}: {{W+|jv|sikil}}, {{W+|jv|cokor}}
* {{Z|kl}}: {{W+|kl|isigak}}
* {{Z|kck}}: {{W-|kck|gumbo}}
* {{Z|xal}}: {{W-|xal|көл}}
* {{Z|rmq}}: {{W-|rmq|pinré|n}}
* {{Z|kn}}: {{W+|kn|ಪಾದ|sc=Knda}}
* {{Z|pam}}: {{W-|pam|bitis}}, {{W-|pam|betis}}
* {{Z|kea}}: {{W-|kea|pé}}
* {{Z|xqa}}: {{W-|xqa|اَذَقْ|tr=aδaq}}
* {{Z|ca}}: {{W+|ca|peu|n}}
* {{Z|qu}}: {{W+|qu|chaki}}
* {{Z|rw}}: {{W-|rw|ikirenge|c7|c8}}, {{W-|rw|ibirenge|p}}
* {{Z|kpv}}: {{W-|kpv|кок}}
* {{Z|ko}}: {{W+|ko|발}}
* {{Z|kw}}: {{W-|kw|troos|n}}
* {{Z|cuk}}: {{W-|cuk|mali}}
* {{Z|lbj}}: {{W-|lbj|རྐང་པ}}
* {{Z|ltg}}: {{W-|ltg|pāds|n}}
* {{Z|la}}: {{W+|la|pēs|n}}
* {{Z|lv}}: {{W+|lv|pēda|m}}, {{W+|lv|kāja|m}}
* {{Z|lo}}: {{W+|lo|ຕີນ}}, {{W-|lo|ຈະລະນະ}}, {{W-|lo|ບາດ}}, {{W-|lo|ປາທະ}}
* {{Z|lij}}: {{W-|lij|pê|n}}
* {{Z|lt}}: {{W+|lt|pėda|m}}, {{W+|lt|koja|m}}
* {{Z|lmo}}: {{W-|lmo|pè}}
* {{Z|lb}}: {{W+|lb|Fouss|n}}
* {{Z|mhn}}: {{W-|mhn|vuas|n}}
* {{Z|mkz}}: {{W-|mkz|iti}}
* {{Z|mk}}: {{W+|mk|стапало|nt}}, {{W+|mk|нога|m}}
* {{Z|ml}}: {{W+|ml|പാദം}}
* {{Z|ms}}: {{W+|ms|kaki}}
* {{Z|mnc}}: {{W-|mnc|ᠪᡝᡨᡥᡝ}}
* {{Z|mi}}: {{W-|mi|waewae}}, {{W-|mi|wae}}
* {{Z|mrw}}: {{W-|mrw|a'i}}
* {{Z|yua}}: {{W-|yua|ook}}
* {{Z|vmb}}: {{W-|vmb|jina}}
* {{Z|hu}}: {{W+|hu|láb}}, {{W+|hu|lábfej}}
* {{Z|xmf}}: {{W-|xmf|კუჩხი}}
* {{Z|egy}}: {{W-egy|rd|h=r:d-rd}}
* {{Z|min}}: {{W-|min|kaki}}
* {{Z|mn}}:
*: Kirîlî: {{W+|mn|хөл|sc=Cyrl}}
*: Mongolî: {{W-|mn|ᠬᠥᠯ}}
* {{Z|nci}}: {{W-|nci|icxitl}}
* {{Z|nah}}: {{W+|nah|icxitl}}
* {{Z|naq}}: {{W-|naq|ǂaidi}}
* {{Z|gld}}: {{W-|gld|бэгди}}
* {{Z|nap}}: {{W-|nap|pere|n}}
* {{Z|nv}}: {{W-|nv|akeeʼ}}
* {{Z|nxq}}: {{W-|nxq|kee}}
* {{Z|nds}}: {{W-|nds|Foot|n}}
* {{Z|nrf}}: {{W-|nrf|pid|n}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|fot|n}}
*: {{Z|nn}}: {{W-|nn|fot|n}}
* {{Z|cst}}: {{W-|cst|konó}}
* {{Z|oj}}: {{W-|oj|nizid}}
* {{Z|oc}}: {{W+|oc|pè|n}}
* {{Z|or}}: {{W+|or|ପଦ}}
* {{Z|om}}: {{W-|om|miilla}}
* {{Z|os}}: {{W-|os|къах}}
* {{Z|ug}}: {{W-|ug|پۇت|sc=ug-Arab}}, {{W+|ug|ئاياغ}}
* {{Z|uz}}: {{W+|uz|oyoq}}
* {{Z|pap}}: {{W-|pap|pia}}
* {{Z|pdt}}: {{W-|pdt|Foot|n}}
* {{Z|pl}}: {{W+|pl|stopa|m}}
* {{Z|roa-opt}}: {{W-|roa-opt|pee}}
* {{Z|pt}}: {{W+|pt|pé|n}}
* {{Z|pim}}: {{W-|pim|mesit}}
* {{Z|pa}}: {{W+|pa|ਪੈਰ|n}}
* {{Z|rgn}}: {{W-|rgn|pè|n}}
* {{Z|rm}}: {{W-|rm|pe}}
* {{Z|rom}}: {{W-|rom|pirri}}, {{W-|rom|pir}}
* {{Z|ro}}: {{W+|ro|picior|nt}}
* {{Z|ru}}: {{W+|ru|нога́|m}}, {{W+|ru|ступня́|m}}, {{W+|ru|стопа́|m}}
* {{Z|ssy}}: {{W-|ssy|iba}}
* Samî:
*: {{Z|smn}}: {{W-|smn|jyelgi}}, {{W-|smn|jyelgilyepi}}
*: {{Z|se}}: {{W-|se|juolgi}}, {{W-|se|juolgeláhpi}}
*: {{Z|sms}}: {{W-|sms|jue´lǧǧ}}, {{W-|sms|jue´lǧǧlää´pp}}
*: {{Z|sma}}: {{W-|sma|juelkie}}
* {{Z|sa}}: {{W+|sa|पद्|tr=pád}}
* {{Z|sc}}: {{W-|sc|pee}}, {{W-|sc|pei|n}}
* {{Z|ceb}}: {{W-|ceb|tiil}}
* {{Z|scn}}: {{W+|scn|pedi|n}}
* {{Z|csm}}: {{W-|csm|háṭ·e·-}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|стопало|nt|sc=Cyrl}}, {{W-|sh|стопа|n}}
*: Latînî: {{W+|sh|stopalo|nt}}, {{W+|sh|stopa|n}}
* {{Z|sco}}: {{W-|sco|fit}}
* {{Z|cu}}: {{W-|cu|нога|m|sc=Cyrs}}
* {{Z|orv}}: {{W-|orv|плесна|m|sc=Cyrs}}
* {{Z|sk}}: {{W+|sk|noha|m}}
* {{Z|sl}}: {{W+|sl|stopalo|nt}}
* {{Z|so}}: {{W-|so|cago}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|noga|m}}
* {{Z|st}}: {{W-|st|leoto}}
* {{Z|es}}: {{W+|es|pie|n}}, {{W+|es|pata|m}}, {{W+|es|pinrel|n}}, {{W+|es|queso}}
* {{Z|su}}: {{W-|su|sampéan}}
* {{Z|sw}}: {{W+|sw|mguu|c7|c8}}
* {{Z|sv}}: {{W+|sv|fot|g}}
* {{Z|xsr}}: {{W-|xsr|རྐང་པ|tr=kangpa}}
* {{Z|tg}}: {{W-|tg|пой}}, {{W+|tg|по}}
* {{Z|tl}}: {{W+|tl|paa}}
* {{Z|twf}}: {{W-|twf|į̏ęnénemą}}
* {{Z|rif}}: {{W-|rif|ḍar|n}}
* {{Z|tsg}}: {{W-|tsg|siki}}
* {{Z|th}}: {{W+|th|เท้า}}
* {{Z|te}}: {{W+|te|పాదము}}
* {{Z|tzm}}: {{W-|tzm|ⴰⴹⴰⵕ|n}}
* {{Z|crh}}: {{W-|crh|ayaq}}
* {{Z|tet}}: {{W-|tet|ain}}
* {{Z|otk}}: {{W-|otk|𐰑𐰴|tr=adaq}}
* {{Z|tr}}: {{W+|tr|ayak}}
* {{Z|bo}}: {{W-|bo|རྐང་པ}}
* {{Z|tpi}}: {{W+|tpi|lek}}, {{W+|tpi|fut}}
* {{Z|xto}}: {{W-|xto|pe}}
* {{Z|txb}}: {{W-|txb|paiyye}}, {{W-|txb|pai}}
* {{Z|tn}}: {{W-|tn|lonao}}
* {{Z|tpn}}: {{W-|tpn|py}}
* {{Z|tpw}}: {{W-|tpw|py}}
* {{Z|tzo}}: {{W-|tzo|okol}}
* {{Z|udi}}: {{W-|udi|тур}}
* {{Z|uga}}: {{W-|uga|𐎔𐎓𐎐}}
* {{Z|xum}}: {{W-|xum|𐌐𐌄𐌛𐌉}}
* {{Z|ur}}: {{W+|ur|پیر|n|tr=pair|sc=ur-Arab}}
* {{Z|uk}}: {{W+|uk|нога́|m}}, {{W-|uk|ступня́|m}}
* {{Z|vec}}: {{W+|vec|pìe}}, {{W+|vec|piè}}, {{W+|vec|pè}}, {{W+|vec|pié}}
* {{Z|vi}}: {{W+|vi|bàn chân}}
* {{Z|vo}}: {{W+|vo|fut}}
* {{Z|wa}}: {{W+|wa|pî}}
* {{Z|war}}: {{W-|war|tiil}}, {{W-|war|siki}}
* {{Z|cy}}: {{W+|cy|troed}}
* {{Z|wym}}: {{W-|wym|füs|n}}
* {{Z|win}}: {{W-|win|sii}}
* {{Z|wo}}: {{W+|wo|tànk}}
* {{Z|km}}: {{W+|km|ជើង}}
* {{Z|yai}}: {{W-|yai|пода}}
* {{Z|yka}}: {{W-|yka|bettis}}
* {{Z|sah}}: {{W-|sah|атах}}
* {{Z|yi}}: {{W-|yi|פֿוס|n}}
* {{Z|esu}}: {{W-|esu|it'gaq}}
* {{Z|el}}: {{W+|el|πόδι|nt}}
*: {{Z|grc}}: {{W-|grc|πούς|n}}
*: {{Z|grc}}: {{W-|grc|πόρ|n}}
* {{Z|zea}}: {{W-|zea|poôt|n}}
* {{Z|za}}: {{W-|za|din}}
* {{Z|zu}}: {{W+|zu|unyawo|c11|c10}}{{werger-bin}}
=== Pêşdaçek ===
{{pêşdaçek|ku}}, {{p-ya nerm}}
# {{maneid|ku|pêşdaçek}} [[bi|Bi]] [[wê]], [[bi]] [[wî]], [[bi]] [[wan]]
#: {{mk|ku|Hevalê min tirimpêl heye, em '''pê''' hatin (anku bi tirimpêlê hatin).}}
#* {{J:Melayê Cizîrî:Dîwana Melayê Cizîrî|jêgirtin=Ji rengê Se'dî û Camî<br>Ji şuhret '''pê''' hisîn 'amî<br>Bi deng û bang û awazê}}
==== Notên bikaranînê ====
[[lêker|Lêkerên]] ku piştî [[lê]]/[[jê]]/[[tê]]/[[pê]] tên, di dema niha a [[bilanî]](subjunctive) de [[bi-]] nastînin. Anku "[[pê xistin|pê bixe]]" na "[[pê xistin|pê xe]]". Heman tişt herwisa gava [[bireser]] "[[xwe]]" dibe jî dibe ("xwe [[gan|bigê]]!" na lê "xwe gê!"). Lê ev tenê bi lêkerên [[qalib]][[req]] ([[stereotypical]]/[[kalıplaşmış]]) li kar e û ew jî [[dever]] bi [[dever]] diguhere, [[mesela]] hin kes dibêjin "lê binêre!, lê bigere!" hin kes jî "lê nêre!, lê gere!", [[bi taybetî]] ên [[hevedudanî]] û [[kurt]] û ên ku [[tim tim]] bi [[lêker]]ên ku [[tim tim]] wek [[lêker]]ên [[alîkar]] tên [[bikaranîn]] (wek [[tê xistin]], [[pê xistin]], [[li xwe kirin]], [[jê kirin]]) "[[bi-]]"a [[rewş]]a [[bilanî]] dikeve.
==== Jê ====
{{kol3|ku
|pê re
}}
==== Etîmolojî ====
Bi [[kurmancî|kurmanciya]] îro [[têkildar]]î {{qertaf|ku|bi|wê}}, [[lê]] di [[esl]]a xwe de ji [[îranî]]kiya [[navîn]] ''pey-'' (bo ku [[mane]]ya ''[[hev]]'' bide [[lêker]]an li kar bû, [[zazakî]] ''{{g|zza|pê}}'' [[hê]] [[wisan]] e) û ''epay'' ([[farisî]] {{g|fa|با|tr=ba}} [[soranî]] ''{{g|ckb|پێ}}'') di [[kurdî|kurdiyên]] [[din]] de [[form]] û [[wate]]ya xwe a [[resen]] a ''pê'' [[parastin|parastiye]] [[ji ber ku]] [[bo ku]] bibêjin ''bi wê/wî'', ew dibêjin ''be'w'' (be ew).
==== Bide ber ====
{{kol3|ku
|jê
|lê
|tê
}}
==== Werger ====
{{werger-ser|bi amûrekê}}
* {{Z|de}}: {{W+|de|mit}}, {{W+|de|mittels}}, {{W+|de|durch}}, {{W+|de|indem}}
* {{Z|az}}: {{W-|az|vasitəsilə}}
* {{Z|cs}}: {{W+|cs|pomocí}}, {{W+|cs|prostřednictvím}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|用|cuda=用…|tr=yòng}}, {{W+|cmn|由|cuda=由…|tr=yóu}}
* {{Z|da}}: {{W+|da|ved}}, {{W-|da|ved at}}
* {{Z|id}}: {{W+|id|kena}}
* {{Z|ar}}: {{W+|ar|بِـ}}
* {{Z|eo}}: {{W+|eo|per}}
* Finnish: ''adessive of the means''
* {{Z|fr}}: {{W+|fr|par}}, {{W+|fr|en}}, au {{W+|fr|moyen}} de
* {{Z|nl}}: {{W+|nl|door}}, {{W+|nl|op}}, {{W+|nl|per}}
* {{Z|he}}: {{W-|he|על ידי|tr=al yedey}}
* {{Z|io}}: {{W+|io|per}}
* {{Z|ang}}: {{W-|ang|þurh}}
* Polish:
* {{Z|en}}: {{W+|en|by}}
* {{Z|it}}: {{W+|it|con}}
* {{Z|ja}}: {{W+|ja|で|cuda=…で|sc=Jpan}}, {{W-|ja|により|cuda=…により|sc=Jpan}}, {{W+|ja|によって|cuda=…によって|tr=…niyotte|sc=Jpan}}
* {{Z|pam}}: {{W-|pam|gamit ing}}, {{W-|pam|gamit naning...}}, {{W-|pam|gamit ning...}}, {{W-|pam|ibat king...}}, {{W-|pam|...ken}}, {{W-|pam|bilang}}
* {{Z|ko}}: {{W+|ko|로써|cuda=...로써}}, {{W+|ko|로|cuda=...로}}
* {{Z|la}}: {{W+|la|per}}, {{W+|la|ab}}
* {{Z|lv}}: {{W+|lv|pa}}
* {{Z|ms}}: {{W+|ms|dengan}}
* {{Z|mt}}: {{W+|mt|bi}}
* {{Z|mi}}: {{W-|mi|nā}}, {{W-|mi|ki}}
* {{Z|hu}}: {{W+|hu|[[-val]]/[[-vel]]}}, {{W+|hu|által}}, {{W+|hu|útján}}, {{W+|hu|révén}}
* {{Z|no}}: {{W+|no|med}}
* {{Z|pt}}: {{W+|pt|por}}, {{W+|pt|a}}
* {{Z|ro}}: {{W+|ro|cu}}
* Russian: }}
* Slovak:, {{W-|sk|so}}, {{W-|sk|pomocou}}}}
* {{Z|sl}}: {{W+|sl|y}}, {{W+|sl|z}}
* {{Z|es}}: {{W+|es|por}}
* {{Z|sv}}: {{W-|sv|genom att}}
* {{Z|zdj}}: {{W-|zdj|ha}}
* {{Z|th}}: {{W+|th|โดย|tr=doy}}
* {{Z|tr}}: {{W+|tr|-la}}, {{W+|tr|-le}}, {{W+|tr|vasıtasıyla}}
* {{Z|uk}}: {{W-|uk|за допомогою}}
* {{Z|vi}}: {{W-|vi|bằng cách}}, {{W-|vi|theo cách}}
* {{Z|cy}}: {{W-|cy|â}}
* {{Z|el}}: {{W+|el|διά}}, {{W+|el|από}}
{{werger-bin}}
:{{werger çavkanî|en|by|beş=Ev qismê Wergerê|oldid=75765074}}
{{werger-ser|bi zimanekî, bi awayekî}}
* {{Z|de}}: {{W+|de|auf}}
* {{Z|my}}: {{W+|my|လို|sc=Mymr}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|用|tr=yòng}}
* {{Z|da}}: {{W+|da|på}}, {{W+|da|med}}
* {{Z|fi}}: {{W+|fi|-ksi}}, {{W-|fi|[[-lla]]/[[-llä]]}}
* {{Z|fr}}: {{W+|fr|en}}
* {{Z|hi}}: {{W+|hi|में}}
* {{Z|nl}}: {{W+|nl|in}}
* {{Z|ang}}: {{W-|ang|on}}
* {{Z|en}}: {{W+|en|in}}
* {{Z|ga}}: {{W+|ga|as}}
* {{Z|it}}: {{W+|it|in}}
* {{Z|ja}}: {{W+|ja|で|sc=Jpan|cuda=...で|tr=...de}}
* {{Z|ko}}: {{W+|ko|로|cuda=...로}}
* {{Z|hu}}: {{W+|hu|-ban}}, {{W+|hu|-ben}}, {{W+|hu|-ul}}, {{W+|hu|-ül}}, {{W+|hu|-val}}, {{W+|hu|-vel}}
* {{Z|nrf}}: {{W-|nrf|en}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|på}}
*: {{Z|nn}}: {{W-|nn|på}}
* {{Z|pl}}: {{W+|pl|po}}, {{W+|pl|w}}
* {{Z|pt}}: {{W+|pt|em}}
* {{Z|ro}}: {{W+|ro|în}}
* {{Z|ru}}: {{W+|ru|по-}}
* {{Z|es}}: {{W+|es|en}}
* {{Z|sv}}: {{W+|sv|på}}, {{W+|sv|i}}
* {{Z|vi}}: {{W+|vi|bằng}}
* {{Z|wa}}: {{W+|wa|e}}
* {{Z|cy}}: {{W+|cy|yn}}
{{werger-bin}}
:{{werger çavkanî|en|in|beş=Ev qismê Wergerê|oldid=75769288}}
=== Hoker ===
{{hoker|ku}}
# {{guharto|ku|pey|w=li pê tiştekî}}
2ixkryqda11h7pj4znaoyjamjzp4o9r
tirimpêl
0
4536
6347589
6325134
2026-09-01T10:54:33Z
Wikihez
7344
/* Notên bikaranînê */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347589
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
=== Navdêr ===
[[Wêne:1947 Dodge Deluxe business coupé.jpg|thumb|250px|tirimpêlek]]
{{navdêr|ku|z=m}}
# {{f|ku|navgîn}} [[makîne|Makîneyeke]] pê[[anîn]] û pê[[birin]]a [[mirov]]an û [[tişt]]an e ku bi taybetî bi [[mazût]]ê dixebite û li ser [[tayre]]yan ango [[teker]]an [[livîn|dilive]].
#: {{hevmane|ku|erebe|otomobîl|seyare|maşîn}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Notên bikaranînê ====
{{agahdarî}} Di kurdî de navê vê [[amraz]]a [[raguhastin]]ê li gor deverên kurd lê dijîn diguhere: Di kurmanciya nivîskî de "tirimpêl" (bi metatezê ji fransî) û "otomobîl" serdest in lê di nav gel de li Bakurê Kurdistanê peyva "[[erebe]]" (bi rêya tirkî ji erebî ji îranî), li Başûr û Rojavayê "[[seyare]]" (ji erebî), li Rojhilatê "[[maşîn]]" (bi rêya farisî ji rusî ji fransî) û di nav kurdên [[Sovyeta berê]] de jî "maşîn" yan "[[avtomaşîn]]" li kar e.
==== Bi alfabeyên din ====
* {{ku-ar|ترمپێل}}
==== Formên alternatîv ====
{{kol3|ku|cure=Herwiha
| {{hw|ku|terembêl}}
| {{hw|ku|terempêl}}
| {{hw|ku|terimbêl}}
| {{hw|ku|terimpêl}}
| {{hw|ku|terumbêl}}
| {{hw|ku|terumpêl}}
| {{hw|ku|tirimbêl}}
| {{hw|ku|tirumbêl}}
| {{hw|ku|tirumpêl}}
| {{hw|ku|torombêl}}
| {{hw|ku|torompêl}}
| {{hw|ku|trembêl}}
| {{hw|ku|trempêl}}
| {{hw|ku|trimbêl}}
| {{hw|ku|trimpêl}}
| {{hw|ku|trumbêl}}
| {{hw|ku|trumpêl}}
| {{hw|ku|turimbêl}}
| {{hw|ku|turimpêl}}
| {{hw|ku|turumbêl}}
| {{hw|ku|turumpêl}}
| {{hw|ku|tumbêl||Amêdî}}
}}
==== Etîmolojî ====
Herwiha {{q|ku|tirimbêl}}, {{q|ku|turumbêl}}, {{q|ku|torombêl}} (û [[hwd]] - ji jor binêre) ji {{q|ku|otomobîl}} ji {{ji|fr|ku|automobile}} ji {{ji|el|ku|αὐτός}} (autós: [[xwe]], bi xwe) + ji {{ji|la|ku|mobilis}} ([[gerok]], [[livok]], [[seyar]], [[mobîl]]). Bo ketina vokalan (herfên bideng) ji destpêka peyvê bide ber: [[Birahîm]] ji [[Îbrahîm]], [[Simaîl]] ji [[Îsmaîl]], [[mîr]] ji [[emîr]]... Zêdebûna dengê R ji ber dengê tirimpêlan e: "rrrr" yan "tirrrr"... Ketina O-ya destpêkê di hin devokên erebî de jî qewimiye, bo nimûne erebiya bakur-rojavayê Afrîkayê: {{g|ar|طوموبيل|tr=tomobîl}}. Bo guherîna B bi P bide ber [[paysikil]] ([[duçerxe]]) ji îngilîzî [[bicycle]], [[pas]] ([[otobûs]]) ji îngilîzî [[bus]] yan [[patrî]] ([[pîl]]) ji îngilîzî [[battery]]... Peyva dirêj "otomobîl" di gelek zimanên din de jî kurt bûye yan guheriye. Bo nimûne di almanî de tenê wek "Auto" û di swêdî de jî bes wek "[[bil]]" maye. Bide ber zazakî {{g|zza|temafîl}}/{{g|zza|temfil}}.
==== Bide ber ====
* {{g|ku|balafir}}
* {{g|ku|keştî}}
* {{g|ku|trên}}
==== Herwiha binêre ====
{{kol3|ku|sernav=Cûnên tirimpêlan
|jêp
|kamyon
|lorî
|qemere
|taksî
|traktor
}}
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W+|af|kar}}, {{W-|af|motorkar}}
* {{Z|akz}}: {{W-|akz|mobìlka}}
* {{Z|sq}}: {{W+|sq|makinë}}, {{W+|sq|automobil|n}}, {{W-|sq|kerr|n}}, {{W-|sq|rrabë}}
* {{Z|pdc}}: {{W-|pdc|Kaer|m}}, {{W-|pdc|Kar|m}}
* {{Z|de}}: {{W+|de|Auto|nt}}, {{W+|de|Automobil|nt}}, {{W+|de|Wagen|n}}, {{W+|de|PKW|n}}, {{W+|de|Karre|m}}
* {{Z|abs}}: {{W-|abs|oto}}
* {{Z|am}}: {{W-|am|መኪና}}
* Apaçî:
*: {{Z|apw}}: {{W-|apw|náłbill}}
* {{Z|aii}}: {{W-|aii|ܪܲܕܵܝܬܵܐ|tr=radāytā|m}}, {{W-|aii|ܐܵܛܢܵܒܹܠ|m}}, {{W-|aii|ܣܲܝܵܪܵܐ|m}}
* {{Z|as}}: {{W-|as|গাড়ী}}
* {{Z|ast}}: {{W-|ast|coche|n}}
* {{Z|az}}: {{W-|az|maşın}}, {{W+|az|avtomobil}}
* {{Z|eu}}: {{W-|eu|autoa}}
* {{Z|ba}}: {{W-|ba|автомобиль}}
* {{Z|be}}: {{W-|be|машы́на|m}}, {{W+|be|аўтамабі́ль|n}}, {{W-|be|аўтамашы́на|m}}, {{W-|be|самахо́д|n}}, {{W-|be|а́ўта|nt}}, {{W-|be|аўто́|nt}}
* {{Z|bn}}: {{W+|bn|গাড়ি}}, {{W+|bn|রথ}}
* {{Z|br}}: {{W+|br|karr|n}}, {{W+|br|gwetur|m}}
* {{Z|bg}}: {{W+|bg|кола́|m}}, {{W+|bg|автомоби́л|n}}
* {{Z|my}}: {{W+|my|ကား}}, {{W+|my|ယဉ်}}
* {{Z|bua}}: {{W-|bua|автомашина}}
* {{Z|cow}}: {{W-|cow|məšín}}
* {{Z|ce}}: {{W-|ce|машен}}, {{W-|ce|автомобиль}}
* {{Z|cs}}: {{W+|cs|auto|nt}}, {{W+|cs|automobil|n}}
* {{Z|chr}}: {{W-|chr|ᏗᎦᏚᎴᏂ}}
* {{Z|ny}}: {{W-|ny|galimoto}}
* {{Z|zh}}:
*: {{Z|yue}}: {{W-|yue|車|tr=ce1}}, {{W-|yue|汽車|tr=hei3 ce1}}
*: {{Z|dng}}: {{W-|dng|машинэ}}, {{W-|dng|чичә}}
*: {{Z|cmn}}: {{W+|cmn|汽車|tr=qìchē}}, {{W+|cmn|車|tr=chē}}, {{W+|cmn|自動車|tr=zìdòngchē}}
*: {{Z|nan}}: {{W+|nan|自動車|tr=chū-tōng-chhia}}, {{W+|nan|風車|tr=hong-chhia}}, {{W+|nan|汽車|tr=khì-chhia}}
* {{Z|da}}: {{W+|da|bil|g}}, {{W+|da|automobil|nt|g}}
* {{Z|dv}}: {{W-|dv|ކާރު|y}}, {{W-|dv|ކާރުތައް|p}}
* {{Z|dtp}}: {{W-|dtp|korita}}
* {{Z|ovd}}: {{W-|ovd|bil|n}}
* {{Z|id}}: {{W+|id|mobil}}, {{W+|id|otomobil}}, {{W+|id|oto}}
* {{Z|ar}}: {{W+|ar|سَيَّارَة|m}}
*: {{Z|arz}}: {{W-|arz|عَرَبِيَّة|m|tr=ʿarabiyya}}
*: {{Z|afb}}: {{W-|afb|سيارة|m|tr=sayyāra}}
*: {{Z|acw}}: {{W-|acw|سَيَّارَة|m|tr=sayyāra}}
*: {{Z|ary}}: {{W-|ary|طوموبيل|m|tr=ṭumubīl}}
* {{Z|hy}}: {{W+|hy|մեքենա}}, {{W+|hy|ավտոմեքենա}}, {{W+|hy|ավտո}},
* {{Z|myv}}: {{W-|myv|ардомапель}}
* {{Z|eo}}: {{W+|eo|aŭtomobilo}}, {{W+|eo|aŭto}}
* {{Z|et}}: {{W+|et|auto}}, {{W-|et|masin}}
* {{Z|gur}}: {{W-|gur|loore}}
* {{Z|fa}}: {{W+|fa|خودرو|tr=xodrow}}, {{W+|fa|ماشین|tr=mâšin}}, {{W+|fa|اتومبیل|tr=otomobil}}, {{W-|fa|موتر|tr=môtar}}
* {{Z|fo}}: {{W+|fo|bilur|n}}
* {{Z|fi}}: {{W+|fi|auto}}
* {{Z|fr}}: {{W+|fr|voiture|m}}, {{W+|fr|auto|m}}, {{W+|fr|automobile|m}}, {{W+|fr|char|n}}
* {{Z|fy}}: {{W-|fy|wein}}
* {{Z|gd}}: {{W-|gd|càr|n}}, {{W-|gd|carbad|n}}
* {{Z|gl}}: {{W+|gl|coche|n}}
* {{Z|gu}}: {{W-|gu|કાર}}
* {{Z|ka}}: {{W-|ka|მანქანა}}, {{W-|ka|ავტო}}, {{W+|ka|ავტომობილი}}, {{W+|ka|ავტომანქანა}}
* {{Z|haw}}: {{W-|haw|kaʻa}}
* {{Z|ha}}: {{W+|ha|mota}}
* {{Z|hi}}: {{W+|hi|गाड़ी|m}}, {{W+|hi|कार|m}}
* {{Z|mww}}: {{W-|mww|lub fai}}
* {{Z|nl}}: {{W+|nl|auto|n}}, {{W+|nl|wagen|n}}, {{W+|nl|automobiel|n}}
* {{Z|hrx}}: {{W-|hrx|Auto|nt}}, {{W-|hrx|Karre|n}}
* {{Z|he}}: {{W+|he|מְכוֹנִית|m|tr=m'khonít}}, {{W+|he|אוֹטוֹ|n|tr=óto}}
* {{Z|io}}: {{W+|io|automobilo}}
* {{Z|ig}}: {{W-|ig|ụgbọ ala}}
* {{Z|en}}: {{W+|en|car}}, {{W+|en|automobile}}
* {{Z|izh}}: {{W-|izh|mašina}}
* {{Z|ia}}: {{W-|ia|auto}}
* {{Z|ik}}: {{W-|ik|qamun}}, {{W-|ik|aksraktuaq}}
* {{Z|ga}}: {{W-|ga|carr|n}}, {{W+|ga|gluaisteán|n}}
* {{Z|it}}: {{W+|it|macchina|m}}, {{W+|it|auto|m}}, {{W+|it|automobile|m}}, {{W+|it|autovettura|m}}
* {{Z|is}}: {{W+|is|bíll|n}}
* {{Z|ja}}: {{W+|ja|車|tr=くるま, kuruma}}, {{W+|ja|自動車|tr=じどうしゃ, jidōsha}}
* {{Z|kl}}: {{W-|kl|biili}}
* {{Z|kam}}: {{W-|kam|ngale}}
* {{Z|kn}}: {{W+|kn|ಕಾರು}}
* {{Z|csb}}: {{W-|csb|aùto|nt}}
* {{Z|ca}}: {{W+|ca|cotxe|n}}, {{W+|ca|automòbil|n}}
* {{Z|qu}}: {{W-|qu|awtu}}
* {{Z|ky}}: {{W+|ky|автомобиль}}, {{W+|ky|машина}}, {{W+|ky|автомашина}}, {{W+|ky|унаа}}
* {{Z|ki}}: {{W-|ki|ngari}}
* {{Z|si}}: {{W-|si|මෝටර රිය}}
* {{Z|kis}}: {{W-|kis|egari}}
* {{Z|ko}}: {{W+|ko|자동차}}, {{W+|ko|차}}
* {{Z|kw}}: {{W-|kw|karr|n}}
* {{Z|co}}: {{W-|co|vittura}}
* {{Z|lou}}: {{W-|lou|shar}}, {{W-|lou|oto}}, {{W-|lou|òdomobìl}}
* {{Z|kri}}: {{W-|kri|motocar}}
* {{Z|cr}}: {{W-|cr|ᒧᐢᑕᑯᒌᐢ}}
* {{Z|lad}}: {{W-|lad|oto}}, {{W-|lad|otomobil}}
* {{Z|la}}: {{W-|la|autocīnētum|nt}}, {{W-|la|autocurrus|n}}, {{W-|la|autovehiculum|nt}}, {{W-|la|autoraeda|m}}
* {{Z|lv}}: {{W-|lv|automašīna|m}}, {{W-|lv|spēkrats|n}}, {{W-|lv|mašīna|m}}
* {{Z|lo}}: {{W+|lo|ລົດ}}, {{W-|lo|ລົດຍົນ}}, {{W-|lo|ລົດໃຫຍ່}}, {{W-|lo|ລົດໂອໂຕ}}, {{W-|lo|ໂອໂຕ}}, {{W-|lo|ຣົຖ}}
* {{Z|lt}}: {{W+|lt|automobilis|n}}, {{W+|lt|mašina|m}}
* {{Z|khb}}: {{W-|khb|ᦷᦟᧆ}}, {{W-|khb|ᦷᦟᧆᦓᦾᧉ}}
* {{Z|luy}}: {{W-|luy|litoka}}
* {{Z|lb}}: {{W+|lb|Auto|nt}}
* {{Z|luo}}: {{W-|luo|mtokaa}}
* {{Z|mk}}: {{W+|mk|кола|m}}, {{W-|mk|автомоби́л|n}}
* {{Z|mg}}: {{W+|mg|fiara}}
* {{Z|ml}}: {{W-|ml|കാര്}}
* {{Z|ms}}: {{W+|ms|kereta}}
* {{Z|mt}}: {{W+|mt|karozza|m}}
* {{Z|mi}}: {{W+|mi|motokā}}, {{W-|mi|motukā}}
* {{Z|mr}}: {{W-|mr|कार}}
* {{Z|mrc}}: {{W-|mrc|tiiwamtor}}
* {{Z|hu}}: {{W+|hu|autó}}, {{W+|hu|automobil}}, {{W+|hu|kocsi}}
* {{Z|mer}}: {{W-|mer|ngari}}
* {{Z|mep}}: {{W-|mep|goorroorij}}
* {{Z|mwl}}: {{W-|mwl|altemoble|n}}, {{W-|mwl|carro|n}}
* {{Z|mn}}:
*: Kirîlî: {{W+|mn|автомашин}}, {{W+|mn|машин}}, {{W-|mn|машин тэрэг}}
*: Mongolî: {{W-|mn|ᠠᠦ᠋ᠲ᠋ᠣᠮᠠᠰᠢᠨ}}, {{W-|mn|ᠮᠠᠱᠢᠨ}}
* {{Z|naq}}: {{W-|naq|audos}}
* {{Z|ne}}: {{W+|ne|कार}}
* {{Z|nrf}}: {{W-|nrf|vaituthe|m}}, {{W-|nrf|moto|n}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|bil|n}}
*: {{Z|no}}: {{W+|no|bil|n}}
* {{Z|oj}}: {{W-|oj|odaabaan}}, {{W-|oj|waasamoowidaabaan}}
* {{Z|ryu}}: {{W-|ryu|車|tr=くるま, kuruma}}
* {{Z|oc}}: {{W+|oc|veitura}}
* {{Z|or}}: {{W+|or|କାର୍}}
* {{Z|om}}: {{W-|om|koonkoolata}}
* {{Z|osa}}: {{W-|osa|oðíhtą}}
* {{Z|os}}: {{W-|os|хӕдтулгӕ}}
* {{Z|ug}}: {{W-|ug|ئاپتوموبىل}}, {{W-|ug|ماشىنا}}
* {{Z|uz}}: {{W+|uz|avtomobil}}, {{W+|uz|avtomashina}}, {{W+|uz|mashina}}
* {{Z|ps}}: {{W+|ps|موټر|n|tr=moṭár}}, {{W-|ps|تېزرفتار|n|tr=tezraftãr}}
* {{Z|pjt}}: {{W-|pjt|mutuka}}
* {{Z|pdt}}: {{W-|pdt|Koa|m}}, {{W-|pdt|Auto|nt}}
* {{Z|pl}}: {{W+|pl|samochód|m-in}}, {{W+|pl|auto|nt}}, {{W+|pl|wóz|}}, {{W+|pl|bryka|}}, {{W+|pl|gablota|}}
* {{Z|pt}}: {{W+|pt|carro|n}}, {{W+|pt|viatura|m}}, {{W+|pt|automóvel|n}}
* Punjabi:
*: Gurmuxî: {{W+|pa|ਗੱਡੀ}}
*: Şahmuxî: {{W-|pa|گَڈّی}}
* {{Z|kk}}: {{W+|kk|машина}}, {{W+|kk|автомобиль}}, {{W-|kk|автомашина}}
* {{Z|cop}}: {{W-|cop|ⲃⲉⲣⲉϭⲱⲟⲩⲧⲥ|m}}
* {{Z|rom}}: {{W-|rom|vurdon|n}}
* {{Z|ro}}: {{W+|ro|mașină|m}}, {{W+|ro|automobil|nt}}
* {{Z|ru}}: {{W+|ru|маши́на|m}}, {{W+|ru|автомоби́ль|n}}, {{W+|ru|автомаши́на|m}}, {{W+|ru|авто́|nt}}, {{W+|ru|та́чка|m}}
* {{Z|rue}}: {{W-|rue|автомобі́л|n}}
* {{Z|se}}: {{W-|se|biila}}
* {{Z|sma}}: {{W-|sma|bïjle}}
* {{Z|smj}}: {{W-|smj|bijlla}}
* {{Z|sms}}: {{W-|sms|autt}}
* {{Z|sm}}: {{W-|sm|taʻavale}}
* {{Z|sa}}: {{W-|sa|कारयान}}
* {{Z|ceb}}: {{W-|ceb|sakyanan}}
* {{Z|szl}}: {{W-|szl|auto|nt}}
* {{Z|srn}}: {{W-|srn|wagi}}, {{W-|srn|oto}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|ко̏ла|nt-p}}, {{W-|sh|а̀уто|nt}}, {{W-|sh|аутомо̀бӣл|n}}
*: Latînî: {{W+|sh|kȍla|nt-p}}, {{W+|sh|àuto|nt}}, {{W+|sh|automòbīl|n}}
* {{Z|sco}}: {{W-|sco|caur}}, {{W-|sco|machine}}
* {{Z|sk}}: {{W+|sk|auto|nt}}, {{W-|sk|automobil|n}}
* {{Z|sl}}: {{W+|sl|avto|n}}, {{W-|sl|avtomobil|n}}
* {{Z|so}}: {{W+|so|babuur|n}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|awto|nt}}
*: {{Z|hsb}}: {{W+|hsb|awto|nt}}
* {{Z|st}}: {{W+|st|koloi}}, {{W-|st|motokara}}
* {{Z|es}}: {{W+|es|coche|n}}, {{W+|es|automóvil|n}}, {{W+|es|auto|n}}, {{W+|es|carro|n}}, {{W+|es|máquina|n}}, {{W+|es|mueble|n}}
* {{Z|su}}: {{W-|su|wahon}}
* {{Z|sux}}: {{W-|sux|𒄑𒇀|tr=gišgigir|ts=gigir}}
* {{Z|sw}}: {{W+|sw|gari|5|6}}, {{W+|sw|motokaa|c9|c10}}
* {{Z|sv}}: {{W+|sv|bil|g}}, {{W+|sv|automobil|g}}
* {{Z|sn}}: {{W-|sn|motokari}}
* {{Z|tg}}: {{W-|tg|автомобил}}, {{W+|tg|мошин}}, {{W-|tg|автомошин}}, {{W-|tg|худрав}}
* {{Z|tl}}: {{W+|tl|kotse}}, {{W-|tl|batlag}}
* {{Z|ta}}: {{W+|ta|வண்டி}}, {{W-|ta|வாகணம்}}
* {{Z|th}}: {{W+|th|รถยนต์}}, {{W+|th|รถ}}
* {{Z|te}}: {{W+|te|కారు}}, {{W+|te|బండి}}, {{W+|te|గాడి}}
* {{Z|tt}}: {{W+|tt|арба}}, {{W-|tt|автомобиль}}
* {{Z|ti}}: {{W-|ti|መኪና}}
* {{Z|tr}}: {{W+|tr|araba}}, {{W+|tr|otomobil}}
* {{Z|tk}}: {{W-|tk|maşyyn}}, {{W+|tk|awtomaşyn}}, {{W+|tk|awtomobil}}
* {{Z|bo}}: {{W-|bo|མོ་ཊ}}
* {{Z|to}}: {{W-|to|kā}}
* {{Z|tum}}: {{W-|tum|galimoto}}
* {{Z|ur}}: {{W-|ur|گاڑی|m|tr=gāṛī}}
* {{Z|uk}}: {{W+|uk|авті́вка|m}}, {{W-|uk|маши́на|m}}, {{W+|uk|авто́|nt}}, {{W+|uk|автомобі́ль|n}}
* {{Z|vi}}: {{W+|vi|xe hơi}}, {{W+|vi|ô tô}}, {{W-|vi|xe ô tô}}, {{W+|vi|xe}}
* {{Z|wa}}: {{W+|wa|oto}}, {{W+|wa|vweteure}}
* {{Z|cy}}: {{W+|cy|car|m}}
* {{Z|wym}}: {{W-|wym|wiöen}}
* {{Z|km}}: {{W+|km|ឡាន}}, {{W+|km|រថ}}
* {{Z|xh}}: {{W-|xh|imoto}}
* {{Z|sah}}: {{W-|sah|массыына}}
* {{Z|yi}}: {{W-|yi|אויטאָמאָביל|n}}, {{W-|yi|אויטאָ|n}}, {{W-|yi|מאַשין|m}}
* {{Z|yo}}: {{W-|yo|ọkọ̀ ayọ́kẹ́lẹ́}}, {{W-|yo|mọ́tò}}, {{W-|yo|ọkọ̀}}
* {{Z|el}}: {{W+|el|αυτοκίνητο|nt}}, {{W+|el|αμάξι|nt}}
* {{Z|za}}: {{W-|za|giceh}}, {{W-|za|heiqci}}, {{W-|za|cihung}}
* {{Z|zu}}: {{W+|zu|imoto}}
{{werger-bin}}
:{{werger çavkanî|en|car|beş=Ev qismê Wergerê|oldid=75740474}}
piohkp0hkhhoxbkdy48ai6twe1bnbvc
xelat
0
4697
6347619
6337962
2026-09-01T11:33:34Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347619
wikitext
text/x-wiki
{{Binêre herwiha|Xelat}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-xelat.wav|dever=Bidlîs}}
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Medals.jpg|thumb|250pix|çend [[medalye]] ku wek xelat tên dayîn]]
{{navdêr|ku|z=m/n}}, {{t-ya nerm}}
# Tiştê kesek [[wergirtin|werdigire]] dema [[biserketin|bi ser dikeve]]<br>(bi taybetî di [[pêşbazî|pêşbaziyekê]] ango [[pêşbirk]]ekê de).
#: {{nm|ku|Xelata yekem 1 000 dolar e.|Yê bibe yekem dê hezar dolaran wergire.|rêz=1}}
#* {{J:Melayê Cizîrî:Dîwana Melayê Cizîrî|jêgirtin=[[ba#Daçek 2|Ba]] mujde û emr û berat</br>Nîşan hinarin hem '''xelat'''</br>Şehzadeya gulgûn qeba}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
{{ku-tewîn-nav|nêr}}
==== Notên bikaranînê ====
:Zayenda vê peyvê di [[kurmanciya navendî]] û [[kurmanciya rojavayî|rojavayî]] de bi piranî mê ye lê di [[kurmanciya rojhilatî]] de bi gelemperî nêr e.
==== Bi alfabeyên din ====
* {{ku-ar|خهلات}}
==== Jê ====
{{kol3|ku|cure=Jê
|xelat bûn<crz:lêker>
|xelat dan<crz:lêker>
|welat girtin
|xelat kirin
|xelat girtin
|xelat danîn
|xelatbûn<crz:navdêr>
|xelatdan<crz:navdêr>
|welatgirtin
|xelatkirin
|xelatwergirtin
|xelatgirtin
|xelatdanîn
|xelatgirtî<crz:rengdêr>
|xelatbexş
|xelatbexşî
|xelatdar
|xelatdarî
|xelatder
|xelatder
|xelatgir
|welatgirî
|xelatî
|xelatwergir
|welatwergirî
}}
==== Etîmolojî ====
Hevreha {{hv|ckb|خهڵات}}, {{hv|fa|خلعت|tr=xel'et|w=[[eba]]yê xelatkirinê}}, {{hv|ota|خلعت}}, {{hv|az|xələt|w=xilat, [[keftan]]}}, {{hv|uz|xalat}}, {{hv|ru|халат}}, {{hv|tr|halat}}... Hemû ji {{deyn|ar|ku|خِلْعَة}} ([[eba]]yê xelatkirinê) ji {{g|ar|خَلَعَ}} ([[ji xwe kirin]], [[ji ber xwe kirin]], [[veşelandin]]). Di zimanên din de wateya "[[eba]], [[kiras]]" yan "ebayê/cilê xelatkirinê" dide lê kurdî (kurmancî û soranî) de wateya "padaşt, xelat" wergirtiye. Bo guherîna ''-i-'' bi ''-e-'' (x'''i'''l'et > x'''e'''lat bidin ber ''[[welat]]'' û ''ʕe'' anku عە (xil'''ʕe'''t > ''xel'''a'''t'') bidin ber ''[['eql]]'' > ''[[aqil]]''.
{{biçûk|
;Çavkanî:
* {{Chyet}},
* {{Tsabolov}}
}}
==== Bide ber ====
{{kol3|ku
|xalet
}}
==== Bi zaravayên din ====
* {{Z|ckb}}: {{W-|ckb|خهڵات}}
Bi kurmancî : psin.
==== Werger ====
{{werger-ser}}
* {{Z|sq}}: {{W+|sq|çmim|n}}
* {{Z|de}}: {{W+|de|Preis|n}}
* {{Z|as}}: {{W-|as|বঁটা}}
* {{Z|az}}: {{W+|az|mükafat}}
* {{Z|be}}: {{W-|be|прэ́мія|m}}, {{W-|be|прыз|n}}, {{W-|be|узнагаро́да|m}}, {{W-|be|нагаро́да|m}}
* {{Z|bn}}: {{W-|bn|প্রাইজ}}, {{W-|bn|পুরষ্কার}}
* {{Z|bg}}: {{W+|bg|награ́да|m}}, {{W+|bg|пре́мия|m}}
* {{Z|my}}: {{W+|my|ဆု}}
* {{Z|cs}}: {{W+|cs|cena|m}}, {{W-|cs|ocenění|nt}}
* {{Z|chr}}: {{W-|chr|ᎠᏓᎪᎾᏙᏗ}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|獎品|tr=jiǎngpǐn}}, {{W+|cmn|獎金|tr=jiǎngjīn}}
* {{Z|da}}: {{W-|da|præmie|g}}, {{W+|da|pris|g}}
* {{Z|ar}}: {{W-|ar|جَائِزَة|m}}, {{W-|ar|مُكَافَأَة|m}}
* {{Z|hy}}: {{W+|hy|մրցանակ}}
* {{Z|et}}: {{W-|et|auhind}}
* {{Z|fa}}: {{W+|fa|جایزه|tr=jâyeze}}, {{W+|fa|مکافات|tr=mokâfât}}, {{W+|fa|انعام|tr=en'âm}}
* {{Z|fi}}: {{W+|fi|palkinto}}
* {{Z|fr}}: {{W+|fr|prix|n}}
* {{Z|ka}}: {{W-|ka|პრიზი}}, {{W+|ka|ჯილდო}}
* {{Z|hi}}: {{W+|hi|इनाम|n}}, {{W+|hi|पुरस्कार|n}}
* {{Z|nl}}: {{W+|nl|prijs|n}}, {{W+|nl|beloning|m}}, {{W+|nl|premie|m}}
* {{Z|he}}: {{W+|he|פְּרָס|n|tr=pras}}
* {{Z|en}}: {{W+|en|prize}}
* {{Z|ga}}: {{W-|ga|duais|m}}
* {{Z|it}}: {{W+|it|premio|n}}
* {{Z|ja}}: {{W+|ja|賞|tr=しょう, shō}}
* {{Z|ca}}: {{W+|ca|premi|n}}
* {{Z|ky}}: {{W+|ky|байге}}, {{W-|ky|приз}}, {{W+|ky|сыйлык}}
* {{Z|ko}}: {{W+|ko|상}}
* {{Z|ltg}}: {{W-|ltg|duovaņs}}, {{W-|ltg|prizs}}
* {{Z|la}}: {{W-|la|praemium|nt}}
* {{Z|lv}}: {{W-|lv|balva|m}}, {{W-|lv|prēmija|m}}
* {{Z|lo}}: {{W-|lo|ລາງວັນ}}
* {{Z|lt}}: {{W-|lt|prizas|n}}, {{W-|lt|premija|m}}
* {{Z|mk}}: {{W-|mk|награда|m}}
* {{Z|mi}}: {{W-|mi|puiaki}}, {{W-|mi|tohu puiaki}}, {{W-|mi|paraihe}}
* {{Z|hu}}: {{W+|hu|díj}}
* {{Z|mn}}:
*: Kirîlî: {{W+|mn|шагнал}}
*: Mongolî: {{W-|mn|ᠱᠠᠩᠨᠠᠯ}}
* {{Z|nds}}: {{W+|nds|Pries}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|premie|n}}, {{W+|nb|pris|n}}
* {{Z|oc}}: {{W+|oc|prèmi|n}}
* {{Z|uz}}: {{W+|uz|mukofot}}, {{W+|uz|sovrin}}
* {{Z|ps}}: {{W+|ps|انعام|n|tr=en'ãm}}
* {{Z|pl}}: {{W+|pl|nagroda|m}}
* {{Z|pt}}: {{W+|pt|prêmio|n}}, {{W+|pt|prémio|n}}
* {{Z|kk}}: {{W-|kk|жүлде}}, {{W-|kk|марапат}}, {{W-|kk|сыйлық}}, {{W-|kk|бәйге}}
* {{Z|ro}}: {{W+|ro|premiu|nt}}
* {{Z|ru}}: {{W+|ru|пре́мия|m}}, {{W+|ru|приз|n}}, {{W+|ru|награ́да|m}}
* {{Z|sa}}: {{W+|sa|मीढ|nt}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|на̑града|m}}
*: Latînî: {{W+|sh|nȃgrada|m}}
* {{Z|sk}}: {{W+|sk|cena|m}}
* {{Z|sl}}: {{W+|sl|nagrada|m}}
* {{Z|es}}: {{W+|es|premio|n}}
* {{Z|sv}}: {{W+|sv|pris|nt}}, {{W+|sv|vinst|g}}
* {{Z|tg}}: {{W+|tg|мукофот}}, {{W-|tg|ҷоиза}}, {{W+|tg|инъом}}
* {{Z|th}}: {{W+|th|รางวัล}}
* {{Z|tt}}: {{W+|tt|бүләк}}
* {{Z|tr}}: {{W+|tr|ödül}}, {{W+|tr|mükafat}}
* {{Z|tk}}: {{W+|tk|baýrak}}
* {{Z|ur}}: {{W+|ur|انعام|n|tr=in'ām}}
* {{Z|uk}}: {{W+|uk|пре́мія|m}}, {{W-|uk|приз|n}}, {{W-|uk|нагоро́да|m}}
* {{Z|vi}}: {{W+|vi|giải thưởng}}, {{W+|vi|giải}}
* {{Z|cy}}: {{W+|cy|gwobr|m}}
* {{Z|km}}: {{W+|km|រង្វាន់}}
* {{Z|yi}}: {{W-|yi|פּרײַז|n}}, {{W-|yi|פּרעמיע|m}}, {{W-|yi|פּריז|n}}
* {{Z|el}}: {{W+|el|βραβείο|nt}}
*: {{Z|grc}}: {{W-|grc|βραβεῖον|nt}}, {{W-|grc|ἆθλον|nt}}
{{werger-bin}}
:{{werger çavkanî|en|prize|beş=Ev qismê Wergerê|oldid=75653361}}
czfjiuhd5iybyg30qg059ie3ykweaic
deqe
0
4795
6347344
6347333
2026-08-31T12:12:10Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347344
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/dɛˈqɛː/}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# 60 [[sanî]]; 1/60 ji [[saet]]ekê.
#* {{bêmînak|ku}}
# [[dem|Demeke]] kurt lê [[nediyar]].
#: ''Ka '''deqe'''kê bise, ez ê vegerim...''
==== Tewandin ====
{{ku-tewîn-nav/nû|mê|guherto=hemû}}
==== Formên alternatîv ====
* [[deqîqe]]
==== Hevmane ====
* [[xulek]]
==== Jê ====
* [[deqeyî]]
==== Etîmolojî ====
Kurtkirina {{q|ku|deqîqe}} ji {{deyn|ar|ku|دَقِيقَة}} ji {{g|ar|دَقِيق|w=hûr, biçûk}} ku herwiha serekaniya peyva {{q|ku|deqîq}} ya kurdî ye jî.
==== Bide ber ====
* [[çirke]]
* [[saet]]
* [[çarêk]]
* [[demjimêrk]]
==== Werger ====
{{werger-ser|16 sanî, 1/60 ji saetekê}}
* {{Z|ab}}: {{W-|ab|аминуҭ}}
* {{Z|ady}}: {{W-|ady|такъикъ}}
* {{Z|af}}: {{W+|af|minuut}}
* {{Z|sq}}: {{W-|sq|imtash|nt}}, {{W+|sq|minutë|n}}
* {{Z|de}}: {{W+|de|Minute|n}}
*: {{Z|gmw-cfr}}: {{W-|gmw-cfr|Menutt}}
* {{Z|am}}: {{W-|am|ደቂቃ}}
* {{Z|an}}: {{W-|an|minuto|nt}}
* {{Z|aii}}: {{W-|aii|ܕܲܩܝܼܩܵܐ|nt|tr=dāqīqa}}
* {{Z|rup}}: {{W-|rup|minutã|n}}
* {{Z|ast}}: {{W+|ast|minutu|nt}}
* {{Z|az}}: {{W+|az|dəqiqə}}
* {{Z|eu}}: {{W+|eu|minutu}}
* {{Z|ba}}: {{W-|ba|минут}}
* {{Z|be}}: {{W-|be|хвілі́на|n}}
* {{Z|bal}}: {{W-|bal|منٹ|tr=minaṭṭ}}
* {{Z|bn}}: {{W+|bn|মিনিট}}
* {{Z|br}}: {{W+|br|munut|nt}}
* {{Z|bg}}: {{W-|bg|мину́та|n}}
* {{Z|my}}: {{W+|my|မိနစ်}}
* {{Z|cs}}: {{W+|cs|minuta|n}}
* {{Z|chr}}: {{W-|chr|ᎢᏯᏔᏬᏍᏔᏅᎢ}}
* {{Z|ny}}: {{W-|ny|miniti}}, {{W-|ny|mphindi}}
* {{Z|zh}}:
*: {{Z|yue}}: {{W-|yue|分鐘|tr=fan1 zung1}}
*: {{Z|dng}}: {{W-|dng|фынҗун}}, {{W-|dng|минута}}
*: {{Z|hak}}: {{W-|hak|分鐘|tr=fûn-chûng}}
*: {{Z|cmn}}: {{W+|cmn|分鐘|tr=fēnzhōng}}, {{W+|cmn|分|tr=fēn}}
*: {{Z|cdo}}: {{W-|cdo|分鐘|tr=hŭng-cṳ̆ng}}
*: {{Z|nan}}: {{W+|nan|分鐘|tr=hun-cheng}}
*: {{Z|wuu}}: {{W-|wuu|分鐘}}
* {{Z|da}}: {{W+|da|minut|nt}}
* {{Z|dtp}}: {{W-|dtp|minit}}
* {{Z|id}}: {{W+|id|menit}}, {{W-|id|minit}}, {{W+|id|minuta}}
* {{Z|ar}}: {{W+|ar|دَقِيقَة|n}}
*: {{Z|afb}}: {{W-|afb|دِقيقة|tr=digīgə}}
*: {{Z|ary}}: {{W-|ary|دقيقة|n|tr=dagīga|cuda=دَقِيقة}}
*: {{Z|ary}}: {{W-|ary|دقيقة|n|tr=dqīqa}}
* {{Z|hy}}: {{W+|hy|րոպե}}, {{W-|hy|վայրկեան}}
*: {{Z|xcl}}: {{W-|xcl|վայրկեան}}
* {{Z|eo}}: {{W+|eo|minuto}}
* {{Z|et}}: {{W+|et|minut}}, {{W+|et|mint}}
* {{Z|gur}}: {{W-|gur|miniti}}
* {{Z|fa}}: {{W+|fa|دقیقه|tr=daqiqe}}
* {{Z|fo}}: {{W-|fo|minuttur|nt}}
* {{Z|fj}}: {{W+|fj|miniti}}
* {{Z|fi}}: {{W+|fi|minuutti}}
* {{Z|fr}}: {{W+|fr|minute|n}}
* {{Z|fy}}: {{W-|fy|minút|g}}
* {{Z|gd}}: {{W-|gd|mionaid|n}}
* {{Z|gl}}: {{W-|gl|minuto|nt}}
* {{Z|gu}}: {{W-|gu|મિનિટ}}
* {{Z|ka}}: {{W-|ka|წუთი}}
* {{Z|ha}}: {{W-|ha|minti}}
* {{Z|hi}}: {{W+|hi|मिनट|nt}}
* {{Z|mww}}: {{W-|mww|feeb}}
* {{Z|nl}}: {{W+|nl|minuut|g}}
* {{Z|he}}: {{W-|he|דַּקָּה|n|tr=daká}}
* {{Z|io}}: {{W+|io|minuto}}
* {{Z|enm}}: {{W-|enm|mynute}}
* {{Z|en}}: {{W+|en|minute}}
* {{Z|inh}}: {{W-|inh|минот}}
* {{Z|ia}}: {{W-|ia|minuta}}
* {{Z|ga}}: {{W+|ga|nóiméad|nt}}, {{W-|ga|bomaite|nt}}
* {{Z|it}}: {{W+|it|minuto|nt}}
* {{Z|is}}: {{W+|is|mínúta|n}}
* {{Z|ja}}: {{W+|ja|分|tr=ふん, fun}}
* {{Z|kbd}}: {{W-|kbd|дакъикъэ}}
* {{Z|xal}}: {{W-|xal|агчм}}
* {{Z|kn}}: {{W+|kn|ನಿಮಿಷ}}
* {{Z|ca}}: {{W+|ca|minut|nt}}
* {{Z|qu}}: {{W-|qu|chinini}}
* {{Z|ky}}: {{W+|ky|мүнөт}}
* {{Z|si}}: {{W+|si|විනාඩිය}}, {{W-|si|මිනිත්තුව}}
* {{Z|ko}}: {{W+|ko|분}}
* {{Z|la}}: {{W+|la|minuta|n}}, {{W-|la|horae pars sexagesima}}
* {{Z|lv}}: {{W-|lv|minūte|n}}
* {{Z|lo}}: {{W+|lo|ນາທີ}}
* {{Z|lez}}: {{W-|lez|декьикьа}}
* {{Z|lt}}: {{W+|lt|minutė|n}}
* {{Z|lb}}: {{W-|lb|Minutt|n}}
* {{Z|mk}}: {{W+|mk|минута|n}}
* {{Z|ml}}: {{W+|ml|മിനിറ്റ്}}
* {{Z|ms}}: {{W+|ms|minit}}
* {{Z|mt}}: {{W-|mt|minuta|n}}
* {{Z|mi}}: {{W-|mi|miniti}}
* {{Z|mr}}: {{W-|mr|मिनिट}}
* {{Z|hu}}: {{W+|hu|perc}}
* {{Z|gdq}}: {{W-|gdq|دقيقت}}
* {{Z|mn}}:
*: {{Z|mn}}: {{W+|mn|минут}}, {{W+|mn|жижиг}}
*: {{Z|mn}}: {{W-|mn|ᠮᠢᠨᠦ᠋ᠲ}}, {{W-|mn|ᠵᠢᠵᠢᠭ}}
* {{Z|nv}}: {{W-|nv|dah alzhin}}
* {{Z|ne}}: {{W-|ne|मिनेट}}
* {{Z|nrf}}: {{W-|nrf|minnute|n}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|minutt|nt}}
*: {{Z|nn}}: {{W+|nn|minutt|nt|nt}}
* {{Z|oj}}: {{W-|oj|diba'igaans}}
* {{Z|oc}}: {{W+|oc|minuta}}
* {{Z|or}}: {{W-|or|ମିନଟ}}
* {{Z|ug}}: {{W-|ug|مىنۇت}}
* {{Z|uz}}: {{W+|uz|daqiqa}}
* {{Z|ps}}: {{W+|ps|دقيقه|n|tr=daqiqá}}, {{W-|ps|منټ|n|tr=minëṭ}}
* {{Z|pdt}}: {{W-|pdt|Minnut|n}}
* {{Z|pl}}: {{W+|pl|minuta|n}}
* {{Z|pt}}: {{W+|pt|minuto|nt}}
* {{Z|pa}}: {{W-|pa|ਮਿੰਟ}}
* {{Z|kk}}: {{W+|kk|минут}}
* {{Z|cop}}: {{W-|cop|ⲥⲟⲩⲥⲟⲩ}}
* {{Z|rgn}}: {{W-|rgn|minùt|nt}}
* {{Z|rm}}: {{W-|rm|minuta|n}}, {{W-|rm|minut|nt}}
* {{Z|ro}}: {{W+|ro|minut|nt}}
* {{Z|ru}}: {{W-|ru|мину́та|n}}
* {{Z|sc}}:
*: {{Z|sc}}: {{W-|sc|minutu|nt}}
* {{Z|ceb}}: {{W-|ceb|gutlo}}, {{W-|ceb|mitna}}, {{W-|ceb|minuto}}
* {{Z|scn}}: {{W+|scn|minutu|nt}}
* {{Z|sh}}:
*: {{Z|sh}}: {{W-|sh|мину́та|n}}, {{W-|sh|мѝнӯт|nt}}
*: {{Z|sh}}: {{W+|sh|minúta|n}}, {{W+|sh|mìnūt|nt}}
* {{Z|sco}}: {{W-|sco|meenit}}
* {{Z|sk}}: {{W+|sk|minúta|n}}
* {{Z|sl}}: {{W+|sl|minuta|n}}
* {{Z|so}}: {{W-|so|daqiiqad}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|minuta|n}}
* {{Z|es}}: {{W+|es|minuto|nt}}
* {{Z|sw}}: {{W+|sw|dakika}}
* {{Z|sv}}: {{W+|sv|minut|g}}
* {{Z|tg}}: {{W-|tg|дақиқа}}
* {{Z|tl}}: {{W+|tl|minuto}}, {{W+|tl|sandali}}
* {{Z|ta}}: {{W+|ta|நிமிடம்}}, {{W+|ta|நிமிஷம்}}, {{W+|ta|மணித்துளி}}, {{W+|ta|நுணுத்தம்}}
* {{Z|th}}: {{W+|th|นาที}}
* {{Z|te}}: {{W+|te|నిమిషము}}
* {{Z|crh}}: {{W-|crh|daqqa}}
* {{Z|tt}}: {{W-|tt|минут}}
* {{Z|ti}}: {{W-|ti|ደቒቕ}}
* {{Z|tr}}: {{W+|tr|dakika}}
* {{Z|tk}}: {{W-|tk|minut}}
* {{Z|bo}}: {{W-|bo|སྐར་མ}}
* {{Z|tyv}}: {{W-|tyv|минут}}, {{W-|tyv|минута}}
* {{Z|ur}}: {{W-|ur|دقیقہ|nt|tr=daqīqā}}, {{W-|ur|مِنَٹ|nt|tr=minaṭ}}
* {{Z|uk}}: {{W-|uk|хвили́на|n}}
* {{Z|vi}}: {{W+|vi|phút}}
* {{Z|vo}}: {{W+|vo|minut}}
* {{Z|wa}}: {{W+|wa|munute|n}}
* {{Z|cy}}: {{W+|cy|munud}}
* {{Z|km}}: {{W+|km|នាទី}}
* {{Z|sah}}: {{W-|sah|мүнүүтэ}}
* {{Z|yi}}: {{W+|yi|מינוט|n}}
* {{Z|el}}: {{W+|el|λεπτό|nt}}
* {{Z|za}}: {{W-|za|faencung}}
{{werger-bin}}
:{{werger çavkanî|en|minute|beş=Ev qismê Wergerê|oldid=75764140}}
{{werger-ser|demeke kurt lê nediyarkirî}}
* {{Z|de}}: {{W+|de|Moment|n}}
* {{Z|ast}}: {{W+|ast|minutu|n}}
* {{Z|eu}}: {{W+|eu|minutu}}, {{W+|eu|momentu}}
* {{Z|bn}}: {{W+|bn|মিনিট}}, {{W-|bn|মুহূর্ত}}
* {{Z|bg}}: {{W-|bg|моме́нт|n}}
* {{Z|cs}}: {{W+|cs|minuta|m}}, {{W+|cs|minutka|m}}, {{W+|cs|vteřina|m}}, {{W+|cs|chvilka|m}}
* {{Z|ny}}: {{W-|ny|mphindi}}
* {{Z|hy}}: {{W+|hy|րոպե}}
* {{Z|et}}: {{W-|et|hetk}}, {{W-|et|hetk}}, {{W+|et|moment}}
* {{Z|fi}}: {{W+|fi|hetki}}, {{W+|fi|hetkinen}}
* {{Z|fr}}: {{W+|fr|minute|m}}, {{W+|fr|moment|n}}, {{W+|fr|instant|n}}
* {{Z|gd}}: {{W-|gd|mionaid|m}}
* {{Z|gl}}: {{W-|gl|minuto|n}}
* {{Z|nl}}: {{W+|nl|minuutje|nt}}, {{W+|nl|secondje|nt}}, {{W+|nl|moment|nt}}
* {{Z|he}}: {{W-|he|רֶגַע|tr=réga|n}}, {{W-|he|זְמַן קָצָר|n|tr=zman katsár}}
* {{Z|enm}}: {{W-|enm|mynute}}
* {{Z|en}}: {{W+|en|minute}}, {{W+|en|moment}}
* {{Z|it}}: {{W+|it|attimo|n}}, {{W+|it|momento|n}}
* {{Z|is}}: {{W-|is|augablik|nt}}, {{W+|is|mínúta|m}}
* {{Z|ca}}: {{W+|ca|segon|n}}, {{W+|ca|moment|n}}
* {{Z|lt}}: {{W+|lt|minutė|m}}, {{W-|lt|akimirka|m}}
* {{Z|mk}}: {{W-|mk|моме́нт|n}}, {{W+|mk|минута|m}}
* {{Z|ms}}: {{W-|ms|sekejap}}
* {{Z|mt}}: {{W-|mt|minuta}}
* {{Z|hu}}: {{W+|hu|perc}}, {{W+|hu|pillanat}}
* {{Z|nrf}}: {{W-|nrf|minnute|m}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|øyeblikk|nt}}
* {{Z|pl}}: {{W+|pl|minuta|m}}, {{W+|pl|minutka|m}}, {{W+|pl|chwila|m}}, {{W+|pl|moment|m-in}}
* {{Z|pt}}: {{W+|pt|instante|n}}, {{W+|pt|minuto|n}}, {{W+|pt|momento|n}}
* {{Z|ro}}: {{W+|ro|minut|nt}}
* {{Z|ru}}: {{W-|ru|мину́та|m}}
* {{Z|ceb}}: {{W-|ceb|kadiyot}}
* {{Z|sco}}: {{W-|sco|meenit}}
* {{Z|es}}: {{W+|es|minuto|n}}, {{W+|es|momento|n}}
* {{Z|sw}}: {{W+|sw|dakika}}
* {{Z|sv}}: {{W+|sv|ögonblick|nt}}
* {{Z|tl}}: {{W+|tl|sandali}}
* {{Z|th}}: {{W-|th|แป๊บเดียว|tr=bpáep dieow}}
* {{Z|tr}}: {{W+|tr|dakika}}
* {{Z|vi}}: {{W+|vi|lát}}, {{W+|vi|chốc}}
* {{Z|wa}}: {{W+|wa|munute|m}}, {{W+|wa|houbonde|m}}, {{W+|wa|åvé|m}}
* {{Z|el}}: {{W+|el|στιγμή|m}}, {{W+|el|λεπτό|nt}}
{{werger-bin}}
:{{werger çavkanî|en|minute|beş=Ev qismê Wergerê|oldid=75764140}}
no5xrro21ai10tsn2os4eghx50vgr5h
hunermendî
0
4887
6347473
6325971
2026-08-31T20:50:16Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347473
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[kar|Kar]]ê [[hunermend]]an; tiştên [[hunermend]] dikin.
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026|jêgirtin=Spîkerê Radyoya Rewanê Keremê Seyad, di sala 1971an li ser '''hunermendiya''' Zadîna Şekir nivîseke gelek hewaskar weşandiye. }}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Formên alternatîv ====
* [[hinerkarî]]
* [[hinermendî]]
* [[hunerkarî]]
* [[hunerwarî]]
* [[hunerane]]
==== Hevmane ====
* [[sin'etkarî]]
==== Etîmolojî ====
Ji {{paş|ku|hunermend|-î}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|Geschicklichkeit}} {{mê}}
* {{Z|fa}}: {{W|fa|هنرمندی}}, {{W|fa|هنرکاری}}, {{W|fa|هنرکاری}}
* {{Z|en}}: {{W|en|artistry}}, {{W|en|knack}}, {{W|en|artistical|guman=erê}}, {{W|en|artefact|guman=erê}}
* {{Z|tr}}: {{W|tr|sanatçılık}}, {{W|tr|sanatkârlık}}, {{W|tr|artistik}}, {{W|tr|sanatvari}}
{{werger-bin}}
ggamoxq7itfpkobddfs676bxxg87hqh
6347504
6347473
2026-08-31T22:12:15Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347504
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[kar|Karê]] [[hunermend]]an; tiştên [[hunermend]] dikin.
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026|jêgirtin=Spîkerê Radyoya Rewanê Keremê Seyad, di sala 1971an li ser '''hunermendiya''' Zadîna Şekir nivîseke gelek hewaskar weşandiye. }}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Formên alternatîv ====
* [[hinerkarî]]
* [[hinermendî]]
* [[hunerkarî]]
* [[hunerwarî]]
* [[hunerane]]
==== Hevmane ====
* [[sin'etkarî]]
==== Etîmolojî ====
Ji {{paş|ku|hunermend|-î}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|Geschicklichkeit}} {{mê}}
* {{Z|fa}}: {{W|fa|هنرمندی}}, {{W|fa|هنرکاری}}, {{W|fa|هنرکاری}}
* {{Z|en}}: {{W|en|artistry}}, {{W|en|knack}}, {{W|en|artistical|guman=erê}}, {{W|en|artefact|guman=erê}}
* {{Z|tr}}: {{W|tr|sanatçılık}}, {{W|tr|sanatkârlık}}, {{W|tr|artistik}}, {{W|tr|sanatvari}}
{{werger-bin}}
82xcsnx2u2pfqw3ajgl7rcpgydayytq
hejîn
0
5414
6347508
6341455
2026-09-01T00:36:21Z
Kamy1r
15310
/* Bi alfabeyên din */
6347508
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Lêker ===
{{ku-tewîn-lk|hejîn|form=negerguhêz|niha=hej|borî=hejî}}
{{lêker|ku|c=x-ngh}}
# [[pêşûpaş]] li [[hewa]] [[livîn]]
#* {{J:Yaşar Kemal:Dara Hinarê|jêgirtin=Şaxên hîro yên ku di tozê de mabûn, '''hejiyan'''. Ew pinpinîka şîn jî '''hejiya''' lê ji cihê xwe tevneliviya.}}
# [[hezîn]], [[cirifîn]], [[lerizîn]], wekî [[erdhejî]]
#* {{J:Firat Cewerî:Girtî:1986|jêgirtin=Dest û çongên wê wilo '''dihejiyan''', ku mirov digot a wextî ew were xwarê.}}
# naveke bo keçan
#* {{bênimûne|ku}}
==== Bi alfabeyên din ====
* {{ku-ar|ههژین}}
2nd coolest human alive and best at eye liner
==== Formên alternatîv ====
{{kol3|ku
|hejan
|hejhan
|hejhîn
|hejihan
|hejihîn
|hejiyan
|hijîn
|hijhan
|hijhîn
|hijihan
|hijihîn
|hijiyan
}}
==== Jê ====
{{kol3|ku
|hejbar
|hejbarî
|hejber
|hejberî
|hejhejok
|hejhejokî
|hejok
|hejokî
}}
==== Têkildar ====
* [[hejandin]]
==== Etîmolojî ====
Ji {{ji|ar|ku|هَزَّ|w=hejandin}} ji rehê {{g|ar|ه ز ز}} + [[paşgir]]a kurdî {{qertaf|ku|-în}}. Di peyvên biyanî ên ku dikevin kurdî de, /d/ dibin /z/ û /z/ dibin /j/; bide ber {{q|ku|miraz}}, {{q|ku|pêşniyaz}}, {{q|ku|diroz}}, {{q|ku|mêj}}. Herwiha, gelek caran teşeyên [[kurdandin|nekurdandî]] jî peyda dibin wek {{q|ku|hezîn}}. Ji heman rehî herwiha soranî {{g|ckb|هەژان}}. Chyet jî peyvê dide ber {{ji|ar|ku|هَزَّ}}; ÇabolovTsabolov idia dike ku bi "[[pêşlêker]]"a "he-" ji [[jenîn]] e lê ev ihtimala vê pir kêm e.
<sup>'''Çavkanî''': <br>* {{Chyet}} <br>* {{Tsabolov}}</sup>
==== Bide ber ====
{{kol2|ku
|firîn
|livîn
|meşîn
}}
==== Herwiha binêre ====
{{kol3|ku
|hejandin
|hejandî
|hejiyayî
|hejîner
|hejînerî
}}
==== Nêzîkî ====
* [[lerizîn]]
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|beben}}, {{W|de|schwingen}}, {{W|de|schaukeln}}, {{W|de|schwanken}}, {{W|de|Anregung|f}}, {{W|de|Erschütterung|f}}, {{W|de|Vibrieren}}, {{W|de|pendeln}}, {{W|de|schlottern}}, {{W|de|sich wiegen}}, {{W|de|vibrieren}}, {{W|de|zittern}}, {{W|de|zucken}}, {{W|de|Fluktuation|f|guman=erê}}, {{W|de|Ruck|m|guman=erê}}
* {{Z|cs}}: {{W|cs|houpat se}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W|cmn|擺動|sc=Hani}}, {{W|cmn|摆动|tr=bǎidòng}}, {{W|cmn|搖擺|sc=Hani}}, {{W|cmn|摇摆|tr=yáobǎi}}, {{W|cmn|擺蕩|sc=Hani}}, {{W|cmn|摆荡|tr=bǎidàng}}, {{W|cmn|擺|sc=Hani}}, {{W|cmn|摆|tr=bǎi}}
* {{Z|ar}}: {{W|ar|تأرجح|tr=ta'árjaHa}}, {{W|ar|الإهتزاز}}, {{W|ar|التمرمر|guman=erê}}, {{W|ar|التهزز|guman=erê}}, {{W|ar|الملد|guman=erê}}
* {{Z|eo}}: {{W|eo|balanci|xs=Esperanto}}
* {{Z|fa}}: {{W|fa|لرزه}}, {{W|fa|لرزش}}, {{W|fa|لرزیدن}}, {{W|fa|تکان خوردن}}, {{W|fa|ارتعاش}}
* {{Z|fi}}: {{W|fi|heilua}}, {{W|fi|keinua}}
* {{Z|fr}}: {{W|fr|osciller}}, {{W|fr|se balancer}}, {{W|fr|balancer}}
* {{Z|en}}: to {{W|en|swing}}, to [[sway]], {{W|en|shake}}, {{W|en|spouse}}, {{W|en|tremble}}, {{W|en|waggle}}, {{W|en|wave}}, {{W|en|jiggly}}, {{W|en|stirring}}, {{W|en|vacillating}}, {{W|en|convulsionary}}, {{W|en|concussion|guman=erê}}, {{W|en|flutier|guman=erê}}, {{W|en|oscillate|guman=erê}}, {{W|en|pendulate|guman=erê}}, {{W|en|quacking|guman=erê}}, {{W|en|quake|guman=erê}}, {{W|en|quivering|guman=erê}}, {{W|en|rattle|guman=erê}}, {{W|en|shiver|guman=erê}}, {{W|en|shudder|guman=erê}}, {{W|en|succussion|guman=erê}}, {{W|en|thrill|guman=erê}}, {{W|en|tremor|guman=erê}}, {{W|en|vacillate|guman=erê}}, {{W|en|vacillation|guman=erê}}, {{W|en|whiffet|guman=erê}}, {{W|en|whiffle|guman=erê}}, {{W|en|wiggle|guman=erê}}
* {{Z|is}}: {{W|is|sveiflast}}
* {{Z|ja}}: {{W|ja|振れる|tr=ふれる, fureru}}, {{W|ja|揺さぶる|tr=ゆさぶる, yusaburu}}, {{W-|ja|揺れる|tr=ゆれる, yureru}}
* {{Z|hu}}: {{W|hu|leng}}, {{W|hu|himbálózik}}
* {{Z|pt}}: {{W|pt|balançar}}
* {{Z|ro}}: {{W|ro|balansa}}, {{W|ro|legăna}}
* {{Z|ru}}: {{W|ru|качаться|tr=kačát’sja}}, {{W|ru|раскачиваться|tr=raskáčivat’sja}}
* {{Z|sv}}: {{W|sv|gunga}}, {{W|sv|svinga}}
* {{Z|tr}}: {{W|tr|deprenmek}}, {{W|tr|sarsılmak}}, {{W|tr|sallanmak}}
* {{Z|el}}: {{W|el|κουνιέμαι|tr=kuniemai}}
{{werger-bin}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# {{mane?|ku}}
#* {{bênimûne|ku}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Werger ====
{{werger-ser}}
* {{Z|tr}}: {{W|tr|deprenme}}, {{W|tr|sallanış}}, {{W|tr|sallanma}}, {{W|tr|sarsılış}}, {{W|tr|sarsılma}}, {{W|tr|sallantı}}, {{W|tr|sarsım}}, {{W|tr|tezelzül}}, {{W|tr|rakıs}}
{{werger-bin}}
7vuiai4klaj7rjxg1i5fbhr7vt4mkdu
6347515
6347508
2026-09-01T06:32:50Z
Wikihez
7344
Guhartinên [[Special:Contributions/Kamy1r|Kamy1r]] ([[User talk:Kamy1r|gotûbêj]]) hatine betalkirin, vegerand guhartoya dawî ya [[User:Balyozbot|Balyozbot]]
6341455
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Lêker ===
{{ku-tewîn-lk|hejîn|form=negerguhêz|niha=hej|borî=hejî}}
{{lêker|ku|c=x-ngh}}
# [[pêşûpaş]] li [[hewa]] [[livîn]]
#* {{J:Yaşar Kemal:Dara Hinarê|jêgirtin=Şaxên hîro yên ku di tozê de mabûn, '''hejiyan'''. Ew pinpinîka şîn jî '''hejiya''' lê ji cihê xwe tevneliviya.}}
# [[hezîn]], [[cirifîn]], [[lerizîn]], wekî [[erdhejî]]
#* {{J:Firat Cewerî:Girtî:1986|jêgirtin=Dest û çongên wê wilo '''dihejiyan''', ku mirov digot a wextî ew were xwarê.}}
# naveke bo keçan
#* {{bênimûne|ku}}
==== Bi alfabeyên din ====
* {{ku-ar|ههژین}}
==== Formên alternatîv ====
{{kol3|ku
|hejan
|hejhan
|hejhîn
|hejihan
|hejihîn
|hejiyan
|hijîn
|hijhan
|hijhîn
|hijihan
|hijihîn
|hijiyan
}}
==== Jê ====
{{kol3|ku
|hejbar
|hejbarî
|hejber
|hejberî
|hejhejok
|hejhejokî
|hejok
|hejokî
}}
==== Têkildar ====
* [[hejandin]]
==== Etîmolojî ====
Ji {{ji|ar|ku|هَزَّ|w=hejandin}} ji rehê {{g|ar|ه ز ز}} + [[paşgir]]a kurdî {{qertaf|ku|-în}}. Di peyvên biyanî ên ku dikevin kurdî de, /d/ dibin /z/ û /z/ dibin /j/; bide ber {{q|ku|miraz}}, {{q|ku|pêşniyaz}}, {{q|ku|diroz}}, {{q|ku|mêj}}. Herwiha, gelek caran teşeyên [[kurdandin|nekurdandî]] jî peyda dibin wek {{q|ku|hezîn}}. Ji heman rehî herwiha soranî {{g|ckb|هەژان}}. Chyet jî peyvê dide ber {{ji|ar|ku|هَزَّ}}; ÇabolovTsabolov idia dike ku bi "[[pêşlêker]]"a "he-" ji [[jenîn]] e lê ev ihtimala vê pir kêm e.
<sup>'''Çavkanî''': <br>* {{Chyet}} <br>* {{Tsabolov}}</sup>
==== Bide ber ====
{{kol2|ku
|firîn
|livîn
|meşîn
}}
==== Herwiha binêre ====
{{kol3|ku
|hejandin
|hejandî
|hejiyayî
|hejîner
|hejînerî
}}
==== Nêzîkî ====
* [[lerizîn]]
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|beben}}, {{W|de|schwingen}}, {{W|de|schaukeln}}, {{W|de|schwanken}}, {{W|de|Anregung|f}}, {{W|de|Erschütterung|f}}, {{W|de|Vibrieren}}, {{W|de|pendeln}}, {{W|de|schlottern}}, {{W|de|sich wiegen}}, {{W|de|vibrieren}}, {{W|de|zittern}}, {{W|de|zucken}}, {{W|de|Fluktuation|f|guman=erê}}, {{W|de|Ruck|m|guman=erê}}
* {{Z|cs}}: {{W|cs|houpat se}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W|cmn|擺動|sc=Hani}}, {{W|cmn|摆动|tr=bǎidòng}}, {{W|cmn|搖擺|sc=Hani}}, {{W|cmn|摇摆|tr=yáobǎi}}, {{W|cmn|擺蕩|sc=Hani}}, {{W|cmn|摆荡|tr=bǎidàng}}, {{W|cmn|擺|sc=Hani}}, {{W|cmn|摆|tr=bǎi}}
* {{Z|ar}}: {{W|ar|تأرجح|tr=ta'árjaHa}}, {{W|ar|الإهتزاز}}, {{W|ar|التمرمر|guman=erê}}, {{W|ar|التهزز|guman=erê}}, {{W|ar|الملد|guman=erê}}
* {{Z|eo}}: {{W|eo|balanci|xs=Esperanto}}
* {{Z|fa}}: {{W|fa|لرزه}}, {{W|fa|لرزش}}, {{W|fa|لرزیدن}}, {{W|fa|تکان خوردن}}, {{W|fa|ارتعاش}}
* {{Z|fi}}: {{W|fi|heilua}}, {{W|fi|keinua}}
* {{Z|fr}}: {{W|fr|osciller}}, {{W|fr|se balancer}}, {{W|fr|balancer}}
* {{Z|en}}: to {{W|en|swing}}, to [[sway]], {{W|en|shake}}, {{W|en|spouse}}, {{W|en|tremble}}, {{W|en|waggle}}, {{W|en|wave}}, {{W|en|jiggly}}, {{W|en|stirring}}, {{W|en|vacillating}}, {{W|en|convulsionary}}, {{W|en|concussion|guman=erê}}, {{W|en|flutier|guman=erê}}, {{W|en|oscillate|guman=erê}}, {{W|en|pendulate|guman=erê}}, {{W|en|quacking|guman=erê}}, {{W|en|quake|guman=erê}}, {{W|en|quivering|guman=erê}}, {{W|en|rattle|guman=erê}}, {{W|en|shiver|guman=erê}}, {{W|en|shudder|guman=erê}}, {{W|en|succussion|guman=erê}}, {{W|en|thrill|guman=erê}}, {{W|en|tremor|guman=erê}}, {{W|en|vacillate|guman=erê}}, {{W|en|vacillation|guman=erê}}, {{W|en|whiffet|guman=erê}}, {{W|en|whiffle|guman=erê}}, {{W|en|wiggle|guman=erê}}
* {{Z|is}}: {{W|is|sveiflast}}
* {{Z|ja}}: {{W|ja|振れる|tr=ふれる, fureru}}, {{W|ja|揺さぶる|tr=ゆさぶる, yusaburu}}, {{W-|ja|揺れる|tr=ゆれる, yureru}}
* {{Z|hu}}: {{W|hu|leng}}, {{W|hu|himbálózik}}
* {{Z|pt}}: {{W|pt|balançar}}
* {{Z|ro}}: {{W|ro|balansa}}, {{W|ro|legăna}}
* {{Z|ru}}: {{W|ru|качаться|tr=kačát’sja}}, {{W|ru|раскачиваться|tr=raskáčivat’sja}}
* {{Z|sv}}: {{W|sv|gunga}}, {{W|sv|svinga}}
* {{Z|tr}}: {{W|tr|deprenmek}}, {{W|tr|sarsılmak}}, {{W|tr|sallanmak}}
* {{Z|el}}: {{W|el|κουνιέμαι|tr=kuniemai}}
{{werger-bin}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# {{mane?|ku}}
#* {{bênimûne|ku}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Werger ====
{{werger-ser}}
* {{Z|tr}}: {{W|tr|deprenme}}, {{W|tr|sallanış}}, {{W|tr|sallanma}}, {{W|tr|sarsılış}}, {{W|tr|sarsılma}}, {{W|tr|sallantı}}, {{W|tr|sarsım}}, {{W|tr|tezelzül}}, {{W|tr|rakıs}}
{{werger-bin}}
r71bzj1sjz94fnz1u8zrub8wyjlln1g
lê
0
5747
6347433
6338005
2026-08-31T19:05:18Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347433
wikitext
text/x-wiki
{{bnr-h|le}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{deng|ku|LL-Q36163_(kmr)-Key Mîrza-lê.wav|dever=Wan}}
* {{ku-kîte}}
=== Girêdek ===
{{girêdek|ku}}
# {{înm|Peyvik e bo [[girê|pevgirêdana]] du [[hevok]]ên dijî hev.}}
#: {{nm|ku|Ew dê biçe '''lê''' ez na.}}
#: {{nm|ku|Ew ne kurd e '''lê''' kurdiyek xweş dizane.}}
#: {{nm|ku|Ne yek '''lê''' du kes lazim in.}}
#: {{nm|ku|Ez çûm '''lê''' min nedît.}}
#: {{nimûne|ku|Min sê heb çêkirin, '''lê''' tu?|Min sê heb çêkirin, te çend çêkirin?|rêz=1}}
#* {{jêder-kovar|ku|jêgirtin='''Lê''' mixabin li Qefqasya, Rûsya û Asya Navîn rewşa xwendin û nivîsandina zimanê Kurdî pir kêm e. Di vî warî de rola saziya Berbangê, kovara Nûbarê û rojnameya Jiyana Kurd gelekî girîng e. Lê diyar e ev xebat têrê nake.|sal=2021|nivîskar=Salihê Kevirbirî|url=http://books.google.com.tr/books?id=qFw3EAAAQBAJ&pg=PA50&hl=&cd=6&source=gbs_api|sernav=Hosteykî Edebiyata Kurdî: Eliyê Evdirehmanê Momîn|kovar=Nûbihar|hejmar=150|rûpel=50}}
==== Bi alfabeyên din ====
* {{ku-ar|لێ}}
* {{ku-kr|ле}}
==== Formên alternatîv ====
{{kol3|ku
|belam
|belê<crz:2>
|belêm
|belêpa
|lêbelê
|welê<crz:1>
}}
==== Hevmane ====
* {{g|ku|bes}} (2)
* {{g|ku|dîsan|dîsan jî}}
* {{g|ku|ema}}
* {{g|ku|feqet}}
* {{g|ku|lakin}}
==== Etîmolojî ====
Ji {{deyn|ar|ku|لكن|tr=lakin}} > [[lêkin]] > [[lê]] ki/ku > lê. Bo hin nimûneyên din jî, ku "a"ya erebî di kurmancî de bûye "ê", binere: kitab > [[kitêb]], hesab > [[hesab|hisêb]], bela > [[belê]]... Bide ber {{hv|el|αλλά}}, {{hv|uk|але}}, {{hv|sh|ali}}, {{hv|pl|ale}}. A xwemalî {{q|ku|nê}} ve cih kiriye.
==== Bi zaravayên din ====
* {{Z|ckb}}: [[bełam]]
==== Werger ====
{{werger-ser|lêbelê, feqet, ema, lêkin, bes}}
* {{Z|ady}}: {{W-|ady|ау}}
* {{Z|af}}: {{W+|af|maar}}
* {{Z|ale}}: {{W-|ale|-iiĝali-}}, {{W-|ale|-ĝdagali-}}, {{W-|ale|-tagali-}}
* {{Z|gmw-ecg}}: {{W-|gmw-ecg|abr}}
* {{Z|de}}: {{W+|de|aber}}, aber {{W+|de|trotzdem}}
* {{Z|as}}: {{W-|as|পিচে}}, {{W-|as|পাচে}}, {{W-|as|কিন্তু}}
* {{Z|ast}}: {{W+|ast|pero}}
* {{Z|az}}: {{W+|az|amma}}, {{W+|az|lakin}}, {{W+|az|ancaq}}, {{W+|az|fəqət}}
* {{Z|eu}}: {{W+|eu|baina}}, {{W-|eu|nahiz eta}}
* {{Z|be}}: {{W-|be|але́}}
* {{Z|bn}}: {{W+|bn|কিন্তু}}
* {{Z|br}}: {{W+|br|met}}
* {{Z|bg}}: {{W+|bg|но}}, {{W-|bg|оба́че}}, {{W-|bg|а́ма}}
* {{Z|my}}: {{W+|my|ဒါပေမဲ့}}
* {{Z|caq}}: {{W-|caq|höng}}, {{W-|caq|lā}}, {{W-|caq|vaich-tö}}
* {{Z|cs}}: {{W+|cs|ale}}
* {{Z|zh}}:
*: {{Z|yue}}: {{W-|yue|但係}}, {{W-|yue|不過|tr=bat1 gwo3}}
*: {{Z|hak}}: {{W-|hak|但係|tr=than-he}}, {{W-|hak|毋過|tr=m̀-ko}}
*: {{Z|cmn}}: {{W+|cmn|可是}}, {{W+|cmn|但是}}, {{W-|cmn|不過}}
*: {{Z|nan}}: {{W+|nan|但是|tr=tān-sī}}, {{W+|nan|不而過|tr=put-jî-kò, put-lî-kò}}, {{W+|nan|毋過|tr=m̄-koh, m̄-kò, m̄-kù}}, {{W-|nan|無過|tr=bû-kò}}, {{W+|nan|不過|tr=put-kò}}, {{W+|nan|總是|tr=chóng-sī}}
* {{Z|cog}}: {{W-|cog|pəntɛː}}
* {{Z|dlm}}: {{W-|dlm|mui}}
* {{Z|da}}: {{W+|da|men}}
* {{Z|id}}: {{W+|id|kecuali}}, {{W+|id|tetapi}}, {{W+|id|tapi}}
* {{Z|ar}}: {{W-|ar|لٰكِن}}, {{W-|ar|لٰكِنَّ}}, {{W-|ar|وَلٰكِن|tr=wa-lākin}}, {{W-|ar|وَلٰكِنَّ|tr=wa-lākinna}}, {{W+|ar|بَلْ}}
*: {{Z|arz}}: {{W-|arz|لكن|tr=laken}}
*: {{Z|ajp}}: {{W-|ajp|لكن|tr=lāken}}, {{W-|ajp|بسّ|tr=bass}}
* {{Z|hy}}: {{W-|hy|թեեւ}}, {{W+|hy|բայց}}, {{W+|hy|սակայն}}
* {{Z|et}}: {{W+|et|kuid}}, {{W+|et|aga}}, {{W+|et|a}}
* {{Z|fa}}: {{W+|fa|گرچه|tr=garče}}, {{W+|fa|ولی|tr=vali}}, {{W+|fa|اگرچه|tr=agarče}}, {{W+|fa|لیکن|tr=liken}}
* {{Z|fo}}: {{W+|fo|men}}
* {{Z|fi}}: {{W+|fi|mutta}}
* {{Z|fr}}: {{W+|fr|mais}}, {{W+|fr|cependant}}
* {{Z|gl}}: {{W+|gl|porén}}, {{W+|gl|macar}}, {{W-|gl|maxer}}, {{W-|gl|magar}}, {{W-|gl|inanque}}, {{W-|gl|inda que}}, {{W-|gl|malia que}}
* {{Z|gu}}: {{W-|gu|પણ}}
* {{Z|ka}}: {{W-|ka|მაგრამ}}, {{W-|ka|თუმცა}}
* {{Z|haw}}: {{W-|haw|akā}}
* {{Z|hi}}: {{W-|hi|लेकिन}}, {{W+|hi|पर}}
* {{Z|nl}}: {{W+|nl|maar}}
* {{Z|he}}: {{W-|he|אֲבָל|tr=avál}}
* {{Z|io}}: {{W+|io|ma}}
* {{Z|ang}}: {{W-|ang|ac}}, {{W-|ang|ah}}
* {{Z|en}}: {{W+|en|but}}, {{t+|en|however}}, {{t+|en|although}}
* {{Z|iu}}: {{W-|iu|-galuaq-}}, {{W-|iu|-kaluaq-}}, {{W-|iu|-raluaq-}}
* {{Z|ga}}: {{W-|ga|ach}}
* {{Z|it}}: {{W+|it|ma}}, {{W+|it|però}}, {{W+|it|tuttavia}}
* {{Z|is}}: {{W+|is|en}}
* {{Z|ja}}: {{W+|ja|が|tr=ga}}, {{W-|ja|けれど|tr=keredo}}, {{W+|ja|けれども|tr=keredomo}}, {{W+|ja|けど|tr=kedo}}, {{W+|ja|しかし|tr=shikashi}}, {{W+|ja|でも|tr=demo}}
* {{Z|kbd}}: {{W-|kbd|ауэ}}
* {{Z|kl}}: {{W-|kl|-galuar}}, {{W-|kl|-kaluar}}, {{W-|kl|-raluar}}
* {{Z|kn}}: {{W+|kn|ಆದರೆ}}
* {{Z|ca}}: {{W+|ca|mes}}, {{W+|ca|però}}, {{W+|ca|mas}}, {{W-|ca|emperò}}
* {{Z|kha}}: {{W-|kha|hynrei}}
* {{Z|swb}}: {{W-|swb|ɓadi}}
* {{Z|ko}}: {{W+|ko|그러나}}, {{W+|ko|하지만}}, {{W+|ko|지만|cuda=-지만}}
* {{Z|kdt}}: {{W-|kdt|paj}}
* {{Z|la}}: {{W+|la|quamvis}}, {{W-|la|licet}}, {{W+|la|ut}}, {{W+|la|sed}}
* {{Z|lv}}: {{W+|lv|bet}}, {{W-|lv|taču}}
* {{Z|lo}}: {{W-|lo|ແຕ່}}
* {{Z|lij}}: {{W-|lij|ma}}
* {{Z|lt}}: {{W+|lt|bet}}, {{W+|lt|tačiau}}, {{W+|lt|nors}}
* {{Z|mk}}: {{W-|mk|но}}, {{W-|mk|а́ма}}
* {{Z|ml}}: {{W+|ml|പക്ഷേ}}
* {{Z|ms}}: {{W-|ms|tetapi}}
* {{Z|mt}}: {{W-|mt|iżda}}
* {{Z|mh}}: {{W-|mh|ma}}
* {{Z|gun}}: {{W-|gun|ha'e rã}}
* {{Z|hu}}: {{W+|hu|de}}, {{W+|hu|viszont}}
* {{Z|cmo}}: {{W-|cmo|តីស|tr=tĭh}}, {{W-|cmo|តីសមា|tr=tĭh ma}}, {{W-|cmo|ប្យាៈលាស|tr=ɓjăʔ lăh}}, {{W-|cmo|មពោៈ|tr=mpŏʔ}}
* {{Z|mn}}:
*: Kirîlî: {{W-|mn|гэхдээ}}
* {{Z|wlc}}: {{W-|wlc|walakini}}
* {{Z|nv}}: {{W-|nv|ndi}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|men}}
* {{Z|oc}}: {{W+|oc|mas}}
* {{Z|pac}}: {{W-|pac|kếh ma}}, {{W-|pac|ma}}, {{W-|pac|icốh ma}}, {{W-|pac|ncốh ma}}, {{W-|pac|nki ma}}
* {{Z|ps}}: {{W-|ps|لېکن|tr=léken}}, {{W+|ps|اما|tr=amã}}, {{W-|ps|مګر|tr=magár}}, {{W-|ps|منګر|tr=mangár}}, {{W-|ps|وليکن|tr=walikén}}, {{W-|ps|ولې|tr=wále}}
* {{Z|pl}}: {{W+|pl|ale}}, {{W+|pl|chociaż}}
* {{Z|pt}}: {{W+|pt|embora}}, {{W+|pt|mas}}
* {{Z|rap}}: {{W-|rap|pero}}
* {{Z|rm}}: {{W-|rm|cumbain che}}
* {{Z|rom}}: {{W-|rom|tha'}}
* {{Z|ro}}: {{W+|ro|dar}}
* {{Z|ru}}: {{W+|ru|но}}, {{W-|ru|то́лько}}, {{W-|ru|хотя́}}, {{W+|ru|хоть}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|а̏ли}}, {{W-|sh|а̏ма}}
*: Latînî: {{W+|sh|ȁli}}, {{W+|sh|ȁma}}
* {{Z|sk}}: {{W-|sk|ale}}
* {{Z|sl}}: {{W+|sl|čepràv}}, {{W+|sl|tóda}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|ale}}
*: {{Z|hsb}}: {{W+|hsb|ale}}
* {{Z|st}}: {{W-|st|empa}}
* {{Z|es}}: {{W+|es|aunque}}, {{W+|es|pero}}, {{W+|es|mas}}
* {{Z|sw}}: {{W-|sw|lakini}}
* {{Z|sv}}: {{W+|sv|men}}, {{W+|sv|fast}}
* {{Z|shn}}: {{W-|shn|သီႈတႄႉ}}, {{W-|shn|သီႈလၵ်း}}, {{W-|shn|သေတႄႉ}}, {{W-|shn|သေလၵ်း}}, {{W-|shn|ၵူၺ်းၵႃႈ}}, {{W-|shn|ၵွႆးၵႃႈ}}, {{W-|shn|ပွႆးၸိုင်}}, {{W-|shn|ပွႆးလၵ်း}}
* {{Z|zdj}}: {{W-|zdj|sha}}, {{W-|zdj|lakini}}, {{W-|zdj|amma}}
* {{Z|tg}}: {{W-|tg|лекин}}, {{W+|tg|аммо}}, {{W-|tg|вале}}, {{W-|tg|агарчи}}, {{W-|tg|гарчи}}
* {{Z|tl}}: {{W-|tl|baga ma't}}, {{W-|tl|bagamat}}
* {{Z|ta}}: {{W+|ta|ஆனால்}}
* {{Z|shi}}: {{W-|shi|macc|tr=mish}}
* {{Z|th}}: {{W+|th|แต่}}, {{W+|th|แต่ว่า}}
* {{Z|tr}}: {{W+|tr|ama}}, {{W+|tr|ancak}}, {{W+|tr|fakat}}, {{W+|tr|lakin}}
* {{Z|bo}}: {{W-|bo|ཡིན་ན་ཡང}}
* {{Z|ur}}: {{W-|ur|لیکن|tr=lekin}}, {{W-|ur|اگرچہ}}
* {{Z|uk}}: {{W-|uk|але́}}
* {{Z|vi}}: {{W+|vi|nhưng}}, {{W+|vi|nhưng mà}}, {{W+|vi|mà}}
* {{Z|vo}}: {{W+|vo|ab}}
* {{Z|cy}}: {{W-|cy|er}}
* {{Z|km}}: {{W+|km|តែ}}, {{W+|km|ប៉ុន្តែ}}, {{W+|km|ក៏ប៉ុន្តែ|tr=kɑɑ pontae}}
* {{Z|yi}}: {{W+|yi|אָבער}}
* {{Z|el}}: {{W+|el|μολονότι}}, {{W+|el|παρόλο}}, {{W+|el|καίτοι}}, {{W+|el|αν και}}
* {{Z|nmn}}: {{W-|nmn|xàbēkà}}, {{W-|nmn|gúʻni tshòo}}
{{werger-bin}}
=== Daçek ===
{{daçek|ku}}
# [[li]] [[wê]]
#* {{bêmînak|ku}}
# [[li]] [[wî]]
#* {{bêmînak|ku}}
# [[li]] [[wan]]
#* {{bêmînak|ku}}
==== Ji wêjeya klasîk ====
* {{J:Feqiyê Teyran|jêgirtin=Dara ku enqa bête ser</br>Belgek heye sih '''lê''' nebî</br>Kî j' ni'metê dê dit xeber}}
==== Notên bikaranînê ====
[[lêker|Lêkerên]] ku piştî [[lê]]/[[jê]]/[[tê]]/[[pê]] tên, di dema niha a [[bilanî]](subjunctive) de [[bi-]] nastînin. Anku "lê bikim" na "lê kim", "li xwe bike" na "li xwe ke". Heman tişt herwisa gava [[bireser]] "[[xwe]]" dibe jî dibe ("xwe [[gan|bigê]]!" na lê "xwe gê!"). Lê ev tenê bi lêkerên [[qalib]][[req]] ([[stereotypical]]/[[kalıplaşmış]]) li kar e û ew jî [[dever]] bi [[dever]] diguhere, [[mesela]] hin kes dibêjin "lê binêre!, lê bigere!" hin kes jî "lê nêre!, lê gere!", [[bi taybetî]] ên [[hevedudanî]] û [[kurt]] û ên ku [[tim tim]] bi [[lêker]]ên ku [[tim tim]] wek [[lêker]]ên [[alîkar]] tên [[bikaranîn]] (wek [[tê xistin]], [[pê xistin]], [[li xwe kirin]], [[jê kirin]]) "[[bi-]]"a [[rewş]]a [[bilanî]] dikeve.
==== Etîmolojî ====
Ji {{qertaf|ku|li|wê}}.
=== Baneşan ===
{{baneşan|ku}}
# Ji bo gazî/bang kirina jin û keçan.
#* {{bêmînak|ku}}
==== Bide ber ====
{{kol3|ku
|lo
}}
==== Werger ====
{{werger-ser}}
* {{Z|fa}}: {{W|fa|آهای}}, {{W|fa|ای}}, {{W|fa|های|guman=erê}}
* {{Z|en}}: {{W|en|hey}}, {{W|en|gland|guman=erê}}, {{W|en|glandule|guman=erê}}, {{W|en|gundula|guman=erê}}
* {{Z|tr}}: {{W+|tr|ey}}, {{W+|tr|kız}}
{{werger-bin}}
{{kontrolWergerr}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# {{f|ku|Xorasan}} {{mj|avrabûn}} {{guherto|ku|lehî}}
#* {{bêmînak|ku}}
== {{ziman|ckb}} ==
=== Daçek ===
{{daçek|ckb|sc=Latn}}
# [[lê]] (li wê / wî / wan)
#* {{bêmînak|ckb}}
== {{ziman|zza}} ==
=== Navdêr ===
{{navdêr|zza|z=n}}
# [[qazan]], [[beroş]], [[qûşxan]]
#* {{bêmînak|zza}}
== {{ziman|vi}} ==
=== Navdêr ===
{{navdêr|vi}}
# {{mijar|vi|riwek}} {{g|ku|hirmî}}
#* {{bêmînak|vi}}
=== Çavkanî ===
{{rûpela wergerê|vi|hirmî}}
e4qtonguin6n3umidvdyk4dbmlf2q0b
wir
0
5754
6347623
6320124
2026-09-01T11:36:10Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347623
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
=== Hoker ===
{{hoker|ku}}
# wê [[der]]ê, wî [[cih]]î
#: {{nm|ku|Ez zû çûm '''wir''' lê kes li '''wir''' tine bû lewre ez jî zû ji '''wir''' çûm.}}
==== Bi alfabeyên din ====
* {{ku-ar|ور}}
==== Formên alternatîv ====
{{kol3|ku
|wê derê
|wê dirê
|wêderê
|wêderê
|wêrê
|wira
|wire
|wirê
}}
==== Hevmane ====
{{kol3|ku
|wê<crz:2>
}}
==== Dijmane ====
{{kol3|ku
|vir
}}
==== Etîmolojî ====
{{qusandin|ku|wê}} + ''[[der]]ê''. Herwiha bide ber ''[[vir]]'' ji ''[[vê]] [[der]]ê'' û peyva devokî ''[[kur#Hoker|kur]]'' (ku/kû derê). Forma ''[[wira]]'' ji ''[[wan]] [[der]]a(n)''.
==== Werger ====
Li jêr wergerên "wir" ya bi wateya "ber bi wir ve, heta wir, bo wir" tên dayîn. Bo "li vir" binêrin: [[li wir]].
{{werger-ser}}
* {{Z|sq}}: {{W+|sq|andej}}
* {{Z|de}}: {{W+|de|dorthin}}, {{W+|de|dahin}}
* {{Z|as}}: {{W-|as|তালৈ}}
* {{Z|ast}}: {{W+|ast|allá}}
* {{Z|ba}}: {{W-|ba|унда|sc=Cyrl}}
* {{Z|be}}: {{W-|be|туды́}}
* {{Z|bg}}: {{W-|bg|ната́м}}, {{W-|bg|ната́тък}}
* {{Z|cs}}: {{W+|cs|tam}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|那裡|tr=nàli}}, {{W+|cmn|那兒|tr=nàr}}
* {{Z|da}}: {{W-|da|did}}, {{W-|da|derhen}}
* {{Z|id}}: {{W-|id|ke situ}}, {{W+|id|ke sana}}
* {{Z|ar}}: {{W-|ar|إِلَى هُنَاكَ}}
* {{Z|hy}}: {{W+|hy|այնտեղ}}
* {{Z|eo}}: {{W+|eo|tien}}
* {{Z|et}}: {{W+|et|sinna}}
* {{Z|fo}}: {{W-|fo|hagar}}
* {{Z|fi}}: {{W+|fi|tuonne}}, {{W+|fi|tuohon}}, {{W+|fi|sinne}}, {{W+|fi|siihen}}
* {{Z|fr}}: {{W+|fr|y}}, {{W+|fr|là}}
* {{Z|got}}: {{W-|got|𐌾𐌰𐌹𐌽𐌳}}
* {{Z|hi}}: {{W+|hi|उधर}}
* {{Z|nl}}: {{W+|nl|daarheen}}, {{W+|nl|aldaar}}
* {{Z|he}}: {{W-|he|[[לְ־]][[שָׁם]]|tr=le-shám}}
* {{Z|ang}}: {{W-|ang|þæder}}
* {{Z|en}}: {{W+|en|there}}, {{W+|en|thither}} (to that place)
* {{Z|ga}}: {{W-|ga|ansin}}
* {{Z|it}}: {{W+|it|ci}}, {{W+|it|vi}}
* {{Z|is}}: {{W+|is|þangað}}
* {{Z|ja}}: {{W-|ja|[[そこ]]へ|tr=sokó e}}, {{W-|ja|[[あそこ]]へ|tr=asokó e}}
* {{Z|ko}}: {{W+|ko|거기|cuda=거기에}}
* {{Z|la}}: {{W-|la|illuc}}, {{W-|la|istuc}}, {{W+|la|eo}}
* {{Z|lv}}: {{W+|lv|tur}}, {{W-|lv|turp}}
* {{Z|lij}}: {{W-|lij|ghe}}
* {{Z|lmo}}: {{W-|lmo|ghe}}
* {{Z|lb}}: {{W-|lb|dohin}}
* {{Z|mk}}: {{W-|mk|та́му}}, {{W-|mk|на́таму}}
* {{Z|ms}}: {{W+|ms|sana|cuda=ke sana}}, {{W+|ms|situ|cuda=ke situ}}
* {{Z|mr}}: {{W-|mr|तिकडे}}
* {{Z|hu}}: {{W+|hu|oda}}
* {{Z|nap}}: {{W-|nap|allà}}
* {{Z|no}}: {{W+|no|dit}}
* {{Z|ps}}: {{W+|ps|هلته|tr=halta}}, {{W-|ps|هورې|tr=hure}}
* {{Z|pt}}: {{W-|pt|[[para]] [[aí]]}}, {{W-|pt|[[para]] [[ali]]}}, {{W+|pt|[[para]] [[lá]]}}
''''
* {{Z|ru}}: {{W+|ru|туда́}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|тамо}}
*: Latînî: {{W+|sh|tamo}}
* {{Z|sk}}: {{W+|sk|tam}}, {{W+|sk|ta}}
* {{Z|sl}}: {{W-|sl|tjá}}
* {{Z|es}}: {{W-|es|por allí}}, {{W-|es|hacia allá}}
* {{Z|sv}}: {{W+|sv|dit}}
* {{Z|cjs}}: {{W-|cjs|аара}}
* {{Z|te}}: {{W-|te|అక్కడికి}}
* {{Z|tr}}: {{W-|tr|şuraya}}, {{W+|tr|oraya}}
* {{Z|uk}}: {{W-|uk|туди́}}
* {{Z|vec}}: {{W+|vec|ghe}}
* {{Z|vi}}: {{W-|vi|đằng kia}}
* {{Z|yo}}: {{W-|yo|síbẹ̀}}, {{W-|yo|[[sí]] [[ibẹ̀]]}}
* {{Z|el}}: {{W-|el|εκείσε}}, {{W-|el|προς τα εκεί}}
*: {{Z|grc}}: {{W-|grc|ἐκεῖσε}}, {{W-|grc|ἔνθα}}
* {{Z|zea}}: {{W-|zea|d'r'ene}}, {{W-|zea|daer'ene}}
{{werger-bin}}
:{{werger çavkanî|en|there|beş=Ev qismê Wergerê|oldid=75803385}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[ew]] [[der]], ew [[cih]]:
#: {{nm|ku|'''Wir''' ji vir xweştir e.|Ew der ji vê derê xweştir e.|rêz=1}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Notên bikaranînê ====
: Nayê tewandin: ''Vir ji wir xweştir e. (Ne "*Vir ji wirê xweştir e.")
== {{ziman|de}} ==
=== Bilêvkirin ===
* {{deng|de|De-wir.ogg}}
* {{deng|de|LL-Q188 (deu)-Lucas Werkmeister-wir.wav|Deng|dever=Berlîn, Almanya}}
* {{deng|de|LL-Q188 (deu)-Nattes à chat-wir.wav|Deng|dever=}}
* {{deng|de|LL-Q188 (deu)-Sebastian Wallroth-wir.wav|Deng|dever=Berlîn, Almanya}}
* {{deng|de|LL-Q188 (deu)-teste (Pamputt)-wir.wav|Deng|dever=}}
* {{deng|de|LL-Q188 (deu)-Student16 de-wir.wav|Deng|dever=}}
* {{deng|de|LL-Q188 (deu)-Natschoba-wir.wav|Deng|dever=Almanya}}
=== Cînav ===
{{cînav|de}}
# [[em]]
#* {{bêmînak|de}}
fg88ivzhr7bnputeg9bbso2pspyke6d
ajotin
0
5779
6347464
6328855
2026-08-31T20:36:34Z
Wikihez
7344
+nimûneya bikaranînê bi amûra « [[Mediawiki:Gadget-wikt.add-examples|Nimûne zêde bike]] » (v2.0).
6347464
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-ajotin.wav|dever=Bidlîs}}
* {{ku-kîte}}
=== Lêker ===
{{ku-tewîn-lk|ajotin|form=gerguhêz|niha=ajo|borî=ajot}}
[[Wêne:Rush Rush Rush.jpg|thumb|Kesek tirimpêlê '''diajo'''.]]
{{lêker|ku|c=x-gh}}
# [[tirimpêl|Tirimpêlek]] yan [[dewar]]ek [[meşandin]] ango anîn yan [[birin]].
#: {{mk|ku|Te çima [[terş]]ê xwe '''ajotiye''' nav [[bûstan]]ê me?!}}
# [[vêkişandin|Vêkişandin]], [[dirêj bûn]].
#: {{mk|ku|Civîna wan seetekê '''ajot'''.|ango civîna wan seetekê dirêj bû|birêz=1}}
#* {{jêder-websîte|ku|nivîskar=Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026|jêgirtin=Bi şaşî “Dêra sorê…” (Kilîsa sor) gotine û nivîsîne. Gelek kesan jî navê kilama Dêre Sorê Piçûkê bi navê bajarê Deyrezor re tevlihev kirine. Vê yekê bi salan '''ajotiye'''.}}
# [[kêlan|Kêlan]], [[cot]] kirin.
#: {{mk|ku|Ew hê jî zeviyên xwe bi [[ga]]yan '''diajon''' (an jî '''[[dojin]]''').}}
# [[teqîb|Teqîb]] kirin, mînak [[şop]] ajotin.
#* {{bêmînak|ku}}
# [[zixtkirin|Zixtkirin]], [[handan]].
#* {{bêmînak|ku}}
# [[sirgûn kirin]]
#* {{jêder-pirtûk|ku|jêgirtin=Walah eve xebera derew biderdikeve ez dê te tālān bikim û kep û guhêd te jî ji boy sosret jê kim û te ji nêva êlê biderînim û '''bajom (biajom)'''! Êdî tu dizanî!|nivîskar=w:Mele Mehmûdê Bazîdî|edîtor= Mîkaîl Bilbil; Mistafa Oztirk |sernav= w:Tûhfetu'l-Xîlan Fî Zimanê Kurdan|weşanxane= Weqfa Mezopotamyayê |sal=1866|sala-weşandinê=2019|çap=1|rûpel=161|isbn=978-605-80975-1-3}}
==== Bi alfabeyên din ====
* {{ku-ar|ئاژۆتن}}
* {{ku-kr|ажотьн}}
==== Jê ====
{{kol3|ku
| ajokar
| ajokarî
| ajoname
| ajonamedar
| ajonamedarî
| ajovan
| ajovanî
| ajozan
| ajozanî
}}
==== Etîmolojî ====
Ji {{ji|ine-pro|ku|*h₂eǵ-}}, {{ji|ira-pro|ku|*aza-}}, [[hevreh]]a {{g|ae|𐬀𐬰𐬀𐬌𐬙𐬌}} ya avestayî, sanskrîtî {{g|sa|अजति}}, ermeniya kevn {{g|xcl|ածեմ|tr=acem}}, yûnaniya kevn {{g|grc|ἄγω|tr=ago}}, latînî {{q|la|agō}}, swêdî {{q|sv|åka}}... Heman peyv ihtimal e ku serekaniya {{q|zza|hêga|tr=[[zevî]]}} ya zazakî ye jî. {{q|fi|ajaa}} ja fînî û {{q|et|ajama}} ya estonî bi ihtimaleke mezin ji {{ji|ine-pro|ku|-}}, bi taybetî ji {{ji|ira-pro|ku|-}} hatine deynkirin.
==== Bi zaravayên din ====
* {{Z|ckb}}: {{W-|ckb|sc=Latn|lê xurrîn}} (1), {{W-|ckb|sc=Latn|xayandin}} (3)
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W+|af|bestuur}}, {{W+|af|lei}}
* {{Z|de}}: {{W+|de|dauern}}, {{W+|de|fahren}}, {{W+|de|lenken}}, {{W+|de|führen}}, {{W+|de|leiten}}, {{W+|de|einfahren}}, {{W+|de|einlenken}}, {{W+|de|Einfahrt|m}}, {{W+|de|abführen}}, {{W+|de|schieben}}, {{W+|de|steuern}}, {{W+|de|treiben|guman=erê}}
* {{Z|cs}}: {{W+|cs|doprovodit}}, {{W-|cs|dovézt}}, {{W+|cs|dovést}}, {{W+|cs|předvést}}, {{W+|cs|převézt}}, {{W+|cs|přinést}}, {{W+|cs|přivézt}}, {{W-|cs|přivážet}}, {{W+|cs|řídit}}, {{W+|cs|vést}}, {{W+|cs|vodit}}, {{W+|cs|vozit}}
* {{Z|da}}: {{W-|da|styrre}}, {{W-|da|føre}}
* {{Z|ar}}: {{W-|ar|السیاقة}}, {{W-|ar|القود}}, {{W-|ar|القیادة}}, {{W-|ar|حرث|guman=erê}}, {{W-|ar|مساق|guman=erê}}, {{W-|ar|القیاد|guman=erê}}
* {{Z|eo}}: {{W+|eo|stiri}}, {{W-|eo|konduki}}
* {{Z|fa}}: {{W+|fa|رانندگی}}, {{W+|fa|راندن}}, {{W+|fa|رانندگی کردن}}, {{W+|fa|هدایت کردن}}, {{W+|fa|فریاد زدن|guman=erê}}
* {{Z|fo}}: {{W-|fo|leiða}}, {{W-|fo|føra}}
* {{Z|fi}}: {{W+|fi|ajaa}}
* {{Z|fr}}: {{W+|fr|conduire}}
* {{Z|fy}}: {{W-|fy|liede}}
* {{Z|nl}}: {{W+|nl|besturen}}, {{W+|nl|sturen}}, {{W+|nl|brengen}}, {{W+|nl|leiden}}, {{W+|nl|geleiden}}, {{W+|nl|voeren}}
* {{Z|he}}: {{W+|he|נחה|n}}, {{W+|he|נהג|n}}, {{W+|he|גרש|cuda=גּרשׁ}}
* {{Z|io}}: {{W+|io|duktar}}
* {{Z|en}}: {{W+|en|drive}}, {{W+|en|steer}}, {{W+|en|fly}}, {{W+|en|conduct}}, {{W+|en|guide}}, {{W+|en|lead}}, {{W+|en|channel}}, {{W+|en|wage}}, {{W+|en|bring}}, {{W+|en|drag on}}, {{W+|en|driving}}, {{W+|en|cruise}}, {{W+|en|prodding}}, {{W+|en|going away|guman=erê}}, {{W+|en|conducting|guman=erê}}, {{W+|en|conn|guman=erê}}, {{W+|en|cox|guman=erê}}, {{W+|en|cruising|guman=erê}}, {{W+|en|foment|guman=erê}}, {{W+|en|fomentation|guman=erê}}, {{W+|en|fomenting|guman=erê}}, {{W+|en|hortation|guman=erê}}, {{W+|en|instigation|guman=erê}}, {{W+|en|leading|guman=erê}}, {{W+|en|navigating|guman=erê}}, {{W+|en|spurring|guman=erê}}, {{W+|en|steerage|guman=erê}}, {{W+|en|tarring|guman=erê}}, {{W+|en|urging|guman=erê}}, {{W+|en|whish|guman=erê}}, {{W+|en|till}}
* {{Z|it}}: {{W+|it|condurre}}, {{W+|it|guidare}}
* {{Z|ca}}: {{W+|ca|conduir}}, {{W+|ca|menar}}
* {{Z|la}}: {{W+|la|ducere}}
* {{Z|ms}}: {{W+|ms|pimpin}}
* {{Z|pl}}: {{W+|pl|prowadzić}}
* {{Z|pt}}: {{W+|pt|conduzir}}, {{W+|pt|dirigir}}, {{W+|pt|guiar}}, {{W+|pt|levar}}
* {{Z|ro}}: {{W+|ro|conduce}}
* {{Z|ru}}: {{W+|ru|вести}}
* {{Z|se}}: {{W-|se|doalvut}} (1-3)
* {{Z|ses}}: {{W-|ses|zurandi}}
* {{Z|es}}: {{W+|es|conducir}}
* {{Z|sv}}: {{W+|sv|köra}}, {{W+|sv|åka}}, {{W+|sv|föra}}
* {{Z|tr}}: {{W+|tr|sürmek}}, {{W+|tr|çift sürmek}}, {{W+|tr|gütmek}}, {{W+|tr|tutmak}}, {{W+|tr|yürütmek}}, {{W+|tr|çekmek|guman=erê}}, {{W-|tr|çığlık atmak|guman=erê}}, {{W+|tr|sürüklenmek|guman=erê}}, {{W+|tr|uzamak|guman=erê}}, {{W+|tr|yağdırmak|guman=erê}}
* {{Z|el}}: {{W+|el|οδηγώ|R=odhigó}}
* {{Z|fsl}}: [http://lsf.wiksign.org/wiki/conduire conduire]
{{werger-bin}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[meşandin|Meşandin]] ango anîn yan [[birin]]a [[tirimpêl]]ek yan [[dewar]]ek.
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Werger ====
{{werger-ser}}
* {{Z|tr}}: {{W+|tr|sürme}}, {{W+|tr|gütme}}, {{W+|tr|hamle}}, {{W+|tr|sürüklenme}}, {{W+|tr|yürütme}}, {{W+|tr|uzama|guman=erê}}, {{W+|tr|yaşatma|guman=erê}}
{{werger-bin}}
hmnmawlzij1dj6evue9z0gt6fi1x2sy
dubare
0
5851
6347394
6231547
2026-08-31T15:35:21Z
Wikihez
7344
/* Rengdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347394
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Rengdêr ===
{{ku-tewîn-rd|dubare}}
{{rengdêr|ku}}
# [[ducarî]], [[car]]a [[duyem]], [[dîsa]], [[ji nû ve]], [[car]]ek [[din]], carek [[dî]]
#: ''Gotina xwe '''dubare''' kir.'' (dîsan got)
#* {{jêder|ku|jêgirtin=Kurmanc û Zaza her tiştî dipirsin. Pir caran '''dubare''' jî dikin. Lê mantiq yek e. Mînak: Kurmanc dibêjin: “tu bi xêr hatî”. Zaza dibêjin: “ti bi xêr ameyî/a”.Kurmanc dibêjin: “di nava xêrê de bî”. Zaza dibêjin: “xêr mîyan de bî”.|''[[w:Beşek Ji Folklora Kurdî: Çîrok|Beşek Ji Folklora Kurdî: Çîrok]]'', [[w:Mehmet Bozkoyun|Mehmet Bozkoyun]], Bingöl Üniversitesi Yaşayan Diller Enstitüsü Dergisi}}
==== Hevmane ====
* {{g|ku|ducar}}
* {{g|ku|ducare}}
* {{g|ku|dupat}}
* {{g|ku|dîsan}}
* {{g|ku|tekrar}}
==== Jê ====
{{stûn|
* {{g|ku|dubarebûyî}}
* {{g|ku|dubarekirî}}
* {{g|ku|dubaretî}}
* {{g|ku|dubareyî}}
* {{mj|lêker}} {{g|ku|dubare bûn}}
* {{mj|lêker}} {{g|ku|dubare kirin}}
* {{mj|navdêr}} {{g|ku|dubarebûn}}
* {{mj|navdêr}} {{g|ku|dubarekirin}}
* {{mj|rengdêr}} {{g|ku|dubarebûyî}}
* {{mj|rengdêr}} {{g|ku|dubarekirî}}
}}
==== Etîmolojî ====
Hevreha soranî {{g|ckb|دووباره}}, herdu ji {{ji|fa|ku|دوباره|tr=dobâre}} ji {{g|fa|دو|tr=do|w=[[du]]}} + {{g|fa|بار|tr=bar|w= [[car]]}} {{g|fa|-ه|tr=-ê/-e|w=[[-î]]}}.
==== Bi zaravayên din ====
* {{Z|zza}}: {{g|zza|reyna}}, {{g|zza|tekrar}}, {{g|zza|dibare}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|abermals}}, {{W|de|zweimal}}, {{W|de|doppelt|guman=erê}}, {{W|de|zweifach|guman=erê}}, {{W|de|Wiederholung|guman=erê}}
* {{Z|fa}}: {{W|fa|تکرار}}, {{W|fa|تکرار}}, {{W|fa|دوباره}}
* {{Z|en}}: {{W|en|afresh}}, {{W|en|again}}, {{W|en|all over again}}, {{W|en|anew}}, {{W|en|once more}}, {{W|en|repeatedly}}, {{W|en|twice}}, {{W|en|frequent}}, {{W|en|reduplication}}, {{W|en|repetition}}, {{W|en|repeated}}, {{W|en|over and over|guman=erê}}, {{W|en|time and again|guman=erê}}, {{W|en|encore|guman=erê}}, {{W|en|sessional|guman=erê}}, {{W|en|tautologous|guman=erê}}, {{W|en|chorus}}, {{W|en|refrain}}
* {{Z|tr}}: {{W|tr|ikileme}}, {{W|tr|tekerrür}}, {{W|tr|tekrar}}, {{W|tr|yineleme}}, {{W|tr|dubara}}, {{W|tr|duble}}
{{werger-bin}}
7ipqrd1j7n1daeh21x3e7bte2fi7de6
piştre
0
6268
6347574
6341696
2026-09-01T10:22:49Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347574
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Hoker ===
{{hoker|ku}}
# [[piştî]] tiştekî, [[dû]] tiştekî re, piştî ku tiştek bibe
#* {{J:Zeynelabidîn Zinar:Balafira Jînê|jêgirtin='''Piştre''' Gurgîn bi peyveke şîranî, rabû xatir ji şêrîna şevê xwest û eniyê gever maçi kir, {{...}}}}
==== Notên bikaranînê ====
''Piştre'' û hevwateyên wê serbixwe tên bikaranîn ango ti [[navdêr]] nadin pey wan. Ger divê navdêr li pey wan hebe, hingê li ''piştre'' divê '''[[piştî]]''' bêt bikaranîn.
==== Formên alternatîv ====
{{kol3|ku
|piştra
|pişt ra
|pişt re
|pişra
|piş ra
|pişre
|piş re
}}
==== Hevmane ====
{{kol3|ku
|dûre
|paşî
|paşê
}}
==== Nêzîk ====
{{kol3|ku
|piştî
}}
==== Dijmane ====
{{kol3|ku
|pêşî
}}
==== Etîmolojî ====
Ji {{qertaf|ku|pişt|-re}}.
==== Bide ber ====
{{kol3|ku
|dawî
|destpêk
}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|dann}}, {{W+|de|nach|guman=erê}}, {{W+|de|alsdann|guman=erê}}, {{W+|de|danach|guman=erê}}, {{W+|de|hinterher|guman=erê}}, {{W+|de|zurück|guman=erê}}
* {{Z|fa}}: {{W-|fa|پس از|guman=erê}}, {{W+|fa|سپس|guman=erê}}
* {{Z|en}}: {{W+|en|later on|guman=erê}}, {{W+|en|subsequently|guman=erê}}
* {{Z|tr}}: {{W+|tr|akabinde|guman=erê}}, {{W+|tr|bilahare|guman=erê}}, {{W+|tr|bilâhare|guman=erê}}, {{W+|tr|müteakiben|guman=erê}}, {{W+|tr|neden sonra|guman=erê}}, {{W+|tr|sonra|guman=erê}}, {{W+|tr|sonradan|guman=erê}}, {{W+|tr|sonraları|guman=erê}}, {{W+|tr|takiben|guman=erê}}, {{W+|tr|ardınca|guman=erê}}
{{werger-bin}}
4hbdby4beln5yzaq1bngrrktcwngxau
zor
0
6322
6347438
6338041
2026-08-31T19:10:29Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347438
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA|zˤoːɾ}}
* {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-zor.wav|dever=Bidlîs}}
* {{ku-kîte}}
=== Rengdêr ===
{{ku-tewîn-rd|zor}}
{{rengdêr|ku}}
# [[dijwar]], [[zehmet]], [[asê]]
#: {{dijmane|ku|hêsan|sanahî}}
# [[pirr]], [[gelek]], [[zêde]], [[zehf]], [[mişe]]
#: {{dijmane|ku|kêm|hindik|piçek}}
==== Ji wêjeya klasîk ====
* {{J:Melayê Cizîrî:Dîwana Melayê Cizîrî|jêgirtin=Mela li 'umrê bêfeyde borî</br>Kêşa bi '''zor''' an qehr û nedamet}}
==== Notên bikaranînê ====
{{agadarî}} "Zor" di eslê xwe de maneya "kotekî, hêz, xurtî" dide. Ji wê di soranî de jî maneya "pirr, gelek, zehf" girtiye. Hin kurmancan jî ew wisa deyn kiriye û dibêjin "zor spas". Lê ji ber ku di kurmancî de zor bi maneya "zehmet, dijwar" tê fehmkirin, "zor spas" neyê bikaranîn û "gelek spas" yan "pirr spas" were gotin çêtir e."
Lê di eslê xwe de "pirr" jî ne bi maneya "gelek" lê bi wateya "tijî" bû û niha jî di soranî û zazakî de bi wê maneyê ye lê di kurmancî de maneya wê guheriye.
"li yekî sûrî kirin" tê maneya li yekî zorbazî kirin.
==== Bi alfabeyên din ====
* {{ku-ar|زۆر}}
==== Jê ====
{{kol3|ku
|zorbaz
|zorbazî
|zordest
|zordestî
|zorî
|zorzan
|zorzanî
}}
==== Etîmolojî ====
Maneya [[resen]] [[hêz]] / [[qewet]] / [[xurtî]] bû, hevreha [[zever]] ya kurdî, ''zaveri'' ya ([[hêz]], [[qudret]]) ya avestayî, ''zor'' ([[hêz]], [[qudret]]) ya pehlewî û {{g|fa|زور|tr=zor}} ya farisî û [[शूर]] (sûra: [[xurt]], [[bihêz]], [[qehreman]]) ya sanskrîtî ye û ji {{ji|ira-pro||-}} ye. "Zor" ya tirkî, [[զօր]] (zōr) ya ermeniya kevn û [[զոռ]] (zoṙ) ya ermeniya devokî ji zimanên îranî hatine deynkirin.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|erbittert}}, {{W+|de|mühsam}}, {{W+|de|rau}}, {{W+|de|schwierig}}, {{W+|de|steil}}{{W+|de|uneben}}, {{W+|de|viel}}, {{W+|de|umständlich|guman=erê}}
* {{Z|ar}}: {{W-|ar|صعب}}, {{W-|ar|شاق}}, {{W-|ar|قاسي}}, {{W+|ar|كتير}}, {{W+|ar|كثير}}, {{W+|ar|جدا}}, {{W-|ar|عنف|guman=erê}}
* {{Z|en}}: {{W+|en|many}}, {{W+|en|much}}, {{W+|en|hard}}, {{W+|en|tough}}, {{W+|en|compulsion|guman=erê}}, {{W+|en|dreadfully|guman=erê}}, {{W+|en|dys|guman=erê}}, {{W+|en|manifold|guman=erê}}, {{W+|en|mordent|guman=erê}}, {{W+|en|multifarious|guman=erê}}, {{W+|en|multifold|guman=erê}}, {{W+|en|demanding|guman=erê}}, {{W+|en|multiphase|guman=erê}}, {{W+|en|multiplex|guman=erê}}, {{W+|en|plentiful|guman=erê}}, {{W+|en|tremendous|guman=erê}}
{{werger-bin}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[sûrî]], [[zilm]], [[stem]], [[neheqî]], [[zulm]], [[kotek]]
#* {{J:Mehmed Uzun:Bîra qederê:2002|jêgirtin=Li cîhê ku dar dest pê dikin, rengê kesk '''zora''' rengên spî û şîn dibe.}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Drang}}, {{W+|de|Druck}}, {{W+|de|Drücken}}, {{W+|de|Gewalt}} {{n}}, {{W+|de|Marter}} {{n}}
* {{Z|ar}}: {{W+|ar|ظلم}},{{W-|ar|ضغط}}, {{W-|ar|اضطهاد}}, {{W-|ar|تعسف}}, {{W-|ar|تحكم}}, {{W-|ar|تسلط}}
* {{Z|fa}}: {{W+|fa|بسیار}}, {{W+|fa|پرالتهاب}}, {{W-|fa|فاجعهبار}}, {{W+|fa|خیلی}}, {{W+|fa|صعب|guman=erê}}
* {{Z|fa}}: {{W+|fa|زحمت}}, {{W+|fa|سختی}}, {{W+|fa|زور}}, {{W+|fa|ظلم}}
* {{Z|en}}: {{W+|en|arduous}}, {{W+|en|dynamic}}, {{W+|en|force}}, {{W+|en|killing}}, {{W+|en|knotty}}, {{W+|en|pressure}}
* {{Z|tr}}: {{W+|tr|basınç}}, {{W+|tr|baskı}}, {{W+|tr|çekişmeli}}, {{W+|tr|çetin}}, {{W+|tr|güç}}, {{W+|tr|kompleks}}, {{W+|tr|korkunç}}, {{W+|tr|koyu}}, {{W+|tr|müşkül}}, {{W+|tr|müthiş}}, {{W+|tr|sarp}}, {{W+|tr|sıkı}}, {{W+|tr|sıkıntı}}, {{W+|tr|yeğin}}, {{W+|tr|zahmetli}}, {{W+|tr|zahmetli iş k}}, {{W+|tr|ziyade}}, {{W+|tr|zorlu}}, {{W+|tr|cebir}}, {{W+|tr|zor}}, {{W+|tr|şiddet}}
{{werger-bin}}
== {{ziman|ckb}} ==
=== Navdêr ===
{{navdêr|ckb|sc=Latn}}
# {{ckb-Arab|زۆر|w=[[gelek]], [[pir]]}}
== {{ziman|lad}} ==
=== Rengdêr ===
{{rengdêr|lad}}
# {{g|ku|zehmet}}, {{g|ku|dijwar}}
#* {{bêmînak|lad}}
=== Çavkanî ===
{{rûpela wergerê|lad|zehmet}}
== {{ziman|tr}} ==
=== Bilêvkirin ===
* {{deng|tr|LL-Q256 (tur)-ToprakM-zor.wav|Deng|dever=}}
=== Navdêr ===
{{navdêr|tr}}
# [[tengavî]], [[tengî]], [[tengayî]], [[nerihetî]]
#: {{mk|tr|Onun için hiç bir '''zorum''', sıkıntım yok.|Ji bo wê tu nerihetiya min nîn e.}}
# {{g|ku|zor}}, [[dijwar]], [[çetîn]], [[zehmet]]
#: {{mk|tr|'''Zor''' bir çalışma.|Xebateke zor e.|rêz=1}}
# [[divê]], [[pêwist]], [[hewce]], [[mecbûr]]
#: {{mk|tr|Oraya gitmek '''zorunda'''.|Divê here wê derê, pêwist e here wê derê.|rêz=1}}
# [[pest]], [[pêkutî]], [[kotek]]
#* {{bêmînak|tr}}
# [[bi zorekê]], [[bi zorê]]
#: {{mk|tr|Halkı '''zor''' zapt ettik.|Me gel bi zorekê zift kir.|rêz=1}}
# {{g|ku|zor}}
#: {{mk|tr|Biraz '''zor''' yaparsın.|Tu dê hinek zor karibî bikî.|rêz=1}}
7o461yjuoszj80msxl9t8m6639gc4th
form
0
8363
6347480
6306855
2026-08-31T20:54:58Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347480
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[teşe]], [[şêwaz]], [[dirûv]], [[şikil]]
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026|jêgirtin=Navê kilamê Dêre Sorê Piçûkê hin caran bi '''forma''' Dêresorê Piçûkê jî tê nivîsîn.}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Bi alfabeyên din ====
* {{ku-ar|فۆرم}}
==== Jê ====
{{kol3|ku
| forme
| formî
| formal
| formalî
| formalîte
}}
==== Etîmolojî ====
Ji {{deyn|en|ku|form}}, deyn ji {{ji|fro|ku|forme}}, ji {{ji|la|ku|fōrma}}.
==== Bide ber ====
* {{g|ku|forûm}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|Abbildung|f}}, {{W|de|Form|f}}
* {{Z|ar}}: {{W|ar|صيغة}}
* {{Z|fa}}: {{W+|fa|فرم}}
* {{Z|en}}: {{W+|en|form}}
* {{Z|tr}}: {{W+|tr|desen}}, {{W|tr|form}}
{{werger-bin}}
{{kontrolWerger}}
== {{ziman|en}} ==
=== Bilêvkirin ===
:{{ku-tîp|form}}
* {{deng|en|en-us-form.ogg|dever=DYA}}
* {{deng|en|LL-Q1860 (eng)-Back ache-form.wav|Deng|dever=London,QY}}
* {{deng|en|LL-Q1860 (eng)-Wodencafe-form.wav|Deng|dever=Teksas, DYA}}
* {{deng|en|LL-Q1860 (eng)-Grendelkhan-form.wav|Deng|dever=Connecticut, DYA}}
=== Navdêr===
{{en-navdêr|~}}
# {{g|ku|form}}, [[şêwaz]], [[dirûv]], [[şikil]]
#* {{bêmînak|en}}
=== Lêker ===
{{en-lêker}}
# [[çêkirin]], [[dariştin]], [[damezrandin]], [[dirist kirin]]
#* {{bêmînak|en}}
== {{ziman|tr}} ==
=== Navdêr ===
{{navdêr|tr}}
# [[dirûv]], [[şêwe]], [[teşe]], [[şekl]]
#* {{bêmînak|tr}}
# [[heng]], [[ordam]], [[kewn]]
#: {{mk|tr|'''Formunda''' değilim.|Ez ne di çax û benga xwe de me.|birêz=1}}
# {{g|ku|form}}
#: {{mk|tr|'''Formu''' doldur bana ver.|Formê dagire û bide min.|birêz=1}}
6dh06dr5bxuyh96o89hysotze2by9a3
tazî
0
8529
6347616
6338907
2026-09-01T11:31:45Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347616
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{beş|Rengdêr}} {{IPA|ku|/tˤɑ:'zi:/}}, طازی
** {{beş|Rengdêr}}: {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-tazî (Rengdêr).wav|dever=Bidlîs}}
* {{beş|Navdêr 1}} {{IPA|ku|/tʰɑ:'zi:/}}, تازی
* {{beş|Navdêr 2}} {{IPA|ku|/tʰɑ:'zi:/}}, تازی
* {{beş|Navdêr 2}}: {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-tazî (Navdêr 2).wav|dever=Bidlîs}}
* {{ku-kîte}}
=== Rengdêr ===
[[Wêne:William-Adolphe_Bouguereau_(1825-1905)_-_Seated_Nude_(1884).jpg|thumb|Jinek li erdê '''tazî''' rûniştiye.]]
{{rengdêr|ku}}, {{bilêv|t|nerm}} û {{bilêv|z|stûr}}
# [[bêcil|Bêcil]], [[rûs]], [[rût]], ti cil li ber ne, ti cil lê ne.
#* {{bêmînak|ku}}
==== Ji wêjeya klasîk ====
* {{J:Feqiyê Teyran|jêgirtin=Hemûwan dê ker bi ker kit</br>Taziyê uryan im ez</br>Perde çû ez mame '''tazî'''}}
==== Jê ====
{{kol3|ku|cure=Jê
|çîptazî
|tazîtî
|tazî bûn<crz:lêker>
|tazî kirin<crz:lêker>
|tazîbûn<crz:navdêr>
|tazîkirin<crz:navdêr>
|tazîbûyî<crz:rengdêr>
|tazîkirî<crz:rengdêr>
}}
==== Etîmolojî ====
Hevreha farisî {{g|fa|تازی}} (tazî: 1. tajî 2. [[talanker]], [[şelîner]]), pehlewî ''tazîk'', têkilî ''-taz-'' ku rehê dema niha ji lêkera ''texten'' ([[bezîn]], [[bazdan]]) e, avestayî ''tek-, teçeyti-'' ([[bezîn]], [[lezîn]]) û ''teke-'' ([[robar]], [[herik]]), osetî [[тæх]] (tex: [[beza]]), sanskrîtî [[तक्ति]] (tekti-), slaviya kevn [[тєшти]] (têşti: [[herikîn]]), rusî [[течь]] (têçi), sirboxirwatî [[teći]] / [[те̏ћи]], yûnaniya kevn [[ταχύς]] (taxûs: [[bilez]], [[beza]]), sekeyî/skîtî ''teke-'' ([[beza]]; [[xurt]]), latviyayî [[čakls]] ([[zîrek]]), almanî û holendî [[dienen]] ([[xizmet]] kirin, "di xizmeta kesekî de bezîn/[[lezîn]]"), swêdî [[tjäna]] ([[xizmet]] kirin), îngilîzî [[thew]] ([[xulam]] - êdî nayê bikaranîn) hemû ji {{ji|ine-pro|ku|-}} * [[tekʷ-]] ([[lezîn]], [[bezîn]]). Ji eynî rehî herwiha: [[tajî]], [[taze]], [[teze]], [[tacik]] û belkî [[tezî]] û [[çist]]. [[tazı|Tazı]] ya tirkî ji zimanekî îranî hatiye wergirtin.
==== Werger ====
{{werger-ser}}
* {{Z|ab}}: {{W-|ab|аҟьантаз}}
* {{Z|ady}}: {{W-|ady|пцӏанэ}}
* {{Z|af}}: {{W+|af|naak}}, {{W+|af|kaal}}, {{W-|af|kaalbas}}, {{W-|af|nakend}}
* {{Z|akl}}: {{W-|akl|oba}}
* {{Z|sq}}: {{W+|sq|lakuriq}}, {{W+|sq|cull}}, {{W-|sq|gollomësh}}
* {{Z|goh}}: {{W-|goh|nackot}}
* {{Z|de}}: {{W+|de|nackt}}
* {{Z|as}}: {{W-|as|নাঙঠ}}, {{W-|as|উদং}}
* {{Z|ast}}: {{W-|ast|desnudu}}, {{W-|ast|desvistíu}}
* {{Z|av}}: {{W-|av|гӏицӏаб}}
* {{Z|az}}: {{W+|az|çılpaq}}
* {{Z|eu}}: {{W-|eu|biluzi}}
* {{Z|ba}}: {{W-|ba|шәрә}}
* {{Z|be}}: {{W-|be|го́лы}}, {{W-|be|нагі́}}
* {{Z|bn}}: {{W+|bn|উদলা}}, {{W+|bn|উলঙ্গ}}, {{W+|bn|নগ্ন}}, {{W-|bn|বিবস্ত্র}}
* {{Z|bcl}}: {{W-|bcl|hubang pulos}}
* {{Z|br}}: {{W+|br|noazh}}
* {{Z|bg}}: {{W+|bg|гол}}
* {{Z|ccc}}: {{W-|ccc|kolochoshko}}
* {{Z|ce}}: {{W-|ce|дерзина}}
* {{Z|cs}}: {{W+|cs|nahý|n}}
* {{Z|chr}}: {{W-|chr|ᎤᏰᎸᎭᎢ}}
* {{Z|zh}}:
*: {{Z|yue}}: {{W-|yue|[[冇]][[著衫]]}}, {{W-|yue|[[冇]][[着衫]]|tr=mou5 zoek3 saam1}}
*: {{Z|cmn}}: {{W+|cmn|赤裸|tr=chìluǒ}}, {{W+|cmn|裸|tr=luǒ}}, {{W+|cmn|裸體|tr=luǒtǐ}}
* {{Z|dlm}}: {{W-|dlm|noid}}
* {{Z|da}}: {{W+|da|nøgen}}, {{W+|da|bar}}, {{W-|da|blottet}}, {{W-|da|splitternøgen}}
* {{Z|ovd}}: {{W-|ovd|nakun}}
* {{Z|id}}: {{W+|id|telanjang}}, {{W+|id|bogel}}
* {{Z|ar}}: {{W-|ar|عُرْيَان}}, {{W-|ar|عَارٍ}}
*: {{Z|arz}}: {{W-|arz|عريان|tr=ʕaryān}}
*: {{Z|acw}}: {{W-|acw|عُرْيان|n|tr=ʕuryān}}
*: {{Z|ary}}: {{W-|ary|عريان|n|tr=ʕaryān}}
*: {{Z|ajp}}: {{W-|ajp|عريان|tr=ʕaryān}}
* {{Z|hy}}: {{W+|hy|մերկ}}, {{W+|hy|տկլոր}}
* {{Z|eo}}: {{W+|eo|nuda}}
* {{Z|et}}: {{W-|et|paljas}}, {{W+|et|alasti}}
* {{Z|eve}}: {{W-|eve|дьулаккан}}
* {{Z|evn}}: {{W-|evn|дюлакин}}
* {{Z|fa}}: {{W+|fa|لخت|tr=loxt}}, {{W+|fa|برهنه|tr=berahne}}
* {{Z|fo}}: {{W-|fo|nakin}}
* {{Z|fi}}: {{W+|fi|alaston}}, {{W+|fi|alasti}}, {{W+|fi|kelteisillään}}
* {{Z|fr}}: {{W+|fr|nu}}
* {{Z|fur}}: {{W-|fur|crot}}, {{W-|fur|nûd}}, {{W-|fur|nût}}
* {{Z|fy}}: {{W-|fy|neaken}}, {{W-|fy|bleat}}
* {{Z|gd}}: {{W-|gd|lomnochd}}, {{W-|gd|rùisgte}}, {{W-|gd|lom}}
* {{Z|gl}}: {{W+|gl|espido|n}}
* {{Z|got}}: {{W-|got|𐌽𐌰𐌵𐌰𐌸𐍃}}
* {{Z|ka}}: {{W-|ka|შიშველი}}, {{W-|ka|ტიტველი}}, {{W-|ka|დედიშობილა}}, {{W-|ka|ტანჩაუცმელი}}
* {{Z|hi}}: {{W+|hi|नंगा}}, {{W+|hi|नग्न}}
* {{Z|nl}}: {{W+|nl|naakt}}, {{W+|nl|bloot}}, {{W+|nl|ongekleed}}
* {{Z|hrx}}: {{W-|hrx|nackich}}
* {{Z|he}}: {{W+|he|עירום|tr=eróm}}, {{W+|he|ערום|tr=aróm/arúm}}
* {{Z|ang}}: {{W-|ang|nacod}}
* {{Z|en}}: {{W+|en|naked}}, {{W+|en|nude}}
* {{Z|inh}}: {{W-|inh|верзан}}
* {{Z|ga}}: {{W-|ga|nocht}}
* {{Z|it}}: {{W+|it|nudo}}, {{W+|it|ignudo|n}}, {{W+|it|svestito|n}}
* {{Z|is}}: {{W+|is|nakinn}}, {{W+|is|ber}}, {{W-|is|allsber}}
* {{Z|ja}}: {{W+|ja|裸|tr=はだか, hadaka|cuda=裸}}
* {{Z|kaw}}: {{W-|kaw|wuda}}
* {{Z|jv}}: {{W+|jv|wuda}}
* {{Z|kbd}}: {{W-|kbd|пцӏанэ}}
* {{Z|ca}}: {{W+|ca|despullat}}, {{W+|ca|nu}}
* {{Z|qu}}: {{W-|qu|q'ara}}
* {{Z|ky}}: {{W+|ky|жылаңач}}
* {{Z|ko}}: {{W-|ko|벌거벗은}}, {{W+|ko|벌거벗다}}
* {{Z|kw}}: {{W-|kw|noth}}
* {{Z|lad}}: {{W-|lad|dezbragado}}, {{W-|lad|desnudo}}
* {{Z|ltg}}: {{W-|ltg|plyks}}
* {{Z|la}}: {{W-|la|nudus}}
* {{Z|lv}}: {{W+|lv|kails}}, {{W+|lv|pliks}}
* {{Z|lo}}: {{W-|lo|ເປືອຍ}}, {{W-|lo|ປະເປືອຍ}}
* {{Z|lt}}: {{W+|lt|nuogas}}, {{W-|lt|plikas}}
* {{Z|lmo}}: {{W-|lmo|biott}}
* {{Z|mk}}: {{W-|mk|гол}}
* {{Z|ms}}: {{W-|ms|telanjang}}
* {{Z|mt}}: {{W-|mt|mikxuf}}
* {{Z|gv}}: {{W-|gv|lhome}}
* {{Z|mi}}: {{W-|mi|tahanga}}, {{W-|mi|kirikau}}, {{W-|mi|hahake}}
* {{Z|mr}}: {{W-|mr|नागडा|n}}, {{W-|mr|नागडी|m}}, {{W-|mr|नागडे|nt}}
* {{Z|hu}}: {{W+|hu|meztelen}}, {{W+|hu|csupasz}}, {{W+|hu|pucér}}
* {{Z|mn}}:
*: Kirîlî: {{W+|mn|нүцгэн}}, {{W+|mn|шалдан}}
*: Mongolî: {{W-|mn|ᠨᠢᠴᠦᠭᠦᠨ}}, {{W-|mn|ᠱᠠᠯᠳᠠᠩ}}
* {{Z|nds}}: {{W-|nds|naakd}}, {{W-|nds|naked}}
* {{Z|non}}: {{W-|non|nakinn|n}}, {{W-|non|berr|n}}, {{W-|non|naktr|n}}
* {{Z|no}}: {{W+|no|naken}}
* {{Z|nys}}: {{W-|nys|balak}}
* {{Z|oc}}: {{W-|oc|desnut}}
* {{Z|or}}: {{W+|or|ନଗ୍ନ}}, {{W+|or|ଲଙ୍ଗଳା}}
* {{Z|os}}: {{W-|os|бӕгънӕг}}
* {{Z|ug}}: {{W-|ug|يالىڭاچ}}, {{W+|ug|ئوچۇق}}
* {{Z|uz}}: {{W+|uz|yalangʻoch}}, {{W+|uz|ochiq}}
* {{Z|ps}}: {{W+|ps|بربنډ|tr=barbanḍ}}, {{W+|ps|لوڅ|tr=luś}}
* {{Z|pdt}}: {{W-|pdt|noaktich}}
* {{Z|pl}}: {{W+|pl|nagi}}, {{W+|pl|goły}}
* {{Z|pt}}: {{W+|pt|nu}}, {{W+|pt|pelado}}, {{W+|pt|despido}}
* {{Z|kk}}: {{W-|kk|жалаңаш}}, {{W-|kk|тыржалаңаш}}
* {{Z|rgn}}: {{W-|rgn|nud}}
* Romani:
*: {{Z|rmf}}: {{W-|rmf|nango}}, {{W-|rmf|uutan koola}}
* {{Z|ro}}: {{W+|ro|dezbrăcat}}, {{W+|ro|gol}}
* {{Z|ru}}: {{W+|ru|го́лый}}, {{W+|ru|наго́й}}, {{W+|ru|обнажённый}}
* {{Z|sm}}: {{W-|sm|telefua}}
* {{Z|sc}}: {{W-|sc|nu}}, {{W-|sc|nuu}}, {{W-|sc|nuo}}, {{W-|sc|nudu}}, {{W-|sc|nutu}}
* {{Z|scn}}: {{W+|scn|nudu}}, {{W+|scn|nuru}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|го}}, {{W-|sh|гол}}, {{W-|sh|наг}}
*: Latînî: {{W+|sh|go}}, {{W+|sh|gol}}, {{W+|sh|nag}}
* {{Z|cu}}: {{W-|cu|нагъ}}, {{W-|cu|голъ}}
* {{Z|sk}}: {{W-|sk|nahý}}, {{W-|sk|holý}}
* {{Z|sl}}: {{W+|sl|gol|n}}, {{W+|sl|nag|n}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|nagi}}
*: {{Z|hsb}}: {{W-|hsb|nahi|n}}
* {{Z|es}}: {{W+|es|desnudo}}, {{W+|es|en cueros}}, {{W+|es|en pelota}}, {{W+|es|en pelotas}}, {{W+|es|en bolas}}, {{W+|es|bichi}}, {{W-|es|calancho}}, {{W+|es|calato}}, {{W+|es|chingo}}, {{W-|es|chulón}}, {{W+|es|chuto}}, {{W+|es|llucho}}, {{W+|es|pilucho}}, {{W+|es|viringo}}
* {{Z|sw}}: {{W+|sw|uchi}}
* {{Z|sv}}: {{W+|sv|naken}}, {{W+|sv|bar}}, {{W+|sv|blottad}}, {{W+|sv|avklädd}}, {{W+|sv|näck}}
* {{Z|tg}}: {{W+|tg|бараҳна}}
* {{Z|tl}}: {{W-|tl|hubo at hubad}}
* {{Z|th}}: {{W+|th|ล่อนจ้อน|tr=lôn-jôn}}, {{W-|th|โล้งโต้ง|tr=lóhng-dtôhng}}
* {{Z|tet}}: {{W-|tet|molik}}
* {{Z|tr}}: {{W+|tr|çıplak}}
* {{Z|tk}}: {{W-|tk|ýalanaç}}, {{W-|tk|ýalaňaç}}
* {{Z|to}}: {{W-|to|telefua}}
* {{Z|tyv}}: {{W-|tyv|чанагаш}}
* {{Z|ur}}: {{W-|ur|ننگا|tr=naṅgā}}
* {{Z|uk}}: {{W-|uk|го́лий}}, {{W-|uk|наги́й}}
* {{Z|vec}}: {{W-|vec|nuo}}, {{W-|vec|desnù}}
* {{Z|vi}}: {{W+|vi|khoả thân}}, {{W+|vi|trần truồng}}
* {{Z|vo}}: {{W+|vo|nüdik}}
* {{Z|cy}}: {{W+|cy|noeth}}
* {{Z|xh}}: {{W-|xh|ntswempu}}, {{W-|xh|ze}}
* {{Z|yi}}: {{W-|yi|נאַקעט}}
* {{Z|el}}: {{W+|el|γυμνός}}, {{W+|el|τσιτσίδι|nt}}
*: {{Z|grc}}: {{W-|grc|γυμνός}}
* {{Z|zu}}: {{W-|zu|nqunu}}
{{werger-bin}}
:{{werger çavkanî|en|naked|beş=Ev qismê Wergerê|oldid=75876136}}
=== Navdêr 1 ===
{{navdêr|ku|z=m}}, {{bilêv|t|req}} û {{bilêv|z|zirav}}
# [[rêûresm|Rêûresma]] [[binaxkirin]]a kesek [[mirî]], [[xemgînî|xemgîniya]] bo kesek [[mirî]].
#: {{hevmane|ku|behî|şînî|sersaxî|serxwaşî}}
#: {{nm|ku|Gundî hemû hatibûna '''taziya''' malbata kesê şehîdbûyî.}}
==== Bi alfabeyên din ====
* {{ku-ar|تازی}}
==== Formên alternatîv ====
{{kol3|ku
|taziye
}}
==== Etîmolojî ====
Ji {{ji|ar|ku|تَعْزِيَة}} ji {{g|ar|عزاء|tr='ezai}}. Guherîna "e'" (e+[[eyn]]) bi "a" di peyvên ji erebî wergirtî de di kurdî de [[diyarde]]yeke [[asayî]] ye. Ketina "-ye" ya nîşana [[zayend]]a [[mê]] ji peyvên ji erebî wergirtî di kurdî de ew jî [[fenomen]]eke [[tîpîk]] e.
==== Bi zaravayên din ====
* {{Z|ckb}}: pirse, rrêwrresmî meyt
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Kondolenz|m}}
* {{Z|be}}: {{W-|be|спачува́нне|nt}}
* Berberî:
*: {{Z|shi}}: {{W-|shi||tr=afcad|n}}
* {{Z|bg}}: {{W+|bg|съболе́знования|nt-p}}
* {{Z|cs}}: {{W-|cs|kondolence|m}}, {{W-|cs|soustrast|m}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|哀悼}}, {{W-|cmn|吊慰}}
* {{Z|da}}: {{W-|da|kondolence|g}}
* {{Z|ar}}: {{W-|ar|تَأْسِيَّة|m}}, {{W-|ar|تَعْزِيَّة|m}}
* {{Z|hy}}: {{W+|hy|ցավակցություն}}
* {{Z|et}}: {{W-|et|kaastunne}}, {{W-|et|kaastundeavaldus}}
* {{Z|fi}}: {{W+|fi|osanotto}}, {{W+|fi|surunvalittelu}}
* {{Z|fr}}: {{W+|fr|condoléances|m-p}}
* {{Z|nl}}: {{W+|nl|condoleance|m}}
* {{Z|en}}: {{W+|en|condolences}}
* {{Z|it}}: {{W+|it|condoglianze}}
* {{Z|ja}}: {{W+|ja|悔やみ|tr=おくやみ, okuyami|cuda=お悔やみ}}, {{W+|ja|哀悼|tr=あいとう, aitō}}, {{W+|ja|弔意|tr=ちょうい, chōi}}
* {{Z|ko}}: {{W+|ko|애도}}, {{W+|ko|조의}}
* {{Z|hu}}: {{W+|hu|részvét}}
* {{Z|no}}:
*: {{Z|nb}}: {{W-|nb|kondolanse|n}}
* {{Z|pl}}: {{W+|pl|kondolencje|m-p}}
* {{Z|pt}}: {{W+|pt|condolência|m}}, {{W+|pt|pêsame|n}}
* {{Z|ro}}: {{W+|ro|condoleanțe|m-p}}
* {{Z|ru}}: {{W+|ru|соболе́знование|nt}}, {{W+|ru|соболе́знования|nt-p}}
* {{Z|sk}}: {{W-|sk|kondolencia|m}}, {{W-|sk|sústrasť|m}}
* {{Z|es}}: {{W+|es|pésame}}
* {{Z|sv}}: {{W+|sv|kondoleans|g}}
* {{Z|tl}}: {{W-|tl|hingaba}}, {{W-|tl|paghihingaba}}, {{W-|tl|pakikiramay}}
* {{Z|tr}}: {{W+|tr|başsağlığı}}, {{W+|tr|taziye}}
* {{Z|uk}}: {{W-|uk|співчуття́|nt}}
{{werger-bin}}
:{{werger çavkanî|en|condolences|beş=Ev qismê Wergerê|oldid=75435192}}
=== Navdêr 2 ===
{{navdêr|ku|z=mn}}, {{bilêv|t|nerm}} û {{bilêv|z|stûr}}
# {{f|ku|kevn}} [[ereb|Ereb]].
#* {{bêmînak|ku}}
==== Notên bikaranînê ====
Tenê di hinek klasîkan de, bi taybetî Ehmedê Xanî
==== Etîmolojî ====
Hevreha farisî {{g|fa|تازی|tr=tâzi|w=ereb}}, {{hv|pal||tāzīgān|sc=Latn}}. Ji navê eşîra ereb a 'Tayy, bide ber aramî {{g|arc|ܛܝܝܐ|tr='teyyaya|w=ereb}}. {{cotreh|ku|tacîk}}.
==== Werger ====
{{werger-bnr|ereb}}
8xv4tkq86osaur544bijtxnqvtcsrgm
diz
0
8585
6347620
6336382
2026-09-01T11:33:51Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347620
wikitext
text/x-wiki
{{ds|diz|dizîker|dizîkar}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr 1 ===
[[Wêne:Jan Cossiers - Fortune Telling.jpg|thumb|'''Diz''' (li çepê) ji kesekî (li naverastê) didize.]]
{{navdêr|ku|z=mn}}
# Kesa/ê tiştan [[dizîn|didize]]; kesa/ê tiştên kesek din bêyî [[hay]] û [[destûr]]a wê / wî bo xwe dibe.
#: {{hevmaneyên peyvê|ku|dizîker}}
#* {{J:Firat Cewerî:Girtî:1986|jêgirtin=Em ne '''diz''' in. Min tu carî jî dizî nekiriye.}}
==== Ji wêjeya klasîk ====
* {{J:Mem û Zîn:1692|jêgirtin=Lê min ji rezan nekir temettu'<br>Manend-i '''dizan''' bi kes tetebbu'<br>Nûrestê hedîqeyê fu'ad e}}
==== Bi alfabeyên din ====
* {{ku-ar|دز}}
==== Formên alternatîv ====
{{kol3|ku
|duz
|dizek
|dizenek
}}
==== Jê ====
{{kol2|ku|cure=Jê
|dizî
|dizîkar
|dizîkarî
|dizîker
|dizîkerî
|dizîkî
|dizîn
|diziyayî
|dizek
}}
==== Etîmolojî ====
* {{ji|ira-pro||-}}: *'''[[dij|dus]]'''- ("dij, dijî") + *'''dhe'''- ("kirin")
*: {{ji|ira-pro||-}}:
::{{ae}}: '''duš'''-'''dah'''- ("xirabî kirin")
::{{pal}}: '''dwz''' ("diz")
::{{fa}}: '''duzd''' ("diz")
::{{bal}}: '''diz''' ("diz") ...{{ir}}
::{{kmr}}: '''diz''' ("diz")
::{{ckb}}: '''diz''' ("diz")
::{{zza}}: '''[[dizd]]''' ("diz")
==== Werger ====
{{werger-ser}}
* {{Z|ab}}: {{W-|ab|аӷьычҩы}}
* {{Z|af}}: {{W+|af|dief}}
* {{Z|sq}}: {{W+|sq|vjedhës|n}}, {{W+|sq|vjedhëse|m}}
* {{Z|de}}: {{W+|de|Dieb|n}}, {{W+|de|Diebin|m}}
* {{Z|am}}: {{W+|am|ሌባ}}
* {{Z|an}}: {{W-|an|furtaire|n}}
* {{Z|aqc}}: {{W-|aqc|цӏогьор}}
* {{Z|rup}}: {{W-|rup|fur|n}}, {{W-|rup|furcudar}}, {{W-|rup|haramiu}}, {{W-|rup|chisãgi}}, {{W-|rup|caceac}}
* {{Z|as}}: {{W-|as|চোৰ}}
* {{Z|ast}}: {{W-|ast|lladrón|n}}
* {{Z|av}}: {{W-|av|цӏогьор}}
* {{Z|az}}: {{W+|az|oğru}}
* {{Z|eu}}: {{W-|eu|lapur}}, {{W-|eu|ebasle}}
* {{Z|ba}}: {{W-|ba|бур}}, {{W-|ba|уғры}}, {{W-|ba|ҡараҡ}}
* {{Z|be}}: {{W-|be|зло́дзей|n}}, {{W-|be|зладзе́йка|m}}
* {{Z|bal}}: {{W-|bal|دز}}
* {{Z|bn}}: {{W-|bn|চোর}}
* {{Z|bcl}}: {{W-|bcl|paraikit}}
* {{Z|br}}: {{W+|br|laer|n}}
* {{Z|bg}}: {{W-|bg|краде́ц|n}}, {{W-|bg|арами́я|n}}, {{W-|bg|арами́йка|m}}
* {{Z|my}}: {{W+|my|သူခိုး}}
* {{Z|cim}}: {{W-|cim|diip|n}}
* {{Z|ccc}}: {{W-|ccc|ma'koleti}}
* {{Z|ce}}: {{W-|ce|къу}}
* {{Z|cs}}: {{W+|cs|zloděj|n}}, {{W+|cs|zlodějka|m}}
* {{Z|chr}}: {{W-|chr|ᎦᏃᏍᎩᏍᎩ}}
* {{Z|ny}}: {{W-|ny|wakuba}}
* {{Z|zh}}:
*: {{Z|yue}}: {{W-|yue|賊|tr=caak6-2}}
*: {{Z|dng}}: {{W-|dng|зый}}, {{W-|dng|вэзый}}
*: {{Z|hak}}: {{W-|hak|賊仔|tr=chhe̍t-é}}
*: {{Z|cmn}}: {{W+|cmn|賊|tr=zéi}}, {{W-|cmn|盜賊|tr=dàozéi}}, {{W+|cmn|小偷|tr=xiǎotōu}}, {{W+|cmn|宵小|tr=xiāoxiǎo}}, {{W+|cmn|竊賊|tr=qièzéi}}
*: {{Z|nan}}: {{W+|nan|賊仔|tr=chha̍t-á}}, {{W+|nan|勍仔|tr=khiang-á}}
* {{Z|cv}}: {{W-|cv|вӑрӑ}}
* {{Z|da}}: {{W+|da|tyv|g}}, {{W-|da|tyveknægt|g}}
* {{Z|id}}: {{W+|id|pencuri}}
* {{Z|ar}}: {{W-|ar|لِصّ|n}}, {{W-|ar|لِصَّة|m}}, {{W+|ar|سَارِق|n}}, {{W-|ar|سَارِقَة|m}}, {{W-|ar|حَرَامِيّ|n}}, {{W-|ar|حَرَامِيَّة|m}}
*: {{Z|arz}}: {{W-|arz|حرامى|n|tr=ḥarāmi}}
*: {{Z|afb}}: {{W-|afb|بايك|n|tr=bāyeg}}
*: {{Z|acw}}: {{W-|acw|حرامي|n|tr=ḥarāmi}}
*: {{Z|ary}}: {{W-|ary|سراق|n|tr=sarrāq}}, {{W-|ary|شفار|m|tr=šaffār}}
* {{Z|hy}}: {{W+|hy|գող}}
* {{Z|eo}}: {{W+|eo|ŝtelisto}}
* {{Z|et}}: {{W+|et|varas}}
* {{Z|ee}}: {{W-|ee|fiafi|nt}}, {{W-|ee|fiafitɔ|nt}}
* {{Z|fa}}: {{W+|fa|دزد|tr=dozd}}, {{W+|fa|حرامی|tr=harâmi}}
* {{Z|phn}}: {{W-|phn|𐤀𐤂𐤓𐤃|p}}
* {{Z|fo}}: {{W-|fo|tjóvur|n}}
* {{Z|fi}}: {{W+|fi|varas}}, {{W+|fi|voro}}, {{W+|fi|ryöväri}}, {{W+|fi|rosvo}}
* {{Z|frp}}: {{W-|frp|lârro|n}}
* {{Z|fr}}: {{W+|fr|voleur|n}}, {{W+|fr|voleuse|m}}
* Frisian:
*: {{Z|frr}}: {{W-|frr|tiif|n}}
* {{Z|fur}}: {{W-|fur|lari|n}}
* {{Z|gd}}: {{W-|gd|mèirleach|n}}
* {{Z|gl}}: {{W-|gl|ladrón|n}}, {{W-|gl|lespio|n}}, {{W-|gl|galafate|n}}, {{W-|gl|ladroeiro|n}}, {{W-|gl|gallofo|n}}, {{W-|gl|regatiñeiro|n}}, {{W-|gl|surpón|n}}
* {{Z|got}}: {{W-|got|𐌷𐌻𐌹𐍆𐍄𐌿𐍃|n}}, {{W-|got|𐌸𐌹𐌿𐍆𐍃|n}}
* {{Z|gu}}: {{W-|gu|દસ્યુ|n}}
* {{Z|ka}}: {{W-|ka|ქურდი}}
* {{Z|hi}}: {{W+|hi|चोर|n}}
* {{Z|hil}}: {{W-|hil|kawatan}}
* {{Z|nl}}: {{W+|nl|dief|n}}, {{W+|nl|dievegge|m}}, {{W+|nl|gannef|n}}
* {{Z|he}}: {{W-|he|גַּנָּב|n|tr=ganáv}}
* {{Z|io}}: {{W+|io|furtanto}}
* {{Z|ilo}}: {{W-|ilo|mannanakaw}}
* {{Z|ang}}: {{W-|ang|þēof|n}}
* {{Z|en}}: {{W+|en|thief}}
* {{Z|izh}}: {{W-|izh|varas}}
* {{Z|inh}}: {{W-|inh|къу}}
* {{Z|ga}}: {{W+|ga|gadaí|n}}
* {{Z|ist}}: {{W-|ist|laro|n}}
* {{Z|it}}: {{W+|it|ladro|n}}, {{W+|it|ladra|m}}, {{W-|it|ladruncolo|n}}, {{W+|it|borsaiolo|n}}, {{W+|it|scippatore|n}}, {{W+|it|mariolo|n}}, {{W+|it|taccheggiatore}}, {{W+|it|malandrino|n}}, {{W+|it|borseggiatore}}
* {{Z|is}}: {{W+|is|þjófur}}
* {{Z|ja}}: {{W+|ja|泥棒|tr=どろぼう, dorobō}}, {{W+|ja|盗賊|tr=とうぞく, tōzoku}}, {{W-|ja|窃盗者|tr=せっとうしゃ, settō-sha}}
* {{Z|jv}}: {{W+|jv|maling}}, {{W+|jv|bajingan}}
* {{Z|xal}}: {{W-|xal|хулхач}}
* {{Z|kn}}: {{W+|kn|ಕಳ್ಳ}}
* {{Z|ca}}: {{W+|ca|lladre|n}}
* {{Z|qu}}: {{W-|qu|suwa}}
* {{Z|ky}}: {{W+|ky|ууру}}
* {{Z|kg}}: {{W-|kg|mwivi}}
* {{Z|ki}}: {{W-|ki|mũici|c1}}
* {{Z|si}}: {{W-|si|හොරා}}
* {{Z|koi}}: {{W-|koi|гусь}}
* {{Z|ko}}: {{W+|ko|도둑}}
* {{Z|co}}: {{W+|co|latru|n}}
* {{Z|lld}}: {{W-|lld|lère|n}}
* {{Z|lad}}:
*: Îbranî: {{W-|lad|לאד׳רון|n}}
*: Latînî: {{W-|lad|ladrón|n}}, {{W-|lad|ladhron|n}}
* {{Z|la}}: {{W+|la|fūr|n|m}}, {{W+|la|latro|n}}
* {{Z|lv}}: {{W-|lv|zaglis|n}}, {{W-|lv|zagle|m}}
* {{Z|lo}}: {{W-|lo|ກະໂມຽ}}, {{W+|lo|ຂະໂມຍ}}, {{W-|lo|ໂຈນ}}
* {{Z|lzz}}: {{W-|lzz|mamxire}}
* {{Z|lez}}: {{W-|lez|угъри}}
* {{Z|lij}}: {{W-|lij|laddro|n}}
* {{Z|lt}}: {{W-|lt|vagis|n}}
* {{Z|liv}}: {{W-|liv|salāj}}
* {{Z|lmo}}: {{W-|lmo|lader|n}}
* {{Z|lb}}: {{W+|lb|Déif|n}}
* {{Z|mk}}: {{W-|mk|крадец|n}}, {{W-|mk|арамија|n}}
* {{Z|mg}}: {{W+|mg|kary}}, {{W+|mg|fangalarina}}
* {{Z|ml}}: {{W+|ml|കള്ളൻ}}, {{W+|ml|മോഷ്ടാവ്}}
* {{Z|ms}}: {{W+|ms|pencuri}}
* {{Z|mt}}: {{W-|mt|ħalliel|n}}
* {{Z|mi}}: {{W-|mi|kaiā}}, {{W-|mi|tāhae}}, {{W-|mi|whānako}}
* {{Z|arn}}: {{W-|arn|weñefe}}
* {{Z|mr}}: {{W-|mr|चोर|n|m}}
* {{Z|yua}}: {{W-|yua|ookol}}
* {{Z|hu}}: {{W+|hu|tolvaj}}
* {{Z|egy}}: {{W-egy|ꜥwꜣy|h=a-V4-A-i-i-A24}}, {{W-egy|jṯꜣ|h=i-TA-A-D51:D40-A1}}
* {{Z|mwl}}: {{W-|mwl|lhadron|n}}
* {{Z|mn}}:
*: Kirîlî: {{W+|mn|хулгайч}}, {{W+|mn|хулгай}}
*: Mongolî: {{W-|mn|ᠬᠤᠯᠠᠭᠠᠢᠢᠴᠢ}}, {{W-|mn|ᠬᠤᠯᠠᠭᠠᠢ}}
* {{Z|wmw}}: {{W-|wmw|mwivi}}
* {{Z|gld}}: {{W-|gld|чово}}
* {{Z|nap}}: {{W-|nap|latro|n}}, {{W-|nap|mariuólo|n}}, {{W-|nap|mariunciéllo|n}}, {{W-|nap|ferraiuólo|n}}, {{W-|nap|màneco 'ancino|n}}
* {{Z|nv}}: {{W-|nv|aniʼįįhii}}
* {{Z|nds}}: {{W-|nds|Deef|n}}
* {{Z|ne}}: {{W+|ne|चोर}}
* {{Z|nrf}}: {{W-|nrf|voleux|n}}
* {{Z|non}}: {{W-|non|þjófr|n}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|tyv|n}}, {{W+|nb|tjuv|n}}
*: {{Z|nn}}: {{W+|nn|tjuv|n}}
* {{Z|oj}}: {{W-|oj|gimoodishk}}
* {{Z|oc}}: {{W+|oc|raubaire|n}}, {{W+|oc|raubaira|m}}, {{W+|oc|laire|n}}, {{W+|oc|laira|m}}
* {{Z|or}}: {{W+|or|ଚୋର}}
* {{Z|om}}: {{W-|om|hattuu}}
* {{Z|ota}}: {{W-|ota|اوغری}}
* {{Z|ug}}: {{W-|ug|ئوغرى}}
* {{Z|uz}}: {{W+|uz|oʻgʻri}}
* {{Z|ps}}: {{W+|ps|غل|n|tr=ǧal}}
* {{Z|pms}}: {{W-|pms|làder|n}}
* {{Z|pl}}: {{W+|pl|złodziej|n}}, {{W+|pl|złodziejka|m}}, {{W+|pl|kradziej}}
* {{Z|pt}}: {{W+|pt|ladrão|n}}, {{W+|pt|ladra|m}}
* {{Z|pa}}: {{W-|pa|ਚੋਰ|n}}
* {{Z|kk}}: {{W-|kk|ұры}}
* {{Z|rhg}}: {{W-|rhg|sur}}
* {{Z|rgn}}: {{W-|rgn|lêdar|n}}
* {{Z|rm}}: {{W-|rm|lader|n}}, {{W-|rm|leder|n}}
* {{Z|rom}}: {{W-|rom|ćor|n}}
* {{Z|ro}}: {{W+|ro|hoț|n}}, {{W+|ro|hoață|m}}
* {{Z|ru}}: {{W+|ru|вор|n}}, {{W-|ru|воро́вка|m}}, {{W-|ru|ворю́га|n|m}}, {{W-|ru|вори́шка|n|m}}
* {{Z|sa}}: {{W+|sa|चोर|n}}, {{W+|sa|चोरी|m}}
* {{Z|ceb}}: {{W-|ceb|kawatan}}
* {{Z|scn}}: {{W+|scn|latru|n}}, {{W+|scn|latruni|n}}, {{W+|scn|larruni|n}}
* {{Z|sid}}: {{W-|sid|mooraancho}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|ло́пов|n}}, {{W-|sh|та̏т|n}}, {{W-|sh|кра̀дљивац|n}}, {{W-|sh|хара̀мија|n}}
*: Latînî: {{W+|sh|lópov|n}}, {{W+|sh|tȁt|n}}, {{W+|sh|kràdljivac|n}}, {{W+|sh|haràmija|n}}
* {{Z|cu}}:
*: Kirîlî: {{W-|cu|татъ|n}}, {{W-|cu|зълодѣи|n}}
* {{Z|sk}}: {{W+|sk|zlodej|n}}, {{W-|sk|zlodejka|m}}
* {{Z|sl}}: {{W+|sl|tat|n}}
* {{Z|so}}: {{W-|so|tuug}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|złoźej|n}}
*: {{Z|hsb}}: {{W-|hsb|paduch|n}}
* {{Z|es}}: {{W+|es|ladrón|n}}, {{W+|es|caco|n}}, {{W+|es|chorizo|n}}, {{W-|es|mangante|n}}, {{W+|es|amigo de lo ajeno}}
* {{Z|su}}: {{W-|su|maling}}
* {{Z|sva}}: {{W-|sva|ქუ̂ით}}
* {{Z|sw}}: {{W+|sw|mwizi}}, {{W+|sw|mnyang'anyi|c1|c2}}
* {{Z|sv}}: {{W+|sv|tjuv|g}}
* {{Z|zdj}}: {{W-|zdj|mwidzi|c1|c2}}
* {{Z|tab}}: {{W-|tab|угъри}}
* {{Z|tg}}: {{W+|tg|дузд}}
* {{Z|tl}}: {{W-|tl|magnanakaw}}
* {{Z|tly}}: {{W-|tly|دزد|tr=dəzd}}
* {{Z|ta}}: {{W+|ta|திருடன்}}
* {{Z|twf}}: {{W-|twf|tràmpi’ína}}
* {{Z|th}}: {{W+|th|ขโมย}}, {{W+|th|โจร}}
* {{Z|te}}: {{W+|te|దొంగ}}
* {{Z|tt}}: {{W+|tt|карак}}
* {{Z|tr}}: {{W+|tr|hırsız}}, {{W+|tr|uğru}}; {{W+|tr|kuldur}}, {{W+|tr|karak}}
* {{Z|tk}}: {{W-|tk|ogry}}
* {{Z|bo}}: {{W-|bo|རྐུ་མ}}
* {{Z|tpi}}: {{W-|tpi|raskol}}
* {{Z|txb}}: {{W-|txb|lyak|n}}
* {{Z|tyv}}: {{W-|tyv|оор}}
* {{Z|ur}}: {{W-|ur|چور|n|tr=cor}}
* {{Z|uk}}: {{W-|uk|зло́дій|n}}, {{W-|uk|зло́дійка|m}}
* {{Z|vec}}: {{W-|vec|laro|n}}, {{W-|vec|ladro|n}}, {{W-|vec|ladron|n}}
* {{Z|vi}}: {{W+|vi|kẻ trộm}}, {{W+|vi|kẻ cắp}}, {{W+|vi|ăn trộm}}
* {{Z|vo}}: {{W+|vo|tifan}}, {{W-|vo|hitifan}}, {{W+|vo|jitifan}}
* {{Z|wa}}: {{W+|wa|voleu|n}}, {{W+|wa|voleuse|m}}, {{W+|wa|volresse|m}}
* {{Z|war}}: {{W-|war|buyon}}
* {{Z|cy}}: {{W+|cy|lleidr|n}}, {{W+|cy|lladron|n-p}}
* {{Z|wym}}: {{W-|wym|dīb}}
* {{Z|km}}: {{W+|km|ចោរ}}
* {{Z|yi}}: {{W-|yi|גנבֿ|n|tr=ganev}}, {{W-|yi|גנבֿטע|m|tr=ganevte}}
* {{Z|el}}: {{W+|el|κλέφτης|n}}
*: {{Z|grc}}: {{W-|grc|κλέπτης|n}}, {{W-|grc|κλώψ|n}}, {{W-|grc|φώρ|n}}
{{werger-bin}}
:{{werger çavkanî|en|thief|beş=Ev beşa Wergerê|oldid=75735930}}
=== Navdêr 2 ===
{{navdêr|ku|z=m}}
# {{f|ku|nadir}} [[asêgeh]], [[keleh]], [[sûr]]
#* {{bêmînak|ku}}
==== Notên bikaranînê ====
* Tenê di navê hinek bajar/deveran de, wek [[Şêladiz]] û [[Qeladiz]].
==== Jê ====
{{kol3|ku
|dizdar
|Dizesor
|Şêladiz
|Qeladiz
}}
==== Etîmolojî ====
Ji {{ji|ine-pro|ku|*dʰeiǵʰ-}} ([[melhem]] lê dan), hevreha avestayî [[𐬛𐬀𐬉𐬰𐬀]] (deêze: [[dîwar]]), ermeniya kevn [[դէզ]] (dêz), {{hv|sa|देग्धि}} ([[melhem]] lê dan), {{hv|grc|τεῖχος}} ([[dîwar]]ê [[kelh]]ê), [[fingō]] ([[dirûv]] danê, [[şikil]] danê)
==== Werger ====
{{werger-ser}}
{{werger-bin}}
== {{ziman|tr}} ==
=== Bilêvkirin ===
* {{deng|tr|LL-Q256 (tur)-ToprakM-diz.wav|Deng|dever=}}
=== Navdêr ===
{{navdêr|tr}}
# [[çok]], [[çong]]
#* {{bêmînak|tr}}
hovbe15d4mwl16zwr35nwweo7alvfih
hilawîstin
0
9860
6347634
6308640
2026-09-01T11:49:33Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347634
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Lêker ===
[[Wêne:Drying laundry, Umag, Istria, Croatia.jpg|thumb|Cil bi [[riste|ristê]] ve '''hilawîstî'''.]]
{{lêker|ku|c=x-gh}}
# [[daliqandin]], [[bi dar ve kirin]], bi [[dîwar]] ve kirin, bi [[rist]]ê ve kirin
#* {{jêder-pirtûk|ku|jêgirtin=û bê hejmar dolikên dîwaran ku komik û sako lê bên '''hilawîstin...''' |nivîskar={{w|J.R.R. Tolkien}}|sernav=Hobbit|wergêr=Samî Hêzil|cîh=Enqere|weşanxane={{w|Weşanên Cervantes|Cervantes}}|sal=2023|çap=1|rûpel=9|isbn=9786257724838}}
#* {{jêder-kitêb|ku|jêgirtin=— "Ev çavê min, di çaxê îşkenceyê de, hate korekirin. Ez bi pankeke bersîvandeyan ve '''hilawîstibûm''', dest û piyên min bi pankeyê ve girêdayî û berê nacçavên min û sînga min ber bi jêr. [..]"|nivîskar=Sidqî Hirorî|sernav=Kurê Zinarê Serbilind|weşanxane=Wejanên NUDEM|sal=1996|rûpel=67|isbn=9188592-200}}
==== Tewandin ====
* ''Rehê niha'': -hilawîs-
* ''Rehê borî'': -hilawîst-
==== Notên bikaranînê ====
* Tevî ku "hilawîstin" [[lêker]]eke [[hevdanî]] ya bi [[hil-]] e jî, ew wek peyvên din yên bi pêşpirtika "hil-" natewe. Anku rehê dema niha "-hilawîs-" (ez dihilawîsim), ne "hil-awîs-" e (*ez hil-di-awîsim" wek "hil-di-girim, hil-di-dim". Sebebê vê [[awarte|awartetiyê]] ew e ku lêkera *awîstin wek peyveke serbixwe di kurdî de nîne.
* Berevajî lêkerên din yên bi "-îstin" (bo nimûne "mîstin > -mîz") di dema niha de "s" nabe "z".
==== Bi alfabeyên din ====
* {{ku-ar|هلاویستن}}
==== Formên alternatîv ====
{{kol3|ku
|helawîstin
|da-awîstin
|hilawistin
}}
==== Hevmane ====
{{kol3|ku
|daliqandin
}}
==== Jê ====
{{kol3|ku
|hilawîstî
}}
==== Têkildar ====
{{kol3|ku
|hilawisîn
|[[daawistin]], [[daawiz]]
|[[awistin]], [[awiz]]
}}
==== Etîmolojî ====
[[hil-]] + *[[awîstin]] (wek peyveke serbixwe di kurdî de nîne), [[hevreh]]a soranî {{g|ckb|هەڵاواسین|tr=heławasîn}} û {{g|ckb|هەڵواسین|tr=hełwasîn}}, farisî {{g|fa|آویختن}} (avîxten - rehê dema niha "-avîz-"), avestayî ''a-veêçe-, a-veêg-'', îngilîzî [[weigh]] (bi [[terazû|terazûyê]] [[kêşan]]), almanî [[wegen]] / [[wägen]] (bi [[terazû|terazûyê]] [[kêşan]]) û [[Waage]] ([[terazû]]), holendî [[wegen]] (bi [[terazû|terazûyê]] [[kêşan]]), swêdî [[väga]] (bi [[terazû|terazûyê]] [[kêşan]]), danmarkî [[veje]] (bi [[terazû|terazûyê]] [[kêşan]]), hemû ji {{ji|ine-pro|ku|*wéǵʰ-|w=[[hilgirtin]], [[rakirin]]}}.
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W|af|hang}}
* {{Z|de}}: {{W|de|hängen}}, {{W|de|aufhängen}}, {{W|de|Aufhängen}}
* {{Z|cic}}: {{W|cic|takaali}}
* {{Z|da}}: {{W|da|hænge}}
* {{Z|ar}}: {{W|ar|علق|tr='eleqe}}, {{W|ar|تعلق}}, {{W|ar|التعلیق|guman=erê}}
* {{Z|eo}}: {{W|eo|pendi}}
* {{Z|fa}}: {{W|fa|آویختن|tr=avîxten}}, {{W|fa|آویختن}}, {{W|fa|آویزان کردن}}, {{W|fa|آویختن}}, {{W|fa|حکاکی کردن}}, {{W|fa|ماندگار کردن}}
* {{Z|fo}}: {{W|fo|hanga}}
* {{Z|fi}}: {{W|fi|riippua}}
* {{Z|fr}}: {{W|fr|pendre}}, {{W|fr|suspendre}}
* {{Z|nl}}: {{W|nl|hangen}}
* {{Z|he}}: {{W|he|תלה}} {{n}}
* {{Z|io}}: {{W|io|pendar}}
* {{Z|en}}: to {{W|en|hang}}, to {{W|en|droop}}, {{W|en|impend|guman=erê}}, {{W|en|suspense|guman=erê}}, {{W|en|suspension|guman=erê}}
* {{Z|it}}: {{W|it|pendere}}
* {{Z|is}}: {{W|is|hanga}}
* {{Z|ca}}: {{W|ca|penjar}}
* {{Z|no}}: {{W|no|henge}}
* {{Z|oc}}: {{W|oc|penjar}}
* {{Z|pl}}: {{W|pl|wisieć}}
* {{Z|pt}}: {{W|pt|pender}}
* {{Z|ro}}: {{W|ro|agăța}}, {{W|ro|atîrna}}
* {{Z|ru}}: {{W|ru|висеть}}
* {{Z|srn}}: {{W|srn|anga}}
* {{Z|es}}: {{W|es|colgar}}, {{W|es|pender}}
* {{Z|sv}}: {{W|sv|hänga}}
* {{Z|tr}}: {{W|tr|asmak}}
{{werger-bin}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# {{mane?|ku}}
#* {{jêder-kitêb|ku|jêgirtin=Sê ristikên cil û kinc '''hilawîstinê''' bi dîwarê mezelkê û dîwarê çeperî ve girêdayî bûn.|nivîskar=Sidqî Hirorî|sernav=Kurê Zinarê Serbilind|weşanxane=Wejanên NUDEM|sal=1996|rûpel=89|isbn=9188592-200}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Werger ====
{{werger-ser}}
* {{Z|tr}}: {{W|tr|ası}}, {{W|tr|asma}}
{{werger-bin}}
lu4o2uzu4jzqnhk2i13d334a67lzunq
pirç
0
12208
6347617
6314679
2026-09-01T11:32:05Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347617
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA|p(')irç(')}}
* {{deng|ku|LL-Q36368 (kur)-Mihemed Qers-pirç.wav|dever=Qers}}
* {{deng|ku|LL-Q36163 (kmr)-Key Mîrza-pirç.wav|dever=Bidlîs}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[mû]]yên li ser [[laş]]ê [[mirov]]an
#* {{bêmînak|ku}}
# [[mû]]yên li [[ser]]ê [[mirov]]an
#* {{bêmînak|ku}}
# [[mû]]yên li ser laşê hin [[heywan]]an
#: {{nm|ku|'''pirça''' hespa}}
# [[pûrt]], [[mû]]
#* {{bêmînak|ku}}
# [[pirt]]
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Notên bikaranînê ====
* [[mû]]: livek-têlek porr, pirç
* [[pirç]]: mûyên li ser laşê mirovan
* [[por]] : mûyên li ser serê mirovan
* [[pûrt]]: kurkên ajalan,
==== Bi alfabeyên din====
* {{ku-ar|پرچ}}
==== Têkildar ====
{{kol3|ku
|mû
|rû
|simêl
}}
==== Etîmolojî ====
Ji {{mîr|ine-pro|ku|*wolḱos}}. Hevreha {{hv|ckb|پرچ}}, [[zazakî]] (pirç), {{hv|fa|گرس|tr=gors}}, {{hv|ae|𐬬𐬀𐬭𐬆𐬯𐬀}}, {{hv|sog||tr=wars|ts=wrs}}, {{hv|sa|वल्श}}, {{hv|ru|во́лос}}, {{hv|cs|vlas}}, {{hv|pl|włos}}...
==== Werger ====
{{werger-ser}}
* {{Z|ab}}: {{W-|ab|ахәы}}
* {{Z|ace}}: {{W-|ace|o'}}
* {{Z|ady}}: {{W-|ady|шъхьэц}}
* {{Z|aa}}: {{W-|aa|xagor}}
* {{Z|af}}: {{W+|af|haar}}
* {{Z|aho}}: {{W-|aho|𑜇𑜤𑜪}}
* {{Z|akk}}: {{W-|akk|𒋠|tr=šārtu|sc=Xsux}}
* {{Z|akl}}: {{W-|akl|buhok}}
* {{Z|sq}}: {{W+|sq|qime}}
* {{Z|pdc}}: {{W-|pdc|Haar|nt}}
* {{Z|de}}: {{W+|de|Haar|nt}}, {{W+|de|Haar|nt|cuda=Haare}}
* {{Z|alt}}: {{W-|alt|чач}}
* {{Z|am}}: {{W-|am|ፀጉር|sc=Ethi}}
* {{Z|aqc}}: {{W-|aqc|чӏааӏри}}
* {{Z|rup}}: {{W-|rup|per|n}}
* {{Z|aer}}: {{W-|aer|alte}}
* {{Z|as}}: {{W-|as|চুলি}}
* {{Z|ast}}: {{W+|ast|pelu|n}}
* {{Z|ain}}: {{W-|ain|ヌマ|tr=numa}}
* {{Z|az}}: {{W+|az|saç}}
* {{Z|bm}}: {{W-|bm|kunsi}}
* {{Z|eu}}: {{W+|eu|ile}}
* {{Z|ba}}: {{W-|ba|сәс}}
* {{Z|bbl}}: {{W-|bbl|ბეჯ}}
* {{Z|be}}: {{W-|be|[[волас|валасы́]]|n-p|sc=Cyrl}}, {{W-|be|во́лас|n|sc=Cyrl}}
* {{Z|bn}}: {{W+|bn|চুল}}
* {{Z|bcl}}: {{W-|bcl|buhok}}
* {{Z|bho}}: {{W-|bho|𑂍𑂵𑂬}}, {{W-|bho|𑂕𑂷𑂀𑂗}}
* {{Z|bor}}: {{W-|bor|ao}}
* {{Z|br}}: {{W+|br|blev}}
* {{Z|kxd}}: {{W-|kxd|rambut}}
* {{Z|bdk}}: {{W-|bdk|чӏер}}
* {{Z|bg}}: {{W+|bg|коса́|n}}
* {{Z|my}}: {{W+|my|ဆံပင်|sc=Mymr}}
* {{Z|ccc}}: {{W-|ccc|shenu}}
* {{Z|ch}}: {{W-|ch|pulu}}
* {{Z|ce}}: {{W-|ce|месаш|p}}
* {{Z|cs}}: {{W+|cs|vlasy|n-p}}, {{W+|cs|vlas|n}}
* {{Z|chr}}: {{W-|chr|ᎤᏍᏘᎬᎢ}}
* {{Z|zh}}:
*: {{Z|yue}}: {{W-|yue|頭髮|tr=tau4 faat3}}
*: {{Z|dng}}: {{W-|dng|туфа}}
*: {{Z|gan}}: {{W-|gan|頭髮|tr=teu2 fat}}
*: {{Z|hak}}: {{W-|hak|頭髮|tr=thèu-fat}}
*: {{Z|cjy}}: {{W-|cjy|頭髮|tr=tou1 fah4}}
*: {{Z|cmn}}: {{W+|cmn|頭髮|tr=tóufa}}
*: {{Z|cdo}}: {{W-|cdo|頭髮|tr=tàu-huók}}
*: {{Z|nan}}: {{W+|nan|頭毛|tr=thâu-mn̂g, thâu-mô͘, thâu-mo͘}}, {{W+|nan|頭鬃|tr=thâu-chang}}
*: {{Z|wuu}}: {{W-|wuu|頭髮}}
*: {{Z|hsn}}: {{W-|hsn|頭髮|tr=tou2 fa6}}
* {{Z|da}}: {{W+|da|hår|nt}}
* {{Z|dlg}}: {{W-|dlg|ас}}
* {{Z|id}}: {{W+|id|rambut}}
* {{Z|enq}}: {{W-|enq|iti}}
* {{Z|ar}}: {{W+|ar|شَعْر}}, {{W+|ar|شَعْرَة|m|sc=Arab}}
*: {{Z|arz}}: {{W-|arz|شعر|n|tr=šaʿr}}, {{W-|arz|شعرة|m|tr=šaʿra}}
*: {{Z|afb}}: {{W-|afb|شعر|n|tr=šaʿar}}, {{W-|afb|شعرة|m|tr=šaʿra}}
* {{Z|hy}}: {{W+|hy|մազեր}}
* {{Z|eo}}: {{W+|eo|haro}}, {{W+|eo|hararo}}
* {{Z|et}}: {{W+|et|juuksed|p}}
* {{Z|ee}}: {{W-|ee|ɖa}}
* {{Z|fa}}: {{W+|fa|مو|tr=mu}}, {{W+|fa|گیس|tr=gis}}
* {{Z|fo}}: {{W+|fo|hár|nt}}
* {{Z|fi}}: {{W+|fi|hiukset|p}}, {{W+|fi|tukka}}
* {{Z|fr}}: {{W+|fr|cheveu|n}}, {{W+|fr|cheveu|cuda=cheveux|n}}, {{W+|fr|chevelure|m}}
*: {{Z|fro}}: {{W-|fro|cheveu|n}}
* {{Z|fur}}: {{W-|fur|cjaveli|n}}, {{W-|fur|čhavêl|n}}
* {{Z|stq}}: {{W-|stq|Hier|nt}}
* {{Z|fy}}: {{W+|fy|hier|nt}}
* {{Z|gd}}: {{W-|gd|falt|n}}, {{W-|gd|fuiltean|n-p}}, {{W-|gd|gruag|m}}, {{W-|gd|gruagan|n-p}}
* {{Z|gl}}: {{W+|gl|cabelo|n}}, {{W+|gl|pelo|n}}
* {{Z|got}}: {{W-|got|𐍃𐌺𐌿𐍆𐍄|nt}}
* {{Z|gu}}: {{W+|gu|વાળ|n}}, {{W-|gu|કેશ|n}}
* {{Z|ka}}: {{W-|ka|თმა}}
* {{Z|gn}}: {{W-|gn|akãrangue}}
* {{Z|ht}}: {{W-|ht|cheve}}
* {{Z|haw}}: {{W-|haw|lauoho}}
* {{Z|mba}}: {{W-|mba|buhuk}}
* {{Z|hi}}: {{W+|hi|बाल|n}}, {{W+|hi|केश|n|sc=Deva}}, {{W+|hi|जटा|m}}, {{W+|hi|वाल|n}}, {{W+|hi|केस|n}}, {{W+|hi|चूल|n}}
* {{Z|mww}}: {{W-|mww|plaub hau}}
* {{Z|nl}}: {{W+|nl|haar|nt}}
* {{Z|he}}: {{W+|he|שֵׂעָר|m|tr=se'ár|sc=Hebr}}
* {{Z|io}}: {{W+|io|haro}}, {{W+|io|hararo}}
* {{Z|ilo}}: {{W-|ilo|buok}}
* {{Z|ang}}: {{W-|ang|feax|nt}}, {{W-|ang|hǣr|nt}}, {{W-|ang|wiffeax|nt}}
* {{Z|en}}: {{W+|en|hair}}
* {{Z|izh}}: {{W-|izh|[[hius|hiukset]]}}, {{l|izh|tukka}}
* {{Z|inh}}: {{W-|inh|мосаш}}
* {{Z|ia}}: {{W-|ia|capillo}}
* {{Z|iu}}: {{W-|iu|ᓄᔭᑦ}}
* {{Z|ga}}: {{W+|ga|gruaig|m}}, {{W-|ga|folt|n}}
*: {{Z|sga}}: {{W-|sga|folt|n}}
* {{Z|ruo}}: {{W-|ruo|per}}
* {{Z|it}}: {{W+|it|capello|n}}, {{W+|it|capelli|n-p}}
* {{Z|is}}: {{W+|is|hár|nt}}
* {{Z|ja}}: {{W+|ja|髪の毛|tr=かみのけ, kami no ke}}, {{W+|ja|髪|tr=かみ, kami}}, {{W+|ja|頭髪|tr=とうはつ, tōhatsu}}
* {{Z|jv}}: {{W+|jv|rambut}}, {{W-|jv|réma}}
* {{Z|jje}}: {{W-|jje|머리꺼럭}}, {{W-|jje|머리털}}, {{W-|jje|머리터럭}}, {{W-|jje|머리까락}}, {{W-|jje|머리껄}}
* {{Z|kbd}}: {{W-|kbd|щхьэц}}
* {{Z|kl}}: {{W-|kl|nujaq}}
* {{Z|kam}}: {{W-|kam|nzue}}
* {{Z|kn}}: {{W+|kn|ಕೇಶ|sc=Knda}}, {{W+|kn|ಕೂದಲು}}
* {{Z|pam}}: {{W-|pam|buak}}
* {{Z|kea}}: {{W-|kea|kabelu}}
* {{Z|xqa}}: {{W-|xqa|سَجْ|tr=sač}}
* {{Z|csb}}: {{W-|csb|włos|n}}
* {{Z|ca}}: {{W+|ca|cabell|n}}, {{W+|ca|pèl|n}}
* {{Z|qu}}: {{W-|qu|chukcha}}
*: {{Z|qu}}: {{W-|qu|cukca}}
*: {{Z|qu}}: {{W-|qu|agca}}
*: {{Z|qu}}: {{W-|qu|agza}}
* {{Z|ky}}: {{W+|ky|чач|sc=Cyrl}}
* {{Z|ki}}: {{W-|ki|jwere}}
* {{Z|si}}: {{W-|si|කොඳ}}
* {{Z|ko}}: {{W+|ko|머리칼}}, {{W+|ko|머리카락}}, {{W+|ko|머리}}
* {{Z|kw}}: {{W-|kw|blew|m}}, {{W-|kw|gols}}
* {{Z|ltg}}: {{W-|ltg|mots}}
* {{Z|la}}: {{W-|la|coma|m}}, {{W-|la|crīnis|n|m}}
* {{Z|lv}}: {{W+|lv|mats|n}}, {{W+|lv|mati|p}}
* {{Z|lo}}: {{W-|lo|ຜົມ}}
* {{Z|lzz}}: {{W-|lzz|თომა}}
* {{Z|lez}}: {{W-|lez|чӏар}}
* {{Z|ln}}: {{W-|ln|nsúki}}
* {{Z|lt}}: {{W-|lt|plaukai}}, {{W-|lt|plaukas|n}}
* {{Z|khb}}: {{W-|khb|ᦕᦳᧄ}}
* {{Z|luy}}: {{W-|luy|lichune}}
* {{Z|lb}}: {{W+|lb|Hoer|nt}}, {{W+|lb|Hoer|p}}
* {{Z|luo}}: {{W-|luo|yie wich}}
* {{Z|mhn}}: {{W-|mhn|hor|nt}}
* {{Z|mag}}: {{W-|mag|𑂒𑂳𑂪|tr=cul}}, {{W-|mag|𑂍𑂵𑂬|tr=kes}}, {{W-|mag|𑂕𑂷𑂀𑂗|tr=jhõṭ}}
* {{Z|mdh}}: {{W-|mdh|buk}}
* {{Z|mk}}: {{W-|mk|коса|m}}, {{W-|mk|прамен|n}}, {{W-|mk|влакно|nt}}
* {{Z|mg}}: {{W+|mg|volo}}
* {{Z|ms}}: {{W+|ms|rambut}}
* {{Z|mt}}: {{W-|mt|xagħar|n}}
* {{Z|mnc}}: {{W-|mnc|ᡶᡠᠨᡳᠶᡝᡥᡝ}}
* {{Z|mni}}: {{W-|mni|ꯁꯝ|tr=sam}}
* {{Z|gv}}: {{W-|gv|gruag|m}}, {{W-|gv|folt|n}}
* {{Z|mi}}: {{W-|mi|uru}}, {{W-|mi|weu}}, {{W+|mi|makawe}}
* {{Z|mrw}}: {{W-|mrw|bok}}
* {{Z|mr}}: {{W-|mr|केस|nt|sc=Deva}}
* {{Z|hu}}: {{W+|hu|haj}}
* {{Z|xmf}}: {{W-|xmf|თომა}}
* {{Z|egy}}: {{W-egy|šnj|h=Sn:n-y:D3|n}}
* {{Z|lus}}: {{W-|lus|sam}}
* {{Z|mn}}:
*: Kirîlî: {{W+|mn|үс}}
* {{Z|mtq}}: {{W-|mtq|thắc}}
* {{Z|nah}}: {{W+|nah|tzontli}}
* {{Z|naq}}: {{W-|naq|ǀûn}}
* {{Z|nap}}: {{W-|nap|capello|n}}
* {{Z|nv}}: {{W-|nv|atsiighaʼ}}
* {{Z|nds}}: {{W-|nds|Hoor|nt}}
* {{Z|ne}}: {{W+|ne|कपाल}}
* {{Z|hlt}}: {{W-|hlt|sam}}
* {{Z|nrf}}: {{W-|nrf|g'veu|n}}, {{W-|nrf|g'veux|n}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|hår|nt}}
*: {{Z|nn}}: {{W-|nn|hår|nt}}
* {{Z|nus}}: {{W-|nus|nhim}}
* {{Z|oc}}: {{W+|oc|cabel|n}}
* {{Z|or}}: {{W+|or|କେଶ}}
* {{Z|om}}: {{W-|om|rifeensa}}
* {{Z|os}}: {{W-|os|сӕрыхъуын}}
* {{Z|ota}}: {{W-|ota|صاچ|tr=saç}}, {{W-|ota|گیسو|tr=gîsû|sc=ota-Arab}}
* {{Z|ug}}: {{W+|ug|چاچ|sc=ug-Arab}}
* {{Z|uz}}: {{W+|uz|soch}}
* {{Z|pag}}: {{W-|pag|buek}}
* {{Z|pap}}: {{W-|pap|kabei}}
* {{Z|bxd}}: {{W-|bxd|tsʰɛ̃⁵⁵}}
* {{Z|ps}}: {{W-|ps|ویښتان|tr=waṣ̌tan|sc=ps-Arab}}, {{W+|ps|وېښته|n|tr=weӽtǝ́}}
* {{Z|pjt}}: {{W-|pjt|mangka}}
* {{Z|pdt}}: {{W-|pdt|Hoa|m}}
* {{Z|pl}}: {{W+|pl|włosy|n-p}}, {{W+|pl|włos|n}}
* {{Z|pt}}: {{W+|pt|cabelo|n}}
* {{Z|pa}}: {{W-|pa|ਵਾਲ|n}}, {{W-|pa|ਬਾਲ|n}}, {{W-|pa|ਕੇਸ|n}}
* {{Z|pua}}: {{W-|pua|jauiri}}
* {{Z|kk}}: {{W+|kk|шаш|sc=Cyrl}}
* {{Z|cop}}: {{W-|cop|ϥⲱⲓ|n}}, {{W-|cop|ⲧⲣⲓⲭⲟⲥ|n}}
* {{Z|rhg}}: {{W-|rhg|sul}}
* {{Z|rm}}: {{W-|rm|chavel|n}}, {{W-|rm|tgavel|n}}, {{W-|rm|chavè|n}}, {{W-|rm|cavegl|n}}
* {{Z|rom}}: {{W-|rom|bal|n}}
* {{Z|ro}}: {{W+|ro|păr|n}}
* {{Z|ru}}: {{W+|ru|во́лосы|n-p}}, {{W+|ru|во́лос|n}}, {{W+|ru|волоси́нка|m}}
* {{Z|skb}}: {{W-|skb|ผรั่ม}}
* {{Z|ssy}}: {{W-|ssy|dagar}}
* Samî:
*: {{Z|smn}}: {{W-|smn|vuoptâ}}, {{W-|smn|vuoptah|p}}
*: {{Z|sjd}}: {{W-|sjd|вӯппт}}
*: {{Z|se}}: {{W-|se|vuokta}}, {{W-|se|vuovttat|p}}
*: {{Z|se}}: {{W-|se|vuõptt}}, {{W-|sms|vuõpt|p}}
*: {{Z|sma}}: {{W-|sma|voepte}}, {{W-|sms|voepth|p}}
* {{Z|sa}}: {{W+|sa|केश|n}}, {{W+|sa|वाल}}
* {{Z|sat}}: {{W-|sat|ᱩᱵᱽ}}
* {{Z|ceb}}: {{W-|ceb|buhok}}
* {{Z|scn}}: {{W-|scn|capiḍḍi|n}}, {{W-|scn|capiḍḍu|n}} (individual)
* {{Z|sid}}: {{W-|sid|danana}}
* {{Z|csm}}: {{W-|csm|juše-}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|ко̀са|m|sc=Cyrl}}, {{W-|sh|дла̏ка|m|sc=Cyrl}}
*: Latînî: {{W+|sh|kòsa|m}}, {{W+|sh|dlȁka|m}}
* {{Z|sco}}: {{W-|sco|hair}}
* {{Z|cu}}:
*: Kirîlî: {{W-|cu|власъ|n}}
*: Glagolîtîk: {{W-|cu|ⰲⰾⰰⱄⱏ|n}}
* {{Z|orv}}: {{W-|orv|волосъ|n}}
* {{Z|sk}}: {{W-|sk|vlasy|n-p}}, {{W-|sk|vlas|n}}
* {{Z|sl}}: {{W-|sl|las|n}}
* {{Z|so}}: {{W-|so|timo}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|włos|n|m}}
*: {{Z|hsb}}: {{W-|hsb|włós|n}}
* {{Z|st}}: {{W-|st|moriri}}
* {{Z|es}}: {{W+|es|cabello|n}}, {{W+|es|pelo|n}}
* {{Z|su}}: {{W-|su|rambut}}, {{W-|su|bu-uk}}
* {{Z|sux}}: {{W-|sux|𒋠|tr=SÍK|sc=Xsux}}
* {{Z|sva}}: {{W-|sva|ფა̈თვ}}
* {{Z|sw}}: {{W-|sw|unywele|11|12}}
* {{Z|sv}}: {{W+|sv|hår|nt}}
* {{Z|shn}}: {{W-|shn|ၽူမ်}}
* {{Z|tab}}: {{W-|tab|чӏар}}
* {{Z|tg}}: {{W-|tg|мӯ}}
* {{Z|tl}}: {{W+|tl|buhok}}
* {{Z|ta}}: {{W+|ta|முடி|sc=Taml}}
* {{Z|twf}}: {{W-|twf|phóna}}
* {{Z|roa-tar}}: {{W-|roa-tar|capìdde|n}}
* {{Z|tsg}}: {{W-|tsg|buhuk}}
* {{Z|nod}}: {{W-|nod|ᨹᩫ᩠ᨾ}}
* {{Z|th}}: {{W+|th|ผม}}
* {{Z|te}}: {{W+|te|వెంట్రుకలు}}, {{W+|te|జుట్టు}}
* {{Z|tzm}}: {{W-|tzm|ⴰⵣⵣⴰⵔ}}
* {{Z|tt}}: {{W+|tt|чәч|sc=Cyrl}}
* {{Z|tet}}: {{W-|tet|fuuk}}
* {{Z|ti}}: {{W-|ti|ጸጉሪ}}
* {{Z|otk}}: {{W-|otk|𐰽𐰲|ts=sač}}
* {{Z|tr}}: {{W+|tr|saç}}
* {{Z|tk}}: {{W-|tk|saç}}
* {{Z|bo}}: {{W-|bo|སྐྲ}}, {{W-|bo|དབུ་སྐྲ}}
* {{Z|tpi}}: {{W-|tpi|gras bilong het}}
* {{Z|txb}}: {{W-|txb|matsi}}
* {{Z|ts}}: {{W-|ts|misisi}}
* {{Z|tyv}}: {{W-|tyv|дүк}}
* {{Z|udi}}: {{W-|udi|поп}}
* {{Z|ur}}: {{W-|ur|بال|n|tr=bāl|sc=ur-Arab}}, {{W-|ur|کیش|n|tr=keś|sc=ur-Arab}}
* {{Z|uk}}: {{W+|uk|воло́сся|nt|sc=Cyrl}}, {{W+|uk|во́лос|n|sc=Cyrl}}, {{W+|uk|во́лоси|n-p}}
* {{Z|vec}}: {{W+|vec|cavel|n}}
* {{Z|vi}}: {{W+|vi|tóc}}
* {{Z|vo}}: {{W+|vo|her}}, {{W-|vo|hel}}
* {{Z|wa}}: {{W+|wa|tchvea|n}}
* {{Z|cy}}: {{W+|cy|gwallt|n}}, {{W+|cy|blew|n-p}}
* {{Z|win}}: {{W-|win|nąąju}}
* {{Z|km}}: {{W+|km|សក់}}
* {{Z|sah}}: {{W-|sah|ас|sc=Cyrl}}
* {{Z|yag}}: {{W-|yag|ušta}}
* {{Z|yi}}: {{W-|yi|האָר|nt|sc=Hebr}}
* {{Z|yo}}: {{W-|yo|irun}}
* {{Z|esu}}: {{W-|esu|nuyaq}}
* {{Z|el}}: {{W+|el|μαλλί|nt}}, {{W+|el|μαλλιά|nt}}
*: {{Z|grc}}: {{W-|grc|κόμη|m}}, {{W-|grc|τρίχες|m-p}}
* {{Z|zea}}: {{W-|zea|aer|nt}}
* {{Z|za}}: {{W-|za|bwn'gyaeuj}}, {{W-|za|byoem}}
* {{Z|zu}}: {{W+|zu|unwele|c11|c10}}
{{werger-bin}}
sc6581irsijbcv2sravtfgsnq70kq0o
qeyd
0
12578
6347361
6338329
2026-08-31T12:58:40Z
Wikihez
7344
/* Jê */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347361
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/qɛjd/}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[bend]], [[ben]], [[zincîr]], [[girê]], [[girêk]]
#: ''Di zîndanê de wan dest û pê min '''qeyd''' kirin.''
# [[bend]], [[rêç]], [[rêbaz]]
#* {{bêmînak|ku}}
# [[tomar]], [[sicil]], [[newar]], [[nivîsandin]]
#: ''Ew li kîjan zanko hate [[qeyd]] kirin.''
==== Ji wêjeya klasîk ====
* {{J:Melayê Cizîrî:Dîwana Melayê Cizîrî|jêgirtin=Heyf di '''qeyda''' xak û gil bit 'arifê çalakê rûh</br>Heyf di '''qeyda''' xak û gil bit 'arifê çalakê rûh}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Formên alternatîv ====
* [[qeîd]]
* [[qeyid]]
* [[qeyîd]]
==== Jê ====
{{kol3|ku|cure=Jê
|qeyd bûn<q:Lêker>
|qeyd kirin<q:Lêker>
|qeydbûn<q:Navdêr>
|qeydkirin<q:Navdêr>
|qeydbûyî<q:Rengdêr>
|qeydkirî<q:Rengdêr>
|bêqeyd
|bêqeydî
|biqeyd
|biqeydî
|qeydî
}}
==== Têkildar ====
* [[qayd]]
==== Etîmolojî ====
Ji {{ji|ar|ku|قيد|cuda=قَيْدٌ}}.
==== Bide ber ====
* [[qey]]
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Band|f}}, {{W+|de|Aufnahme|f}}, {{W+|de|Aufzeichnung|f}}, {{W+|de|Eintragung|f}}, {{W+|de|Fessel|f}}, {{W+|de|Fußfessel|f}}, {{W-|de|Fußkette|f}}, {{W+|de|Verzeichnis|n}}, {{W-|de|Vormerk}}, {{W+|de|Anmeldung|f|guman=erê}}, {{W+|de|Grundlage|f|guman=erê}}
* {{Z|ar}}: {{W-|ar|تسجيل}}, {{W-|ar|قيد}}, {{W-|ar|اعتقال}}, {{W-|ar|احتجاز}}, {{W-|ar|تقييد}}, {{W+|ar|حبس}}
* {{Z|fa}}: {{W+|fa|بایگانی}}, {{W+|fa|ثبت}}, {{W+|fa|ضبط}}, {{W+|fa|قید|guman=erê}}
* {{Z|fi}}: {{W+|fi|kahleet}}, {{W-|fi|ketjut}}, {{W-|fi|jalkakahleet}}, {{W+|fi|kirjaus}}, {{W+|fi|nauhoite}}, {{W+|fi|tallenne}}, {{W+|fi|äänite}}, {{W+|fi|äänitys}}
* {{Z|en}}: {{W+|en|registration}}, {{W+|en|registry}}, {{W+|en|chains}}, {{W+|en|record}}, {{W+|en|rule}}, {{W+|en|bond|guman=erê}}, {{W+|en|chain|guman=erê}}, {{W+|en|enrolment|guman=erê}}
* {{Z|tr}}: {{W+|tr|asa}}, {{W-|tr|ayak prangası}}, {{W+|tr|katalog}}, {{W+|tr|kayıt}}, {{W+|tr|keşen}}, {{W+|tr|köstek}}, {{W+|tr|kural}}, {{W+|tr|künde}}, {{W+|tr|norm}}, {{W+|tr|pranga}}, {{W+|tr|sicil}}, {{W+|tr|tomar}}, {{W+|tr|zincir|guman=erê}}, {{W+|tr|bukağı|guman=erê}}
{{werger-bin}}
0zdehgyqqzh7u63ui6ks9lul1wp2fit
lîstik
0
12909
6347442
6338342
2026-08-31T19:13:01Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347442
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Paul Cézanne, Les joueurs de carte (1892-95).jpg|thumb|'''Lîstika''' bi karteyan.]]
{{navdêr|ku|z=m}}
# tişta/ê bo [[xweşî|xweşiyê]] tê kirin
#: {{mk|ku|Zarok heta evarê '''lîstikan''' dilîzin.}}
#* {{jêder|ku|2=Eyüp Kıran, ''Dewrêşê Evdî: Kulîlka Bilbizêk û Rim'', Nûbihar, r. 105, 2015, 9789944360951|url=http://books.google.com.tr/books?id=SmfEEAAAQBAJ&pg=PA105&dq=%22l%C3%AEstikan%22+OR+%22l%C3%AEstik%22+OR+%22l%C3%AEstikine%22+OR+%22l%C3%AEstikeke%22+OR+%22l%C3%AEstikino%22+OR+%22l%C3%AEstikin%22+OR+%22l%C3%AEstika%22+OR+%22l%C3%AEstik%C3%AA%22+OR+%22l%C3%AEstikek%22+OR+%22l%C3%AEstikinan%22+OR+%22l%C3%AEstik%C3%AAn%22+OR+%22l%C3%AEstikek%C3%AA%22+OR+%22l%C3%AEstikek%C3%AE%22+OR+%22l%C3%AEstiko%22+OR+%22l%C3%AEstik%C3%AE%22&hl=&cd=16&source=gbs_api|jêgirtin=Navên '''lîstikên''' wan Huyo, Çirê û Çavçirtonek bûn. Ji kîjanê aciz bûbûna '''lîstika''' din dilîstin.}}
# tişta ku pê dileyîzin.
#* {{bêmînak|ku}}
# tişta/ê ne [[jidil]] anku [[cidî]]
#* {{bêmînak|ku}}
==== Ji wêjeya klasîk ====
* {{J:Feqiyê Teyran|jêgirtin=Dinê mehd e û mehlok e</br>Weku lebe û '''leyzok''' e</br>Çi zanin tifl û zarok e}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Notên bikaranînê ====
Lêkera wê bi giştî [[lîstin]] e (bi devokî: leyîstin, lehîstin, leyizîn). Rehê dema niha û ya bê -lîz- e: Ez di-lîz-im, tu di-lîz-î, ew dilîze (devokî dîsa: -leyîz- yan -lehîz-). Wek navdêr bi maneya "game" yan îngilîzî, "لعب" (le'b) ya erebî, "oyun" ya tirkî û "بازی" (bazî) ya farisî herî zêde di zimanê nivîskî de [[lîstik]] (kêmtir: leyistik, lîsk, leyizok) tên bikaranîn. LÎSTOK carinan bi heman maneyê û hin car jî bi maneya [[pêlîstok]] anku amûrên ku mirov (bi taybetî zarok) pê dilîzin hatiye xebitandin (ing. "toy", tirkî "oyuncak", farisî "بازیچه" (bazîçe) û erebî "لعبة" (lu'be).
Herwiha bi taybetî li Başûrê Kurdistanê peyva "yarî" bi maneya "lîstik", "yarîk" bi maneya "pêlîstok" û "yarî kirin" wek sînonîma "lîstin"ê tên bikaranîn. Ew ji peyva "yar" in ku berê ji bilî maneya "dilber, berdilî, destgirtî, evîndar" herwiha maneya "heval" jî dida anku "yarî": tiştên ku heval bi hev re dikin.
Di peyvên hevdanî/hevedudanî de carinan "-bazî" ya ji farisî tê xebitandin lê bi giştî ne bi maneya lîstinê zarokan: cambazî, şûrbazî, rimbazî, sihirbazî...
Di kurdî de herwiha paşgira "-anê" bi maneya "lîstik"ê tê bikaranîn: "bûkokanê" (lîstika bi bûkokan anku bûkên lastîkî), tebelanê (lîstika bi tebelan anku gogên mermerî), "şûranê" (lîstika bi şûran)...
[[lîstik|Lîstik]] û [[lîstin]] dikarin hem bo xwemijûlkirinên zarokan û hem jî spor û werzişê jî werin bikaranîn. Lê baştir e ku ew bo berhemên tiyatroyê û sînemayê neyên xebitandin. Bo van "şano, piyes" bikêrhatîtir in.
==== Formên alternatîv ====
{{kol3|ku
|lehîstik
|lehîztik
|leyistik
|leyiztik
|leyîstik
|leyîztik
|leystik
|leyztik
|lîztik
}}
==== Hevmane ====
* {{g|ku|yarî}}
* {{g|ku|bazî}}
* {{g|ku|geme}}
* {{g|ku|le'b}},
==== Jê ====
{{kol3|ku
|lîstikgeh
|lîstikvan
|lîstikvanî
}}
==== Etîmolojî ====
Ji {{paş|ku|lîstin|cuda1=lîst|-ik}}.
==== Bide ber ====
{{kol3|ku
|lîstok
|pêlîstok
}}
==== Werger ====
{{werger-ser}}
* {{Z|sq}}: {{W+|sq|lojë|m}}
* {{Z|de}}: {{W+|de|Spiel|nt}}
* {{Z|az}}: {{W+|az|oyun}}
* {{Z|ba}}: {{W-|ba|уйын}}
* {{Z|be}}: {{W-|be|гу́льня|m}}, {{W-|be|ігра́|m}}
* {{Z|bn}}: {{W+|bn|খেলা}}
* {{Z|bg}}: {{W+|bg|игра́|m}}, {{W+|bg|забавле́ние|nt}}
* {{Z|cs}}: {{W+|cs|hra|m}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|玩|tr=wán}}, {{W+|cmn|玩兒}}
* {{Z|da}}: {{W+|da|leg|g}}, {{W+|da|spil|nt}}
* {{Z|id}}: {{W+|id|permainan}}
* {{Z|ar}}: {{W+|ar|لَعِب|m}}
* {{Z|hy}}: {{W+|hy|խաղ}}
* {{Z|eo}}: {{W-|eo|ludo}}
* {{Z|et}}: {{W-|et|mäng}}
* {{Z|eve}}: {{W-|eve|эвин}}
* {{Z|evn}}: {{W-|evn|эвин}}
* {{Z|ee}}: {{W-|ee|fefe}}
* {{Z|fi}}: {{W+|fi|leikki}}, {{W+|fi|peli}}
* {{Z|fr}}: {{W+|fr|jeu|n}}
* {{Z|fur}}: {{W-|fur|zogho}}
* {{Z|gd}}: {{W-|gd|cleasachd|m}}
* {{Z|gl}}: {{W+|gl|xogo|n}}
* {{Z|ka}}: {{W-|ka|თამაში}}
* {{Z|hi}}: {{W+|hi|खेल|n}}
* {{Z|nl}}: {{W+|nl|spel|nt}}
* {{Z|he}}: {{W+|he|מִשְׂחָק|n|tr=miskhák}}, {{W-|he|שַׁעֲשׁוּעַ|n|tr=sha'ashúa}}
* {{Z|en}}: {{W+|en|play}}
* {{Z|ga}}: {{W-|ga|imirt|m}}, {{W-|ga|súgradh|n}}
*: {{Z|sga}}: {{W-|sga|spled}}
* {{Z|it}}: {{W+|it|gioco|n}}
* {{Z|is}}: {{W+|is|leikur|n}}, {{W+|is|spil|nt}}
* {{Z|ja}}: {{W+|ja|遊び|tr=あそび, asobi}}
* {{Z|jv}}: {{W+|jv|dolanan}}
* {{Z|ca}}: {{W+|ca|joc|n}}
* {{Z|ky}}: {{W+|ky|ойноо}}
* {{Z|ko}}: {{W+|ko|놀이}}
* {{Z|ltg}}: {{W-|ltg|kaita|m}}
* {{Z|la}}: {{W+|la|lūdus|n}}
* {{Z|lv}}: {{W+|lv|spēle|m}}, {{W-|lv|rotaļa|m}}
* {{Z|lo}}: {{W-|lo|ການຫຼິ້ນ}}
* {{Z|lt}}: {{W-|lt|žaidimas|n}}
* {{Z|lmo}}: {{W-|lmo|giögh}}, {{W-|lmo|giœugh|n}}
* {{Z|mk}}: {{W+|mk|игра|m}}
* {{Z|ml}}: {{W+|ml|കളി}}
* {{Z|hu}}: {{W+|hu|játék}}
* {{Z|mn}}:
*: Kirîlî: {{W+|mn|тоглоом}}
*: Mongolî: {{W-|mn|ᠲᠣᠭᠯᠠᠭᠠᠮ}}
* {{Z|no}}:
*: {{Z|no}}: {{W+|no|spill|nt}}
*: {{Z|nn}}: {{W-|nn|spel|nt}}
* {{Z|oc}}: {{W+|oc|joc|n}}
* {{Z|ota}}: {{W-|ota|اویون|tr=oyun}}
* {{Z|fa}}: {{W-|fa|بازی}}
* {{Z|ug}}: {{W-|ug|ئويۇن}}
* {{Z|uz}}: {{W+|uz|oʻyin}}
* {{Z|pdt}}: {{W-|pdt|Spell|n}}
* {{Z|pl}}: {{W+|pl|zabawa|m}}
* {{Z|pt}}: {{W+|pt|jogo|n}}, {{W+|pt|brincadeira|m}}
* {{Z|kk}}: {{W-|kk|ойын}}
* {{Z|ro}}: {{W+|ro|joc|nt}}
* {{Z|ru}}: {{W+|ru|игра́|m}}
* {{Z|sa}}: {{W+|sa|लीला|m}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|ѝгра|m}}
*: Latînî: {{W+|sh|ìgra|m}}
* {{Z|sk}}: {{W+|sk|hra|m}}
* {{Z|sl}}: {{W+|sl|igra|m}}
* {{Z|so}}: {{W-|so|ciyaar}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|graśe|nt}}
* {{Z|es}}: {{W+|es|juego|n}}
* {{Z|sw}}: {{W+|sw|mchezo}}
* {{Z|sv}}: {{W+|sv|spel|nt}}, {{W+|sv|lek|g}}
* {{Z|tg}}: {{W+|tg|бозӣ}}
* {{Z|tl}}: {{W-|tl|laro}}
* {{Z|th}}: {{W+|th|การเล่น}}
* {{Z|tr}}: {{W+|tr|oyun}}
* {{Z|tk}}: {{W-|tk|oýun}}
* {{Z|bo}}: {{W-|bo|རྩེད་མོ}}
* {{Z|txb}}: {{W-|txb|kāñme}}
* {{Z|ur}}: {{W-|ur|کھیل|n}}
* {{Z|uk}}: {{W+|uk|гра|m}}
* {{Z|vi}}: {{W+|vi|chơi}}, {{W+|vi|trò chơi}}
* {{Z|cy}}: {{W+|cy|gêm|m}}
* {{Z|km}}: {{W+|km|ល្បែង}}, {{W-|km|ការលេង}}
* {{Z|yi}}: {{W-|yi|שפּיל|m|nt}}
* {{Z|el}}:
*: {{Z|grc}}: {{W-|grc|παιγνία|m}}
{{werger-bin}}
:{{werger çavkanî|en|play|beş=Ev qismê Wergerê|oldid=82478688}}
ir1xld3uuhx96c4m4auryrouluqdes0
unîversîte
0
13828
6347367
6324833
2026-08-31T13:11:30Z
Wikihez
7344
+nimûneya bikaranînê bi amûra « [[Mediawiki:Gadget-wikt.add-examples|Nimûne zêde bike]] » (v2.0).
6347367
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[fêrgeh|Fêrgeha]] mirov dikare lê bibe [[dadnas]] û [[nijdar]] û [[mamoste]] û hwd.
#: {{hevmaneyên peyvê|ku|zanko|zanîngeh|camî'e}}
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Behra Reş Dibe Goristan (1942)|url=https://www.kovarabir.com/505/rohat-alakom-behra-res-dibe-goristan-1942/kmr/|tarîx=17.05.2021|jêgirtin=Dema Wagner wek mêvanê rûmetê yê '''Unîversîteya''' Stembolê ji bo konferansekê tê Tirkiyê sekretera '''unîversîteyê''' ya bi navê Maya Duran diçe pêşwaziya wî û mêvanê xwe tîne Pera Palasê cîwar dike.}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Formên alternatîv ====
{{kol3|ku|cure=Herwiha
|unîversite
|unîversitet
|unîversitêt
|unîversîtet
|unîversîtêt
|unîversitî
|unîversîtî
|unîvêrsite
|unîvêrsitet
|unîvêrsitêt
|unîvêrsîte
|unîvêrsîtet
|unîvêrsîtêt
|unîvêrsîtî
}}
==== Jê ====
* {{g|ku|unîversîteyî}}
==== Etîmolojî ====
Ji {{deyn|fr|ku|université}}, ji {{ji|fro|ku|universitei}}, ji {{ji|ML.|ku|universitas}}.
==== Bide ber ====
* {{g|ku|unîvers}}
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W+|af|universiteit}}
* {{Z|sq}}: {{W-|sq|fakulltet|n}}, {{W+|sq|universitet|n}}
* {{Z|de}}: {{W+|de|Universität|m}}, {{W+|de|Hochschule|m}}, {{W+|de|Uni|m}}
* {{Z|am}}: {{W-|am|ዩኒቨርሲቲ}}
* {{Z|an}}: {{W-|an|universidat|m}}
* {{Z|rup}}: {{W-|rup|univirsitati|m}}
* {{Z|as}}: {{W-|as|বিশ্ববিদ্যালয়}}
* {{Z|ast}}: {{W+|ast|universidá|m}}
* {{Z|az}}: {{W-|az|universitet}}, {{W-|az|danişgah}}, {{W-|az|darülfünun}}
* {{Z|eu}}: {{W+|eu|unibertsitate}}
* {{Z|be}}: {{W-|be|універсітэ́т|n}}, {{W-|be|унівэрсытэ́т|n}}
* {{Z|bn}}: {{W+|bn|বিশ্ববিদ্যালয়}}, {{W+|bn|জামেয়া}}
* {{Z|br}}: {{W+|br|skol-veur|m}}
* {{Z|bg}}: {{W-|bg|университе́т|n}}
* {{Z|my}}: {{W+|my|တက္ကသိုလ်}}
* {{Z|ch}}: {{W-|ch|unibetsedåt}}
* {{Z|ce}}: {{W-|ce|университет}}, {{W-|ce|говзарт}}
* {{Z|cs}}: {{W+|cs|univerzita|m}}, {{W+|cs|vysoká škola|m}}, {{W-|cs|vysoké učení|nt}}
* {{Z|zh}}:
*: {{Z|yue}}: {{W-|yue|大學}}
*: {{Z|dng}}: {{W-|dng|дащүә}}
*: {{Z|hak}}: {{W-|hak|大學|tr=thai-ho̍k}}
*: {{Z|cmn}}: {{W+|cmn|大學}}
*: {{Z|nan}}: {{W+|nan|大學|tr=tāi-ha̍k}}
* {{Z|da}}: {{W+|da|universitet|nt}}
* {{Z|id}}: {{W+|id|universitas}}, {{W+|id|universitet}}
* {{Z|ar}}: {{W+|ar|جَامِعَة|m}}
*: {{Z|arz}}: {{W-|arz|جامعة|m|tr=gamʕa}}
*: {{Z|afb}}: {{W-|afb|جامعة|tr=jamʕə}}
* {{Z|hy}}: {{W+|hy|համալսարան}}
* {{Z|eo}}: {{W+|eo|universitato}}
* {{Z|et}}: {{W+|et|ülikool}}
* {{Z|fa}}: {{W+|fa|دانِشگاه|tr=dânešgâh}}, {{W-|fa|پوهنتون|tr=pôhantûn}}
* {{Z|fo}}: {{W-|fo|fróðskaparsetur|nt}}, {{W-|fo|universitet|nt}}
* {{Z|fi}}: {{W+|fi|yliopisto}}
* {{Z|fr}}: {{W+|fr|université|m}}, {{W+|fr|fac|m}}, {{W+|fr|univ|m}}
* {{Z|fy}}: {{W-|fy|universiteit|g}}
* {{Z|ff}}:
*: Adlamî: {{W-|ff|𞤶𞤢𞥄𞤩𞤭 𞤸𞤢𞥄𞤪𞤼𞤭𞤣𞤫}},
*: Latînî: {{W-|ff|jaaɓi haartide}}
* {{Z|gd}}: {{W-|gd|oilthigh|n}}
* {{Z|gl}}: {{W+|gl|universidade|m}}
* {{Z|glk}}: {{W-|glk|دانشگا|tr=dânišgâ}}
* {{Z|gu}}: {{W-|gu|યુનિવર્સિટી}}
* {{Z|ka}}: {{W+|ka|უნივერსიტეტი}}
* {{Z|gn}}: {{W-|gn|mbo'ehao guasu}}
* {{Z|ht}}: {{W-|ht|inivèsite}}
* {{Z|ha}}: {{W-|ha|jami'a}}
* {{Z|hi}}: {{W+|hi|विश्वविद्यालय|n}}, {{W+|hi|यूनिवर्सिटी|m}}, {{W+|hi|महाविद्यालय|n}}, {{W-|hi|विद्यापीठ|n}}, {{W+|hi|वीद्यापीठ|n}}, {{W-|hi|जामिया|n}}, {{W+|hi|कालिज|n}}, {{W-|hi|विश्वविद्यानिलय|n}}
* {{Z|nl}}: {{W+|nl|universiteit|m}}, {{W+|nl|universitair}}, {{W+|nl|unief|m}}
* {{Z|he}}: {{W+|he|אוּנִיבֶרְסִיטָה|m|tr=univérsita}}
* {{Z|io}}: {{W+|io|universitato}}
* {{Z|en}}: {{W+|en|university}}
* {{Z|izh}}: {{W-|izh|universitetta}}, {{W-|izh|ylioppi}}
* {{Z|ia}}: {{W-|ia|universitate}}
* {{Z|ga}}: {{W+|ga|ollscoil}}
* {{Z|it}}: {{W+|it|università|m}}, {{W+|it|accademia|m}}, {{W+|it|istituto|n}}, {{W+|it|politecnico|n}}, {{W+|it|collegio|n}}, {{W+|it|ateneo|n}}
* {{Z|is}}: {{W+|is|háskóli|n}}
* {{Z|ja}}: {{W+|ja|大学|tr=だいがく daigaku}}, {{W+|ja|大学校}}
* {{Z|kl}}: {{W-|kl|ilisimatusarfik}}, {{W-|kl|universiteti}}
* {{Z|xal}}: {{W-|xal|ик сурһуль}}
* {{Z|kn}}: {{W+|kn|ವಿಶ್ವವಿದ್ಯಾನಿಲಯ}}, {{W+|kn|ಕಲಿವೀಡು}}
* {{Z|ca}}: {{W+|ca|universitat|m}}
* {{Z|qu}}: {{W-|qu|jatun yachay wasi}}
* {{Z|ky}}: {{W+|ky|университет}}
* {{Z|si}}: {{W-|si|විශ්ව විද්යාලය}}, {{W+|si|විශ්වවිද්යාල}}
* {{Z|rw}}: {{W-|rw|kaminuza|c9|c10}}
* {{Z|ko}}: {{W+|ko|대학}}, {{W+|ko|대학교}}
* {{Z|kw}}: {{W-|kw|pennskol|m}}, {{W-|kw|universita|n}}
* {{Z|co}}: {{W+|co|università|m}}
* {{Z|lad}}: {{W-|lad|universita}}
* {{Z|la}}: {{W-|la|universitas|m}}, {{W-|la|studium generale|nt}}
* {{Z|lv}}: {{W-|lv|universitāte|m}}, {{W-|lv|augstskola|m}}
* {{Z|lo}}: {{W+|lo|ມະຫາວິທະຍາໄລ}}
* {{Z|lt}}: {{W+|lt|universitetas|n}}
* {{Z|lb}}: {{W+|lb|Universitéit|m}}
* {{Z|mk}}: {{W-|mk|универзите́т|n}}
* {{Z|ml}}: {{W+|ml|സർവ്വകലാശാല}}, {{W-|ml|യൂനിവേഴ്സിറ്റി}}, {{W-|ml|യൂണിവേഴ്സിറ്റി}}
* {{Z|ms}}: {{W+|ms|universiti}}, {{W-|ms|menara gading}}, {{W-|ms|madrasah jamiah}}
* {{Z|mt}}: {{W+|mt|università|m}}
* {{Z|mnc}}: {{W-|mnc|ᠠᠮᠪᠠ ᡨᠠᠴᡳᡴᡡ}}
* {{Z|mr}}: {{W-|mr|विद्यापीठ}}, {{W-|mr|युनिव्हर्सिटी|m}}
* {{Z|hu}}: {{W+|hu|egyetem}}, {{W+|hu|tudományegyetem}}
* {{Z|mn}}:
*: Kirîlî: {{W-|mn|их сургууль}}
* {{Z|nrf}}: {{W-|nrf|euniversitaé|m}}, {{W-|nrf|unnivèrsité|m}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|universitet|nt}}
*: {{Z|nn}}: {{W-|nn|universitet|nt}}
* {{Z|oc}}: {{W+|oc|universitat|m}}
* {{Z|ug}}: {{W-|ug|ئۇنىۋېرسىتېت}}, {{W-|ug|داشۆ}}, {{W-|ug|ئالىي مەكتەپ}}
* {{Z|uz}}: {{W+|uz|universitet}}
* {{Z|ps}}: {{W+|ps|پوهنتون|n|tr=pohantun}}
* {{Z|pl}}: {{W+|pl|uniwersytet|n}}, {{W+|pl|wszechnica|m}}, {{W+|pl|uczelnia|m}}
* {{Z|pt}}: {{W+|pt|universidade|m}}
* Puncabî:
*: Şaxmuxî: {{W+|pa|یونیورسٹی}}
*: Gurmuxî: {{W+|pa|ਯੂਨੀਵਰਸਿਟੀ}}
* {{Z|kk}}: {{W+|kk|университет}}
* {{Z|ro}}: {{W+|ro|universitate|m}}
* {{Z|ru}}: {{W+|ru|университе́т|n}}
* {{Z|se}}: {{W-|se|universitehtta}}
* {{Z|scn}}: {{W+|scn|univirsitati|m}}, {{W+|scn|univirsità|m}}
* {{Z|sd}}: {{W-|sd|ڪاليج}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|универзѝте̄т|n}}, {{W-|sh|свеу̀чилӣште|nt}}
*: Latînî: {{W+|sh|univerzìtēt|n}}, {{W+|sh|sveùčilīšte|nt}}
* {{Z|sco}}: {{W-|sco|varsitie}}
* {{Z|sk}}: {{W+|sk|univerzita|m}}
* {{Z|sl}}: {{W+|sl|univerza|m}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|uniwersita|m}}
*: {{Z|hsb}}: {{W-|hsb|uniwersita|m}}
* {{Z|es}}: {{W+|es|universidad|m}}
* {{Z|swg}}: {{W-|swg|Universidäd}}
* {{Z|sw}}: {{W+|sw|chuo kikuu}}
* {{Z|sv}}: {{W+|sv|universitet|nt}}, {{W+|sv|högskola}}
* {{Z|shn}}: {{W-|shn|ႁူင်းႁဵၼ်းၸၼ်ႉၸွမ်}}, {{W-|shn|ၸၼ်ႉၸွမ်}}, {{W-|shn|တၵ်ႈၵသူဝ်ႇ}}, {{W-|shn|တၵ်ႉၵသူဝ်ႇ}}
* {{Z|tg}}: {{W+|tg|донишгоҳ}}
* {{Z|tl}}: {{W+|tl|pamantasan}}, {{W+|tl|unibersidad}}
* {{Z|ta}}: {{W+|ta|பல்கலைக்கழகம்}}
* {{Z|th}}: {{W+|th|มหาวิทยาลัย}}
* {{Z|te}}: {{W+|te|విశ్వవిద్యాలయము}}
* {{Z|tt}}: {{W-|tt|университет}}
* {{Z|tr}}: {{W+|tr|üniversite}}, {{W+|tr|darülfünun}}
* {{Z|tk}}: {{W-|tk|uniwersitet}}
* {{Z|bo}}: {{W-|bo|སློབ་གྲྭ་ཆེན་མོ}}
* {{Z|tpi}}: {{W-|tpi|yunivesiti}}
* {{Z|ur}}: {{W-|ur|جامِعَہ|n|tr=jāmi'a}}, {{W-|ur|دانِش گاہ|m|tr=dāniś gāh}}
* {{Z|uk}}: {{W+|uk|університе́т|n}}
* {{Z|vi}}: {{W+|vi|trường đại học}}, {{W+|vi|đại học}}
* {{Z|vo}}: {{W+|vo|niver}}
* {{Z|wa}}: {{W+|wa|univiersité|m}}
* {{Z|wrz}}: {{W-|wrz|yunibersidad}}, {{W-|wrz|unibersidad}}
* {{Z|cy}}: {{W+|cy|prifysgol|m}}
* {{Z|km}}: {{W+|km|សាកលវិទ្យាល័យ}}, {{W+|km|មហាវិទ្យាល័យ}}
* {{Z|yi}}: {{W-|yi|אוניווערסיטעט|m}}
* {{Z|yo}}: {{W-|yo|yunifásítì}}, {{W-|yo|ifásítì}}, {{W-|yo|fásítì}}
* {{Z|el}}: {{W+|el|πανεπιστήμιο|nt}}
* {{Z|za}}: {{W-|za|dayoz}}
{{werger-bin}}
:{{werger çavkanî|en|university|beş=Ev qismê Wergerê|oldid=75959120}}
79oc9c3blecvpjf566c66k2s4h3uzed
ereq
0
14804
6347641
6336344
2026-09-01T11:56:27Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347641
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr 1 ===
{{navdêr|ku|z=m}}
# [[vexwarin|Vexwarina]] mirov pê [[serxweş]] dibe.
#: {{hevmane|ku|mey|bade|elkol}}
#* {{bêmînak|ku}}
==== Formên alternatîv ====
{{kol3|ku|cure=Herwiha
|araq
|areq
|'araq
|'areq
|eraq
|'eraq
|'ereq
}}
==== Jê ====
{{kol3|ku|cure=Jê
|ereqgêrr
|ereqgêrrî
|ereqfiroş
|ereqfiroşgeh
|ereqfiroşxane
|ereqfiroşî
|ereqvexwer
|ereqvexwerî
|ereqxane
|ereqxwer
|ereqxwerî
}}
==== Etîmolojî ====
Ji {{ji|ar|ku|عرق}} ('ereq) bi forma xwe ya rengdêr {{g|ckb|عرقي|tr='ereqî|w=[[ereqî]], ji [[ereq]]ê, biereq}} bi rêya {{hv|tr|rakı}} herwiha serekaniya peyva {{cotreh|ku|raqî|nivîs=na}} ye jî.
==== Bide ber ====
{{kol3|ku
|ereb
|Iraq
}}
==== Werger ====
{{werger-ser}}
* {{Z|fi}}: {{W+|fi|alkoholijuoma}}, {{W+|fi|viina}}
* {{Z|en}}: {{W-|en|alcoholic drink}}, {{W-|en|alcoholic beverage}}
{{werger-bin}}
=== Navdêr 2 ===
{{navdêr|ku|z=?}}
# [[xuh]], [[xwêdan]]
#* {{bêmînak|ku}}
==== Ji wêjeya klasîk ====
* {{J:Mem û Zîn:1692|jêgirtin=Durdaneyê xwe birêje navê</br>Ye'nî ''''ereqa''' wekî gulavê</br>Dem dem bide destê meyperestan}}
==== Formên alternatîv ====
{{kol3|ku|cure=Herwiha
|araq
|areq
|'araq
|'areq
|'ereq
}}
==== Werger ====
{{werger-ser}}
* {{Z|fi}}: {{W+|fi|hiki}}
* {{Z|en}}: {{W+|en|perspiration}}, {{W+|en|sweat}}
{{werger-bin}}
== {{ziman|zza}} ==
=== Navdêr ===
{{navdêr|zza}}
# [[xwêdan]]
#* {{bêmînak|zza}}
==== Notên bikaranînê ====
:Ev navdêr tenê yekjimar e, wek pirjimar nayê bikaranîn.
aj0747rospfn6tqzyabmj3d557t9hzn
kevir
0
15033
6347439
6310013
2026-08-31T19:11:31Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347439
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/kˤɛˈvɪɾ/}}
* {{kîte|ku|ke|vir}}
=== Navdêr ===
[[Wêne:RockWithLichen.jpg|thumb|Kevirek]]
{{wp}}
{{navdêr|ku|z=n}}, {{k-ya nerm}}, {{r-ya nerm}}
# [[ber|Ber]], [[kuç]], [[teht]], [[tat]], [[helan]], [[ferş]], [[berd]], [[late]].
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|nêr}}
==== Notên bikaranînê ====
{{agadarî}} Di hin devokan de "kevir" maneya hemû beran/sengan/kuçan didin lê di hinan de "kevir" tenê wateya "berên gir" (wek teht, helan, ferş) dide û yên hûrik "[[ber]]" in ku hevreha [[berd]] ya soranî ye.
==== Bi alfabeyên din ====
* {{ku-ar|کهڤر}}
==== Formên alternatîv ====
* {{hw|ku|kevr}}
==== Jê ====
{{kol3|ku
|kevirî
|kevirîn
}}
==== Têkildar ====
{{kol3|ku
|şijik
|hestem
|kevizgal
}}
==== Etîmolojî ====
Hevreha zazakî ''[[kemer]]'' (di kurmancî de "m" ya îranî bi pirranî dibe "v"), vafsî ''[[kavar]]'', abyanayî, cowşaqanî, tarî û komcanî ''[[kamar]]'', qohrudî '' [[kemerša]]'' ji {{ji|ira}}. Ihtimal heye ku ji {{ji|ine-pro|ku|-}} {{recons|ine-pro|h₂éḱmō}} (kevir) û wisa hevreha {{hv|ru|камень}} (kamêni: kevir, ber), {{hv|grc|ακμή}} ([[gupik]], [[ser]]ê [[teht]]an yan [[gir]](ik)an û [[ἄκμων]] ([[sindan]]), îngilîzî [[hammer]] ([[çakûç]]), kurdî [[esman]]... K-ya {{ji|ine-pro|ku|-}} di zimanên îranî de bi gelemperî dibe "s" lê ne diyar e ka çima di peyva "kevir" de wek xwe maye. Lê ne tenê di kurdî de lê herwiha di zimanên baltî de jî du peyvên ji hev cuda bi maneyên ji hev ferq ji eynî rehî peyda bûne ku yek jê maneya "kevir" dide, yan din jî ya "devê amûrên [[birrok]]": latviyayî [[akmens]] (kevir) û [[asmens]] (devê amûrên birrok) û {{hv|lt|akmuo}} (kevir) û [[ašmenys]] (devê amûrên birrok). Herwiha bidin ber {{hv|arc|כיפא}} (kêpa: kevir, ber)
==== Bide ber ====
{{kol3|ku
|kevl
|kevn
|kepir
|xilik
}}
==== Bi zaravayên din ====
* {{Z|zza}}: {{W-|zza|kemere|m}}, {{W-|zza|kerra|m}}, {{W-|zza|sî|m}}, {{W-|zza|kuçe|m}}, {{W-|zza|bere|m}}, {{W-|zza|xirxe|m}}
==== Werger ====
{{werger-ser}}
* {{Z|ab}}: {{W-|ab|ахацə}}
* {{Z|aa}}: {{W-|aa|xaa}}
* {{Z|xag}}: {{W-|xag|𐔻𐔴}}
* {{Z|agr}}: {{W-|agr|kaya}}
* {{Z|akk}}: {{W-|akk|𒉌𒌓}}
* {{Z|ak}}: {{W-|ak|ɛboɔ}}, {{W-|ak|ɔboɔ}}, {{W-|ak|ɔbo}}, {{W-|ak|bo}}
* {{Z|akl}}: {{W-|akl|bato}}
* {{Z|sq}}: {{W+|sq|gur|n}}
* {{Z|de}}: {{W+|de|Stein|n}}
*: {{Z|gsw}}: {{W-|gsw|Stain}}
* {{Z|amm}}: {{W-|amm|tomoki}}
* {{Z|ami}}: {{W-|ami|fokeloh}}
* {{Z|apn}}: {{W-|apn|kẽn}}
* {{Z|rup}}: {{W-|rup|cheatrã}}, {{W-|rup|chiatrã}}
* {{Z|as}}: {{W-|as|পাথৰ}}, {{W-|as|শিল}}
* {{Z|ast}}: {{W+|ast|piedra|m}}
* {{Z|tay}}: {{W-|tay|btunux}}
* {{Z|djk}}: {{W-|djk|siton}}
* {{Z|av}}: {{W-|av|гамачӏ}}, {{W-|av|кьуру}}
* {{Z|ae}}: {{W-|ae|𐬀𐬯𐬀𐬥}}, {{W-|ae|𐬀𐬯𐬆𐬥𐬔𐬀}}
* {{Z|ain}}: {{W-|ain|スマ|tr=suma}}
* {{Z|az}}: {{W+|az|daş}}
* {{Z|pkc}}: {{W-|pkc|珍惡|tr=durak}}
* {{Z|eu}}: {{W-|eu|harri}}
* {{Z|ba}}: {{W-|ba|таш}}
* {{Z|be}}: {{W-|be|ка́мень|n}}
* {{Z|bal}}: {{W-|bal|سنگ|tr=sang, sing}}
* {{Z|bn}}: {{W+|bn|পাথর}}
* {{Z|bqi}}: {{W-|bqi|برد|tr=bard}}
* {{Z|kap}}: {{W-|kap|кьало}}, {{W-|kap|шед}}
* {{Z|bho}}: {{W-|bho|𑂣𑂞𑂹𑂟𑂪}}, {{W-|bho|𑂣𑂰𑂟𑂩}}
* {{Z|brh}}: {{W-|brh|خَل}}
* {{Z|br}}: {{W+|br|maen|n}}, {{W+|br|mein|p}}
* {{Z|kxd}}: {{W-|kxd|batu}}
* {{Z|bg}}: {{W-|bg|ка́мък|n}}
* {{Z|bnn}}: {{W-|bnn|batu}}
* {{Z|my}}: {{W+|my|ကျောက်}}
* {{Z|bua}}: {{W-|bua|шулуун}}
* {{Z|dz}}: {{W-|dz|རྡོ}}
* {{Z|can}}: {{W-|can|kẽn}}
* {{Z|ccc}}: {{W-|ccc|chena}}
* {{Z|ce}}: {{W-|ce|тӏулг}}, {{W-|ce|тарх}}
* {{Z|cs}}: {{W+|cs|kámen|n}}
* {{Z|chr}}: {{W+|chr|ᏅᏳ}}
* {{Z|ny}}: {{W-|ny|mwala}}
* {{Z|cic}}: {{W-|cic|tali'}}
* {{Z|zh}}:
*: {{Z|dng}}: {{W-|dng|шыту}}
*: {{Z|cmn}}: {{W+|cmn|石|tr=shí}}, {{W+|cmn|石頭|tr=shítou}}
* {{Z|cv}}: {{W-|cv|чул}}
* {{Z|dag}}: {{W-|dag|kuɣli}}
* {{Z|dlm}}: {{W-|dlm|pitra|m}}
* {{Z|da}}: {{W+|da|sten|g}}
* {{Z|dar}}: {{W-|dar|къаркъа}}
* {{Z|dlg}}: {{W-|dlg|таас}}
* {{Z|duu}}: {{W-|duu|lung}}
* {{Z|duo}}: {{W-|duo|pugedu}}
* {{Z|id}}: {{W+|id|batu}}
* {{Z|ar}}: {{W-|ar|حَجَر|n}}
*: {{Z|arz}}: {{W-|arz|حجر|n|tr=ḥagar}}
* {{Z|hy}}: {{W+|hy|քար}}
* {{Z|eo}}: {{W+|eo|ŝtono}}
* {{Z|et}}: {{W+|et|kivi}}
* {{Z|gez}}: {{W-|gez|እብን}}
* {{Z|eve}}: {{W-|eve|дёл}}
* {{Z|evn}}: {{W-|evn|дёло}}
* {{Z|ext}}: {{W-|ext|paira|m}}
* {{Z|peo}}: {{W-|peo|tr=aθaⁿga-}}, {{W-|peo|tr=asan-}}
* {{Z|pal}}: {{W-|pal|sng|tr=sang}}
* {{Z|fa}}: {{W+|fa|سنگ|tr=sang}}, {{W+|fa|برد|tr=bard}}
* {{Z|phn}}: {{W-|phn|𐤀𐤁𐤍}}
* {{Z|fo}}: {{W+|fo|steinur|n}}
* {{Z|hif}}: {{W-|hif|patthar}}
* {{Z|fi}}: {{W+|fi|kivi}}
* {{Z|gmw-rfr}}: {{W-|gmw-rfr|Schdää}}
* {{Z|fr}}: {{W+|fr|pierre|m}}, {{W+|fr|roche|m}}
* {{Z|fur}}: {{W-|fur|piere|m}}
* {{Z|frr}}: {{W-|frr|stian|n}}
* {{Z|fy}}: {{W+|fy|stien|n}}
* {{Z|gd}}: {{W-|gd|clach|m}}
* {{Z|car}}: {{W-|car|tupo}}
* {{Z|gl}}: {{W+|gl|pedra|m}}
* {{Z|gor}}: {{W-|gor|botu}}
* {{Z|got}}: {{W-|got|𐍃𐍄𐌰𐌹𐌽𐍃|n}}
* {{Z|ka}}: {{W-|ka|ქვა}}
* {{Z|gn}}: {{W-|gn|ita}}
* {{Z|bgc}}: {{W-|bgc|भाठा}}
* {{Z|haw}}: {{W-|haw|pōhaku}}
* {{Z|mba}}: {{W-|mba|bato}}
* {{Z|hi}}: {{W+|hi|पत्थर|n}}, {{W+|hi|शिला}}, {{W+|hi|रोड़ा}}, {{W+|hi|हजर|n}}, {{W+|hi|संग|n}}, {{W+|hi|शिल|m}}, {{W+|hi|सिल|m}}
* {{Z|gin}}: {{W-|gin|гамачӏ}}, {{W-|gin|лъад}}
* {{Z|ho}}: {{W-|ho|nadi}}
* {{Z|hil}}: {{W-|hil|bato}}
* {{Z|meu}}: {{W-|meu|nadi}}
* {{Z|nl}}: {{W+|nl|steen|n}}
* {{Z|hrx}}: {{W-|hrx|Steen|n}}, {{W-|hrx|xtayn}}
* {{Z|huz}}: {{W-|huz|гамачІ|tr=gamačʼ}}, {{W-|huz|кьа̇лу|tr=ƛ̄ʼɑlu}}
* {{Z|esh}}: {{W-|esh|سینگ|tr=sing}}
* {{Z|he}}: {{W-|he|אֶבֶן|m|tr=éven}}
* {{Z|io}}: {{W+|io|petro}}
* {{Z|ijs}}: {{W-|ijs|ikputu}}
* {{Z|ilo}}: {{W-|ilo|bato}}
* {{Z|ang}}: {{W-|ang|stān|n}}
* {{Z|enm}}: {{W-|enm|ston}}
* {{Z|en}}: {{W+|en|stone}}, {{W+|en|rock}}
* {{Z|ia}}: {{W-|ia|petra}}
* {{Z|ill}}: {{W-|ill|watu}}
* {{Z|ga}}: {{W+|ga|cloch|m}}
* {{Z|ist}}: {{W-|ist|pera|m}}
* {{Z|it}}: {{W+|it|pietra|m}}, {{W+|it|roccia|m}}
* {{Z|is}}: {{W+|is|steinn|n}}
* {{Z|ojp}}: {{W-|ojp|石|tr=isi}}
* {{Z|ja}}: {{W+|ja|石|tr=ishi}}
* {{Z|kaw}}: {{W-|kaw|watu}}
* {{Z|jv}}: {{W+|jv|watu}}, {{W-|jv|séla}}
* {{Z|juc}}: {{W-|juc|wehe}}
* {{Z|kl}}: {{W-|kl|ujarak}}
* {{Z|xal}}: {{W-|xal|чолун}}
* {{Z|xnb}}: {{W-|xnb|vatu}}
* {{Z|pam}}: {{W-|pam|batú}}
* {{Z|cak}}: {{W-|cak|ab’äj}}
* {{Z|csb}}: {{W-|csb|kam}}
* {{Z|ca}}: {{W+|ca|pedra|m}}, {{W+|ca|roca|m}}
* {{Z|chc}}: {{W-|chc|iti}}, {{W-|chc|inti}}
* {{Z|ktw}}: {{W-|ktw|se}}
* {{Z|ckv}}: {{W-|ckv|bettu}}
* {{Z|txu}}: {{W-|txu|kẽn}}
* {{Z|kgp}}: {{W-|kgp|pó}}
* {{Z|qu}}: {{W-|qu|rumi}}
* {{Z|kjj}}: {{W-|kjj|мыда}}, {{W-|kjj|къайа}}, {{W-|kjj|кІачІын}}
* {{Z|si}}: {{W-|si|ගල්}}
* {{Z|koi}}: {{W-|koi|из}}
* {{Z|ko}}: {{W+|ko|돌}}
* {{Z|co}}: {{W+|co|petra|m}}
* {{Z|xra}}: {{W-|xra|kẽn}}
* {{Z|crs}}: {{W-|crs|pyer}}
* {{Z|lbj}}: {{W-|lbj|རྡོ་བ}}
* {{Z|lbe}}: {{W-|lbe|чару}}, {{W-|lbe|ххяли}}
* {{Z|ltg}}: {{W-|ltg|akmiņs}}
* {{Z|la}}: {{W+|la|lapis|n}}, {{W-|la|petra|m}}
* {{Z|lv}}: {{W+|lv|akmens|n}}
* {{Z|lo}}: {{W+|lo|ຫີນ}}
* {{Z|lez}}: {{W-|lez|къван}}
* {{Z|li}}: {{W+|li|stein}}
* {{Z|lt}}: {{W+|lt|akmuo|n}}
* {{Z|liv}}: {{W-|liv|kiv}}
* {{Z|luy}}: {{W-|luy|libale}}
* {{Z|lb}}: {{W+|lb|Steen|n}}
* {{Z|mag}}: {{W-|mag|𑂣𑂞𑂹𑂟𑂪|tr=patthal}}
* {{Z|mai}}: {{W-|mai|पाथर}}, {{W-|mai|पाहन}}
* {{Z|mk}}: {{W-|mk|камен|n}}
* {{Z|mqs}}: {{W-|mqs|mai}}
* {{Z|mg}}: {{W+|mg|vato}}
* {{Z|ml}}: {{W+|ml|കല്ല്}}
* {{Z|ms}}: {{W+|ms|batu}}
* {{Z|mnc}}: {{W-|mnc|ᠸᡝᡥᡝ}}
* {{Z|gv}}: {{W-|gv|clagh}}
* {{Z|mns-nor}}: {{W-|mns-nor|а̄хвтас}}
* {{Z|mi}}: {{W-|mi|whatu}}
* {{Z|mrw}}: {{W-|mrw|wato}}, {{W-|mrw|bato}}
* {{Z|mr}}: {{W-|mr|दगड|n}}
* {{Z|yua}}: {{W-|yua|tuunich}}, {{W-|yua|tuunichoob|p}}
* {{Z|hu}}: {{W+|hu|kő}}
* {{Z|egy}}: {{W-egy|jnr|h=i-n:r:O39}}
* {{Z|mvi}}: {{W-|mvi|石|tr=isu}}
* {{Z|min}}: {{W-|min|batu}}
* {{Z|moh}}: {{W-|moh|onén:ia}}
* {{Z|mov}}: {{W-|mov|'avii}}
* {{Z|mn}}: {{W+|mn|чулуу}}
* {{Z|xmz}}: {{W-|xmz|watu}}
* {{Z|wmw}}: {{W-|wmw|mwala}}, {{W-|wmw|riwe}}
* {{Z|nah}}: {{W+|nah|tetl}}
* {{Z|gld}}: {{W-|gld|дёло}}
* {{Z|nv}}: {{W-|nv|tsé}}
* {{Z|nds}}:
*: {{Z|nds-nl}}: {{W-|nds-nl|steen|n}}
*: {{Z|nds-de}}: {{W-|nds-de|Steen|n}}
* {{Z|neg}}: {{W-|neg|ӡolo}}
* {{Z|nkg}}: {{W-|nkg|si}}
* {{Z|ne}}: {{W-|ne|ढुङ्गा}}
* {{Z|nrf}}: {{W-|nrf|pièrre|m}}
* {{Z|non}}: {{W-|non|steinn|n}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|stein|n}}, {{W+|nb|sten|n}}
*: {{Z|nn}}: {{W+|nn|stein|n}}
* {{Z|oj}}: {{W-|oj|asin}}
* {{Z|ryu}}: {{W-|ryu|石|tr=ishi}}
* {{Z|oc}}: {{W+|oc|pèira|m}}, {{W+|oc|ròca|m}}
* {{Z|or}}: {{W+|or|ପଥର}}
* {{Z|oac}}: {{W-|oac|дёло}}
* {{Z|oaa}}: {{W-|oaa|ӡоло}}
* {{Z|om}}: {{W-|om|dhagaa}}
* {{Z|orh}}: {{W-|orh|dʒɔlɔ}}
* {{Z|os}}: {{W-|os|дур}}
* {{Z|ota}}: {{W-|ota|طاش|tr=taş}}, {{W-|ota|جندل|tr=cendel}}
* {{Z|ug}}: {{W+|ug|تاش}}
* {{Z|uz}}: {{W+|uz|tosh}}
* {{Z|pwn}}: {{W-|pwn|qaciljai}}
* {{Z|pau}}: {{W-|pau|bad}}
* {{Z|kre}}: {{W-|kre|kjẽn}}
* {{Z|gvp}}: {{W-|gvp|kẽn}}
* {{Z|xpr}}: {{W-|xpr|𐫀𐫘𐫗𐫃}}
* {{Z|pms}}: {{W-|pms|pera|m}}
* {{Z|myp}}: {{W-|myp|xaxái}}
* {{Z|pjt}}: {{W-|pjt|apu}}, {{W-|pjt|puḻi}}
* {{Z|pl}}: {{W+|pl|kamień|n}}
* {{Z|pt}}: {{W+|pt|pedra|m}}, {{W+|pt|rocha|m}}
* {{Z|pua}}: {{W-|pua|tsakapu}}
* {{Z|pyu}}: {{W-|pyu|barasa}}
* {{Z|sai-pyk}}: {{W-|sai-pyk|quẽn}}
* {{Z|kk}}: {{W+|kk|тас}}
* {{Z|rah}}: {{W-|rah|ৰংকা}}
* {{Z|lml}}: {{W-|lml|vatu}}
* {{Z|rhg}}: {{W-|rhg|fattór}}
* {{Z|rm}}: {{W-|rm|crap|n}}
* {{Z|ro}}: {{W+|ro|piatră|m}}
* {{Z|dru}}: {{W-|dru|lrenege}}
* {{Z|ru}}: {{W-|ru|ка́мень|n}}
* {{Z|sxr}}: {{W-|sxr|vatu'u}}
* {{Z|ssy}}: {{W-|ssy|dhaa}}
* {{Z|xsy}}: {{W-|xsy|bato'}}
* {{Z|szy}}: {{W-|szy|ba'tu}}
* {{Z|se}}: {{W-|se|geađgi}}
* {{Z|sa}}: {{W+|sa|शिला|m}}, {{W+|sa|पाषी|m}}
* {{Z|sat}}: {{W-|sat|ᱫᱷᱤᱨᱤ}}
* {{Z|sc}}: {{W-|sc|pedra}}
*: {{Z|sc}}: {{W-|sc|preda|m}}
* {{Z|ceb}}: {{W-|ceb|bato}}
* {{Z|scn}}: {{W+|scn|petra}}
* {{Z|sid}}: {{W-|sid|kina}}
* {{Z|srn}}: {{W-|srn|ston}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|ка̏ме̄н|n}}
*: Latînî: {{W+|sh|kȁmēn|n}}
* {{Z|syl}}: {{W-|syl|ꠙꠣꠕ꠆ꠕꠞ}}, {{W-|syl|ꠢꠤꠟ}}
* {{Z|sco}}: {{W-|sco|stane}}
* {{Z|cu}}: {{W-|cu|камꙑ|n}}
* {{Z|sk}}: {{W-|sk|kameň|n}}
* {{Z|sl}}: {{W+|sl|kamen|n}}
* {{Z|tuw-sol}}: {{W-|tuw-sol|дёло}}
* {{Z|so}}: {{W-|so|dhagax}}
* {{Z|es}}: {{W+|es|piedra|m}}, {{W+|es|roca|m}}
* {{Z|suy}}: {{W-|suy|khẽnẽ}}
* {{Z|swg}}: {{W-|swg|stoe}}, {{W-|swg|Schdõẽ}}
* {{Z|sw}}: {{W+|sw|jiwe}}
* {{Z|sv}}: {{W+|sv|sten|g}}
* {{Z|xsr}}: {{W-|xsr|རྡོ|tr=do}}
* {{Z|tg}}: {{W+|tg|санг}}
* {{Z|tl}}: {{W+|tl|bato}}
* {{Z|tbc}}: {{W-|tbc|pat}}
* {{Z|ta}}: {{W+|ta|கல்}}
* {{Z|sai-tap}}: {{W-|sai-tap|khẽnẽ}}
* {{Z|rif}}: {{W-|rif|aẓru|n}}
* {{Z|tsg}}: {{W-|tsg|batu}}
* {{Z|th}}: {{W+|th|หิน}}, {{W+|th|ศิลา}}
* {{Z|te}}: {{W+|te|రాయి}}
* {{Z|tft}}: {{W-|tft|mare}}
* {{Z|tet}}: {{W-|tet|fatuk}}
* {{Z|ssf}}: {{W-|ssf|fatu}}
* {{Z|otk}}: {{W-|otk|𐱃𐱁}}
* {{Z|tr}}: {{W+|tr|taş}}
* {{Z|bo}}: {{W-|bo|རྡོ}}
* {{Z|txb}}: {{W-|txb|kärweñe}}
* {{Z|ddo}}: {{W-|ddo|гъІул|tr=ɣˤul}}, {{W-|ddo|лъад|tr=ɬad}}, {{W-|ddo|гуз|tr=guz}}
* {{Z|tsu}}: {{W-|tsu|fatu}}
* {{Z|tum}}: {{W-|tum|liwe}}
* {{Z|tpn}}: {{W-|tpn|itá}}
* {{Z|tyv}}: {{W-|tyv|даш}}
* {{Z|tpw}}: {{W-|tpw|itá}}
* {{Z|ude}}: {{W-|ude|ӡоло}}
* {{Z|udi}}: {{W-|udi|жӏеъ}}
* {{Z|udm}}: {{W-|udm|из}}
* {{Z|uga}}: {{W-|uga|𐎀𐎁𐎐}}
* {{Z|ulc}}: {{W-|ulc|ӡolo}}
* {{Z|ur}}: {{W-|ur|پتھر|n|tr=patthar}}, {{W-|ur|شلا|m|tr=śilā}}
* {{Z|uk}}: {{W-|uk|ка́мінь|n}}
* {{Z|vec}}: {{W-|vec|piera|m}}, {{W+|vec|pièra|m}}, {{W-|vec|piéra}}, {{W-|vec|pria}}, {{W-|vec|prèa}}, {{W-|vec|rocia|m}}
* {{Z|vi}}: {{W+|vi|đá}}
* {{Z|vo}}: {{W+|vo|ston}}
* {{Z|wa}}: {{W+|wa|pire|m}}, {{W+|wa|rotche|m}}
* {{Z|cy}}: {{W+|cy|carreg|m}}
* {{Z|wo}}: {{W-|wo|xeer wi}}
* {{Z|xav}}: {{W-|xav|ẽtẽ}}, {{W-|xav|ẽnẽ}}
* {{Z|xer}}: {{W-|xer|ktẽ}}
* {{Z|km}}: {{W+|km|ថ្ម|tr=tmɑɑ}}
* {{Z|xok}}: {{W-|xok|kózy}}
* {{Z|rys}}: {{W-|rys|石|tr=isï}}
* {{Z|sah}}: {{W-|sah|таас}}
* {{Z|yag}}: {{W-|yag|aiya}}
* {{Z|tao}}: {{W-|tao|vato}}, {{W-|tao|veysen}}
* {{Z|yi}}: {{W-|yi|שטיין|n}}
* {{Z|yoi}}: {{W-|yoi|石|tr=ichi}}
* {{Z|yo}}: {{W-|yo|òkúta}}
* {{Z|el}}: {{W+|el|λίθος|n}}
*: {{Z|grc}}: {{W-|grc|λίθος|n}}, {{W-|grc|πέτρα|m}}, {{W-|grc|λᾶας|n}}
* {{Z|zea}}: {{W-|zea|steên}}
* {{Z|zu}}: {{W-|zu|itshe|c5}}
{{werger-bin}}
:{{werger çavkanî|en|stone|beş=Ev beşa Wergerê|oldid=75701526}}
=== Rengdêr ===
{{rengdêr|ku}}
# {{f|ku|mecazî}} [[gelek|Gelek]] [[req]].
#* {{bêmînak|ku}}
==== Werger ====
{{werger-ser}}
{{werger-bin}}
=== Anagram ===
* {{g|ku|virek}}
* {{g|ku|vekir}}
kc7x5761t8d5g0vd75dms73c6fdypvt
îlan
0
15445
6347625
6329610
2026-09-01T11:40:06Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347625
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Wiener Parlament Detail.jpg|thumb|250px|Îlanek li ser dîwarekî]]
{{navdêr|ku|z=m}}
# [[belavok]], [[daxwiyanî]], [[peyam]], [[beyan]], [[mesaj]], [[beyanname]], [[reklam]]
#* {{jêder-kovar|ku|jêgirtin=Wê bala xwe dida '''îlanên''' kar ku ewê çawa hinek pere ji bo mala xwe pêde bike û bidebirîne.|sal=2012|url=http://books.google.com.tr/books?id=0xPUDwAAQBAJ&pg=PA23&dq=%22%C3%AElan%C3%AAn%22&hl=&cd=2&source=gbs_api|kovar=tabularasa 2: ji wêjeya cîhanê||weşanxane=Flîtto Weşan|ISBN=9786056258817|rûpel= 23}}
#* {{jêder-pirtûk|ku|jêgirtin=Eywana bi sûretên dîwarî, bi '''îlanên''' mezin bixwe ya bilêtfiroşan bû.|sal=1994|nivîskar=Fawaz Husên|url=http://books.google.com.tr/books?id=orXT8GO6H9wC&q=%22%C3%AElan%C3%AAn%22&dq=%22%C3%AElan%C3%AAn%22&hl=&cd=3&source=gbs_api|sernav=''Siwarên êşê|weşanxane=Wesanen Welat}}
==== Formên alternatîv ====
{{kol3|ku
|î'lan
}}
==== Jê ====
{{kol3|ku|cure=Jê
|îlander
|îlanderî
|îlankar
|îlankarî
|îlanker
|îlankerî
|îlan bûn<crz:lêker>
|îlan kirin<crz:lêker>
|îlan dan<crz:lêker>
|îlanbûn<crz:navdêr>
|îlankirin<crz:navdêr>
|îlandan<crz:navdêr>
|îlanbûyî<crz:rengdêr>
|îlankirî<crz:rengdêr>
}}
==== Etîmolojî ====
Ji {{deyn|ar|ku|اعلان|tr=i'lan}} ji {{g|ar|علن|tr='elene|w=[[diyar]] bûn, [[eşkere]] bûn}} ku serekaniya [[elind]] ya kurdî ye jî.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|Kundgebung}} {{mê}}, {{W|de|Benachrichtigung}} {{mê}}, {{W|de|Bekanntgabe|guman=erê}}
* {{Z|ar}}: {{W|ar|اعلن|guman=erê}}
* {{Z|fa}}: {{W|fa|آگهی}}, {{W|fa|بیان}}, {{W|fa|اطلاع رسانی}}, {{W|fa|اعلام}}
* {{Z|en}}: {{W|en|announcement}}, {{W|en|annunciation}}, {{W|en|enunciation}}, {{W|en|proclamation}}, {{W|en|pronouncement}}
* {{Z|tr}}: {{W|tr|beyan}}, {{W|tr|beyanat}}, {{W|tr|beyanname}}, {{W|tr|duyuru}}, {{W|tr|ilân}}, {{W|tr|car}}
{{werger-bin}}
=== Rengdêr ===
{{rengdêr|ku}}
# [[belav]], [[diyar]], [[xwiya]], [[berçav]], [[eşkere]], [[beyan]]
#* {{bêmînak|ku}}
==== Werger ====
{{werger-ser}}
{{werger-bin}}
=== Navdêr 2 ===
{{navdêr|ku|z=m}}
[[Wêne:Naja-naja-kobra.jpg|thumb|"Îlanek"]]
# {{tirkmancî}} [[mar]] ([[heywan]]ê [[pêveder]] / [[zîldar]])
#* {{J:Mela Hisênê Bateyî:Mewlûda Kurdî|jêgirtin=Ew çi dêm e, şahebax e, gulşena darulqerar<br>Sed hezaran nal û awazên bilbil di çarkenar<br>Helqe pê da best û hatin 'eqreb û '''îlan''' û mar<br>Nêrgiza şehla şepalî, asimîna murx î zar<br> Lebxemûşê meyfiroşê dêmpeyala kê yî tu?}}
==== Notên bikaranînê ====
* Tenê di klasîkan de yan jî di [[tirkmancî]] de
==== Formên alternatîv ====
{{kol3|ku
|yilan
}}
==== Etîmolojî ====
Ji {{deyn|tr|ku|yılan}}, hevreha gagawzî [[yılan]], tirkmenistanî [[ýylan]], oyxurî {{g|ug|يىلان|tr=yilan}}, ozbekî [[ilon]], teterî [[елан]] (yilan), başkîrî [[йылан]] (yïlan), azerî [[ilan]], kumikî [[йылан]] (yılan), tuvanî [[чылан]] (çylan), altayiya başûrî [[јылан]] (cılan), kirgîzî [[жылан]] (cılan), xakasî [[чылан]] (çılan), qazaxî [[жылан]] (jılan), qereçayî-balkarî [[жылан]] (cılan), [[джылан]] (cılan), çuvaşî [[ҫӗлен]] (śĕlen)... Bo ketina Y ji destpêka peyvên ji tirkî wergirtî, binêre: [[aprax]], [[ol]] û [[egîd]].
==== Werger ====
{{werger-bnr|mar|id=heywan}}
k855bpgbjefhc1wkbqw4rdzm1yht7tj
pên
0
15737
6347519
6315085
2026-09-01T08:55:09Z
Balyozbot
7867
sererastkirina nimûneyên edebiyatê (bi destî) [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347519
wikitext
text/x-wiki
{{bnr-h|pen|Pen}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Boykickingball-slowmotion-tokyo-20160423.webm|thumb|Kurikek '''pênê''' li gogê dide.]]
{{navdêr|ku|z=m}}
# [[derbe]]ya bi [[pê]], [[lêdan]]a bi [[ling]]î
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|pên lêdan<crz:lêker>
|pên lêxistin<crz:lêker>
|[[pên danîn]] (kesekê/î)<crz:lêker>
|pên lêdan<cuda:pên li kesekê/î yan tiştekê/î dan><crz:lêker>
|pêndanîn<crz:navdêr>
|pênlêdan<crz:navdêr>
}}
==== Formên alternatîv ====
{{kol3|ku
|pehîn
|peḧîn
|pêhin
|pêhn
|pihin
|pihîn
|pihn
|piḧîn
|pîn
}}
==== Nêzîk ====
{{kol3|ku
|lot
|zirç
}}
==== Etîmolojî ====
Ji '''[[pê]]''' ([[ling]], [[nig]])
==== Bide ber ====
{{kol3|ku
|hutik
|kulm
|mist
}}
==== Binêre herwiha ====
{{kol3|ku
|bên
}}
==== Werger ====
{{werger-ser}}
* {{Z|as}}: {{W-|as|লাথ}}, {{W-|as|গুৰি}}
* {{Z|bg}}: {{W+|bg|ритни́к|n}}
* {{Z|cs}}: {{W+|cs|kop|n}}
* {{Z|da}}: {{W-|da|spark|nt}}
* {{Z|id}}: {{W+|id|tendangan}}
* {{Z|ar}}: {{W-|ar|رَكْلَة}}
* {{Z|fa}}: {{W+|fa|لگد|tr=lagad}}
* {{Z|fo}}: {{W-|fo|spark|nt}}
* {{Z|fi}}: {{W+|fi|potku}}
* {{Z|fr}}: {{W+|fr|coup de pied}}, {{W+|fr|botter}}
* {{Z|gd}}: {{W-|gd|breab|g}}
* {{Z|gl}}: {{W-|gl|patada|m}}, {{W+|gl|couce|m}}
* {{Z|ka}}: {{W-|ka|ჭიტლაყი}}, {{W-|ka|პანღური}}
* {{Z|nl}}: {{W+|nl|schop|n}}, {{W+|nl|trap|n}}, {{W+|nl|stamp|n}}
* {{Z|he}}: {{W+|he|בעיטה|m}}
* {{Z|en}}: {{W+|en|kick}}
* {{Z|ga}}: {{W-|ga|cic|n}}, {{W-|ga|speach|m}}
* {{Z|it}}: {{W+|it|calcio|n}}, {{W-|it|piedata|m}}, {{W-|it|colpo di piede|n}}
* {{Z|is}}: {{W+|is|spark|nt}}
* {{Z|qu}}: {{W-|qu|hayt'a}}
* {{Z|ko}}: {{W+|ko|차다|cuda=차기}}
* {{Z|lv}}: {{W-|lv|spēriens|n}}
* {{Z|lt}}: {{W-|lt|spyris|n}}
* {{Z|mk}}: {{W-|mk|клоца|m}}
* {{Z|ms}}: {{W+|ms|sepakan}}, {{W+|ms|tendangan}}
* {{Z|no}}:
*: {{Z|nb}}: {{W-|nb|spark|nt}}
*: {{Z|nn}}: {{W-|nn|spark|nt}}
* {{Z|oc}}: {{W+|oc|reguitnada|m}}
* {{Z|pl}}: {{W+|pl|kopnięcie|nt}}, {{W+|pl|wykop|n}}, {{W+|pl|kop|n}}
* {{Z|pt}}: {{W+|pt|chute|n}}, {{W+|pt|pontapé|n}}, {{W+|pt|coice|n}}
* {{Z|ro}}: {{W+|ro|șut|nt}}, {{W-|ro|lovitură cu piciorul|m}}
* {{Z|ru}}: {{W+|ru|пино́к|n}}
* {{Z|sl}}: {{W+|sl|brca|m}}
* {{Z|es}}: {{W+|es|patada|m}}, {{W+|es|puntapié|n}}, {{W+|es|coz|m}}
* {{Z|sv}}: {{W+|sv|spark|nt}}
* {{Z|zdj}}: {{W-|zdj|nɗaru|c9|c10}}
* {{Z|te}}: {{W+|te|తాపు}}
* {{Z|tr}}: {{W+|tr|tekme}}
* {{Z|ur}}: {{W-|ur|لات}}
* {{Z|uk}}: {{W-|uk|копня́к|n}}
* {{Z|vi}}: {{W+|vi|[[đòn]] [[đá]]}}, {{W-|vi|[[cú]] [[đá]]}}
* {{Z|el}}:
*: {{Z|grc}}: {{W-|grc|λάκτισμα|nt}}
{{werger-bin}}
:{{werger çavkanî|en|kick|beş=Ev qismê Wergerê|oldid=76034390}}
gm0i8utwtys5c1lwowjn4holbw7a6m2
6347537
6347519
2026-09-01T09:41:12Z
Balyozbot
7867
[[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan
6347537
wikitext
text/x-wiki
{{bnr-h|pen|Pen}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Boykickingball-slowmotion-tokyo-20160423.webm|thumb|Kurikek '''pênê''' li gogê dide.]]
{{navdêr|ku|z=m}}
# [[derbe]]ya bi [[pê]], [[lêdan]]a bi [[ling]]î
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Formên alternatîv ====
{{kol3|ku
|pehîn
|peḧîn
|pêhin
|pêhn
|pihin
|pihîn
|pihn
|piḧîn
|pîn
}}
==== Nêzîk ====
{{kol3|ku
|lot
|zirç
}}
==== Jê ====
{{kol3|ku
|pên lêdan<crz:lêker>
|pên lêxistin<crz:lêker>
|[[pên danîn]] (kesekê/î)<crz:lêker>
|pên lêdan<cuda:pên li kesekê/î yan tiştekê/î dan><crz:lêker>
|pêndanîn<crz:navdêr>
|pênlêdan<crz:navdêr>
}}
==== Etîmolojî ====
Ji '''[[pê]]''' ([[ling]], [[nig]])
==== Bide ber ====
{{kol3|ku
|hutik
|kulm
|mist
}}
==== Herwiha binêre ====
{{kol3|ku
|bên
}}
==== Werger ====
{{werger-ser}}
* {{Z|as}}: {{W-|as|লাথ}}, {{W-|as|গুৰি}}
* {{Z|bg}}: {{W+|bg|ритни́к|n}}
* {{Z|cs}}: {{W+|cs|kop|n}}
* {{Z|da}}: {{W-|da|spark|nt}}
* {{Z|id}}: {{W+|id|tendangan}}
* {{Z|ar}}: {{W-|ar|رَكْلَة}}
* {{Z|fa}}: {{W+|fa|لگد|tr=lagad}}
* {{Z|fo}}: {{W-|fo|spark|nt}}
* {{Z|fi}}: {{W+|fi|potku}}
* {{Z|fr}}: {{W+|fr|coup de pied}}, {{W+|fr|botter}}
* {{Z|gd}}: {{W-|gd|breab|g}}
* {{Z|gl}}: {{W-|gl|patada|m}}, {{W+|gl|couce|m}}
* {{Z|ka}}: {{W-|ka|ჭიტლაყი}}, {{W-|ka|პანღური}}
* {{Z|nl}}: {{W+|nl|schop|n}}, {{W+|nl|trap|n}}, {{W+|nl|stamp|n}}
* {{Z|he}}: {{W+|he|בעיטה|m}}
* {{Z|en}}: {{W+|en|kick}}
* {{Z|ga}}: {{W-|ga|cic|n}}, {{W-|ga|speach|m}}
* {{Z|it}}: {{W+|it|calcio|n}}, {{W-|it|piedata|m}}, {{W-|it|colpo di piede|n}}
* {{Z|is}}: {{W+|is|spark|nt}}
* {{Z|qu}}: {{W-|qu|hayt'a}}
* {{Z|ko}}: {{W+|ko|차다|cuda=차기}}
* {{Z|lv}}: {{W-|lv|spēriens|n}}
* {{Z|lt}}: {{W-|lt|spyris|n}}
* {{Z|mk}}: {{W-|mk|клоца|m}}
* {{Z|ms}}: {{W+|ms|sepakan}}, {{W+|ms|tendangan}}
* {{Z|no}}:
*: {{Z|nb}}: {{W-|nb|spark|nt}}
*: {{Z|nn}}: {{W-|nn|spark|nt}}
* {{Z|oc}}: {{W+|oc|reguitnada|m}}
* {{Z|pl}}: {{W+|pl|kopnięcie|nt}}, {{W+|pl|wykop|n}}, {{W+|pl|kop|n}}
* {{Z|pt}}: {{W+|pt|chute|n}}, {{W+|pt|pontapé|n}}, {{W+|pt|coice|n}}
* {{Z|ro}}: {{W+|ro|șut|nt}}, {{W-|ro|lovitură cu piciorul|m}}
* {{Z|ru}}: {{W+|ru|пино́к|n}}
* {{Z|sl}}: {{W+|sl|brca|m}}
* {{Z|es}}: {{W+|es|patada|m}}, {{W+|es|puntapié|n}}, {{W+|es|coz|m}}
* {{Z|sv}}: {{W+|sv|spark|nt}}
* {{Z|zdj}}: {{W-|zdj|nɗaru|c9|c10}}
* {{Z|te}}: {{W+|te|తాపు}}
* {{Z|tr}}: {{W+|tr|tekme}}
* {{Z|ur}}: {{W-|ur|لات}}
* {{Z|uk}}: {{W-|uk|копня́к|n}}
* {{Z|vi}}: {{W+|vi|[[đòn]] [[đá]]}}, {{W-|vi|[[cú]] [[đá]]}}
* {{Z|el}}:
*: {{Z|grc}}: {{W-|grc|λάκτισμα|nt}}
{{werger-bin}}
:{{werger çavkanî|en|kick|beş=Ev qismê Wergerê|oldid=76034390}}
7o6bc0nlkhsqv4i7nl6y8p2c80blfst
zîl
0
16131
6347635
6321520
2026-09-01T11:51:12Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347635
wikitext
text/x-wiki
{{bnr-h|zil|zill}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{kîte|ku|zîl}}
=== Navdêr 1 ===
{{navdêr|ku|z=m}}
# {{f|ku|ziman}} [[ziman]]ê [[mar]]î (yan wek yê [[mar]]î)
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Formên alternatîv ====
{{kol3|ku
|zîlik
|zîlk
}}
==== Bide ber ====
{{kol3|ku
|zal
|zel
|zil
}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Ausläufer|m|guman=erê}}, {{W-|de|Läutwerk|guman=erê}}, {{W+|de|Schößling|guman=erê}}
* {{Z|ar}}: {{W+|ar|إبرة|guman=erê}}
* {{Z|fa}}: {{W+|fa|جوانه|guman=erê}}, {{W-|fa|گیاهان بهاری|guman=erê}}, {{W-|fa|نیش مار|guman=erê}}
* {{Z|en}}: {{W+|en|aculeus|guman=erê}}, {{W+|en|bell|guman=erê}}
* {{Z|tr}}: {{W+|tr|bızır}}, {{W+|tr|cücük}}, {{W+|tr|klitoris}}, {{W+|tr|oğulcuk}}, {{W+|tr|zil}}, {{W+|tr|tiz|guman=erê}}, {{W-|tr|ayak otu|guman=erê}}, {{W-|tr|dığdığının dığdığı|guman=erê}}, {{W+|tr|dılak|guman=erê}}
{{werger-bin}}
=== Navdêr 2 ===
{{navdêr|ku|z=m}}
# [[zengil]], [[zeng]], [[çeng]], [[zingil]], [[ceres]]
==== Jê ====
{{kol3|ku
|zîl lê dan<crz:lêker>
|zîllêdan<crz:navdêr>
|zîllêder
}}
==== Werger ====
{{werger-ser}}
* {{Z|tr}}: {{W+|tr|zil}}
{{werger-bin}}
=== Navdêr 3 ===
[[Wêne:Onion growing shoots.jpg|thumb|150px|'''Zîla''' pîvazê.]]
{{navdêr|ku|z=m}}
# {{maneid|ku|aj}} [[aj]], [[kat]], [[bişkoj]]
==== Jê ====
{{kol3|ku
|zîl dan<crz:lêker>
|zîldan<crz:navdêr>
|zîldayî<crz:rengdêr>
| bêzîl
| bêzîlî
| bêzîlîtî
| bêzîltî
| bizîl
| bizîlî
| bizîlîtî
| bizîltî
| zîldar
| zîldarî
| zîldarî
| zîldarîtî
| zîldartî
| zîlder
| zîlderî
| zîlderîtî
| zîldertî
| zîldêr
| zîldêrî
| zîldêrî
| zîldêrîtî
| zîldêrtî
| zîlik
| zîlikî
| zîlk
| zîlkî
}}
==== Etîmolojî ====
Belkî ji {{ji|hy|ku}} ''çil/cil'' yan jî ya ermenî ji kurdî ye, çawa be jî, herdu ji {{ji|ine-pro|ku|*ġī-|w=zîl dan}}.
==== Bi zaravayên din ====
* {{Z|ckb}}: {{W-|ckb|چووزەرە}}, {{W-|ckb|چەکەرە}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: [[trieb|Trieb]] ''(nêr; die ~e)'', [[schössling|Schössling]] ''(nêr; die ~e)'', [[spross|Spross]] ''(nêr; die Sprosse, des Sprosses)''
* {{Z|fi}}: {{W+|fi|verso}}
* {{Z|fr}}: {{W+|fr|germe|n}}, {{W+|fr|pousse|m}}, {{W+|fr|bourgeon|m}}
* {{Z|nl}}: {{W+|nl|scheut}}, {{W+|nl|spruit}}
* {{Z|en}}: {{W+|en|sprout}}
* {{Z|it}}: {{W+|it|germoglio|m}}
* {{Z|ru}}: [[отросток]] [[росток]], {{W+|ru|побег}}
* {{Z|es}}: {{W+|es|brote|m}}, {{W+|es|retoño|m}}, {{W+|es|renuevo|m}}
* {{Z|sv}}: {{W-|sv|skott|tr=stamdel}}
* {{Z|tr}}: {{W+|tr|filiz}}
{{werger-bin}}
=== Navdêr 4 ===
{{navdêr|ku|z=m}}
# [[cemse]], [[tirimpêl]]ên [[esker]]an yên mîna [[kamyon]]an lê biçûktir
==== Werger====
{{werger-ser}}
{{werger-bin}}
=== Navdêr 5 ===
{{navdêr|ku|z=n}}
# ''(parçe)'' {{guherto|ku|zûl}}
=== Navdêr 6 ===
[[Wêne:Waspstinger1658-2.jpg|thumb|Zîl.]]
{{navdêr|ku|z=?}}
# {{maneid|ku|derzî}} [[endam|Endamekê]] mêşa [[hingiv]]iye ku pê bi [[mirov]]î ve dide.
==== Werger====
{{werger-ser}}
* {{Z|en}}: {{W+|en|stinger}}
* {{Z|tr}}: {{W-|tr|arı iğnesi}}
{{werger-bin}}
=== Hoker ===
{{hoker|ku}}
# [[zêde]], [[gelek]], [[pirr]]
#* {{jêder|ku|jêgirtin=Sala çûyî Hîlton xanimê '''zîl''' serxweş trimbêl ajotibû û hatibû girtin. Tu nabê dilê polîs û hakiman pê dişewite û wê bi şert berdidin ku carek din bi serxweşî tribêlê najo. Lê xuyaye kurmê şîrî heta pîrî ye û Parîs xanim cardin bi serxweşî daye ser rê û gaz daye trimbêlê.|Lotikxane.com, 5/2007}}
==== Werger ====
{{werger-ser}}
{{werger-bin}}
sw387kfdu3yp5wna115k38gdmpat5zj
lê dan
0
16638
6347578
6341177
2026-09-01T10:26:52Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347578
wikitext
text/x-wiki
{{bnr-n|lêdan}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Lêker ===
{{ku-tewîn-lk|lê dan|form=gerguhêz|niha=d|borî=da|pêşgir=lê|valahî=erê}}
{{lêker|ku|c=h-gh|nd=lêdan}}
# [[lê xistin]], [[qutan]], [[kutan]], [[pê dadan]], [[pê ketin]]:
#: {{mk|ku|Min çend kulm '''li''' Aradî '''dan'''.}}
# [[amûr]]eke [[muzîk]]ê [[jenîn]]
#: {{mk|ku|Ez [[saz]]ê lê didim.}}
#* {{J:Serdar Roşan:Çîroka Hezar û Şevekê|jêgirtin={{...}} gava min xwarin dixwar, wan musîkeke zindî ku miriyan ji gorê radike '''lê dida'''; bi dengên efsûnkar stran digotin; û çend ji wan dest bi reqsê kirin.}}
# [[girtin]], [[pê ketin]]:
#: {{mk|ku|Sermayê '''li''' birayê min '''daye''', nexweş bûye.}}
# {{f|ku|Dihok}} (kirêt) [[destperkî kirin]]
#* {{bêmînak|ku}}
==== Bi alfabeyên din ====
* {{ku-ar|لێ دان}}
==== Jê ====
{{kol3|ku
|lêdayî
|lêder
}}
==== Etîmolojî ====
Ji {{heve|ku|lê|dan}}.
==== Werger ====
{{werger-ser|lê xistin, kutan, qutan}}
* {{Z|sq}}: {{W+|sq|rrah}}, {{W-|sq|rraf}}, {{W+|sq|dëkoj}}, {{W+|sq|zhdëp}}, {{W+|sq|mëshoj|n}}
* {{Z|de}}: {{W+|de|schlagen}}, {{W+|de|hauen}}
* {{Z|rup}}: {{W+|rup|bat}}
* {{Z|az}}: {{W+|az|döymək}}, {{W+|az|vurmaq}}
* {{Z|be}}: {{W-|be|біць|impf}}, {{W-|be|пабі́ць|pf}}; {{W-|be|удара́ць|impf}}, {{W-|be|ўдара́ць|impf}}, {{W-|be|уда́рыць|pf}}, {{W-|be|ўда́рыць|pf}}
* {{Z|bn}}: {{W+|bn|পেটা}}, {{W+|bn|মারা}}
* {{Z|bg}}: {{W+|bg|у́дрям}}, {{W+|bg|би́я|impf}}
* {{Z|cs}}: {{W+|cs|bít|impf}}, {{W+|cs|tlouct}}, {{W+|cs|mlátit}}
* {{Z|zh}}:
*: {{Z|dng}}: {{W-|dng|да}}
*: {{Z|cmn}}: {{W+|cmn|打擊|tr=dǎjī}}, {{W+|cmn|打|tr=dǎ}}
* {{Z|dlm}}: {{W-|dlm|batar}}, {{W-|dlm|báter}}
* {{Z|ar}}: {{W+|ar|ضَرَبَ}}, {{W+|ar|دَقَّ}}
*: {{Z|arz}}: {{W-|arz|ضرب|tr=ḍarab}}
*: {{Z|acw}}: {{W-|acw|ضرب|tr=ḍarab}}, {{W-|acw|طرق|tr=ṭarag}}, {{W-|acw|صقع|tr=ṣagaʕ}}, {{W-|acw|رقع|tr=ragaʕ}}
* {{Z|hy}}: {{W+|hy|ծեծել}}
* {{Z|eo}}: {{W+|eo|bati}}
* {{Z|eve}}: {{W-|eve|куси-}}
* {{Z|fa}}: {{W+|fa|زدن|tr=zadan}}
* {{Z|fi}}: {{W+|fi|hakata}}, {{W+|fi|lyödä}}, {{W+|fi|iskeä}}
* {{Z|fr}}: {{W+|fr|battre}}
* {{Z|fur}}: {{W-|fur|bati}}
* {{Z|gd}}: {{W-|gd|buail}}
* {{Z|gl}}: {{W+|gl|bater}}, {{W-|gl|zoscar}}, {{W-|gl|zorregar}}, {{W-|gl|zoupar}}, {{W+|gl|bourar}}
* {{Z|sdn}}: {{W-|sdn|fusticà}}, {{W-|sdn|addubbà}}
* {{Z|got}}: {{W-|got|𐌱𐌻𐌹𐌲𐌲𐍅𐌰𐌽}}
* {{Z|hi}}: {{W+|hi|पीटना}}, {{W+|hi|मारना}}
* {{Z|nl}}: {{W+|nl|slaan}}, {{W+|nl|kloppen}}
* {{Z|he}}: {{W-|he|היכה|tr=hiká|cuda=היכה \ הִכָּה}}
* {{Z|io}}: {{W+|io|batar}}
* {{Z|enm}}: {{W-|enm|beten}}
* {{Z|en}}: {{W+|en|beat}}, {{W+|en|hit}}, {W+|en|knock}}, {{W+|en|strike}}, {{W+|en|pound}}
* {{Z|izh}}: {{W-|izh|löövvä}}, {{W-|izh|tappaa}}, {{W-|izh|iskiä}}, {{W-|izh|peeksää}}, {{W-|izh|issuttaa}}
* {{Z|ga}}: {{W-|ga|buail}}, {{W-|ga|gread}}
* {{Z|ruo}}: {{W-|ruo|båte}}
* {{Z|it}}: {{W+|it|colpire}}, {{W+|it|battere}}
* {{Z|ja}}: {{W+|ja|殴る|tr=なぐる, naguru}}, {{W+|ja|叩く|tr=たたく, tataku}}
* {{Z|kln}}: {{W-|kln|piring'}}
* {{Z|xal}}: {{W-|xal|цокх}}
* {{Z|ca}}: {{W+|ca|batre}}
* {{Z|qu}}: {{W-|qu|maqay}}
* {{Z|ks}}: {{W-|ks|لایُن}}, {{W-|ks|چوب دِنؠ}}
* {{Z|ky}}: {{W+|ky|уруу}}
* {{Z|ki}}: {{W-|ki|hora}}
* {{Z|swb}}: {{W-|swb|u[[rema]]}}
* {{Z|ko}}: {{W+|ko|치다}}
* {{Z|lad}}: {{W-|lad|aharvar}}, {{W-|lad|ajarvar}}
* {{Z|la}}: {{W-|la|pulso}}, {{W-|la|cūdō}}, {{W-|la|verbero}}, {{W-|la|battuo}}
* {{Z|lv}}: {{W+|lv|sist}}
* {{Z|lo}}: {{W-|lo|ຕີ}}
* {{Z|lmo}}: {{W-|lmo|batt}}
* {{Z|luy}}: {{W-|luy|khupa}}
* {{Z|mk}}: {{W-|mk|бие|impf}}
* {{Z|ml}}: {{W+|ml|അടിക്കുക}}
* {{Z|mt}}: {{W-|mt|sawwat}}
* {{Z|msk}}: {{W-|msk|bonal}}
* {{Z|mi}}: {{W-|mi|tukituki}}, {{W-|mi|tuangau}}
* {{Z|hu}}: {{W+|hu|üt}}
* {{Z|ne}}: {{W-|ne|ठोक्नु}}
* {{Z|nrf}}: {{W-|nrf|battre}}, {{W-|nrf|dêfoncer}}
* {{Z|no}}: {{W+|no|slå}}
* {{Z|oc}}: {{W+|oc|batre}}
* {{Z|ota}}: {{W-|ota|چالمق|tr=çalmak}}
* {{Z|pap}}: {{W-|pap|bati}}
* {{Z|pl}}: {{W+|pl|uderzać|impf}}, {{W+|pl|uderzyć|pf}}; {{W+|pl|bić|impf}}, {{W+|pl|pobić|pf}}
* {{Z|pt}}: {{W+|pt|bater}}
* {{Z|kk}}: {{W-|kk|сою}}
* {{Z|ro}}: {{W+|ro|bate}}
* {{Z|ru}}: {{W+|ru|бить|impf}}, {{W+|ru|поби́ть|pf}}, {{W+|ru|ударя́ть|impf}}, {{W+|ru|уда́рить|pf}}
* {{Z|sa}}: {{W+|sa|वादयति}}
* {{Z|sc}}:
*: Kampîdanî: {{W-|sc|surrare}}, {{W-|sc|sagamare}}
*: Logudorî: {{W-|sc|surrare}}, {{W-|sc|sagamare}}
* {{Z|sdc}}: {{W-|sdc|sagamare}}, {{W-|sdc|fusthigà}}, {{W-|sdc|adubbà}}, {{W-|sdc|iscudí}}
* {{Z|scn}}: {{W+|scn|bàttiri}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|би̏ти|impf}}
*: Latînî: {{W+|sh|bȉti|impf}}
* {{Z|cu}}:
*: Kirîlî: {{W-|cu|бити|impf}}
* {{Z|sk}}: {{W-|sk|biť|impf}}, {{W-|sk|tĺcť}}
* {{Z|sl}}: {{W-|sl|tolči}}, {{W+|sl|tepsti}}, {{W+|sl|bíti|impf}}
* {{Z|so}}: {{W-|so|tumid}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|biś|impf}}
* {{Z|es}}: {{W+|es|golpear}}, {{W+|es|pegar}}, {{W+|es|aporrear}}, {{W+|es|batir}}, {{W+|es|apalizar}}
* {{Z|sw}}: {{W+|sw|chapa}}
* {{Z|sv}}: {{W+|sv|slå}}
* {{Z|zdj}}: {{W-|zdj|u[[rema]]}}, {{W-|zdj|u[[fufua]]}}
* {{Z|tg}}: {{W-|tg|задан}}
* {{Z|tl}}: {{W-|tl|ihampas}}
* {{Z|th}}: {{W+|th|ตี}}
* {{Z|tet}}: {{W-|tet|baku}}, {{W-|tet|tuku}}
* {{Z|tr}}: {{W+|tr|vurmak}}
* {{Z|uga}}: {{W-|uga|𐎎𐎃𐎕}}
* {{Z|ur}}: {{W-|ur|پیٹنا|tr=pīṭnā}}, {{W-|ur|مارنا|tr=mārnā}}
* {{Z|uk}}: {{W+|uk|би́ти|impf}}, {{W-|uk|поби́ти|pf}}, {{W-|uk|вдаря́ти|impf}}, {{W-|uk|ударя́ти|impf}}, {{W-|uk|вда́рити|pf}}, {{W-|uk|уда́рити|pf}}
* {{Z|vec}}: {{W+|vec|bàtar}}, {{W-|vec|bàter}}
* {{Z|vi}}: {{W+|vi|đánh}}, {{W+|vi|đập}}
* {{Z|vo}}: {{W+|vo|flapön}}, {{W-|vo|leflapön}}
* {{Z|cy}}: {{W+|cy|baeddu}}
* {{Z|km}}: {{W+|km|វាយ}}
* {{Z|yi}}: {{W-|yi|שלאָגן}}, {{W-|yi|קלאַפּן}}
* {{Z|el}}:
*: {{Z|grc}}: {{W-|grc|τύπτω}}, {{W-|grc|πλήσσω}}
{{werger-bin}}
:{{werger çavkanî|en|beat|beş=Ev qismê Wergerê|oldid=76030023}}
{{werger-ser|amûreke muzîkê lê dan}}
* {{Z|de}}: {{W+|de|spielen}}
* {{Z|as}}: {{W-|as|বজোৱা}}, {{W-|as|বোৱা}}
* {{Z|az}}: {{W+|az|çalmaq}}
* {{Z|eu}}: {{W+|eu|jo}}
* {{Z|ba}}: {{W-|ba|уйнау}}, {{W-|ba|тартыу}}
* {{Z|be}}: {{W-|be|граць|impf}}
* {{Z|bn}}: {{W+|bn|বাজানো}}
* {{Z|bg}}: {{W+|bg|свиря|impf}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|演奏|tr=yǎnzòu}}, {{W+|cmn|彈|tr=tán}}&{{W-|cmn|彈奏|tr=tánzòu}}, {{W+|cmn|拉|tr=lā}}, {{W+|cmn|吹|tr=chuī}}&{{W+|cmn|吹奏|tr=chuīzòu}}, {{W+|cmn|敲|tr=qiāo}}, {{W+|cmn|打|tr=dǎ}}
* {{Z|da}}: {{W+|da|spille|cuda=spille på}}
* {{Z|dlg}}: {{W-|dlg|оойноо|tr=ooynoo}}, {{W-|dlg|оойньоо|tr=ooyńoo}}
* {{Z|id}}: {{W+|id|bermain}}, {{W+|id|memainkan}}, {{W+|id|membunyikan}}
* {{Z|ar}}: {{W-|ar|عَزَفَ}}
* {{Z|hy}}: {{W+|hy|նվագել}}
* {{Z|eo}}: {{W-|eo|muziki per}}, {{W+|eo|ludi}}
* {{Z|et}}: {{W-|et|mängida}}
* {{Z|fo}}: {{W+|fo|leika}}, {{W+|fo|spæla}}
* {{Z|fi}}: {{W+|fi|soittaa}}
* {{Z|fr}}: {{W+|fr|jouer|cuda=jouer de}}
* {{Z|gl}}: {{W+|gl|tocar}}, {{W+|gl|tanguer}}
* {{Z|ka}}: {{W-|ka|უკრავს}}
* {{Z|gn}}: {{W-|gn|mbopu}}
* {{Z|hi}}: {{W+|hi|बजाना}}
* {{Z|nl}}: {{W+|nl|spelen}}, {{W+|nl|bespelen}}
* {{Z|he}}: {{W-|he|ניגן|cuda=ניגן |tr=nigén }}
* {{Z|io}}: {{W+|io|plear}}
* {{Z|ang}}: {{W-|ang|lācan}}, {{W-|ang|gliwian}}
* {{Z|enm}}: {{W-|enm|pleyen}}, {{W-|enm|singen}}
* {{Z|en}}: {{W+|en|play}} (a musical instrument)
* {{Z|izh}}: {{W-|izh|soittaa}}
* {{Z|ga}}: {{W-|ga|seinn}}
* {{Z|it}}: {{W+|it|suonare}}
* {{Z|is}}: {{W-|is|spila}}, {{W-|is|spila á}}
* {{Z|ja}}: {{W+|ja|演奏|tr=えんそうする, ensō suru|cuda=えんそうする}}, {{W+|ja|奏でる|tr=かなでる, kanaderu}} {{W+|ja|弾く|tr=ひく, hiku}}, {{W+|ja|吹く|tr=ふく, fuku}}, {{W+|ja|叩く|tr=たたく, tataku}}
* {{Z|jv}}: {{W+|jv|dolanan}}
* {{Z|krl}}: {{W-|krl|soittua}}
* {{Z|ca}}: {{W+|ca|tocar}}
* {{Z|qu}}: {{W+|qu|takiy}}
* {{Z|kok}}: {{W-|kok|वाजंव्चे|tr=vājavce}}
* {{Z|kum}}: {{W-|kum|сокъмакъ}}
* {{Z|ltg}}: {{W-|ltg|spieļuot}}
* {{Z|la}}: {{W+|la|cano}}
* {{Z|lv}}: {{W-|lv|spēlēt}}
* {{Z|lt}}: {{W-|lt|groti}}
* {{Z|mk}}: {{W-|mk|свири}}
* {{Z|mt}}: {{W-|mt|daqq}}
* {{Z|mi}}: {{W-|mi|whakatangi}}
* {{Z|yua}}: {{W-|yua|pax}}
* {{Z|hu}}: {{W+|hu|játszik}}
* {{Z|nrf}}: {{W-|nrf|jouer}}, {{W-|nrf|sonner}}
* {{Z|oc}}: {{W+|oc|tocar}}
* {{Z|ota}}: {{W-|ota|چالمق|tr=çalmak}}
* {{Z|ps}}: {{W+|ps|ږغول|tr=ģağawəl|sc=ps-Arab}}
* {{Z|pl}}: {{W+|pl|grać|cuda=grać na|impf}}, {{W+|pl|muzykować|cuda=muzykować na|impf}}
* {{Z|pt}}: {{W+|pt|tocar}}
* {{Z|ro}}: {{W+|ro|cânta}}
* {{Z|ru}}: {{W+|ru|игра́ть|impf}}, {{W+|ru|поигра́ть|pf}}
* {{Z|sh}}: {{W+|sh|svirati}}
* {{Z|sk}}: {{W-|sk|hrať}}
* {{Z|sl}}: {{W+|sl|igrati}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|graś|impf}}
* {{Z|es}}: {{W+|es|tocar}}
* {{Z|sv}}: {{W+|sv|spela}}
* {{Z|tl}}: {{W-|tl|tumugtog}}
* {{Z|th}}: {{W+|th|เล่น}}
* {{Z|tr}}: {{W+|tr|çalmak}}
* {{Z|ur}}: {{W-|ur|بجانا|tr=bajānā|sc=ur-Arab}}
* {{Z|uk}}: {{W+|uk|гра́ти|impf}}
* {{Z|km}}: {{W+|km|ដេញ}}
* {{Z|sah}}: {{W-|sah|оонньоо}}
* {{Z|el}}: {{W+|el|παίζω}}
{{werger-bin}}
:{{werger çavkanî|en|play|beş=Ev qismê Wergerê|oldid=76107332}}
9stpc3m3pvq5ccvyobhizhjy7uf5v40
çay
0
16836
6347621
6326207
2026-09-01T11:34:50Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347621
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/t͡ʃʰɑːj/}}
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Cup of tea, Scotland.jpg|thumb|Fincaneke '''çayê'''. (1)]]
[[Wêne:Teestrauch Detail.jpg|thumb|Riweka '''çayê'''. (2)]]
{{navdêr|ku|z=m}}, {{ç-ya req}}
# {{e|ku|vexwarin}} Vexwarinek e ku bi ava [[kelandin|kelandî]] tê çêkirin û [[reng]]ê wê nêzîkî [[qehweyî]] ye.
#: {{mk|ku|'''Çaya''' tehl/bêşekir, '''çaya''' şîrîn, '''çaya''' zelal, '''çaya''' tarî, '''çaya''' germ, '''çaya''' sar.}}
#: {{mk|ku|Fincaneke '''çayê''', piyaleke '''çayê'''.}}
#: {{mk|ku|Were em '''çayekê''' vexwin.}}
#: {{mk|ku|Hişyar be, '''çay''' germ e, bi xwe de [[riştin|nerêje]]!}}
#* {{jêder|ku|jêgirtin="Di vê bêhnikê de çiqasî dixwest ku çaydanekî '''çayê''' vexwara û bi ser de tam qutiyeke tûtina Xursê bikişanda."|Laleş Qaso: ''Sê şev û sê roj'', roman 2002}}
#* {{jêder-pirtûk|ku|jêgirtin=Got "heyran tu çi zû razayî, ka were em '''çayekê''' vexwin. Ez ji ser cî rabûm min got, "hema ez ji nizanim çawa di xew re çûme."|nivîskar=Mihemed Şarman|sernav=Pirça Winda|cîh=Stembol|weşanxane={{w|Weşanên Avesta|Avesta}}|sal=2016|çap=2|rûpel=82|isbn=978-605-5585-41-9}}
# {{e|ku|riwek}} [[devî|Deviyek]] anku [[teraş]]ek e ku ji [[pel]]ên wê [[vexwarin]]ek tê çêkirin.
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Notên bikaranînê ====
{{kol3|ku
|çay [[dem]] kirin
|çay [[îkram]] kirin, çay [[pêşkêş]] kirin
|çay [[kelandin]]
|çay [[tê kirin]]
|çay [[vexwarin]]
}}
==== Bi alfabeyên din====
* {{ku-ar|چای}}
* {{ku-kr|ч'ай}}
==== Formên alternatîv ====
{{kol3|ku
|ça
|çayê<qq:di hin devokan de wek forma ne[[çemandî]]/ne[[tewandî]] jî>
|çey-<qq:di hinek [[peyvên pêkhatî]] anku [[hevedudanî]] de, bo nimûne ''[[çeyxane]]''>
}}
==== Navê zanistî ====
* Navê zanistî yê riwekê: ''[[Camellia sinensis]]''
==== Jê ====
{{kol3|ku
|çaya kesk
|çaya reş
|çaydan
|çaydank
|çaygêr
|çaygêrî
|çayî
|çayvan
|çayvanî
|çayvexwer
|çayxane
|çayxanevan
|çayxanevanî
|çayxwer
|tovça
|tovçay
}}
==== Etîmolojî ====
Herwiha ''[[ça]]'', hevreha soranî {{g|ckb|چای}} û {{g|ckb|چا}}, zazakî ''{{g|zza|çay}}'' û ''{{g|zza|ça}}'', farisî {{g|fa|چای|tr=çay}} û {{g|fa|چا|tr=ça}}, tirkiya osmanî {{g|ota|چای|tr=çay}} û {{g|ota|چا|tr=ça}}, tirkiya niha {{g|tr|çay}}, siryanî [[ܟ݈ܐܝ]] (çay), azerî ''{{g|az|çay}}'', erebî {{g|ar|شای|tr=şay}}, peştûyî {{g|ur|چای|tr=çay}}, ûrdûyî {{g|ur|چای|tr=çay}} û {{g|ur|چا|tr=ça}}, hindî [[चाय]] (çāy)û [[चा]] (çā), {{hv|hy|չայ}} (čʿay), gurcî [[ჩაი]] (čay), {{hv|ru|чай}} (čay), bulgarî [[чай]] (čay), romanî ''[[ceai]]'' (/çay/), tirkmen(istan)î ''[[çaý]]'', qazaxî [[шай]] (şay), ozbekî ''[[choy]]'', albanî ''[[çaj]]'' (/çay/), çekî/kroatî/slovakî/slovenî ''[[čaj]]'' (/çay/), sirbî [[ча̏ј]] (/çay/), portugalî ''{{g|pt|chá}}''... hemû ji {{ji|zh|ku|茶}} (bilêvkirina çîniya [[mandarînî]]: /chá/: çay, ça) û [[茶葉]] (/cháyè/: [[pel]]ên çayê).
Heman peyva çînî di çîniya [[minanî]] de bi eynî awayî tê nivîsîn lê wek ''/tê/'' tê gotin. Ew serekaniya peyva bi wateya "çay, ça" ya piraniya zimanên Rojavaya Ewropayê ye, bo nimûne: îngilîzî ''{{g|en|tea}}'', fransî ''{{g|fr|thé}}'', almanî ''{{g|de|Tee}}'', spanî ''{{g|es|té}}'', holendî ''[[thee]]'', danmarkî/norwecî/swêdî ''[[te]]'', fînlandî ''[[tee]]''...
Çay ji [[Çîn]]ê li seranserî dinyayê belav bûye. Di rastiyê de teqrîben li tevahiya dinyayê peyveke ji heman peyva çînî wergirtî tê bikaranîn. Sebebê cudahiya peyvên rojhilatî û rojavayî ew e ku yên rojhilatî ji çîniya [[mandarînî]] lê yên rojavayî ji çîniya [[minanî]] hatine wergirtin.
Tevî ku bi giştî peyva bi wateya ''çay, ça'' di zimanên Rojavaya Ewropayê de wek "tea, thé, Tee..." be jî, vê dawiyê bi manaya hinek çayên taybet herwiha forma rojhilatî wek ''[[chai]]'' jî ketiye zimanên Rojavaya Ewropayê jî.
;{{biçûk|Çavkanî
* {{Chyet}}
* {{Wals}}
* {{Tsabolov}}
}}
==== Werger ====
{{werger-ser}}
* {{Z|abx}}: {{W-|abx|simente}}
* {{Z|af}}: {{W+|af|tee}} {{n}}
* {{Z|aht}}: {{W-|aht|tsaey}}
* {{Z|sq}}: {{W+|sq|çaj}} {{n}}
* {{Z|de}}: {{W+|de|Tee|n}}
* {{Z|alt}}: {{W-|alt|чай}}
* {{Z|ast}}: {{W+|ast|te}} {{n}}
* {{Z|bm}}: {{W-|bm|lipton}}
* {{Z|eu}}: {{W+|eu|te}}
* {{Z|ba}}: {{W-|ba|сәй}}
* {{Z|br}}: {{W+|br|te}}
* {{Z|bg}}: {{W+|bg|чай|R=čaj}} {{n}}
* {{Z|cs}}: {{W+|cs|čaj}}
* {{Z|zh}}: {{W+|zh|茶|R=chá}}, {{W+|zh|茶叶|R=cháyè}}
* {{Z|cv}}: {{W-|cv|чей}}
* {{Z|da}}: {{W+|da|te}}
* {{Z|dlg}}: {{W-|dlg|чаай}}
* {{Z|id}}: {{W+|id|teh}}
* {{Z|ar}}: {{W+|ar|شاي|R=şay}} {{n}}
* {{Z|eo}}: {{W+|eo|teo}}
* {{Z|et}}: {{W+|et|tee}}
* {{Z|fa}}: {{W+|fa|چای|tr=çay}}
* {{Z|fo}}: {{W-|fo|te}}
* {{Z|fi}}: {{W+|fi|tee}}
* {{Z|fr}}: {{W+|fr|thé}}
* {{Z|fy}}: {{W-|fy|tee}} {{n}}
* {{Z|gd}}: {{W-|gd|tì}}
* {{Z|gwi}}: {{W-|gwi|lìdii}}
* {{Z|haw}}: {{W-|haw|kī}}
* {{Z|ha}}: {{W+|ha|shayi}}
* {{Z|hi}}: {{W+|hi|चाय|R=chāya}}
* {{Z|nl}}: {{W+|nl|thee}}
* {{Z|hoi}}: {{W-|hoi|tsay}}
* {{Z|io}}: {{W+|io|teo}}
* {{Z|en}}: {{W+|en|tea}}
* {{Z|ia}}: {{W+|ia|the}}
* {{Z|iu}}: {{W-|iu|ᑏ|R=[[tii]]}}
* {{Z|ga}}: {{W+|ga|tae}} {{n}}
* {{Z|it}}: {{W+|it|tè}} {{n}}
* {{Z|is}}: {{W+|is|te}} {{n}}
* {{Z|ja}}: {{W+|ja|茶|R=cha}}
* {{Z|krc}}: {{W-|krc|шай}}
* {{Z|ca}}: {{W+|ca|te}} {{n}}
* {{Z|ky}}: {{W+|ky|чай}}
* {{Z|ko}}: {{W+|ko|차|R=cha}}
* {{Z|co}}: {{W-|co|tè}}
* {{Z|kum}}: {{W-|kum|чай}}
* {{Z|lv}}: {{W+|lv|tēja}} {{mê}}
* {{Z|lt}}: {{W-|lt|arbata}}
* {{Z|lb}}: {{W-|lb|Téi}} {{n}}
* {{Z|mk}}: {{W-|mk|чај}} {{n}}
* {{Z|mg}}: {{W+|mg|dite}}
* {{Z|ms}}: {{W+|ms|teh}}
* {{Z|mt}}: {{W-|mt|te}}
* {{Z|gv}}: {{W-|gv|tey}}
* {{Z|hu}}: {{W+|hu|tea}}
* {{Z|moh}}: {{W-|moh|iekanerahtóhon}}
* {{Z|nap}}: {{W-|nap|ttè}}
* {{Z|nio}}: {{W-|nio|чаи}}
* {{Z|ngh}}: {{W-|ngh|teesi}}
* {{Z|nog}}: {{W-|nog|шай}}
* {{Z|no}}: {{W+|no|te}}
* {{Z|oc}}: {{W+|oc|tè}}
* {{Z|pap}}: {{W-|pap|té}}
* {{Z|pl}}: {{W+|pl|herbata}}
* {{Z|pt}}: {{W+|pt|chá}} {{n}}
* {{Z|kk}}: {{W+|kk|шай|tr=şay}}
* {{Z|ro}}: {{W+|ro|ceai}} {{n}}
* {{Z|ru}}: {{W+|ru|чай|R=tchaï}} {{n}}
* {{Z|se}}: {{W-|se|deadja}}
* {{Z|srn}}: {{W-|srn|te}}
* {{Z|sh}}: {{W+|sh|čaj}} {{n}}
* {{Z|sh}}: {{W+|sh|čaj}} {{n}}
* {{Z|sh}}: {{W-|sh|чај}} {{n}}
* {{Z|sk}}: {{W+|sk|čaj}} {{n}}
* {{Z|sl}}: {{W+|sl|čaj}} {{n}}
* {{Z|ses}}: {{W-|ses|attay}}
* {{Z|es}}: {{W+|es|té}} {{n}}
* {{Z|sw}}: {{W+|sw|chai}}
* {{Z|sv}}: {{W+|sv|te}} {{nt}}
* {{Z|zdj}}: {{W-|zdj|tshai}}
* {{Z|tl}}: {{W-|tl|tsaá}}
* {{Z|th}}: {{W+|th|ชา}}
* {{Z|crh}}: {{W-|crh|çay}}
* {{Z|tt}}: {{W+|tt|чәй}}
* {{Z|tet}}: {{W-|tet|xà}}
* {{Z|tr}}: {{W+|tr|çay}}
* {{Z|tk}}: {{W-|tk|çaý}}
* {{Z|kim}}: {{W-|kim|шэй}}
* {{Z|tyv}}: {{W-|tyv|шай}}
* {{Z|uk}}: {{W+|uk|чай|R=tchaï}} {{n}}
* {{Z|wa}}: {{W+|wa|té}} {{n}}
* {{Z|cy}}: {{W+|cy|te}} {{n}}
* {{Z|kjh}}: {{W-|kjh|чай}}
* {{Z|sah}}: {{W-|sah|чэй}}
* {{Z|el}}: {{W+|el|τσάι|R=tsái}} {{nt}}
* {{Z|zza}}: {{W|zza|çay|m}}
* {{Z|zu}}: {{W+|zu|ilitiye}}, {{W+|zu|itiye}}
{{werger-bin}}
=== Hevok ===
{{hevok|ku}}
# {{f|ku|devokî}} [[çawa]] [[yî]], tu [[çawa]] [[yî]]?
#* {{bêmînak|ku}}
==== Etîmolojî ====
[[ça]] (2) + [[y]] ([[yî]])
==== Werger ====
{{werger-ser}}
{{werger-bin}}
== {{ziman|zza}} ==
=== Navdêr ===
[[Wêne:Rosehiptea.png|thumb|Çay (1)]]
{{navdêr|zza|z=n}}
# {{e|zza|vexwarin}} {{g|ku|çay}}
#* {{bêmînak|ku}}
# {{e|zza|riwek}} {{g|ku|çay}}
#* {{bêmînak|ku}}
== {{ziman|crh}} ==
=== Navdêr ===
{{navdêr|crh}}
# {{f|crh|vexwarin}} [[çay#ku|çay]]
#* {{bêmînak|crh}}
== {{ziman|az}} ==
=== Navdêr ===
{{navdêr|az}}
# {{f|az|erdnîgarî}} {{g|ku|çem}}, {{g|ku|ro}}, {{g|ku|robar}}
#* {{bêmînak|az}}
=== Çavkanî ===
{{rûpela wergerê|az|çem}}
== {{ziman|tr}} ==
=== Bilêvkirin ===
* {{deng|tr|LL-Q256 (tur)-ToprakM-çay.wav|Deng|dever=}}
=== Navdêr ===
{{navdêr|tr}}
# {{g|ku|çay}}, [[ça]]
#* {{bêmînak|tr}}
bodmkj6nr4usxdxl32q2wd0e1syczbx
6347622
6347621
2026-09-01T11:35:18Z
Wikihez
7344
/* Notên bikaranînê */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347622
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/t͡ʃʰɑːj/}}
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Cup of tea, Scotland.jpg|thumb|Fincaneke '''çayê'''. (1)]]
[[Wêne:Teestrauch Detail.jpg|thumb|Riweka '''çayê'''. (2)]]
{{navdêr|ku|z=m}}, {{ç-ya req}}
# {{e|ku|vexwarin}} Vexwarinek e ku bi ava [[kelandin|kelandî]] tê çêkirin û [[reng]]ê wê nêzîkî [[qehweyî]] ye.
#: {{mk|ku|'''Çaya''' tehl/bêşekir, '''çaya''' şîrîn, '''çaya''' zelal, '''çaya''' tarî, '''çaya''' germ, '''çaya''' sar.}}
#: {{mk|ku|Fincaneke '''çayê''', piyaleke '''çayê'''.}}
#: {{mk|ku|Were em '''çayekê''' vexwin.}}
#: {{mk|ku|Hişyar be, '''çay''' germ e, bi xwe de [[riştin|nerêje]]!}}
#* {{jêder|ku|jêgirtin="Di vê bêhnikê de çiqasî dixwest ku çaydanekî '''çayê''' vexwara û bi ser de tam qutiyeke tûtina Xursê bikişanda."|Laleş Qaso: ''Sê şev û sê roj'', roman 2002}}
#* {{jêder-pirtûk|ku|jêgirtin=Got "heyran tu çi zû razayî, ka were em '''çayekê''' vexwin. Ez ji ser cî rabûm min got, "hema ez ji nizanim çawa di xew re çûme."|nivîskar=Mihemed Şarman|sernav=Pirça Winda|cîh=Stembol|weşanxane={{w|Weşanên Avesta|Avesta}}|sal=2016|çap=2|rûpel=82|isbn=978-605-5585-41-9}}
# {{e|ku|riwek}} [[devî|Deviyek]] anku [[teraş]]ek e ku ji [[pel]]ên wê [[vexwarin]]ek tê çêkirin.
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Herwiha binêre ====
{{kol3|ku
|çay [[dem]] kirin
|çay [[îkram]] kirin, çay [[pêşkêş]] kirin
|çay [[kelandin]]
|çay [[tê kirin]]
|çay [[vexwarin]]
}}
==== Bi alfabeyên din====
* {{ku-ar|چای}}
* {{ku-kr|ч'ай}}
==== Formên alternatîv ====
{{kol3|ku
|ça
|çayê<qq:di hin devokan de wek forma ne[[çemandî]]/ne[[tewandî]] jî>
|çey-<qq:di hinek [[peyvên pêkhatî]] anku [[hevedudanî]] de, bo nimûne ''[[çeyxane]]''>
}}
==== Navê zanistî ====
* Navê zanistî yê riwekê: ''[[Camellia sinensis]]''
==== Jê ====
{{kol3|ku
|çaya kesk
|çaya reş
|çaydan
|çaydank
|çaygêr
|çaygêrî
|çayî
|çayvan
|çayvanî
|çayvexwer
|çayxane
|çayxanevan
|çayxanevanî
|çayxwer
|tovça
|tovçay
}}
==== Etîmolojî ====
Herwiha ''[[ça]]'', hevreha soranî {{g|ckb|چای}} û {{g|ckb|چا}}, zazakî ''{{g|zza|çay}}'' û ''{{g|zza|ça}}'', farisî {{g|fa|چای|tr=çay}} û {{g|fa|چا|tr=ça}}, tirkiya osmanî {{g|ota|چای|tr=çay}} û {{g|ota|چا|tr=ça}}, tirkiya niha {{g|tr|çay}}, siryanî [[ܟ݈ܐܝ]] (çay), azerî ''{{g|az|çay}}'', erebî {{g|ar|شای|tr=şay}}, peştûyî {{g|ur|چای|tr=çay}}, ûrdûyî {{g|ur|چای|tr=çay}} û {{g|ur|چا|tr=ça}}, hindî [[चाय]] (çāy)û [[चा]] (çā), {{hv|hy|չայ}} (čʿay), gurcî [[ჩაი]] (čay), {{hv|ru|чай}} (čay), bulgarî [[чай]] (čay), romanî ''[[ceai]]'' (/çay/), tirkmen(istan)î ''[[çaý]]'', qazaxî [[шай]] (şay), ozbekî ''[[choy]]'', albanî ''[[çaj]]'' (/çay/), çekî/kroatî/slovakî/slovenî ''[[čaj]]'' (/çay/), sirbî [[ча̏ј]] (/çay/), portugalî ''{{g|pt|chá}}''... hemû ji {{ji|zh|ku|茶}} (bilêvkirina çîniya [[mandarînî]]: /chá/: çay, ça) û [[茶葉]] (/cháyè/: [[pel]]ên çayê).
Heman peyva çînî di çîniya [[minanî]] de bi eynî awayî tê nivîsîn lê wek ''/tê/'' tê gotin. Ew serekaniya peyva bi wateya "çay, ça" ya piraniya zimanên Rojavaya Ewropayê ye, bo nimûne: îngilîzî ''{{g|en|tea}}'', fransî ''{{g|fr|thé}}'', almanî ''{{g|de|Tee}}'', spanî ''{{g|es|té}}'', holendî ''[[thee]]'', danmarkî/norwecî/swêdî ''[[te]]'', fînlandî ''[[tee]]''...
Çay ji [[Çîn]]ê li seranserî dinyayê belav bûye. Di rastiyê de teqrîben li tevahiya dinyayê peyveke ji heman peyva çînî wergirtî tê bikaranîn. Sebebê cudahiya peyvên rojhilatî û rojavayî ew e ku yên rojhilatî ji çîniya [[mandarînî]] lê yên rojavayî ji çîniya [[minanî]] hatine wergirtin.
Tevî ku bi giştî peyva bi wateya ''çay, ça'' di zimanên Rojavaya Ewropayê de wek "tea, thé, Tee..." be jî, vê dawiyê bi manaya hinek çayên taybet herwiha forma rojhilatî wek ''[[chai]]'' jî ketiye zimanên Rojavaya Ewropayê jî.
;{{biçûk|Çavkanî
* {{Chyet}}
* {{Wals}}
* {{Tsabolov}}
}}
==== Werger ====
{{werger-ser}}
* {{Z|abx}}: {{W-|abx|simente}}
* {{Z|af}}: {{W+|af|tee}} {{n}}
* {{Z|aht}}: {{W-|aht|tsaey}}
* {{Z|sq}}: {{W+|sq|çaj}} {{n}}
* {{Z|de}}: {{W+|de|Tee|n}}
* {{Z|alt}}: {{W-|alt|чай}}
* {{Z|ast}}: {{W+|ast|te}} {{n}}
* {{Z|bm}}: {{W-|bm|lipton}}
* {{Z|eu}}: {{W+|eu|te}}
* {{Z|ba}}: {{W-|ba|сәй}}
* {{Z|br}}: {{W+|br|te}}
* {{Z|bg}}: {{W+|bg|чай|R=čaj}} {{n}}
* {{Z|cs}}: {{W+|cs|čaj}}
* {{Z|zh}}: {{W+|zh|茶|R=chá}}, {{W+|zh|茶叶|R=cháyè}}
* {{Z|cv}}: {{W-|cv|чей}}
* {{Z|da}}: {{W+|da|te}}
* {{Z|dlg}}: {{W-|dlg|чаай}}
* {{Z|id}}: {{W+|id|teh}}
* {{Z|ar}}: {{W+|ar|شاي|R=şay}} {{n}}
* {{Z|eo}}: {{W+|eo|teo}}
* {{Z|et}}: {{W+|et|tee}}
* {{Z|fa}}: {{W+|fa|چای|tr=çay}}
* {{Z|fo}}: {{W-|fo|te}}
* {{Z|fi}}: {{W+|fi|tee}}
* {{Z|fr}}: {{W+|fr|thé}}
* {{Z|fy}}: {{W-|fy|tee}} {{n}}
* {{Z|gd}}: {{W-|gd|tì}}
* {{Z|gwi}}: {{W-|gwi|lìdii}}
* {{Z|haw}}: {{W-|haw|kī}}
* {{Z|ha}}: {{W+|ha|shayi}}
* {{Z|hi}}: {{W+|hi|चाय|R=chāya}}
* {{Z|nl}}: {{W+|nl|thee}}
* {{Z|hoi}}: {{W-|hoi|tsay}}
* {{Z|io}}: {{W+|io|teo}}
* {{Z|en}}: {{W+|en|tea}}
* {{Z|ia}}: {{W+|ia|the}}
* {{Z|iu}}: {{W-|iu|ᑏ|R=[[tii]]}}
* {{Z|ga}}: {{W+|ga|tae}} {{n}}
* {{Z|it}}: {{W+|it|tè}} {{n}}
* {{Z|is}}: {{W+|is|te}} {{n}}
* {{Z|ja}}: {{W+|ja|茶|R=cha}}
* {{Z|krc}}: {{W-|krc|шай}}
* {{Z|ca}}: {{W+|ca|te}} {{n}}
* {{Z|ky}}: {{W+|ky|чай}}
* {{Z|ko}}: {{W+|ko|차|R=cha}}
* {{Z|co}}: {{W-|co|tè}}
* {{Z|kum}}: {{W-|kum|чай}}
* {{Z|lv}}: {{W+|lv|tēja}} {{mê}}
* {{Z|lt}}: {{W-|lt|arbata}}
* {{Z|lb}}: {{W-|lb|Téi}} {{n}}
* {{Z|mk}}: {{W-|mk|чај}} {{n}}
* {{Z|mg}}: {{W+|mg|dite}}
* {{Z|ms}}: {{W+|ms|teh}}
* {{Z|mt}}: {{W-|mt|te}}
* {{Z|gv}}: {{W-|gv|tey}}
* {{Z|hu}}: {{W+|hu|tea}}
* {{Z|moh}}: {{W-|moh|iekanerahtóhon}}
* {{Z|nap}}: {{W-|nap|ttè}}
* {{Z|nio}}: {{W-|nio|чаи}}
* {{Z|ngh}}: {{W-|ngh|teesi}}
* {{Z|nog}}: {{W-|nog|шай}}
* {{Z|no}}: {{W+|no|te}}
* {{Z|oc}}: {{W+|oc|tè}}
* {{Z|pap}}: {{W-|pap|té}}
* {{Z|pl}}: {{W+|pl|herbata}}
* {{Z|pt}}: {{W+|pt|chá}} {{n}}
* {{Z|kk}}: {{W+|kk|шай|tr=şay}}
* {{Z|ro}}: {{W+|ro|ceai}} {{n}}
* {{Z|ru}}: {{W+|ru|чай|R=tchaï}} {{n}}
* {{Z|se}}: {{W-|se|deadja}}
* {{Z|srn}}: {{W-|srn|te}}
* {{Z|sh}}: {{W+|sh|čaj}} {{n}}
* {{Z|sh}}: {{W+|sh|čaj}} {{n}}
* {{Z|sh}}: {{W-|sh|чај}} {{n}}
* {{Z|sk}}: {{W+|sk|čaj}} {{n}}
* {{Z|sl}}: {{W+|sl|čaj}} {{n}}
* {{Z|ses}}: {{W-|ses|attay}}
* {{Z|es}}: {{W+|es|té}} {{n}}
* {{Z|sw}}: {{W+|sw|chai}}
* {{Z|sv}}: {{W+|sv|te}} {{nt}}
* {{Z|zdj}}: {{W-|zdj|tshai}}
* {{Z|tl}}: {{W-|tl|tsaá}}
* {{Z|th}}: {{W+|th|ชา}}
* {{Z|crh}}: {{W-|crh|çay}}
* {{Z|tt}}: {{W+|tt|чәй}}
* {{Z|tet}}: {{W-|tet|xà}}
* {{Z|tr}}: {{W+|tr|çay}}
* {{Z|tk}}: {{W-|tk|çaý}}
* {{Z|kim}}: {{W-|kim|шэй}}
* {{Z|tyv}}: {{W-|tyv|шай}}
* {{Z|uk}}: {{W+|uk|чай|R=tchaï}} {{n}}
* {{Z|wa}}: {{W+|wa|té}} {{n}}
* {{Z|cy}}: {{W+|cy|te}} {{n}}
* {{Z|kjh}}: {{W-|kjh|чай}}
* {{Z|sah}}: {{W-|sah|чэй}}
* {{Z|el}}: {{W+|el|τσάι|R=tsái}} {{nt}}
* {{Z|zza}}: {{W|zza|çay|m}}
* {{Z|zu}}: {{W+|zu|ilitiye}}, {{W+|zu|itiye}}
{{werger-bin}}
=== Hevok ===
{{hevok|ku}}
# {{f|ku|devokî}} [[çawa]] [[yî]], tu [[çawa]] [[yî]]?
#* {{bêmînak|ku}}
==== Etîmolojî ====
[[ça]] (2) + [[y]] ([[yî]])
==== Werger ====
{{werger-ser}}
{{werger-bin}}
== {{ziman|zza}} ==
=== Navdêr ===
[[Wêne:Rosehiptea.png|thumb|Çay (1)]]
{{navdêr|zza|z=n}}
# {{e|zza|vexwarin}} {{g|ku|çay}}
#* {{bêmînak|ku}}
# {{e|zza|riwek}} {{g|ku|çay}}
#* {{bêmînak|ku}}
== {{ziman|crh}} ==
=== Navdêr ===
{{navdêr|crh}}
# {{f|crh|vexwarin}} [[çay#ku|çay]]
#* {{bêmînak|crh}}
== {{ziman|az}} ==
=== Navdêr ===
{{navdêr|az}}
# {{f|az|erdnîgarî}} {{g|ku|çem}}, {{g|ku|ro}}, {{g|ku|robar}}
#* {{bêmînak|az}}
=== Çavkanî ===
{{rûpela wergerê|az|çem}}
== {{ziman|tr}} ==
=== Bilêvkirin ===
* {{deng|tr|LL-Q256 (tur)-ToprakM-çay.wav|Deng|dever=}}
=== Navdêr ===
{{navdêr|tr}}
# {{g|ku|çay}}, [[ça]]
#* {{bêmînak|tr}}
3j9f6nglqk4bzainbatmgeb2nn2ixir
6347626
6347622
2026-09-01T11:41:07Z
Balyozbot
7867
[[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan
6347626
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/t͡ʃʰɑːj/}}
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Cup of tea, Scotland.jpg|thumb|Fincaneke '''çayê'''. (1)]]
[[Wêne:Teestrauch Detail.jpg|thumb|Riweka '''çayê'''. (2)]]
{{navdêr|ku|z=m}}, {{ç-ya req}}
# {{e|ku|vexwarin}} Vexwarinek e ku bi ava [[kelandin|kelandî]] tê çêkirin û [[reng]]ê wê nêzîkî [[qehweyî]] ye.
#: {{mk|ku|'''Çaya''' tehl/bêşekir, '''çaya''' şîrîn, '''çaya''' zelal, '''çaya''' tarî, '''çaya''' germ, '''çaya''' sar.}}
#: {{mk|ku|Fincaneke '''çayê''', piyaleke '''çayê'''.}}
#: {{mk|ku|Were em '''çayekê''' vexwin.}}
#: {{mk|ku|Hişyar be, '''çay''' germ e, bi xwe de [[riştin|nerêje]]!}}
#* {{jêder|ku|jêgirtin="Di vê bêhnikê de çiqasî dixwest ku çaydanekî '''çayê''' vexwara û bi ser de tam qutiyeke tûtina Xursê bikişanda."|Laleş Qaso: ''Sê şev û sê roj'', roman 2002}}
#* {{jêder-pirtûk|ku|jêgirtin=Got "heyran tu çi zû razayî, ka were em '''çayekê''' vexwin. Ez ji ser cî rabûm min got, "hema ez ji nizanim çawa di xew re çûme."|nivîskar=Mihemed Şarman|sernav=Pirça Winda|cîh=Stembol|weşanxane={{w|Weşanên Avesta|Avesta}}|sal=2016|çap=2|rûpel=82|isbn=978-605-5585-41-9}}
# {{e|ku|riwek}} [[devî|Deviyek]] anku [[teraş]]ek e ku ji [[pel]]ên wê [[vexwarin]]ek tê çêkirin.
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Bi alfabeyên din====
* {{ku-ar|چای}}
* {{ku-kr|ч'ай}}
==== Formên alternatîv ====
{{kol3|ku
|ça
|çayê<qq:di hin devokan de wek forma ne[[çemandî]]/ne[[tewandî]] jî>
|çey-<qq:di hinek [[peyvên pêkhatî]] anku [[hevedudanî]] de, bo nimûne ''[[çeyxane]]''>
}}
==== Navê zanistî ====
* Navê zanistî yê riwekê: ''[[Camellia sinensis]]''
==== Jê ====
{{kol3|ku
|çaya kesk
|çaya reş
|çaydan
|çaydank
|çaygêr
|çaygêrî
|çayî
|çayvan
|çayvanî
|çayvexwer
|çayxane
|çayxanevan
|çayxanevanî
|çayxwer
|tovça
|tovçay
}}
==== Etîmolojî ====
Herwiha ''[[ça]]'', hevreha soranî {{g|ckb|چای}} û {{g|ckb|چا}}, zazakî ''{{g|zza|çay}}'' û ''{{g|zza|ça}}'', farisî {{g|fa|چای|tr=çay}} û {{g|fa|چا|tr=ça}}, tirkiya osmanî {{g|ota|چای|tr=çay}} û {{g|ota|چا|tr=ça}}, tirkiya niha {{g|tr|çay}}, siryanî [[ܟ݈ܐܝ]] (çay), azerî ''{{g|az|çay}}'', erebî {{g|ar|شای|tr=şay}}, peştûyî {{g|ur|چای|tr=çay}}, ûrdûyî {{g|ur|چای|tr=çay}} û {{g|ur|چا|tr=ça}}, hindî [[चाय]] (çāy)û [[चा]] (çā), {{hv|hy|չայ}} (čʿay), gurcî [[ჩაი]] (čay), {{hv|ru|чай}} (čay), bulgarî [[чай]] (čay), romanî ''[[ceai]]'' (/çay/), tirkmen(istan)î ''[[çaý]]'', qazaxî [[шай]] (şay), ozbekî ''[[choy]]'', albanî ''[[çaj]]'' (/çay/), çekî/kroatî/slovakî/slovenî ''[[čaj]]'' (/çay/), sirbî [[ча̏ј]] (/çay/), portugalî ''{{g|pt|chá}}''... hemû ji {{ji|zh|ku|茶}} (bilêvkirina çîniya [[mandarînî]]: /chá/: çay, ça) û [[茶葉]] (/cháyè/: [[pel]]ên çayê).
Heman peyva çînî di çîniya [[minanî]] de bi eynî awayî tê nivîsîn lê wek ''/tê/'' tê gotin. Ew serekaniya peyva bi wateya "çay, ça" ya piraniya zimanên Rojavaya Ewropayê ye, bo nimûne: îngilîzî ''{{g|en|tea}}'', fransî ''{{g|fr|thé}}'', almanî ''{{g|de|Tee}}'', spanî ''{{g|es|té}}'', holendî ''[[thee]]'', danmarkî/norwecî/swêdî ''[[te]]'', fînlandî ''[[tee]]''...
Çay ji [[Çîn]]ê li seranserî dinyayê belav bûye. Di rastiyê de teqrîben li tevahiya dinyayê peyveke ji heman peyva çînî wergirtî tê bikaranîn. Sebebê cudahiya peyvên rojhilatî û rojavayî ew e ku yên rojhilatî ji çîniya [[mandarînî]] lê yên rojavayî ji çîniya [[minanî]] hatine wergirtin.
Tevî ku bi giştî peyva bi wateya ''çay, ça'' di zimanên Rojavaya Ewropayê de wek "tea, thé, Tee..." be jî, vê dawiyê bi manaya hinek çayên taybet herwiha forma rojhilatî wek ''[[chai]]'' jî ketiye zimanên Rojavaya Ewropayê jî.
;{{biçûk|Çavkanî
* {{Chyet}}
* {{Wals}}
* {{Tsabolov}}
}}
==== Herwiha binêre ====
{{kol3|ku
|çay [[dem]] kirin
|çay [[îkram]] kirin, çay [[pêşkêş]] kirin
|çay [[kelandin]]
|çay [[tê kirin]]
|çay [[vexwarin]]
}}
==== Werger ====
{{werger-ser}}
* {{Z|abx}}: {{W-|abx|simente}}
* {{Z|af}}: {{W+|af|tee}} {{n}}
* {{Z|aht}}: {{W-|aht|tsaey}}
* {{Z|sq}}: {{W+|sq|çaj}} {{n}}
* {{Z|de}}: {{W+|de|Tee|n}}
* {{Z|alt}}: {{W-|alt|чай}}
* {{Z|ast}}: {{W+|ast|te}} {{n}}
* {{Z|bm}}: {{W-|bm|lipton}}
* {{Z|eu}}: {{W+|eu|te}}
* {{Z|ba}}: {{W-|ba|сәй}}
* {{Z|br}}: {{W+|br|te}}
* {{Z|bg}}: {{W+|bg|чай|R=čaj}} {{n}}
* {{Z|cs}}: {{W+|cs|čaj}}
* {{Z|zh}}: {{W+|zh|茶|R=chá}}, {{W+|zh|茶叶|R=cháyè}}
* {{Z|cv}}: {{W-|cv|чей}}
* {{Z|da}}: {{W+|da|te}}
* {{Z|dlg}}: {{W-|dlg|чаай}}
* {{Z|id}}: {{W+|id|teh}}
* {{Z|ar}}: {{W+|ar|شاي|R=şay}} {{n}}
* {{Z|eo}}: {{W+|eo|teo}}
* {{Z|et}}: {{W+|et|tee}}
* {{Z|fa}}: {{W+|fa|چای|tr=çay}}
* {{Z|fo}}: {{W-|fo|te}}
* {{Z|fi}}: {{W+|fi|tee}}
* {{Z|fr}}: {{W+|fr|thé}}
* {{Z|fy}}: {{W-|fy|tee}} {{n}}
* {{Z|gd}}: {{W-|gd|tì}}
* {{Z|gwi}}: {{W-|gwi|lìdii}}
* {{Z|haw}}: {{W-|haw|kī}}
* {{Z|ha}}: {{W+|ha|shayi}}
* {{Z|hi}}: {{W+|hi|चाय|R=chāya}}
* {{Z|nl}}: {{W+|nl|thee}}
* {{Z|hoi}}: {{W-|hoi|tsay}}
* {{Z|io}}: {{W+|io|teo}}
* {{Z|en}}: {{W+|en|tea}}
* {{Z|ia}}: {{W+|ia|the}}
* {{Z|iu}}: {{W-|iu|ᑏ|R=[[tii]]}}
* {{Z|ga}}: {{W+|ga|tae}} {{n}}
* {{Z|it}}: {{W+|it|tè}} {{n}}
* {{Z|is}}: {{W+|is|te}} {{n}}
* {{Z|ja}}: {{W+|ja|茶|R=cha}}
* {{Z|krc}}: {{W-|krc|шай}}
* {{Z|ca}}: {{W+|ca|te}} {{n}}
* {{Z|ky}}: {{W+|ky|чай}}
* {{Z|ko}}: {{W+|ko|차|R=cha}}
* {{Z|co}}: {{W-|co|tè}}
* {{Z|kum}}: {{W-|kum|чай}}
* {{Z|lv}}: {{W+|lv|tēja}} {{mê}}
* {{Z|lt}}: {{W-|lt|arbata}}
* {{Z|lb}}: {{W-|lb|Téi}} {{n}}
* {{Z|mk}}: {{W-|mk|чај}} {{n}}
* {{Z|mg}}: {{W+|mg|dite}}
* {{Z|ms}}: {{W+|ms|teh}}
* {{Z|mt}}: {{W-|mt|te}}
* {{Z|gv}}: {{W-|gv|tey}}
* {{Z|hu}}: {{W+|hu|tea}}
* {{Z|moh}}: {{W-|moh|iekanerahtóhon}}
* {{Z|nap}}: {{W-|nap|ttè}}
* {{Z|nio}}: {{W-|nio|чаи}}
* {{Z|ngh}}: {{W-|ngh|teesi}}
* {{Z|nog}}: {{W-|nog|шай}}
* {{Z|no}}: {{W+|no|te}}
* {{Z|oc}}: {{W+|oc|tè}}
* {{Z|pap}}: {{W-|pap|té}}
* {{Z|pl}}: {{W+|pl|herbata}}
* {{Z|pt}}: {{W+|pt|chá}} {{n}}
* {{Z|kk}}: {{W+|kk|шай|tr=şay}}
* {{Z|ro}}: {{W+|ro|ceai}} {{n}}
* {{Z|ru}}: {{W+|ru|чай|R=tchaï}} {{n}}
* {{Z|se}}: {{W-|se|deadja}}
* {{Z|srn}}: {{W-|srn|te}}
* {{Z|sh}}: {{W+|sh|čaj}} {{n}}
* {{Z|sh}}: {{W+|sh|čaj}} {{n}}
* {{Z|sh}}: {{W-|sh|чај}} {{n}}
* {{Z|sk}}: {{W+|sk|čaj}} {{n}}
* {{Z|sl}}: {{W+|sl|čaj}} {{n}}
* {{Z|ses}}: {{W-|ses|attay}}
* {{Z|es}}: {{W+|es|té}} {{n}}
* {{Z|sw}}: {{W+|sw|chai}}
* {{Z|sv}}: {{W+|sv|te}} {{nt}}
* {{Z|zdj}}: {{W-|zdj|tshai}}
* {{Z|tl}}: {{W-|tl|tsaá}}
* {{Z|th}}: {{W+|th|ชา}}
* {{Z|crh}}: {{W-|crh|çay}}
* {{Z|tt}}: {{W+|tt|чәй}}
* {{Z|tet}}: {{W-|tet|xà}}
* {{Z|tr}}: {{W+|tr|çay}}
* {{Z|tk}}: {{W-|tk|çaý}}
* {{Z|kim}}: {{W-|kim|шэй}}
* {{Z|tyv}}: {{W-|tyv|шай}}
* {{Z|uk}}: {{W+|uk|чай|R=tchaï}} {{n}}
* {{Z|wa}}: {{W+|wa|té}} {{n}}
* {{Z|cy}}: {{W+|cy|te}} {{n}}
* {{Z|kjh}}: {{W-|kjh|чай}}
* {{Z|sah}}: {{W-|sah|чэй}}
* {{Z|el}}: {{W+|el|τσάι|R=tsái}} {{nt}}
* {{Z|zza}}: {{W|zza|çay|m}}
* {{Z|zu}}: {{W+|zu|ilitiye}}, {{W+|zu|itiye}}
{{werger-bin}}
=== Hevok ===
{{hevok|ku}}
# {{f|ku|devokî}} [[çawa]] [[yî]], tu [[çawa]] [[yî]]?
#* {{bêmînak|ku}}
==== Etîmolojî ====
[[ça]] (2) + [[y]] ([[yî]])
==== Werger ====
{{werger-ser}}
{{werger-bin}}
== {{ziman|zza}} ==
=== Navdêr ===
[[Wêne:Rosehiptea.png|thumb|Çay (1)]]
{{navdêr|zza|z=n}}
# {{e|zza|vexwarin}} {{g|ku|çay}}
#* {{bêmînak|ku}}
# {{e|zza|riwek}} {{g|ku|çay}}
#* {{bêmînak|ku}}
== {{ziman|crh}} ==
=== Navdêr ===
{{navdêr|crh}}
# {{f|crh|vexwarin}} [[çay#ku|çay]]
#* {{bêmînak|crh}}
== {{ziman|az}} ==
=== Navdêr ===
{{navdêr|az}}
# {{f|az|erdnîgarî}} {{g|ku|çem}}, {{g|ku|ro}}, {{g|ku|robar}}
#* {{bêmînak|az}}
=== Çavkanî ===
{{rûpela wergerê|az|çem}}
== {{ziman|tr}} ==
=== Bilêvkirin ===
* {{deng|tr|LL-Q256 (tur)-ToprakM-çay.wav|Deng|dever=}}
=== Navdêr ===
{{navdêr|tr}}
# {{g|ku|çay}}, [[ça]]
#* {{bêmînak|tr}}
a2kza10jj1h0607fujqsyz47th72so2
gernas
0
16935
6347424
6293868
2026-08-31T18:28:11Z
Wikihez
7344
/* Etîmolojî */
6347424
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/ɡæɾˈnɑːs/}}
* {{deng|ku|LL-Q36163 (kmr)-Key Mîrza-gernas.wav|dever=Bidlîs}}
* {{ku-kîte}}
=== Rengdêr ===
{{ku-tewîn-rd|gernas}}
{{rengdêr|ku}} {{r-ya req}}
# [[çeleng]], [[fêris]], [[aza]], [[egîd]], [[çalak]], [[zîrek]], [[wêrek]], [[qehreman]], [[mêrxas]]
#* {{bêmînak|ku}}
# {{kontrol|rêz=erê|[[palewan]], [[xweşmêr]], [[biste]], [[netirs]], [[bêtirs]], [[jîr]], [[camêr]]}}
==== Bi alfabeyên din ====
* {{ku-ar|گهرناس}}
==== Jê ====
{{kol3|ku|cure=Jê
|gernasane
|gernasî
|gernasîtî
|gernastî
|gernas bûn<pos:lêker>
|gernas kirin<pos:lêker>
|gernasbûn<pos:navdêr>
|gernaskirin<pos:navdêr>
|gernasbûyî<pos:rengdêr>
|gernaskirî<pos:rengdêr>
}}
==== Etîmolojî ====
Ji {{paş|ku|ger|-nas}}. Hevrreha {{hv|ckb|گەڕناس|w=gerrnas, şerrvan, wêrek}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|mutig}}, {{W|de|Wanderbursch|guman=erê}}, {{W|de|Vagabund|guman=erê}}, {{W|de|Wanderer|guman=erê}}
* {{Z|fa}}: {{W|fa|قهرمان}}, {{W|fa|شجاع}}
* {{Z|en}}: {{W|en|hero}}, {{W|en|paladin}}
* {{Z|tr}}: {{W|tr|kahraman}}, {{W|tr|böke}}, {{W|tr|yiğit}}
{{werger-bin}}
p10ctmgjd0h5xo2g0uxt10jlsu4b1al
meşk
0
17980
6347457
6312202
2026-08-31T19:44:19Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347457
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-meşk.wav|dever=Bidlîs}}
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:ButterMakingPalestine1914.jpg|thumb|250px|Çend kes '''meşkê''' [[kan|dikên]] anku [[kilandin|dikilînin]].]]
{{navdêr|ku|z=m}}
# [[kil]], [[post]]ê [[sewal]]an yê ku [[şîr]] tê de tê [[kan]] / [[kilandin]] anku [[şilqandin]] daku [[nîvişk]] bi ser [[ketin|bikeve]]
#* {{bêmînak|ku}}
# {{f|ku|henekî}} [[beş|Beş]]ê [[leş]]î yê ku dikeve [[navber]]a [[sîng]]î û [[navteng]]ê; [[cih]]ê ku [[xwarin]]a xwarî diçe tê de.
#: {{hevmane|ku|zik|ûr}}
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Bi alfabeyên din ====
* {{ku-ar|مهشک}}
* {{ku-kr|мәшк}}
==== Jê ====
{{kol3|ku
|meşk kan<crz:lêker>
|meşk kilandin<crz:lêker>
|meşkkan<crz:navdêr>
|meşkkilandin<crz:navdêr>
|meşkî
|meşko
|meşkvan
|meşkvanî
|zikmeşk
|zikmeşkî
}}
==== Têkildar ====
{{kol3|ku
|himban
|kune
}}
==== Etîmolojî ====
Hevreha soranî {{g|ckb|مهشک}} û {{g|ckb|مهشکه|tr=meşke}}, [[kurdiya başûrî]] ''[[meşke]]'', farisî {{g|fa|مشک|tr=meşk}}, {{hv|pal||meşk|sc=Latn}}, hexamenişî {{g|peo|𐎶𐏁𐎣𐎠|tr=meşka-}}, hindî [[मशक]] (maśak), tirkiya osmanî {{g|ota|مشك|tr=meşk}}, ermeniya kevn [[մաշկ]] (maşk), {{hv|grc|μέσκος}} (méskos), yûnaniya kapadokî [[μάσκι]] (máski), gurciya kevn [[მაშკი]] (maşki)... hemû ji {{ji|arc}} [[ܡܫܟܐ]] (meşka), hevreha erebî {{g|ar|مسك}} (mesk), {{hv|he|משך}} (meşek), akadî [[𒋢]] (mašku [KUŠ]), misriya kevn <hiero>ms-kA-F27</hiero> ([[msk3]])... hemû ji [[proto-afroasyayî]] *''[[masak-]]''.
Eslê peyvê di zimanên [[afroasyayî]] de bi wateya giştî ya ''[[post]] / [[pîst]]'' e lê di zimanên din de wê wateyeke bertengtir û taybetî wergirtiye.
==== Bide ber ====
{{kol3|ku
|meşq
|mişk
}}
==== Werger ====
{{werger-ser}}
* {{Z|br}}: {{W+|br|ribod}}
* {{Z|cs}}: {{W|cs|máselnice}}
* {{Z|de}}: {{W+|de|Butterfass}} {{nt}}
* {{Z|ar}}: {{W|ar|إبریج}}
* {{Z|fa}}: {{W|fa|مشک}}
* {{Z|en}}: {{W+|en|churner}}
* {{Z|co}}: {{W-|co|battitoghju|n}}, {{W-|co|zancula|f}}
* {{Z|es}}: {{W-|es|mantequera}}
* {{Z|eo}}: {{W-|eo|buterigilo}}
* {{Z|fi}}: {{W+|fi|kirnu}}
* {{Z|fr}}: {{W+|fr|barrate}}
* {{Z|it}}: {{W+|it|zangola}}
* {{Z|lb}}: {{W-|lb|rompfaass}}
* {{Z|nl}}: {{W-|nl|karnmachine}}, {{W+|nl|karn}}, {{W-|nl|karnton}}
* {{Z|oc}}: {{W-|oc|burrièra}}, {{W-|oc|batador}}
* {{Z|pcd}}: {{W--|pcd|cheraine}}
* {{Z|pt}}: {{W-|pt|batedeira}}
* {{Z|ru}}: {{W+|ru|маслобойка}}
* {{Z|es}}: {{W|es|mantequera}}
* {{Z|tr}}: {{W|tr|yayık}}, {{W|tr|tulum}}
{{werger-bin}}
== {{ziman|tr}} ==
=== Navdêr ===
{{navdêr|tr}}
# [[meşq]]
#* {{bêmînak|tr}}
# [[heng]], [[bezm]]
#* {{bêmînak|tr}}
t8bz4tj453gu2aswlftkaqfggyb0k5d
6347490
6347457
2026-08-31T21:12:11Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347490
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-meşk.wav|dever=Bidlîs}}
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:ButterMakingPalestine1914.jpg|thumb|250px|Çend kes '''meşkê''' [[kan|dikên]] anku [[kilandin|dikilînin]].]]
{{navdêr|ku|z=m}}
# [[kil]], [[post]]ê [[sewal]]an yê ku [[şîr]] tê de tê [[kan]] / [[kilandin]] anku [[şilqandin]] daku [[nîvişk]] bi ser [[ketin|bikeve]]
#* {{bêmînak|ku}}
# {{f|ku|henekî}} [[beş|Beşê]] [[leş]]î yê ku dikeve [[navber]]a [[sîng]]î û [[navteng]]ê; [[cih]]ê ku [[xwarin]]a xwarî diçe tê de.
#: {{hevmane|ku|zik|ûr}}
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Bi alfabeyên din ====
* {{ku-ar|مهشک}}
* {{ku-kr|мәшк}}
==== Jê ====
{{kol3|ku
|meşk kan<crz:lêker>
|meşk kilandin<crz:lêker>
|meşkkan<crz:navdêr>
|meşkkilandin<crz:navdêr>
|meşkî
|meşko
|meşkvan
|meşkvanî
|zikmeşk
|zikmeşkî
}}
==== Têkildar ====
{{kol3|ku
|himban
|kune
}}
==== Etîmolojî ====
Hevreha soranî {{g|ckb|مهشک}} û {{g|ckb|مهشکه|tr=meşke}}, [[kurdiya başûrî]] ''[[meşke]]'', farisî {{g|fa|مشک|tr=meşk}}, {{hv|pal||meşk|sc=Latn}}, hexamenişî {{g|peo|𐎶𐏁𐎣𐎠|tr=meşka-}}, hindî [[मशक]] (maśak), tirkiya osmanî {{g|ota|مشك|tr=meşk}}, ermeniya kevn [[մաշկ]] (maşk), {{hv|grc|μέσκος}} (méskos), yûnaniya kapadokî [[μάσκι]] (máski), gurciya kevn [[მაშკი]] (maşki)... hemû ji {{ji|arc}} [[ܡܫܟܐ]] (meşka), hevreha erebî {{g|ar|مسك}} (mesk), {{hv|he|משך}} (meşek), akadî [[𒋢]] (mašku [KUŠ]), misriya kevn <hiero>ms-kA-F27</hiero> ([[msk3]])... hemû ji [[proto-afroasyayî]] *''[[masak-]]''.
Eslê peyvê di zimanên [[afroasyayî]] de bi wateya giştî ya ''[[post]] / [[pîst]]'' e lê di zimanên din de wê wateyeke bertengtir û taybetî wergirtiye.
==== Bide ber ====
{{kol3|ku
|meşq
|mişk
}}
==== Werger ====
{{werger-ser}}
* {{Z|br}}: {{W+|br|ribod}}
* {{Z|cs}}: {{W|cs|máselnice}}
* {{Z|de}}: {{W+|de|Butterfass}} {{nt}}
* {{Z|ar}}: {{W|ar|إبریج}}
* {{Z|fa}}: {{W|fa|مشک}}
* {{Z|en}}: {{W+|en|churner}}
* {{Z|co}}: {{W-|co|battitoghju|n}}, {{W-|co|zancula|f}}
* {{Z|es}}: {{W-|es|mantequera}}
* {{Z|eo}}: {{W-|eo|buterigilo}}
* {{Z|fi}}: {{W+|fi|kirnu}}
* {{Z|fr}}: {{W+|fr|barrate}}
* {{Z|it}}: {{W+|it|zangola}}
* {{Z|lb}}: {{W-|lb|rompfaass}}
* {{Z|nl}}: {{W-|nl|karnmachine}}, {{W+|nl|karn}}, {{W-|nl|karnton}}
* {{Z|oc}}: {{W-|oc|burrièra}}, {{W-|oc|batador}}
* {{Z|pcd}}: {{W--|pcd|cheraine}}
* {{Z|pt}}: {{W-|pt|batedeira}}
* {{Z|ru}}: {{W+|ru|маслобойка}}
* {{Z|es}}: {{W|es|mantequera}}
* {{Z|tr}}: {{W|tr|yayık}}, {{W|tr|tulum}}
{{werger-bin}}
== {{ziman|tr}} ==
=== Navdêr ===
{{navdêr|tr}}
# [[meşq]]
#* {{bêmînak|tr}}
# [[heng]], [[bezm]]
#* {{bêmînak|tr}}
fhhtzz4jl4suvscoxmfo2qf8uhzchee
lot
0
17983
6347458
6335849
2026-08-31T19:47:24Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347458
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[bilind|Bilind]]kirin û [[hejandin]]a [[ling]]ên xwe.
#: {{hevmane|ku|zîtik|pên|pehîn|zîçik}}
#* {{bênimûne|ku}}
# Bazdana berxika ku dileyize
#* {{bênimûne|ku}}
==== Ji wêjeya klasîk ====
* {{J:Mem û Zîn:1692|jêgirtin=Her bengî û serxweşê di Botan</br>Têk hatine çerx û baz û '''lot'''an</br>Bêrîte sema û saz û govend}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Formên alternatîv ====
{{kol3|ku
|lotik
|lotk
}}
==== Jê ====
{{kol3|ku
|lotik avêtin<crz:lêker>
|lotavêj
|lotavêjî
|lotikane
|lotikavêj
|lotikavêjî
|lotikî
|lotî
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|Sprung|m}}
* {{Z|fa}}: {{W+|fa|حرکت تند}}, {{W+|fa|لگد پراندن}}
* {{Z|en}}: {{W+|en|skip}}
* {{Z|tr}}: {{W+|tr|zıplama}}, {{W+|tr|hoplama}}, {{W+|tr|iskandil}}
{{werger-bin}}
== {{ziman|sq}} ==
=== Navdêr ===
{{navdêr|sq|z=m}}
# {{g|ku|hêsir}}, {{g|ku|rondik}}
#* {{bênimûne|sq}}
=== Çavkanî ===
{{rûpela wergerê|sq|hêsir}}
== {{ziman|nl}} ==
=== Navdêr ===
{{navdêr|nl|z=nt}}
# {{g|ku|qeder}}, {{g|ku|qismet}}, {{g|ku|nesîb}}
#* {{bênimûne|nl}}
=== Çavkanî ===
{{rûpela wergerê|nl|qeder}}
== {{ziman|en}} ==
=== Bilêvkirin ===
* {{deng|en|en-us-lot.ogg|dever=DYA}}
* {{deng|en|En-uk-a lot.ogg|dever=QY}}
* {{deng|en|LL-Q1860 (eng)-Back ache-lot.wav|Deng|dever=London,QY}}
* {{deng|en|LL-Q1860 (eng)-Nattes à chat-lot.wav|Deng|dever=}}
* {{deng|en|LL-Q1860 (eng)-Wodencafe-lot.wav|Deng|dever=Teksas, DYA}}
=== Rengdêr ===
{{rengdêr|en}}
# [[gelek]], [[pirr]], [[zehf]], [[mişe]]
#* {{bênimûne|en}}
=== Navdêr ===
{{navdêr|en}}
# [[par]], [[hise]]
#* {{bênimûne|en}}
asonsujndx0difd06k8le7ffenc1m2i
6347489
6347458
2026-08-31T21:12:08Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347489
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[bilind|Bilindkirin]] û [[hejandin]]a [[ling]]ên xwe.
#: {{hevmane|ku|zîtik|pên|pehîn|zîçik}}
#* {{bênimûne|ku}}
# Bazdana berxika ku dileyize
#* {{bênimûne|ku}}
==== Ji wêjeya klasîk ====
* {{J:Mem û Zîn:1692|jêgirtin=Her bengî û serxweşê di Botan</br>Têk hatine çerx û baz û '''lot'''an</br>Bêrîte sema û saz û govend}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Formên alternatîv ====
{{kol3|ku
|lotik
|lotk
}}
==== Jê ====
{{kol3|ku
|lotik avêtin<crz:lêker>
|lotavêj
|lotavêjî
|lotikane
|lotikavêj
|lotikavêjî
|lotikî
|lotî
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|Sprung|m}}
* {{Z|fa}}: {{W+|fa|حرکت تند}}, {{W+|fa|لگد پراندن}}
* {{Z|en}}: {{W+|en|skip}}
* {{Z|tr}}: {{W+|tr|zıplama}}, {{W+|tr|hoplama}}, {{W+|tr|iskandil}}
{{werger-bin}}
== {{ziman|sq}} ==
=== Navdêr ===
{{navdêr|sq|z=m}}
# {{g|ku|hêsir}}, {{g|ku|rondik}}
#* {{bênimûne|sq}}
=== Çavkanî ===
{{rûpela wergerê|sq|hêsir}}
== {{ziman|nl}} ==
=== Navdêr ===
{{navdêr|nl|z=nt}}
# {{g|ku|qeder}}, {{g|ku|qismet}}, {{g|ku|nesîb}}
#* {{bênimûne|nl}}
=== Çavkanî ===
{{rûpela wergerê|nl|qeder}}
== {{ziman|en}} ==
=== Bilêvkirin ===
* {{deng|en|en-us-lot.ogg|dever=DYA}}
* {{deng|en|En-uk-a lot.ogg|dever=QY}}
* {{deng|en|LL-Q1860 (eng)-Back ache-lot.wav|Deng|dever=London,QY}}
* {{deng|en|LL-Q1860 (eng)-Nattes à chat-lot.wav|Deng|dever=}}
* {{deng|en|LL-Q1860 (eng)-Wodencafe-lot.wav|Deng|dever=Teksas, DYA}}
=== Rengdêr ===
{{rengdêr|en}}
# [[gelek]], [[pirr]], [[zehf]], [[mişe]]
#* {{bênimûne|en}}
=== Navdêr ===
{{navdêr|en}}
# [[par]], [[hise]]
#* {{bênimûne|en}}
2x9u85pfiwpg9lz446cj6tcih7o8ro1
danser
0
18367
6347638
6304582
2026-09-01T11:52:24Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347638
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Navdêr ===
[[Wêne:783 3 (+ 3) dancers performing on stage V-P.jpg|thumb|250px|Çend danser anku dansker]]
{{navdêr|ku|z=mn}}
# kesa/ê [[dans]]ê dike, <br>[[reqas]], [[semaker]], [[govendker]], [[dîlanker]], [[dawetker]], [[reqisker]]
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê û nêr}}
==== Formên alternatîv ====
{{kol3|ku
|danskar
|dansker
|dansvan
}}
==== Nêzîk ====
{{kol3|ku
|dansoz
}}
==== Jê ====
{{kol3|ku
|danserî
|danserîtî
|dansertî
}}
==== Etîmolojî ====
Ji {{deyn|en|ku|dancer}}, binêre {{paş|ku|dans|-er}}.
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W-|af|danser}}
* {{Z|sq}}: {{W+|sq|valltar|n}}, {{W+|sq|kërcimtar|n}}
* {{Z|de}}: {{W+|de|Tänzer|n}}
* {{Z|as}}: {{W-|as|নর্তকী}}
* {{Z|ast}}: {{W-|ast|baillador|n}}, {{W-|ast|baillarín|n}}
* {{Z|az}}: {{W-|az|rəqqas}}
* {{Z|eu}}: {{W-|eu|dantzari}}
* {{Z|ba}}: {{W-|ba|бейеүсе}}
* {{Z|be}}: {{W-|be|танцо́р|n}}
* {{Z|bn}}: {{W-|bn|নর্তকী}}
* {{Z|bg}}: {{W-|bg|танцьо́р|n}}, {{W+|bg|балети́ст|n}}
* {{Z|my}}: {{W+|my|ကချေသည်}}
* {{Z|ce}}: {{W-|ce|хелхархо}}
* {{Z|cs}}: {{W+|cs|tanečník|n}}, {{W+|cs|tanečnice|m}}
* {{Z|cic}}: {{W-|cic|hilha'}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|舞蹈家|tr=wǔdǎojiā}}, {{W-|cmn|[[舞蹈]][[演員]]|tr=wǔdǎo yǎnyuán}}, {{W-|cmn|跳舞者|tr=tiàowǔzhě}}
*: {{Z|nan}}: {{W-|nan|舞蹈家|tr=bú-tō-ka}}
* {{Z|da}}: {{W+|da|danser|g}}
* {{Z|id}}: {{W+|id|penari}}
* {{Z|ar}}: {{W-|ar|رَاقِص|n}}, {{W-|ar|رَاقِصَة|m}}
*: {{Z|arz}}: {{W-|arz|رقاص|n|tr=raʔāṣ}}
* {{Z|hy}}: {{W+|hy|պարող}}
* {{Z|eo}}: {{W-|eo|dancisto}}, {{W-|eo|virdancisto}}
* {{Z|et}}: {{W-|et|tantsija}}
* {{Z|fa}}: {{W+|fa|رقاص|tr=raqqâs}}
* {{Z|fo}}: {{W-|fo|dansari|n}}
* {{Z|fi}}: {{W+|fi|tanssija}}
* {{Z|fr}}: {{W+|fr|danseur|n}}
* {{Z|gd}}: {{W-|gd|dannsair|n}}
* {{Z|gl}}: {{W-|gl|bailador|n}}, {{W+|gl|bailarín|n}}, {{W-|gl|danzarín|n}}
* {{Z|ka}}: {{W-|ka|მოცეკვავე}}
* {{Z|hi}}: {{W-|hi|नृत्यनर्तक|n}}
* {{Z|nl}}: {{W+|nl|danser|n}}
* {{Z|he}}: {{W+|he|רקדן|n|tr=rakdán|cuda=רקדן \ רַקְדָן}}
* {{Z|io}}: {{W+|io|dansanto}}, {{W-|io|dansantulo}}, {{W+|io|dansero}}, {{W+|io|danserulo}}, {{W+|io|dansisto}}, {{W-|io|dansistulo}}
* {{Z|ang}}: {{W-|ang|hlēapere|n}}, {{W-|ang|hoppere|n}}, {{W-|ang|tumbere|n}}
* {{Z|en}}: {{W+|en|dancer}}
* {{Z|ga}}: {{W-|ga|rinceoir|n}}, {{W-|ga|damhsóir|n}}
* {{Z|it}}: {{W+|it|ballerino|n}}, {{W+|it|danzatore|n}}
* {{Z|is}}: {{W+|is|dansari|n}}
* {{Z|ja}}: {{W+|ja|ダンサー|tr=dansā}}, {{W-|ja|舞踊家|tr=ぶようか, buyōka}}
* {{Z|xal}}: {{W-|xal|биич}}
* {{Z|kn}}: {{W+|kn|ಪಾಣ}}
* {{Z|pam}}: {{W-|pam|talaterak}}
* {{Z|ca}}: {{W-|ca|ballador|n}}, {{W-|ca|ballarí|n}}, {{W-|ca|dansador|n}}, {{W-|ca|dansaire|n|m}}
* {{Z|qu}}: {{W-|qu|tusuq}}
* {{Z|ky}}: {{W-|ky|бийчи киши}}, {{W+|ky|бийчи}}
* {{Z|ko}}: {{W+|ko|춤꾼}}
* {{Z|la}}: {{W-|la|saltator|n}}, {{W-|la|saltatrix|m}}, {{W-|la|histrio|n}}, {{W-|la|ludius|n}}
* {{Z|lv}}: {{W-|lv|dejotājs|n}}
* {{Z|lo}}: {{W-|lo|ນັກເຕັ້ນລຳ}}
* {{Z|lt}}: {{W-|lt|šokėjas|n}}
* {{Z|lb}}: {{W-|lb|Dänzer|n}}
* {{Z|mk}}: {{W-|mk|танчер|n}}
* {{Z|ml}}: {{W-|ml|തുളളിച്ചാടുന്നവൻ}}
* {{Z|ms}}: {{W-|ms|penari}}
* {{Z|mi}}: {{W-|mi|kaikanikani}}
* {{Z|hu}}: {{W+|hu|táncos|n}}
* {{Z|mn}}: {{W+|mn|бүжигчин}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|danser|n}}
*: {{Z|nn}}: {{W-|nn|dansar|n}}
* {{Z|oc}}: {{W+|oc|dançaire|n}}
* {{Z|or}}: {{W+|or|ନର୍ତ୍ତକ}}
* {{Z|uz}}: {{W+|uz|tansachi}}, {{W+|uz|raqqos}}
* {{Z|pl}}: {{W+|pl|tancerz|n}}, {{W+|pl|tancerka|m}}
* {{Z|pt}}: {{W+|pt|bailarino|n}}, {{W+|pt|dançarino|n}}
* {{Z|kk}}: {{W-|kk|биші}}, {{W+|kk|билеуші}}
* {{Z|ro}}: {{W+|ro|dansator|n}}
* {{Z|ru}}: {{W+|ru|танцо́р|n}}, {{W+|ru|танцо́вщик|n}}, {{W+|ru|балеру́н|n}}, ; {{W+|ru|плясу́н|n}}
* {{Z|str}}: {{W-|str|SJELW̱EṈ}}
* {{Z|sh}}: {{W+|sh|plèsāč|n}}
* {{Z|sk}}: {{W+|sk|tanečník|n}}, {{W-|sk|tanečnica|m}}
* {{Z|sl}}: {{W+|sl|plesalec|n}}
* {{Z|es}}: {{W+|es|bailarín|n}}, {{W+|es|bailador|n}}
* {{Z|sv}}: {{W+|sv|dansare|g}}
* {{Z|tg}}: {{W-|tg|раққос}}
* {{Z|tl}}: {{W-|tl|mananayaw}}
* {{Z|ta}}: {{W-|ta|நடனக்காரர்}}
* {{Z|twf}}: {{W-|twf|tò’óna}}
* {{Z|th}}: {{W-|th|นักเต้น}}, {{W-|th|หางเครื่อง}}
* {{Z|te}}: {{W+|te|నర్తకి}}
* {{Z|tt}}: {{W+|tt|биюче}}
* {{Z|tr}}: {{W+|tr|dansçı}}
* {{Z|tk}}: {{W-|tk|tansçy}}
* {{Z|uk}}: {{W-|uk|танцюри́ст|n}}
* {{Z|vi}}: {{W-|vi|người nhảy}}, {{W-|vi|người múa}}, {{W-|vi|người khiêu vũ}}, {{W-|vi|vũ công}}
* {{Z|vo}}: {{W+|vo|danüdan}}, {{W-|vo|hidanüdan}}
* {{Z|cy}}: {{W-|cy|dawnsiwr|n|m}}, {{W-|cy|dawnswr|n|m}}
* {{Z|km}}: {{W-|km|អ្នករាំ}}
* {{Z|yi}}: {{W-|yi|טענצער|n}}
* {{Z|el}}: {{W+|el|χορευτής|n}}
*: {{Z|grc}}: {{W-|grc|ὀρχηστής|n}}, {{W-|grc|ὀρχηστρίς|m}}
{{werger-bin}}
:{{werger çavkanî|en|dancer|beş=Ev qismê Wergerê|oldid=75822426}}
== {{ziman|af}} ==
=== Navdêr ===
{{navdêr|af}}
# {{g|ku|danser}}, {{g|ku|reqisker}}, {{g|ku|reqas}}, {{g|ku|semager}}
#* {{bêmînak|af}}
=== Çavkanî ===
{{rûpela wergerê|af|danser}}
== {{ziman|da}} ==
=== Navdêr ===
{{navdêr|da}}
# {{g|ku|danser}}, {{g|ku|reqisker}}, {{g|ku|reqas}}, {{g|ku|semager}}
#* {{bêmînak|da}}
=== Çavkanî ===
{{rûpela wergerê|da|danser}}
== {{ziman|fr}} ==
=== Bilêvkirin ===
* dansê
* {{deng|fr|LL-Q150 (fra)-WikiLucas00-danser.wav|Deng|dever=Lyon, Fransa}}
* {{deng|fr|LL-Q150 (fra)-LoquaxFR-danser.wav|Deng|dever=Vosges, Fransa}}
* {{deng|fr|LL-Q150 (fra)-Jérémy-Günther-Heinz Jähnick-danser.wav|Deng|dever=Somain, Fransa}}
* {{deng|fr|LL-Q150 (fra)-Helenou66-danser.wav|Deng|dever=Saint-Laurent-de-Cerdans, Fransa}}
=== Lêker ===
{{lêker|fr}}
# [[dans]] kirin, [[sema]] kirin, [[govend]] kirin, [[dawet]] kirin, [[dîlan]] kirin
#* {{bêmînak|fr}}
== {{ziman|nl}} ==
=== Navdêr ===
{{navdêr|nl|z=n}}
# [[danser#Kurdî|danser]], [[reqas]], [[semavan]], [[govendker]], [[dîlanker]], [[dawetker]]
#* {{bêmînak|nl}}
==== Têkildar ====
{{kol3|nl
|danseres<c:m>
}}
== {{ziman|nb}} ==
=== Navdêr ===
{{navdêr|nb|z=n}}
# {{g|ku|danser}}, {{g|ku|reqisker}}, {{g|ku|reqas}}, {{g|ku|semager}}
#* {{bêmînak|nb}}
=== Çavkanî ===
{{rûpela wergerê|nb|danser}}
jar5w3y6bcvqbsqddjnt1d5cezl1kat
misoger
0
18444
6347449
6327061
2026-08-31T19:39:37Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347449
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Rengdêr ===
{{ku-tewîn-rd|misoger}}
{{rengdêr|ku}}
# [[temîn]], [[ekîd]], [[garantî]]kirî, [[bêguman]], [[eseh]], [[bivê-nevê]]
#: {{nm|ku|Biserketina Miletê Kurd '''misoger''' e.|Kurd dê [[île]] bi ser bikevin.|rêz=1}}
# {{kontrol|rêz=erê|[[bêşik]], [[piştrast]], [[tekîdkirî]], [[diyar]], [[esehî]], [[dabîn]]}}
==== Bi alfabeyên din ====
* {{ku-ar|مسۆگهر}}
==== Jê ====
{{kol3|ku
|misogerî
|misoger bûn<crz:lêker>
|misoger kirin<crz:lêker>
|misogerbûn<crz:navdêr><c:m>
|misogerkirin<crz:navdêr><c:m>
|misogerbûyî<crz:rengdêr>
|misogerkirî<crz:rengdêr>
}}
==== Etîmolojî ====
Divê ji مصوگر (Erebî ya Îraqê), navê berkar ji صوگر, ji صوگرتا, ji سکرتاه (= insurance), belkî ji ''security''<ref> Ferhenga Kurmancî-Îngilîzî; Michael L Chyet</ref>
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|sicher}}
* {{Z|zh}}: {{W|zh|確定}}, {{W-|zh|确定|tr=quèdìng}}, {{W-|zh|当然|tr=dāngrán}}
* {{Z|ar}}: {{W-|ar|اكيد|tr=ekîd}}, {{W|ar|محتوم|guman=erê}}
* {{Z|fa}}: {{W|fa|حتمی}}, {{W|fa|تضمینی}}
* {{Z|fi}}: {{W|fi|varma}}
* {{Z|fr}}: {{W|fr|sûr}} {{n}}, {{W|fr|sûre}} {{mê}}
* {{Z|gu}}: {{W|gu|biztos}}
* {{Z|nl}}: {{W|nl|zeker}}
* {{Z|en}}: {{W|en|sure}}, {{W|en|certain}}, {{W|en|guaranteed}}, {{W|en|secure}}, {{W|en|surely}}, {{W|en|foolproof|guman=erê}}
* {{Z|it}}: {{W|it|sicuro}} {{n}}, {{W|it|sicura}} {{mê}}, {{W|it|certo}} {{n}}, {{W|it|certa}} {{mê}}
* {{Z|ja}}: [[確か]]な (たしかな, tashika na)
* {{Z|ca}}: {{W+|ca|garantit}}, {{W+|ca|ver}}, {{W+|ca|vertader}}, {{W+|ca|cert}}, {{W+|ca|verdader}}, {{W+|ca|veritable}}
* {{Z|ko}}: {{W-|ko|확실한|tr=hwaksilhan}}
* {{Z|pl}}: {{W|pl|pewny}}, {{W|pl|pewien}} {{n}}, {{W|pl|pewna}} {{mê}}, {{W|pl|pewne}} {{nt}}
* {{Z|pt}}: {{W|pt|certo}}, {{W|pt|seguro}}
* {{Z|ru}}: {{W-|ru|уверенный|tr=uvérennyj}}
* {{Z|es}}: {{W|es|seguro}}
* {{Z|sv}}: {{W|sv|säker}}
* {{Z|tr}}: {{W|tr|radikal}}, {{W|tr|kesin}}, {{W|tr|kaçınılmaz}}, {{W|tr|muhakkak}}, {{W|tr|garanti|guman=erê}}, {{W|tr|gayri kabili|guman=erê}}, {{W|tr|kati|guman=erê}}, {{W|tr|kat'î|guman=erê}}
{{werger-bin}}
0enurwnlgx72i7z60425vf35jzxe4mz
xilwe
0
18700
6347550
6338732
2026-09-01T09:49:54Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347550
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Rengdêr ===
{{ku-tewîn-rd|xilwe}}
{{rengdêr|ku}}
# [[varê]], [[avarê]], [[veder]], ne li [[ser]] yan [[nêz]]î [[rê]], [[dûr]]î [[navend]]ê, [[dûr]]
#* {{bênimûne|ku}}
==== Ji wêjeya klasîk ====
* {{J:Feqiyê Teyran|jêgirtin=Birme dêra xaçperestan<br>'''Xelwe'''ya xumxane tê<br>Birme nê xemr û şerabê}}
==== Formên alternatîv ====
{{kol3|ku
|xewle
|xelwe
}}
==== Jê ====
{{kol3|ku
|xilwe bûn<crz:lêker>
|xilwe kirin<crz:lêker>
|xilwebûn<crz:navdêr>
|xilwekirin<crz:navdêr>
|xilwebûyî<crz:rengdêr>
|xilwekirî<crz:rengdêr>
|xilwebar
|xilwebarî
|xilweber
|xilweberî
|xilwekar
|xilwekarî
|xilweker
|xilwekerî
|xilweyî
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Bide ber ====
{{kol3|ku
|xilwet
}}
==== Werger ====
{{werger-ser}}
* {{Z|fi}}: {{W+|fi|syrjäinen}}, {{W+|fi|syrjässä}}
* {{Z|en}}: {{W+|en|apart}}, {{W+|en|aloof}}, {{W+|en|remote}}, {{W+|en|distant}}
{{werger-bin}}
lpj1j7vecws6cauatyu47ptpensoq76
petat
0
19303
6347628
6327345
2026-09-01T11:41:50Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347628
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Potatoes.jpg|thumb|Petat]]
{{navdêr|ku|z=m}}
# [[riwek]]ek e, di [[xwarin]]ên [[cûr bi cûr]] de tê [[kelandin]] û xwarin, [[sêva bin erd]].
#* {{bêmînak|ku}}
==== Formên alternatîv ====
{{kol3|ku
|patat
|patate
|patatês
|petate
|pitat
|pitate
}}
==== Navê zanistî ====
* {{g|navz|Solanum tuberosum}}
==== Hevmane ====
{{kol3|ku
|sêvik
|kartol
|qompîr
|kirtoye<ee:Akrê>
|ritax<ee:Rêkanî>
}}
==== Jê ====
{{kol3|ku
|petatik
|petatî
|petatk
}}
==== Etîmolojî ====
Ji {{ji|es|ku|patata}} ji zimanekî [[hindiyanî]] yê bi navê [[taynoyî]] ku niha miriye. Peyva îngilîzî [[potato]], ya {{hv|tr|patates}}, ya erebî {{g|ar|بطاطا}} û yên gelek zimanên din jî ji eynî rehî ne.
==== Bi zaravayên din ====
* {{Z|ckb}}: [[kirtope]], [[petate]], [[sêvok]]
* Goranîya [[sêvzemînî]]: [[sêv]] + [[zemîn]]
==== Werger ====
{{werger-ser}}
* {{Z|ab}}: {{W-|ab|акартош}}
* {{Z|ady}}: {{W-|ady|чӏырыкӏу}}
* {{Z|af}}: {{W+|af|aartappel}}, {{W+|af|ertappel}}
* {{Z|sq}}: {{W+|sq|patate}}, {{W+|sq|kërtollë}}
* {{Z|gmw-ecg}}: {{W-|gmw-ecg|Arber}}, {{W-|gmw-ecg|Ardeppel}}, {{W-|gmw-ecg|Ardeppl|n}}
* {{Z|pdc}}: {{W-|pdc|Grumbeer|m}}
* {{Z|de}}: {{W+|de|Kartoffel|m}}, {{W+|de|Erdapfel|n}}, {{W-|de|Grumbeere|m}}, {{W+|de|Erdbirne|m}}, {{W+|de|Grundbirne|m}}, {{W+|de|Bramburi|m}}
*: {{Z|gsw}}: {{W-|gsw|Härdöpfel|n}}, {{W-|gsw|Herdapfel|n}}, {{W-|gsw|artuffula}}, {{W-|gsw|Grandbere}}, {{W-|gsw|Guml}}, {{W-|gsw|Gummle}}, {{W-|gsw|Grumbeer}}, {{W-|gsw|Häpärä}}, {{W-|gsw|Hääbi}}, {{W-|gsw|Herdäpfel}}, {{W-|gsw|Herdöpfel}}, {{W-|gsw|Grumpre}}, {{W-|gsw|Grumpara}}, {{W-|gsw|Grumbira}}, {{W-|gsw|Härpfl}}, {{W-|gsw|häpfäl}}, {{W-|gsw|Häärdepfel}}, {{W-|gsw|héerfél}}, {{W-|gsw|trifflu}}, {{W-|gsw|trüffulu}}
*: {{Z|gmw-cfr}}: {{W-|gmw-cfr|Ääpel|n}}
* {{Z|am}}: {{W-|am|ድንች}}
* {{Z|an}}: {{W-|an|trunfa|m}}
* {{Z|aii}}: {{W-|aii|ܟܸܪܬܘܿܦܵܐ|n|tr=kirtopa}}
* {{Z|agj}}: {{W-|agj|ድንች|tr=dənnəč}}
* {{Z|rup}}: {{W-|rup|pãtatã|m}}, {{W-|rup|patatã}}, {{W+|rup|combar}}, {{W-|rup|pãpati}}, {{W-|rup|curcaci}}, {{W-|rup|cumpir}}
* {{Z|as}}: {{W-|as|আলু}}
* {{Z|ast}}: {{W+|ast|pataca|m}}
* {{Z|ay}}: {{W-|ay|ch'uqi}}
* {{Z|az}}: {{W+|az|kartof}}
* {{Z|eu}}: {{W+|eu|patata}}, {{W-|eu|lursagar}}
* {{Z|ba}}: {{W-|ba|бәрәңге}}, {{W-|ba|картуф}}
* {{Z|bar}}: {{W-|bar|Eadäpfe}}, {{W-|bar|gartufela}}, {{W-|bar|kartufula}}, {{W-|bar|eapfl}}, {{W-|bar|erdepfl}}
* {{Z|be}}: {{W+|be|бу́льба|m}}
* {{Z|bn}}: {{W+|bn|আলু}}
* {{Z|br}}: {{W+|br|aval-douar}}
* {{Z|bg}}: {{W+|bg|карто́ф|n}}
* {{Z|my}}: {{W+|my|အာလူး}}
* {{Z|bua}}: {{W-|bua|түмһэн}}
* {{Z|cim}}: {{W-|cim|pataata}}, {{W-|cim|patát}}, {{W-|cim|petate}}
* {{Z|ccc}}: {{W-|ccc|ma'kona}}
* {{Z|ce}}: {{W-|ce|картол}}, {{W-|ce|картог}}
* {{Z|cs}}: {{W+|cs|brambor|n}}, {{W+|cs|brambora|m}}
* {{Z|chr}}: {{W-|chr|ᏄᎾ}}
* {{Z|chn}}: {{W-|chn|wapato}}
* {{Z|cic}}: {{W-|cic|ahi'}}
* {{Z|zh}}:
*: {{Z|yue}}: {{W-|yue|薯仔|tr=syu4 zai2}}, {{W-|yue|馬鈴薯|tr=maa5 ling4 syu4}}
*: {{Z|dng}}: {{W-|dng|ёнйү}}, {{W-|dng|йүдү}}
*: {{Z|hak}}: {{W-|hak|馬鈴薯|tr=mâ-làng-sù}}
*: {{Z|cmn}}: {{W+|cmn|土豆|tr=tǔdòu}}, {{W+|cmn|馬鈴薯|tr=mǎlíngshǔ}}, {{W+|cmn|洋芋|tr=yángyù}}
*: {{Z|cdo}}: {{W-|cdo|番囝薯|tr=huăng-giāng-sṳ̀}}
*: {{Z|nan}}: {{W+|nan|馬鈴薯|tr=má-lêng-chî, má-lêng-chû}}, {{W-|nan|蕳砃|tr=kan-tan}}, {{W-|nan|蕳砃薯|tr=kan-tan-chîr}}
*: {{Z|wuu}}: {{W-|wuu|洋山芋}}
* {{Z|cv}}: {{W-|cv|ҫӗр улми}}, {{W-|cv|паранка}}
* {{Z|da}}: {{W+|da|kartoffel|g}}
* {{Z|ovd}}: {{W-|ovd|pära|m}}
* {{Z|id}}: {{W+|id|kentang}}
* {{Z|ar}}: {{W+|ar|بَطَاطَا|m}}, {{W-|ar|بَطَاطِس|n}}
*: {{Z|arz}}: {{W-|arz|بطاطس|n|tr=baṭāṭis}}, {{W-|arz|بطاطسة|m|tr=baṭāṭisa}}
*: {{Z|ary}}: {{W-|ary|بطاطا|m|tr=bṭāṭa, baṭāṭa}}
* {{Z|hy}}: {{W+|hy|կարտոֆիլ}}
* {{Z|myv}}: {{W-|myv|модамарь}}
* {{Z|eo}}: {{W+|eo|terpomo}}
* {{Z|et}}: {{W+|et|kartul}}
* {{Z|fa}}:
*: {{Z|fa}}: {{W-|fa|کچالو|tr=kačālū}}
*: {{Z|fa}}: {{W+|fa|سیبزمینی|tr=sib-zamini}}
* {{Z|fo}}: {{W+|fo|epli|nt}}, {{W-|fo|epl|nt}}
* {{Z|fi}}: {{W+|fi|peruna}}, {{W+|fi|pottu}}
* {{Z|gmw-cfr}}: {{W-|gmw-cfr|Grumber}}; {{W-|gmw-cfr|Ärpel}}, {{W-|gmw-cfr|Grompere}}, {{W-|gmw-cfr|Schrumpern}}, {{W-|gmw-cfr|Grumbeer}}, {{W-|gmw-cfr|Krombier}}, {{W-|gmw-cfr|Doffel}}, {{W-|gmw-cfr|Duffel}}, {{W-|gmw-cfr|Äpel}}, {{W-|gmw-cfr|Erdäpel}}
* {{Z|gmw-rfr}}: {{W-|gmw-rfr|Grumber}}, {{W-|gmw-rfr|Grumbeer}}, {{W-|gmw-rfr|Kadoffl}}, {{W-|gmw-rfr|Kardoffel}}
* {{Z|fr}}: {{W+|fr|pomme de terre|m}}, {{W+|fr|patate|m}}
* {{Z|fur}}: {{W-|fur|patate|m}}
* {{Z|fy}}: {{W-|fy|ierappel}}
* {{Z|gd}}: {{W-|gd|buntàta|n}}
* {{Z|gl}}: {{W+|gl|pataca|m}}, {{W-|gl|patoa|m}}, {{W-|gl|baloca|m}}, {{W-|gl|castaña da terra|m}}
* {{Z|gu}}: {{W-|gu|બટાટો|n}}
* {{Z|ka}}: {{W-|ka|კარტოფილი}}
* {{Z|gn}}: {{W-|gn|yvy'a}}
* {{Z|haw}}: {{W-|haw|ʻuala kahiki}}
* {{Z|hi}}: {{W+|hi|आलू|n}}, {{W+|hi|आलु|n}}
* {{Z|hil}}: {{W-|hil|patatas}}
* {{Z|mww}}: {{W-|mww|qos yaj ywv}}
* {{Z|nl}}: {{W+|nl|aardappel|m}}, {{W+|nl|pieper|n}}, {{W+|nl|patat|m}}
* {{Z|hrx}}: {{W-|hrx|Kartoffel|m}}, {{W-|hrx|Grummbeer|m}}
* {{Z|he}}: {{W+|he|תַּפּוּחַ אֲדָמָה|n|tr=tapuákh adamá}}, {{W+|he|בּוּלְבּוּס|n|tr=bulbus}}
* {{Z|io}}: {{W+|io|terpomo}}, {{W+|io|potato}}
* {{Z|en}}: {{W+|en|potato}}
* {{Z|izh}}: {{W-|izh|maamuna}}, {{W-|izh|maaomena}}
* {{Z|ga}}: {{W+|ga|práta|m}}, {{W+|ga|fata|n}}
* {{Z|it}}: {{W+|it|patata|m}}
* {{Z|is}}: {{W+|is|kartafla|m}}, {{W+|is|jarðepli|nt}}
* {{Z|ja}}: {{W+|ja|じゃがいも|tr=jagaimo}}, {{W+|ja|馬鈴薯|tr=ばれいしょ, bareisho}}, {{W-|ja|ポテト|tr=poteto}}
* {{Z|jv}}: {{W-|jv|kenthang}}
* {{Z|jje}}: {{W-|jje|지슬}}
* {{Z|kl}}: {{W-|kl|naatsiiaq}}, {{W-|kl|kartoffeli}}, {{W-|kl|eertaasaq}}, {{W-|kl|issuusaq}}
* {{Z|xal}}: {{W-|xal|боднцг}}
* {{Z|kn}}: {{W+|kn|ಆಲೂಗಡ್ಡೆ}}, {{W+|kn|ಬಟಾಟೆ}}, {{W+|kn|ಉರುಳೆಗಡ್ಡೆ}}
* {{Z|krc}}: {{W-|krc|гардош}}, {{W-|krc|картоф}}
* {{Z|csb}}: {{W-|csb|bùlwa|m}}
* {{Z|ca}}: {{W+|ca|patata|m}}
*: {{Z|ca}}: {{W+|ca|creïlla|m}}
* {{Z|kgp}}: {{W-|kgp|pén'ó}}
* {{Z|qu}}: {{W-|qu|papa}}
* {{Z|ky}}: {{W+|ky|картөшкө}}, {{W-|ky|жералма}}
* {{Z|si}}: {{W+|si|අල}}
* {{Z|kok}}: {{W-|kok|आळूं}}
* {{Z|ko}}: {{W+|ko|감자}}, {{W+|ko|지실}}
* {{Z|kw}}: {{W-|kw|aval dor|n}}, {{W-|kw|patatysen|m}}, {{W-|kw|tetti|n}}
* {{Z|co}}: {{W+|co|pomu|n}}
* {{Z|crs}}: {{W-|crs|ponmdeter}}
* {{Z|kum}}: {{W-|kum|картоп}}
* {{Z|ltg}}: {{W-|ltg|buļbe|m}}
* {{Z|la}}: {{W-|la|patata|m}}
* {{Z|lv}}: {{W+|lv|kartupelis|n}}, {{W-|lv|tupenis|n}}, {{W+|lv|rācenis|n}}, {{W-|lv|pampalis|n}}
* {{Z|lo}}: {{W+|lo|ມັນຝະລັ່ງ}}
* {{Z|li}}: {{W+|li|aerpel|n}}
* {{Z|lt}}: {{W+|lt|bulvė|m}}
* {{Z|liv}}: {{W-|liv|naggõrz}}
* {{Z|lmo}}: {{W-|lmo|pòm da tèra|m}}
* {{Z|luy}}: {{W-|luy|silasi}}
* {{Z|lb}}: {{W+|lb|Gromper|m}}
* {{Z|mhn}}: {{W-|mhn|ruab|m}}
* {{Z|mk}}: {{W-|mk|компир|n}}
* {{Z|mg}}: {{W+|mg|ovy}}
* {{Z|ml}}: {{W-|ml|ഉരുളക്കിഴങ്ങ്}}
* {{Z|ms}}: {{W+|ms|kentang}}
* {{Z|mt}}: {{W-|mt|patata|m}}
* {{Z|gv}}: {{W-|gv|praase|n}}
* {{Z|mi}}: {{W-|mi|parareka}}, {{W-|mi|taewa}}, {{W+|mi|rīwai}}, {{W-|mi|kāpana}}
* {{Z|arn}}: {{W-|arn|poñi}}
* {{Z|mr}}: {{W-|mr|बटाटा|n}}
* {{Z|hu}}: {{W+|hu|burgonya}}, {{W+|hu|krumpli}}
* {{Z|mod}}: {{W-|mod|ahé}}
* {{Z|mn}}: {{W+|mn|төмс}}, {{W-|mn|ᠲᠥᠮᠦᠰᠦ}}
* {{Z|nah}}: {{W+|nah|camohtli}}
* {{Z|nv}}: {{W-|nv|nímasii}}
* {{Z|nds}}:
*: {{Z|nds-de}}: {{W-|nds-de|Kantüffel|m}}, {{W-|nds-de|Kartuffel|m}}, {{W-|nds-de|Kartüffel|m}}, {{W-|nds-de|Kortüffel|m}}
* {{Z|nrf}}: {{W-|nrf|patate|m}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|potet|n}}, {{W+|nb|jordeple|nt}}
*: {{Z|nn}}: {{W-|nn|potet|n|m}}, {{W-|nn|jordeple|nt}}
* {{Z|oj}}: {{W-|oj|opin|an}}, {{W-|oj|pin|an}}
* {{Z|oc}}: {{W+|oc|trufa|m}}, {{W+|oc|patana|m}}
* {{Z|or}}: {{W-|or|ଆଳୁ}}
* {{Z|om}}: {{W-|om|dinnicha}}
* {{Z|osa}}: {{W-|osa|tóoska}}
* {{Z|os}}: {{W-|os|картоф}}
* {{Z|ota}}: {{W-|ota|یر الماسی|tr=yer elması}}
* {{Z|ug}}: {{W-|ug|ياڭيۇ}}
* {{Z|uz}}: {{W+|uz|kartoshka}}
* {{Z|ps}}: {{W-|ps|کچالو|n-p|tr=kačālú}}, {{W+|ps|الو|n|tr=alú}}
* {{Z|pcd}}: {{W-|pcd|pétote|m}}, {{W-|pcd|peu'n tierre|m}}
* {{Z|pdt}}: {{W-|pdt|Ieedschock|m}}
* {{Z|pl}}: {{W+|pl|ziemniak|n}}, {{W+|pl|kartofel|n}}, {{W+|pl|pyra|m}}
* {{Z|pt}}: {{W+|pt|batata|m}}
* {{Z|pa}}: {{W+|pa|ਆਲੂ}}
* {{Z|kk}}: {{W+|kk|картоп}}, {{W-|kk|жералма}}
* {{Z|rhg}}: {{W-|rhg|alu}}, {{W-|rhg|aalu}}
* {{Z|rm}}: {{W-|rm|tartuffel|n}}, {{W-|rm|truffel|n}}, {{W-|rm|hardefel|n}}, {{W-|rm|tiffel|n}}, {{W-|rm|ardöffel|n}}, {{W-|rm|mailinterra|m}}
* {{Z|ro}}: {{W+|ro|cartof|n}}, {{W+|ro|barabulă|m}}
* {{Z|ru}}: {{W+|ru|карто́фель|n}}, {{W+|ru|карто́шка|m}}
* {{Z|rue}}: {{W-|rue|банду́рка|m}}
* {{Z|str}}: {{W-|str|sqewθ}}
* {{Z|se}}: {{W-|se|buđeita}}, {{W-|se|buđet}}
* {{Z|smn}}: {{W-|smn|potás}}
* {{Z|sms}}: {{W-|sms|pååttaǩ}}
* {{Z|sm}}: {{W-|sm|pateta}}
* {{Z|sgs}}: {{W-|sgs|bolbė|m}}
* {{Z|sa}}: {{W+|sa|आलुकम्|nt}}
* {{Z|szl}}: {{W-|szl|kartofel|n}}
* {{Z|sd}}: {{W-|sd|پٽاٽو|n|tr=paṯaṯo}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|кромпир|n}}, {{W-|sh|крумпир|n}}
*: Latînî: {{W+|sh|krompir|n}}, {{W+|sh|krumpir}}
* {{Z|gmq-scy}}: {{W-|gmq-scy|pära|g}}, {{W-|gmq-scy|potät|g}}, {{W-|gmq-scy|pantoffel|g}}, {{W-|gmq-scy|pantolla|g}}
* {{Z|sco}}: {{W-|sco|pitattie}}
* {{Z|sk}}: {{W+|sk|zemiak|n}}
* {{Z|sl}}: {{W+|sl|krompir|n}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|kulka|m}}
* {{Z|es}}: {{W+|es|patata|m}}, {{W+|es|papa|m}}
* {{Z|swg}}: {{W-|swg|Bodabirra}}, {{W-|swg|Grombiere}}, {{W-|swg|Erdepfel}}, {{W-|swg|Aidepfl}}, {{W-|swg|Äbirre}}
* {{Z|sw}}: {{W+|sw|kiazi}}, {{W-|sw|kiazi ulaya}}
* {{Z|sv}}: {{W+|sv|potatis|g}}, {{W+|sv|potät|g}}, {{W+|sv|jordäpple|nt}}, {{W+|sv|pära|g}}, {{W+|sv|pantoffel|g}}, {{W+|sv|plugg|g}}
* {{Z|tg}}: {{W+|tg|себзаминӣ}}
* {{Z|tl}}: {{W-|tl|patatas}}
* {{Z|ta}}: {{W+|ta|உருளைக்கிழங்கு}}
* {{Z|th}}: {{W+|th|มันฝรั่ง}}
* {{Z|te}}: {{W+|te|ఆలుగడ్డ}}, {{W+|te|ఉర్లగడ్డ}}, {{W+|te|బంగాళాదుంప}}
* {{Z|crh}}: {{W-|crh|qartop}}
* {{Z|tt}}: {{W+|tt|бәрәңге}}
* {{Z|tet}}: {{W-|tet|fehuk-ropa}}, {{W-|tet|fehuk-malae}}, {{W-|tet|fehuk-midar}}
* {{Z|ti}}: {{W-|ti|ድንሽ}}
* {{Z|tr}}: {{W+|tr|patates}}, {{W+|tr|yerelması}}, {{W-|tr|badadez}}, {{W-|tr|çisil}}
* {{Z|tk}}: {{W-|tk|kartoşka}}
* {{Z|bo}}: {{W-|bo|ཞོ་ཁོག}}, {{W-|bo|ཞོག་གོག}}
* {{Z|to}}: {{W-|to|pateta}}
* {{Z|ur}}: {{W+|ur|آلو|n|tr=ālū, ālu}}
* {{Z|uk}}: {{W+|uk|карто́пля|m}}, {{W-|uk|картопли́на|m}}{{W+|uk|бу́льба|m}}, {{W+|uk|барабо́ля|m}}
* {{Z|vec}}: {{W+|vec|tartùfola|n}}, {{W+|vec|pomo de tèra|n}}, {{W-|vec|patata|m}}
* {{Z|vi}}: {{W+|vi|khoai tây}}
* {{Z|vo}}: {{W+|vo|pötet}}, {{W-|vo|pötetaplan}}
* {{Z|vot}}: {{W-|vot|maamuna}}
* {{Z|wa}}: {{W+|wa|crompire|m}}, {{W+|wa|canada|n}}, {{W+|wa|truke|m}}, {{W+|wa|petote|m}}, {{W+|wa|cartoxhe|m}}
* {{Z|cy}}: {{W+|cy|taten|m}}
* {{Z|wym}}: {{W-|wym|aorpuł|n}}
* {{Z|wo}}: {{W-|wo|pombiteer}}
* {{Z|kjh}}: {{W-|kjh|яблах}}
* {{Z|km}}: {{W+|km|ដំឡូង}}
* {{Z|xh}}: {{W-|xh|itapile}}
* {{Z|sah}}: {{W-|sah|хортуоппуй}}
* {{Z|yi}}: {{W-|yi|קאַרטאָפֿל|n|m}}, {{W-|yi|בולבע|m}}
* {{Z|ydk}}: {{W-|ydk|sarembʌt}}
* {{Z|yo}}: {{W-|yo|ọ̀dùnkún}}
* {{Z|esu}}: {{W-|esu|patitussaaq}}, {{W-|esu|kantuuvvilaq}}
* {{Z|el}}: {{W+|el|πατάτα|m}}
* {{Z|za}}: {{W-|za|majlingzsuz}}
* {{Z|zu}}: {{W+|zu|izambane|c5|c6}}
{{werger-bin}}
:{{werger çavkanî|en|potato|oldid=75593517|beş=Ev qismê Wergerê}}
{{mijar|ku|riwek}}
3pw06ec28dug583tzh1hvjpe67kjt5v
tû
0
19338
6347566
6336797
2026-09-01T10:17:11Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes)
6347566
wikitext
text/x-wiki
{{bnr-h|tu}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
** (''[[rojhilatî]]'') {{IPA|ku|/tʉː/}}
* {{kîte|ku|tû}}
=== Navdêr 1 ===
[[Wêne:Mulberry_in_Libya.jpg|thumb|'''Tû''' bi darê ve.]]
[[Wêne:Mulberries_of_different_species.jpg|thumb|'''Tûyên''' [[çinîn|çinî]] di [[sênîk]]ekê de.]]
[[Wêne:Tû (Morus) Amed 2012.JPG|thumb|'''tûspî''']]
{{navdêr|ku|z=m}}, {{t-ya nerm}}
# {{f|ku|dar}} [[dar|Dar]]ek e ku [[dirî]]kên [[nerm]] yên [[têrav]] û [[xwerbar]] dide.
#: {{hevmane|ku|dartû}}
#* {{J:Mîran Janbar:Qolyeya Cecileê|r=35|jêgirtin=Husên piçekî li dûrî wî, li binê dara '''tûyê''' bû, di destekî wî de, werîsê çêleka ku bi dû xwe ve dikişkişand, di destê din de jî şivterkek hebû, ku carinan li çêlekê dizivirî û li pişta çêlekê dadiweşand...}}
# {{f|ku|fêkî}} [[dirî|Dirîkên]] wê [[dar]]ê.
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Bi alfabeyên din ====
* {{ku-ar|توو}}
* {{ku-kr|ту}}
==== Formên alternatîv ====
* [[twî]]
* [[tî]] (3)
==== Navê zanistî ====
* ''[[Morus]]''
==== Jê ====
{{stûn|
* [[dartû]]
* [[tûreşk]]
* [[tûspî]]
* [[tûyî]]
* [[tûzerk]]
* [[tûsork]]
* [[tûşîn]]
* [[tûkesk]]
* [[tûfrengî]]
* [[tûşêmî]]
* [[tûkûvî]]
* [[tûqesp]]
}}
==== Etîmolojî ====
Hevreha soranî {{g|ckb|توو|tr=tû}}, farisî {{g|fa|توت|tr=tût}} û {{g|fa|دوت|tr=}}, erebî {{g|ar|توت|tr=tût}}... hemû ji {{ji|arc|ku|ܬܘܬܐ}} (tuθa), hevreha îbrî [[תות]] (tûṭ) û akadî [[𒄑𒌅𒌓𒌈]] (/tuttu/).
Heman peyv ji Rojhilata Navîn derbazî gelek zimanên Kafkasyayê, Rojhilata Ewropayê û Navenda Asyayê jî bûye: tirkî ''[[dut]]'', azerî ''[[tut]]'', ermenî [[թութ]] (tʿutʿ), bosnî ''[[dud]]'', serbokroatî ''[[dud]]'' / [[дуд]], romanî ''[[dud]] / [[dudă]]'', makedonî [[дудинка]] (dudinka), maltî ''[[tut]] / [[tuta]]'', peştûyî {{g|ps|توت|tr=tût}}, urdûyî {{g|ps|توت|tr=tût}}, osetî [[тута]] (tuta), gurcî [[თუთა]] (t’ut’a), rûsî [[тут]] (tut), hindî [[तूत]] (tūt)...
==== Bide ber ====
* [[dû]]
* [[tu]]
* [[ti]]
==== Gotinên pêşiyan ====
* havînê tû xwar, zivistanê gû xwar (kesê ku malê xwe naparêze, zû xerc dike)
* dar bitû ye, lê xwedî tûle ye
==== Bi zaravayên din ====
* {{Z|ckb}}: {{g|ckb|توو|tr=tû}}
* {{Z|sdh}}: [[tîw]], [[tuy]]
* {{Z|lki}}: [[tivî]]
* {{Z|zza}}: [[tuy]], [[tuw]], (''dartû:'') [[tuwêr]], [[tuyêr]]
==== Werger ====
{{werger-ser|dara tûyan|1}}
* {{Z|akk}}: {{W-|akk|𒄑𒌅𒌓𒌈|tr=tuttu}}
* {{Z|sq}}: {{W+|sq|man}}
* {{Z|de}}: {{W+|de|Maulbeerbaum|n}}
* {{Z|arc}}: {{W-|arc|ܬܘܬܐ|tr=tuθa}}
* {{Z|az}}: {{W-|az|tut ağacı}}
* {{Z|eu}}: {{W-|eu|masustondo}}
* {{Z|be}}: {{W-|be|шаўко́віца|m}}
* {{Z|bg}}: {{W+|bg|черница|m}}
* {{Z|cs}}: {{W+|cs|moruše|m}}
* {{Z|chr}}: {{W-|chr|ᎫᏩ|tr=kuwa}}
* {{Z|zh}}: {{W+|cmn|桑樹}}, {{W+|cmn|桑树|tr=sāngshù}}
* {{Z|ar}}: {{W-|ar|توت|tr=tût}} {{n}}, {{W-|ar|توتة|tr=tûte}} {{mê}}
* {{Z|hy}}: {{W+|hy|թթենի}}
* {{Z|eo}}: {{W-|eo|moruso}}
* {{Z|fa}}: {{W+|fa|توت|tr=tut}}
* {{Z|fo}}: {{W-|fo|morberjatræ|nt}}
* {{Z|fi}}: {{W+|fi|mulperipuu}}, {{W+|fi|mulperi}}
* {{Z|fr}}: {{W+|fr|mûrier}}
* {{Z|gl}}: {{W+|gl|moreira|m}}
* {{Z|gu}}: {{W-|gu|શેતૂર}}
* {{Z|ka}}: {{W+|ka|თუთა}}
* {{Z|hi}}: {{W+|hi|शहतूत|n}}, {{W+|hi|तूत|n}}
* {{Z|nl}}: {{W+|nl|moerbeiboom|n}}
* {{Z|hrx}}: {{W-|hrx|Maulbeerebaam|n}}
* {{Z|he}}: {{W-|he|אוכמן|m}}
* {{Z|io}}: {{W+|io|morusiero}}
* {{Z|ang}}: {{W-|ang|mōrbēam|n}}
* {{Z|en}}: {{W-|en|mulberry tree}}
* {{Z|it}}: {{W+|it|moro|n}}, [[gelso]]
* {{Z|is}}: {{W-|is|mórberjatré|nt}}
* {{Z|ja}}: {{W+|ja|桑|tr=くわ, kuwa}}, {{W+|ja|クワ|tr=kuwa}}
* {{Z|ca}}: {{W+|ca|morera|m}}
* {{Z|ko}}: {{W-|ko|뽕나무}}
* {{Z|la}}: {{W+|la|mōrus|m}}
* {{Z|mk}}: {{W-|mk|црница|m}}, {{W-|mk|дуд|n}}
* {{Z|mnc}}: {{W-|mnc|ᠨᡳᠮᠠᠯᠠᠨ|tr=nimalan}}
* {{Z|mi}}: {{W-|mi|māpere}}, {{W-|mi|maupere}}
* {{Z|hu}}: {{W+|hu|eperfa}}
* {{Z|oc}}: {{W+|oc|amora|m}}, {{W+|oc|ase|n}}
* {{Z|uz}}: {{W-|uz|maymujon}}
* {{Z|ps}}: {{W+|ps|توت|tr=tut}}
* {{Z|pl}}: {{W+|pl|morwa|m}}
* {{Z|pt}}: {{W+|pt|amoreira|m}}
* {{Z|ro}}: {{W+|ro|dud|n}}
* {{Z|ru}}: {{W+|ru|шелкови́ца|m}}, {{W+|ru|шелко́вица|m}}, {{W+|ru|ту́та|m}}, {{W+|ru|ту́товое де́рево|nt}}
* {{Z|sh}}: {{W-|sh|ду̏д|n}}, {{W-|sh|му̑рва|m}} / {{W+|sh|dȕd|n}}, {{W+|sh|mȗrva|m}}
* {{Z|sl}}: {{W+|sl|murva}}
* {{Z|es}}: {{W+|es|moral|n}}, {{W+|es|moro}}
* {{Z|sw}}: {{W-|sw|mforsadi}}
* {{Z|tg}}: {{W-|tg|марминьон}}
* {{Z|th}}: {{W+|th|หม่อน}}
* {{Z|tr}}: {{W+|tr|dut}}
* {{Z|uk}}: {{W-|uk|шовковиця|f|cuda=шовкови́ця, шовко́виця}}
* {{Z|cy}}: {{W-|cy|morwydden|m}}
* {{Z|grc}}: {{W-|grc|μορέα|m}}, {{W-|grc|συκάμινος}}
* {{Z|el}}: {{W+|el|μουριά|m}}
{{werger-bin}}
{{werger-ser|berhemê xwerbar yê wê darê|2}}
* {{Z|af}}: {{W+|af|moerbei}}
* {{Z|sq}}: {{W+|sq|man}}
* {{Z|de}}: {{W+|de|Maulbeere|m}}
* {{Z|az}}: {{W+|az|tut}}
* {{Z|eu}}: {{W+|eu|masusta}}
* {{Z|be}}: {{W-|be|шаўко́віца|m}}
* {{Z|cs}}: {{W+|cs|moruše|m}}
* {{Z|zh}}: {{W+|cmn|桑椹|tr=sāngshèn}}
* {{Z|da}}: {{W-|da|morbær|nt}}
* {{Z|id}}: {{W+|id|bebesaran}}, {{W+|id|murbei}}
* {{Z|ar}}: {{W-|ar|توت|tr=tût}}
* {{Z|hy}}: {{W+|hy|թութ}}
* {{Z|eo}}: {{W-|eo|moruso}}
* {{Z|fa}}: {{W+|fa|توت|tr=tût}}, {{W-|fa|شاتوت|tr=šâtut}}
* {{Z|fo}}: {{W-|fo|morber|nt}}
* {{Z|fi}}: {{W-|fi|mulperinmarja}}
* {{Z|fr}}: {{W+|fr|mûre|m}}
* {{Z|gl}}: {{W+|gl|amora|m}}
* {{Z|grv}}: {{W-|grc|μόρον|nt}}, {{W-|grc|συκάμινον|nt}}
* {{Z|ka}}: {{W+|ka|თუთა}}, {{W-|ka|ბჟოლა}}
* {{Z|hi}}: {{W-|ht|sikomò}}
* {{Z|hi}}: {{W+|hi|शहतूत}}, {{W+|hi|तूत}}
* {{Z|nl}}: {{W+|nl|moerbei|m}}
* {{Z|hrx}}: {{W-|hrx|Maulbeer|m}}
* {{Z|he}}: {{W+|he|תות|tr=tut}}
* {{Z|io}}: {{W+|io|moruso}}
* {{Z|ang}}: {{W-|ang|mōrberiġe|m}}
* {{Z|en}}: {{W+|en|mulberry}}
* {{Z|ga}}: {{W-|ga|maoildearg|m}}
* {{Z|it}}: {{W+|it|mora|m}}
* {{Z|is}}: {{W-|is|mórber|nt}}
* {{Z|ja}}: {{W-|ja|クワの実|tr=kuwa no mi}}
* {{Z|ca}}: {{W+|ca|móra|m}}
* {{Z|ko}}: {{W+|ko|오디}}
* {{Z|la}}: {{W+|la|mōrum|nt}}
* {{Z|lo}}: {{W-|lo|ປໍສາ}}
* {{Z|ml}}: {{W-|mk|црница|m}}, {{W-|mk|дудинка|m}}
* {{Z|ms}}: {{W-|ms|mulberi}}
* {{Z|mt}}: {{W-|mt|tut|n}}, {{W-|mt|tuta|m}}
* {{Z|mi}}: {{W-|mi|māpere}}, {{W-|mi|maupere}}
* {{Z|mr}}: {{W-|mr|तुतीचे झाड|m|tr=tutīcē jhāḍa}}
* {{Z|hu}}: {{W+|hu|faeper}}, {{W+|hu|eper}}
* {{Z|nds}}: {{W-|nds|Muulbeer|m}}
* {{Z|no}}: {{W-|no|morbær|nt}}
* {{Z|os}}: {{W-|os|тута}}
* {{Z|ps}}: {{W+|ps|توت|tr=tût}}
* {{Z|pl}}: {{W+|pl|morwa|m}}
* {{Z|pt}}: {{W+|pt|amora|m}}
* {{Z|rm}}: {{W-|rm|mura|m}}
* {{Z|ro}}: {{W+|ro|dudă|m}}
* {{Z|ru}}: {{W+|ru|шелкови́ца|m}}, {{W+|ru|шелко́вица|m}}, {{W+|ru|тут|n}}
* {{Z|sh}}: {{W-|sh|ду̏д|n}}, {{W-|sh|му̑рва|m}} / {{W+|sh|dȕd|n}}, {{W+|sh|mȗrva|m}}
* {{Z|sl}}: {{W+|sl|murva}}
* {{Z|es}}: {{W+|es|mora|m}}
* {{Z|sw}}: {{W-|sw|forsadi}}, {{W-|sw|forosadi}}
* {{Z|sv}}: {{W+|sv|mullbär|nt}}
* {{Z|tg}}: {{W+|tg|тут}}
* {{Z|tl}}: {{W-|tl|moras}}
* {{Z|th}}: {{W+|th|หม่อน}}
* {{Z|tr}}: {{W+|tr|dut}}
* {{Z|to}}: {{W-|to|fuamelie}}
* {{Z|ur}}: {{W-|ur|شہتوت|tr=śehtūt}}, {{W-|ur|توت|tr=tūt}}
* {{Z|uk}}: {{W-|uk|шовковиця|f|cuda=шовкови́ця, шовко́виця}}
* {{Z|vec}}: {{W+|vec|moraro}}
* {{Z|vi}}: {{W-|vi|trái dâu}}
* {{Z|cy}}: {{W-|cy|mwyar Mair}}
* {{Z|yai}}: {{W-|yai|тут}}
* {{Z|el}}: {{W+|el|μούρο|nt}}
{{werger-bin}}
=== Navdêr 2 ===
{{navdêr|ku|z=n}}
[[Wêne:Cream_Drop.jpg|thumb|250px| tû (2)]]
# [[çerm]]ikê ku [[ser]] [[mast]]ê [[meyandin|meyandî]] [[girtin|digire]]
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav/nû|nêr}}
==== Hevmane ====
* [[tûk]]
* [[to]]
* [[sertû]]
* [[sertûk]]
* [[qeymax]]
* [[krêm]]
==== Jê ====
* [[sertû]]
* [[sertûk]]
* [[tûk]]
==== Etîmolojî ====
Hevreha soranî {{g|ckb|توێژ|tr=twêj}} û {{g|ckb|توێژاڵ|tr=twêjał}}, farisî {{g|fa|تو|tr=to}}, tatiya başûrî ''tûye''... hemû ji {{ji|ira}}.
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W-|af|room}}
* {{Z|sq}}: {{W+|sq|ajkë}}
* {{Z|de}}: {{W+|de|Rahm}}, {{W+|de|Sahne}}
* {{Z|alt}}: {{W-|alt|каймак}}
* {{Z|ba}}: {{W-|ba|ҡаймаҡ}}
* {{Z|br}}: {{W+|br|dienn}} {{mê}}
* {{Z|cs}}: {{W+|cs|smetana}}
* {{Z|cv}}: {{W-|cv|хăйма}}
* {{Z|da}}: {{W+|da|fløde}}
* {{Z|arz}}: {{W-|arz|قشطة|R=qišṭa}}
* {{Z|ar}}: {{W-|ar|قشطة|tr=qişṭe|cuda=قِشْطة}}, {{W-|ar|قشدة|tr=qişde|cuda=قِشْدة}}
* {{Z|eo}}: {{W-|eo|kremo}}
* {{Z|et}}: {{W-|et|kreem}}
* {{Z|fa}}: {{W+|fa|کرم|R=kêrêm}}
* {{Z|fo}}: {{W+|fo|rómi}}
* {{Z|gd}}: {{W-|gd|uachdar}}
* {{Z|gag}}: {{W-|gag|kaymak}}
* {{Z|gl}}: {{W+|gl|nata}}
* {{Z|nl}}: {{W+|nl|crème}}, {{W-|nl|puikje}}, {{W+|nl|room}}
* {{Z|he}}: {{W+|he|חמאה|cuda=חֶמְאָה}} {{mê}}
* {{Z|io}}: {{W+|io|kremo}}
* {{Z|en}}: {{W+|en|cream}}
* {{Z|it}}: {{W+|it|panna}} (1), {{W+|it|crema}}
* {{Z|krc}}: {{W-|krc|сют башы}}
* {{Z|ca}}: {{W+|ca|crema}}, {{W+|ca|nata}}
* {{Z|qu}}: {{W-|qu|nata}}
* {{Z|ky}}: {{W+|ky|каймак}}
* {{Z|co}}: {{W-|co|crema}}
* {{Z|kum}}: {{W-|kum|къаймакъ}}
* {{Z|moh}}: {{W-|moh|kawistohserókwen}}
* {{Z|nog}}: {{W-|nog|каймак}}
* {{Z|no}}: {{W-|no|fløte}}
* {{Z|oc}}: {{W+|oc|crèma}}
* {{Z|pap}}: {{W-|pap|krem}}, {{W-|pap|krèm}}, {{W-|pap|krema}}
* {{Z|pt}}: {{W+|pt|creme}}, {{W+|pt|nata}}
* {{Z|kk}}: {{W-|kk|қаймақ|tr=qaymaq}}
* {{Z|ro}}: {{W+|ro|smântână}}
* {{Z|se}}: {{W-|se|lákca}}
* {{Z|sk}}: {{W+|sk|smotana|f}}
* {{Z|ses}}: {{W-|ses|doonu}}
* {{Z|es}}: {{W+|es|crema}}, {{W+|es|nata}}, {{W-|es|natilla}}
* {{Z|sv}}: {{W+|sv|grädde}}, {{W+|sv|fläter}}
* {{Z|tt}}: {{W+|tt|каймак}}
* {{Z|tk}}: {{W-|tk|gaýmak}}
* {{Z|kim}}: {{W-|kim|сүт үзү}}
* {{Z|sah}}: {{W-|sah|чөчөгөй}}
* {{Z|el}}: {{W+|el|κρέμα}}
* {{Z|zu}}: {{W+|zu|ulaza}}
{{werger-bin}}
=== Navdêr 2 ===
{{navdêr|ku|z=}}
# (ava ji devî têt avêtin) {{bnr2|tif}}
== {{ziman|hac}} ==
=== Cînav ===
{{cînav|hac|sc=Latn}}
# [[tu]]
#* {{bêmînak|hac}}
== {{ziman|lki}} ==
=== Cînav ===
{{cînav|lki|sc=Latn}}
# [[tu]]
#* {{bêmînak|lki}}
51o8255do4m7w48jspkjx5jqorr1ity
protesto
0
19610
6347526
6314956
2026-09-01T09:28:51Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347526
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[xwe]] [[dij]]î kesekî yan tiştekî ne[[razî]]kirin, <br>kesek yan tiştek [[şermezar]]kirin, <br>[[diyar]]kirin ku kesekî yan tiştekî ne[[pejirandin|pejirîne]]
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Formên alternatîv ====
{{kol3|ku
|pirotest
|pirotesto
|protest
}}
==== Jê ====
{{kol3|ku
|protestoker
|protestoyî
|protesto kirin<crz:lêker>
|protestokirin<crz:navdêr>
|protestokirî<crz:rengdêr>
}}
==== Etîmolojî ====
{{ji?|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W-|af|beswaar}}, {{W-|af|protes}}
* {{Z|de}}: {{W+|de|Einspruch|m}}, {{W+|de|Protest|m}}, {{W+|de|Widerspruch|m}}
* {{Z|da}}: {{W-|da|protest}}
* {{Z|eo}}: {{W-|eo|protesto#Esperantoyî}}
* {{Z|fo}}: {{W-|fo|mótmæli}}
* {{Z|fi}}: {{W+|fi|vastalause}}, {{W+|fi|protesti}}
* {{Z|fr}}: {{W+|fr|protestation}}
* {{Z|nl}}: {{W+|nl|bezwaar}}, {{W+|nl|tegenwerping}}, {{W+|nl|protest}}
* {{Z|en}}: {{W+|en|protest}}, {{W+|en|objection}}, {{W+|en|outcry}}, {{W+|en|remonstrance}}, {{W+|en|remonstration}}
* {{Z|it}}: {{W+|it|protesta}}
* {{Z|pap}}: {{W-|pap|protesta}}
* {{Z|pt}}: {{W-|pt|protesto#Portugalî}}
* {{Z|es}}: {{W+|es|protesta}}, {{W+|es|objeción}}, {{W+|es|reparo}}
* {{Z|sv}}: {{W+|sv|protest}}
* {{Z|tr}}: {{W-|tr|protesto#Tirkî}}, {{W+|tr|ihtarname}}
{{werger-bin}}
== {{ziman|pt}} ==
=== Navdêr ===
{{navdêr|pt|z=n}}
# [[protesto]], [[xwe]][[ne]][[razî]][[kirin]]
#* {{bêmînak|pt}}
== {{ziman|tr}} ==
=== Navdêr ===
{{navdêr|tr}}
# [[protesto#Kurdî|protesto]], [[xwe]][[ne]][[razî]][[kirin]]
#* {{bêmînak|tr}}
4dno8qemr4m65urkelfh4vlwft1gfmm
6347536
6347526
2026-09-01T09:41:09Z
Balyozbot
7867
[[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan
6347536
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[xwe]] [[dij]]î kesekî yan tiştekî ne[[razî]]kirin, <br>kesek yan tiştek [[şermezar]]kirin, <br>[[diyar]]kirin ku kesekî yan tiştekî ne[[pejirandin|pejirîne]]
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Formên alternatîv ====
{{kol3|ku
|pirotest
|pirotesto
|protest
}}
==== Jê ====
{{kol3|ku
|protestoker
|protestoyî
|protesto kirin<crz:lêker>
|protestokirin<crz:navdêr>
|protestokirî<crz:rengdêr>
}}
==== Etîmolojî ====
{{ji?|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W-|af|beswaar}}, {{W-|af|protes}}
* {{Z|de}}: {{W+|de|Einspruch|m}}, {{W+|de|Protest|m}}, {{W+|de|Widerspruch|m}}
* {{Z|da}}: {{W-|da|protest}}
* {{Z|eo}}: {{W-|eo|protesto#Esperantoyî}}
* {{Z|fo}}: {{W-|fo|mótmæli}}
* {{Z|fi}}: {{W+|fi|vastalause}}, {{W+|fi|protesti}}
* {{Z|fr}}: {{W+|fr|protestation}}
* {{Z|nl}}: {{W+|nl|bezwaar}}, {{W+|nl|tegenwerping}}, {{W+|nl|protest}}
* {{Z|en}}: {{W+|en|protest}}, {{W+|en|objection}}, {{W+|en|outcry}}, {{W+|en|remonstrance}}, {{W+|en|remonstration}}
* {{Z|it}}: {{W+|it|protesta}}
* {{Z|pap}}: {{W-|pap|protesta}}
* {{Z|pt}}: {{W-|pt|protesto#Portugalî}}
* {{Z|es}}: {{W+|es|protesta}}, {{W+|es|objeción}}, {{W+|es|reparo}}
* {{Z|sv}}: {{W+|sv|protest}}
* {{Z|tr}}: {{W-|tr|protesto#Tirkî}}, {{W+|tr|ihtarname}}
{{werger-bin}}
== {{ziman|pt}} ==
=== Navdêr ===
{{navdêr|pt|z=n}}
# [[protesto]], [[xwe]][[ne]][[razî]][[kirin]]
#* {{bêmînak|pt}}
== {{ziman|tr}} ==
=== Navdêr ===
{{navdêr|tr}}
# [[protesto#Kurdî|protesto]], [[xwe]][[ne]][[razî]][[kirin]]
#* {{bêmînak|tr}}
64hbwbhvu72y9v5v4f3v85vzke5wx7z
teşî
0
20783
6347528
6327031
2026-09-01T09:30:50Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347528
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/tɛˈʃiː/}}
* {{kîte|ku|te|şî}}
=== Navdêr ===
[[Wêne:Drop spindles.jpg|thumb|teşî]]
{{navdêr|ku|z=m}}
# [[darik|Darik]]ek e mirov [[hirî|hiriyê]] pê dike [[ben]] û [[dezî]].
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Bi alfabeyên din ====
* {{ku-ar|تهشی}}
==== Jê ====
{{kol3|ku
|teşî ristin<crz:lêker>
|teşîristin<c:m><crz:navdêr>
|teşîrês
|teşîrêsî
}}
==== Etîmolojî ====
Ji {{ji|ine-pro|ku|-}} *[[terkʷ-]] ([[badan]], [[alandin]]), hevreha {{hv|sa|तर्कु}} (terku), hîtîtî [[𒋻𒆪𒉿𒀭𒍣]] (tarkuwanzi), slavoniya kevn [[тракъ]] (trakŭ), {{hv|grc|τρέπω}} (trêpo) û {{hv|la|torqueo}}
==== Bide ber ====
{{kol3|ku
|teşk
|tîşk
}}
==== Herwiha binêre ====
{{kol3|ku
|berhan
|nêk
|serteşî
|teşîrês
}}
==== Werger ====
{{kontrolWerger}}
{{werger-ser}}
* {{Z|de}}: {{W+|de|Spindel|f}}, {{W-|de|Spinnrocken}}, {{W-|de|Handspindel}}
* {{Z|ar}}: {{W-|ar|مغزل}}, {{W-|ar|القرناس|guman=erê}}, {{W-|ar|عرناس|guman=erê}}
* {{Z|fa}}: {{W+|fa|دوک}}, {{W+|fa|دوک}}
* {{Z|fi}}: {{W+|fi|värttinä}}
* {{Z|en}}: {{W-|en|spindle|tr=for spinning fibres into thread}}, {{W+|en|distaff}}, {{W+|en|trunnion}}, {{W-|en|hand spindle|guman=erê}}
* {{Z|is}}: {{W-|is|snælda}}
* {{Z|pl}}: {{W+|pl|wrzeciono}}
* {{Z|tr}}: {{W+|tr|iğ}}, {{W+|tr|cehre}}, {{W+|tr|kirmen}}, {{W+|tr|öreke}}, {{W-|tr|oklu}}, {{W+|tr|eğirmen|guman=erê}}, {{W+|tr|iğlik|guman=erê}}
{{werger-bin}}
7puuoaifa4ocfwhj5khsnxde7zetnt6
6347603
6347528
2026-09-01T11:12:17Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347603
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/tɛˈʃiː/}}
* {{kîte|ku|te|şî}}
=== Navdêr ===
[[Wêne:Drop spindles.jpg|thumb|teşî]]
{{navdêr|ku|z=m}}
# [[darik|Darikek]] e mirov [[hirî|hiriyê]] pê dike [[ben]] û [[dezî]].
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Bi alfabeyên din ====
* {{ku-ar|تهشی}}
==== Jê ====
{{kol3|ku
|teşî ristin<crz:lêker>
|teşîristin<c:m><crz:navdêr>
|teşîrês
|teşîrêsî
}}
==== Etîmolojî ====
Ji {{ji|ine-pro|ku|-}} *[[terkʷ-]] ([[badan]], [[alandin]]), hevreha {{hv|sa|तर्कु}} (terku), hîtîtî [[𒋻𒆪𒉿𒀭𒍣]] (tarkuwanzi), slavoniya kevn [[тракъ]] (trakŭ), {{hv|grc|τρέπω}} (trêpo) û {{hv|la|torqueo}}
==== Bide ber ====
{{kol3|ku
|teşk
|tîşk
}}
==== Herwiha binêre ====
{{kol3|ku
|berhan
|nêk
|serteşî
|teşîrês
}}
==== Werger ====
{{kontrolWerger}}
{{werger-ser}}
* {{Z|de}}: {{W+|de|Spindel|f}}, {{W-|de|Spinnrocken}}, {{W-|de|Handspindel}}
* {{Z|ar}}: {{W-|ar|مغزل}}, {{W-|ar|القرناس|guman=erê}}, {{W-|ar|عرناس|guman=erê}}
* {{Z|fa}}: {{W+|fa|دوک}}, {{W+|fa|دوک}}
* {{Z|fi}}: {{W+|fi|värttinä}}
* {{Z|en}}: {{W-|en|spindle|tr=for spinning fibres into thread}}, {{W+|en|distaff}}, {{W+|en|trunnion}}, {{W-|en|hand spindle|guman=erê}}
* {{Z|is}}: {{W-|is|snælda}}
* {{Z|pl}}: {{W+|pl|wrzeciono}}
* {{Z|tr}}: {{W+|tr|iğ}}, {{W+|tr|cehre}}, {{W+|tr|kirmen}}, {{W+|tr|öreke}}, {{W-|tr|oklu}}, {{W+|tr|eğirmen|guman=erê}}, {{W+|tr|iğlik|guman=erê}}
{{werger-bin}}
ntck28vyudhntb71afby3dyqo1wy4j1
ajar
0
21288
6347571
6296317
2026-09-01T10:21:49Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347571
wikitext
text/x-wiki
{{bnr-h|Ajar}}
== {{ziman|ku}} ==
=== Navdêr ===
{{navdêr|ku|z=m}} {{r-ya req}}
# [[binemal]], [[dûnde]], [[zuryet]], [[ûcax]], [[malbat]], [[silale]], [[komrig]], [[eylet]], [[dol]]
#* {{bêmînak|ku}}
# {{kontrol|rêz=erê|[[secere]], [[darav]], [[ayle]]}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Notên bikaranînê ====
''Ev peyv di ferhenga tirkî-kurdî ya Zana Farqînî de, li ber peyva "sülale" ya tirkî hatiye dîtin. Di weşanên din yên kurdî de em pêrgî vê peyvê nehatine.''
==== Formên alternatîv ====
{{kol3|ku
|ajer
}}
==== Jê ====
{{kol3|ku|cure=Jê
|bêajar
|bêajarî
|bêajarîtî
|bêajartî
|biajar
|biajarî
|biajarîtî
|biajartî
|ajardar
|ajardarî
|ajardêr
|ajardêrî
|ajarkor
|ajarkorî
}}
==== Etîmolojî ====
Hevreh bi {{hv|ckb|ئاژاڵ|w=terş, dewar}}. Dibe ku têkilî {{q|ku|aj}} û {{q|ku|ajro}}. {{cotreh|ku|ajal}}.
==== Bide ber ====
{{kol3|ku
|ajal
|azar
}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Abkömmling|n}}, {{W+|de|Nachkomme|n}}
* {{Z|fa}}: {{W-|fa|سبزینه یونجه}}
* {{Z|fi}}: {{W+|fi|jälkeläinen}}
* {{Z|fr}}: {{W+|fr|progéniture}}, {{W+|fr|lignée}}
* {{Z|en}}: {{W+|en|descendent}}, {{W+|en|progeny}}, [[descendent]]s, [[offspring]]s
* {{Z|it}}: {{W+|it|progenie}}
* {{Z|pt}}: {{W+|pt|progênie}}
* {{Z|ru}}: {{W+|ru|потомок}}, {{W+|ru|отпрыск}}
* {{Z|es}}: {{W+|es|descendencia}}, {{W-|es|progenitura}}, {{W+|es|progenie}}
* {{Z|sv}}: {{W+|sv|avkomma}}, {{W+|sv|efterkommande}}
* {{Z|tr}}: {{W+|tr|soy}}, {{W+|tr|sülale}}, {{W+|tr|zürriyet}}, {{W+|tr|cephane}}
{{werger-bin}}
== {{ziman|en}} ==
=== Bilêvkirin ===
* {{deng|en|en-us-ajar.ogg|dever=DYA}}
* {{deng|en|en-au-ajar.ogg|dever=Awistralya}}
=== Hoker ===
{{hoker|en}}
# piçekê vekirî<ref>Ferhenga Kurdî-Îngîlîzî ya Salah Sadallah</ref>
#* {{bêmînak|en}}
=== Rengdêr ===
{{rengdêr|en}}
# piçekê vekirî
#* {{bêmînak|en}}
=== Çavkanî ===
{{çavkanî}}
fm4te0jkes4ci0r5v1ji3y6gg7iwqzn
pena
0
22360
6347618
6314236
2026-09-01T11:32:40Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347618
wikitext
text/x-wiki
{{bnr-h|Pena}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/pɛˈnɑː/}}
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Udaygiri cave (dwellings), Orissa.jpg|thumb|250px|Mirov û heywanan [[şkeft]] bo xwe wek penagehan bi kar anîne.]]
{{navdêr|ku|z=m}}
# Cihê ku mirov diçiyê daku ji [[bela]] û [[talûke]]yan [[revîn|bireve]] û [[filitîn|bifilite]].
#: {{hevmane|ku|sitare|sitargeh|[[cih]]ê [[ewle]]|[[der]]a [[temîn]]}}
#* {{bêmînak|ku}}
# [[pişgirî]], [[piştevanî]], [[destek]], [[alîkarî]]
#* {{bêmînak|ku}}
# [[gazî]], [[hewar]], [[hêvî]], [[rica]]
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Bi alfabeyên din ====
* {{ku-ar|پهنا}}
==== Jê ====
{{kol3|ku
|penaber
|penaberî
|penageh
|penahind
|penahindî
|penaxwaz
|penaxwazî
|pena birin
|pena xwe bo (yekî) birin
}}
==== Etîmolojî ====
Ji {{deyn|ckb|ku|پهنا|tr=pena}} yan bi rêya soranî ji {{ji|fa|ku|پناه|tr=penah}}, hevreha pehlewî [[𐭯𐭭𐭠𐭧]] (penah). Peyva "pena" vê dawiyê bi rêya zimanê nivîskî ketiye nav gel, di devokên kurmancî bi xwe de nîne. {{q|tr|penah}} ya tirkî, {{g|ar|پناه|tr=penah}} ya urdûyî û [[पनाह]] (penah) ya hindî ji îranî - bi taybetî ji farisî - hatine wergirtin.
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W-|af|toevlugsoord}}
* {{Z|sq}}: {{W+|sq|strehim}}
* {{Z|de}}: {{W+|de|Asyl|n}}, {{W+|de|Bucht|f}}, {{W+|de|Zuflucht}}
* {{Z|bg}}: {{W+|bg|убежище}}
* {{Z|cs}}: {{W+|cs|refýž}}, [[chodníèe]]k, {{W-|cs|útulek}}, {{W-|cs|útoèištì}}
* {{Z|zh}}: {{W+|zh|避难所}}, {{W-|zh|避難所}}
* {{Z|id}}: {{W+|id|berlindung}}
* {{Z|ar}}: {{W-|ar|ملجأ}}, {{W-|ar|مأوى}}, {{W-|ar|لجأ}}, {{W-|ar|لجأ|guman=erê}}, {{W-|ar|ملجأ|guman=erê}}
* {{Z|eo}}: {{W-|eo|rifuĝo}}
* {{Z|fa}}: {{W-|fa|پناه|tr=penah}}, {{W-|fa|پناهگاه|tr=penagah}}, {{W-|fa|پناهندگی|tr=penahendegî}}, {{W+|fa|پناه}}, {{W+|fa|خواسته}}, {{W+|fa|امید}}, {{W-|fa|محل امن|guman=erê}}
* {{Z|fi}}: {{W+|fi|turvapaikka}}, {{W-|fi|rauhoitusalue}}, {{W+|fi|suoja}}
* {{Z|fr}}: {{W+|fr|refuge}}, {{W+|fr|abri}}, {{W+|fr|asile}}
* {{Z|nl}}: {{W+|nl|toevlucht}}
* {{Z|he}}: {{W+|he|מקלט}}, {{W+|he|מפלט}}, {{W-|he|מחסע}}, {{W+|he|מסתור}}
* {{Z|en}}: {{W+|en|refuge}}, {{W+|en|sanctuary}}, {{W+|en|shelter}}, {{W+|en|asylum}}, {{W+|en|haven}}, {{W+|en|lodge|guman=erê}}, {{W+|en|lodgement|guman=erê}}, {{W+|en|lodgment|guman=erê}}, {{W+|en|purlieu|guman=erê}}, {{W+|en|tabernacle|guman=erê}}, {{W+|en|hiding place|guman=erê}}, {{W+|en|siegeworks|guman=erê}}
* {{Z|it}}: {{W+|it|rifugio}}, {{W+|it|ricovero}}, {{W+|it|lustra}}
* {{Z|ja}}: {{W+|ja|隠れ家}}, {{W-|ja|隠れ場所}}, {{W-|ja|逃で場}}, {{W-|ja|駆け込み寺}}
* {{Z|gv}}: {{W-|gv|kemmyrk}}
* {{Z|hu}}: {{W+|hu|óvóhely}}
* {{Z|pt}}: {{W+|pt|refúgio}}
* {{Z|ro}}: {{W+|ro|refugiu}}, {{W-|ro|scutealã}}, {{W+|ro|azil}}
* {{Z|ru}}: {{W+|ru|убежище}}
* {{Z|sco}}: {{W-|sco|tèarmunn}}
* {{Z|es}}: {{W+|es|refugio}}
* {{Z|sv}}: {{W+|sv|asyl}}, {{W+|sv|fristad}}, {{W+|sv|tillflykt}}
* {{Z|tr}}: {{W+|tr|barınak}}, {{W+|tr|sığınak}}, {{W+|tr|refüj}}, {{W+|tr|iltica}}, {{W+|tr|penah}}, {{W+|tr|sığınma|guman=erê}}, {{W+|tr|korunak|guman=erê}}
* {{Z|tk}}: {{W-|tk|halas}}
* {{Z|uk}}: {{W+|uk|притулок}}, {{W-|uk|порятунок}}, {{W-|uk|сховатися}}, {{W-|uk|утіха}}
* {{Z|el}}: {{W+|el|καταφύγιο}}
{{werger-bin}}
== {{ziman|tr}} ==
=== Navdêr ===
{{navdêr|tr}}
# [[mizrab]]
#* {{bêmînak|tr}}
o6sp8k8dgwkebpmlv9fmotdl2myr0lw
kotek
0
23907
6347445
6329200
2026-08-31T19:30:03Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347445
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[zordarî]], [[tade]], [[zilm]], [[zor]], [[darê zorê]], [[stem]], [[sengî]], [[fişar]], [[pesto]], [[zompe]]
#* {{jêder-malper|ku|jêgirtin=Şixul nabe bi '''kotek''' û zorê.|nivîskar=Karapetê Xaço|sernav=Zembîlfiroş|url=http://www.stranenkurdi.com/karapete-xaco-zembilfiros/|malper=stranenkurdi.com}}
#* {{jêder-pirtûk|ku|jêgirtin=Lewranê Ekrad ku hene xoşnişîn in û bi kêfa xo ne. Bi '''kotek''' nabitin|nivîskar=w:Mele Mehmûdê Bazîdî|edîtor=w:Mîkaîl Bilbil; w:Mistafa Oztirk |sernav=w:Tûhfetu'l-Xîlan Fî Zimanê Kurdan |weşanxane= Weqfa Mezopotamyayê |sal=1866|sala-weşandinê=2019|çap=1|rûpel=103|isbn=978-605-80975-1-3}}
#* {{jêder|ku|jêgirtin=Umîd me herdem bi xwe serdarê li Berzan<br>Wek Tîrêj dibêje: jîn divê '''kotek''' û zor e.|''Bilbilê Dilşadî'', [[w:Seydayê Tîrêj|Seydayê Tîrêj]]}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Bi alfabeyên din ====
* {{ku-ar|کۆتەک}}
==== Formên alternatîv ====
{{kol3|ku
|kutik<t:[[lêdan]]>
}}
==== Jê ====
{{kol3|ku
|kotekî
|bi kotek
|kotekxwarin<crz:navdêr>
|kotek xwarin<crz:lêker>
}}
==== Etîmolojî ====
Hevreha {{hv|fa|کوتنگ|tr=koteng|t=[[dar]], [[dardest]], [[doqişk]], darê [[lê dan|lêdanê]]}}, belkî ji {{ji|el|ku|κώδικος}} (kodîkos: [[qurm]]ê darê). Di kurdî de tenê bi maneya xwe ya [[mecazî]] peyda dibe. {{g|tr|[[kötek|Kötek]]}} û {{g|tr|kütük}} yên tirkî ji eynî rehî ne.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|Drang}} {{n}}, {{W|de|Druck}} {{n}}, {{W|de|Drücken}}, {{W|de|Gewalt}} {{mê}}, {{W|de|Zwang}} {{n}}, {{W|de|Holzhammer|guman=erê}}, {{W|de|Despot|m|guman=erê}}
* {{Z|fa}}: {{W|fa|کتک}}, {{W|fa|زدن}}, {{W|fa|تکلیف|guman=erê}}, {{W|fa|میرغضب|guman=erê}}
* {{Z|en}}: {{W|en|crackdown}}, {{W|en|pressure}}, {{W|en|oppression}}, {{W|en|cruelty}}, {{W|en|bastinado}}, {{W|en|pest}}, {{W|en|beating}}, {{W|en|despot|guman=erê}}, {{W|en|pestle|guman=erê}}, {{W|en|pounder|guman=erê}}, {{W|en|tamp|guman=erê}}, {{W|en|demanding|guman=erê}}, {{W|en|thrashing|guman=erê}}
* {{Z|tr}}: {{W|tr|basınç}}, {{W|tr|baskı}}, {{W|tr|dayak}}, {{W|tr|dövme}}, {{W|tr|kötek}}, {{W|tr|patak}}, {{W|tr|pest}}, {{W|tr|zor}}, {{W|tr|bastırık|guman=erê}}, {{W|tr|cebir|guman=erê}}, {{W|tr|istinat|guman=erê}}, {{W|tr|istinat direği|guman=erê}}, {{W|tr|kazık|guman=erê}}, {{W|tr|payanda|guman=erê}}
{{werger-bin}}
== {{ziman|ms}} ==
=== Navdêr ===
{{navdêr|ms}}
# {{mijar|ms|anatomî}} {{g|ku|kîr}}
#* {{bêmînak|ms}}
=== Çavkanî ===
{{rûpela wergerê|ms|kîr}}
bgyp0zjx91i3ds3mxzelimmgcca9jel
bêvan
0
27573
6347599
6263924
2026-09-01T11:12:06Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes)
6347599
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/beːˈvɑːn/}}
* {{kîte|ku|bê|van}}
=== Navdêr ===
{{navdêr|ku}}
# [[kes|Kesên]] yan [[tişt|tiştên]] ku [[nav|navê]] wan [[nayê gotin]]
#: {{hevmane|ku|filan|fîstan}}
#:''Got ji filanî û bêvanî bipirse. Min pirsî lê wan jî nedizanî.''
==== Formên alternatîv ====
* [[bêhvan]]
* [[bihvan]]
==== Nîşeyên karînanê ====
Di kurdiya nûjen de bi tena serê xwe bi kar nayê, tenê wek ''filan û bêvan''.
==== Etîmolojî ====
Herwiha [[bêhvan]], hevzaya {{hv|fa|بهمان|tr=behman}}, {{hv|pal|𐭥𐭠𐭧𐭬𐭠𐭭𐭩||tr=wahman}}. Bide ber {{q|ku|wihan}} û {{q|ku|heman}}.
==== Anagram ====
* {{anagram|ku|bênav}}
==== Werger ====
{{werger-ser}}
* {{Z|fa}}: {{W+|fa|ناپیدا}}, {{W+|fa|مکتوم}}, {{W+|fa|پنهان}}
* {{Z|fi}}: [[se-ja-se]] [[henkilö]]
* {{Z|en}}: {{W+|en|so-and-so}}, {{W+|en|thingamy|guman=erê}}, {{W-|en|what's HIS NAME|guman=erê}}
* {{Z|pt}}: {{W+|pt|fulano}}
* {{Z|ru}}: {{W-|ru|так-то и так-то}}
* {{Z|es}}: {{W+|es|fulano}}
* {{Z|tr}}: {{W+|tr|filan}}
{{werger-bin}}
5wuvm80gk8ca9a9t5k89vk7onfkblad
6347605
6347599
2026-09-01T11:12:23Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347605
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/beːˈvɑːn/}}
* {{kîte|ku|bê|van}}
=== Navdêr ===
{{navdêr|ku}}
# [[kes|Kesên]] yan [[tişt|tiştên]] ku [[nav|navê]] wan [[nayê gotin]].
#: {{hevmane|ku|filan|fîstan}}
#: {{nm|ku|Got ji filanî û bêvanî bipirse. Min pirsî lê wan jî nedizanî.}}
==== Formên alternatîv ====
* [[bêhvan]]
* [[bihvan]]
==== Nîşeyên karînanê ====
Di kurdiya nûjen de bi tena serê xwe bi kar nayê, tenê wek ''filan û bêvan''.
==== Etîmolojî ====
Herwiha [[bêhvan]], hevzaya {{hv|fa|بهمان|tr=behman}}, {{hv|pal|𐭥𐭠𐭧𐭬𐭠𐭭𐭩||tr=wahman}}. Bide ber {{q|ku|wihan}} û {{q|ku|heman}}.
==== Anagram ====
* {{anagram|ku|bênav}}
==== Werger ====
{{werger-ser}}
* {{Z|fa}}: {{W+|fa|ناپیدا}}, {{W+|fa|مکتوم}}, {{W+|fa|پنهان}}
* {{Z|fi}}: [[se-ja-se]] [[henkilö]]
* {{Z|en}}: {{W+|en|so-and-so}}, {{W+|en|thingamy|guman=erê}}, {{W-|en|what's HIS NAME|guman=erê}}
* {{Z|pt}}: {{W+|pt|fulano}}
* {{Z|ru}}: {{W-|ru|так-то и так-то}}
* {{Z|es}}: {{W+|es|fulano}}
* {{Z|tr}}: {{W+|tr|filan}}
{{werger-bin}}
gpf6402fypgtn6vx0qccdfe3cuvslv5
6347627
6347605
2026-09-01T11:41:10Z
Balyozbot
7867
[[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan
6347627
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/beːˈvɑːn/}}
* {{kîte|ku|bê|van}}
=== Navdêr ===
{{navdêr|ku}}
# [[kes|Kesên]] yan [[tişt|tiştên]] ku [[nav|navê]] wan [[nayê gotin]].
#: {{hevmane|ku|filan|fîstan}}
#: {{nm|ku|Got ji filanî û bêvanî bipirse. Min pirsî lê wan jî nedizanî.}}
==== Formên alternatîv ====
* [[bêhvan]]
* [[bihvan]]
==== Etîmolojî ====
Herwiha [[bêhvan]], hevzaya {{hv|fa|بهمان|tr=behman}}, {{hv|pal|𐭥𐭠𐭧𐭬𐭠𐭭𐭩||tr=wahman}}. Bide ber {{q|ku|wihan}} û {{q|ku|heman}}.
==== Nîşeyên karînanê ====
Di kurdiya nûjen de bi tena serê xwe bi kar nayê, tenê wek ''filan û bêvan''.
==== Werger ====
{{werger-ser}}
* {{Z|fa}}: {{W+|fa|ناپیدا}}, {{W+|fa|مکتوم}}, {{W+|fa|پنهان}}
* {{Z|fi}}: [[se-ja-se]] [[henkilö]]
* {{Z|en}}: {{W+|en|so-and-so}}, {{W+|en|thingamy|guman=erê}}, {{W-|en|what's HIS NAME|guman=erê}}
* {{Z|pt}}: {{W+|pt|fulano}}
* {{Z|ru}}: {{W-|ru|так-то и так-то}}
* {{Z|es}}: {{W+|es|fulano}}
* {{Z|tr}}: {{W+|tr|filan}}
{{werger-bin}}
==== Anagram ====
* {{anagram|ku|bênav}}
13wvblhnhtv2xjr4r887593swimho4w
lawij
0
28427
6347529
6335813
2026-09-01T09:35:18Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347529
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[daxwaz]|Daxwaz]ên ku mirov ji [[Xwedê]] dike bi taybetî [[stran]]ên [[dînî]], [[neşîde]], [[îlahî]].
#: {{hevmane|ku|lava|dua}}
#* {{J:Mele Mehmûdê Bayezîdî:Adat û Rusûmatnameê Ekradiye|r=112|jêgirtin=Wekû mirovek fewt bûyî (miriye), feryad û girîn peyda dibi. îcarê ehlê (kesên) mala meyyitî (yê mirî) berhev cihekî dikin û jinêd dengbêj heyîn, '''Lawjok''' û Siwaro dibêjin û dikine quri (hawar û gazî)}}
# {{kontrol|rêz=erê|[[daxwaz]], [[hewîş]], [[parîn]], [[niyaz]], [[hêvî]]}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|lawij kirin<crz:lêker>
|lawijkirin<crz:navdêr><c:m>
|lawijkar
|lawijkarî
|lawijker
|lawijkerî
|lawijî
}}
==== Etîmolojî ====
Herwiha [[lavij]], [[lawje]], gengazkî hevreha [[lava]], {{q|ku|law|w=kurr}}, {{q|ku|law|w=stran}}, [[lawir]]; bi ramana "''deng derxistin''". Dibe ku ji lêkerek berê a {{jinûvesazî|ku|lawijîn}}/{{jinûvesazî|ku|lavijîn}} (wek [[kelij]] < [[kelijîn]]). Dibe ku [[nimêj]] (devokî [[limêj]], [[livêj]]) jî hevreh bibe lê ev bi pirsgirêkên dengnasîkî tê.
==== Bide ber ====
{{kol3|ku
|lawik
}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: [[Gebet]] {{nt}} [[Beten]] {{nt}}, {{W|de|Gottesdienst|m}}, {{W|de|Lied|m}}
* {{Z|fi}}: {{W+|fi|rukous}}
* {{Z|fr}}: {{W|fr|prière|f}}, [[prières]] ''f pl''
* {{Z|nl}}: {{W|nl|gebed|n}}
* {{Z|ang}}: {{W+|ang|gebed}}
* {{Z|en}}: {{W-|en|prayer}}, {{W+|en|anthem}}, {{W|en|heroic song|guman=erê}}, {{W|en|love song|guman=erê}}
* {{Z|la}}: {{W|la|molitva|f}}, {{W|la|molba|f}}
* {{Z|pl}}: {{W|pl|modlitwa|f}}
* {{Z|ro}}: {{W|ro|rugăciune|f}}, [[rugăciuni]] {{p}}
* {{Z|sh}}: {{W|sh|molitva|f}}, {{W|sh|molba|f}}, [[молитва]] {{mê}}, [[молба]] {{mê}}
* {{Z|sl}}: {{W|sl|molitev|f}}
* {{Z|es}}: {{W+|es|rezo}}, {{W+|es|oración}}
* {{Z|tr}}: {{W+|tr|dua#Tirkî}}, {{W+|tr|deyiş}}, {{W+|tr|ilâhî}}, {{W+|tr|litürji}}
* {{Z|grc}}: {{W|grc|προσευχή|f}}
* {{Z|el}}: {{W|el|προσευχή|f}}
{{werger-bin}}
jqf47a3ynyvutvinj3xgnquj7zun105
6347530
6347529
2026-09-01T09:35:29Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347530
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[daxwaz|Daxwaz]]ên ku mirov ji [[Xwedê]] dike bi taybetî [[stran]]ên [[dînî]], [[neşîde]], [[îlahî]].
#: {{hevmane|ku|lava|dua}}
#* {{J:Mele Mehmûdê Bayezîdî:Adat û Rusûmatnameê Ekradiye|r=112|jêgirtin=Wekû mirovek fewt bûyî (miriye), feryad û girîn peyda dibi. îcarê ehlê (kesên) mala meyyitî (yê mirî) berhev cihekî dikin û jinêd dengbêj heyîn, '''Lawjok''' û Siwaro dibêjin û dikine quri (hawar û gazî)}}
# {{kontrol|rêz=erê|[[daxwaz]], [[hewîş]], [[parîn]], [[niyaz]], [[hêvî]]}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|lawij kirin<crz:lêker>
|lawijkirin<crz:navdêr><c:m>
|lawijkar
|lawijkarî
|lawijker
|lawijkerî
|lawijî
}}
==== Etîmolojî ====
Herwiha [[lavij]], [[lawje]], gengazkî hevreha [[lava]], {{q|ku|law|w=kurr}}, {{q|ku|law|w=stran}}, [[lawir]]; bi ramana "''deng derxistin''". Dibe ku ji lêkerek berê a {{jinûvesazî|ku|lawijîn}}/{{jinûvesazî|ku|lavijîn}} (wek [[kelij]] < [[kelijîn]]). Dibe ku [[nimêj]] (devokî [[limêj]], [[livêj]]) jî hevreh bibe lê ev bi pirsgirêkên dengnasîkî tê.
==== Bide ber ====
{{kol3|ku
|lawik
}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: [[Gebet]] {{nt}} [[Beten]] {{nt}}, {{W|de|Gottesdienst|m}}, {{W|de|Lied|m}}
* {{Z|fi}}: {{W+|fi|rukous}}
* {{Z|fr}}: {{W|fr|prière|f}}, [[prières]] ''f pl''
* {{Z|nl}}: {{W|nl|gebed|n}}
* {{Z|ang}}: {{W+|ang|gebed}}
* {{Z|en}}: {{W-|en|prayer}}, {{W+|en|anthem}}, {{W|en|heroic song|guman=erê}}, {{W|en|love song|guman=erê}}
* {{Z|la}}: {{W|la|molitva|f}}, {{W|la|molba|f}}
* {{Z|pl}}: {{W|pl|modlitwa|f}}
* {{Z|ro}}: {{W|ro|rugăciune|f}}, [[rugăciuni]] {{p}}
* {{Z|sh}}: {{W|sh|molitva|f}}, {{W|sh|molba|f}}, [[молитва]] {{mê}}, [[молба]] {{mê}}
* {{Z|sl}}: {{W|sl|molitev|f}}
* {{Z|es}}: {{W+|es|rezo}}, {{W+|es|oración}}
* {{Z|tr}}: {{W+|tr|dua#Tirkî}}, {{W+|tr|deyiş}}, {{W+|tr|ilâhî}}, {{W+|tr|litürji}}
* {{Z|grc}}: {{W|grc|προσευχή|f}}
* {{Z|el}}: {{W|el|προσευχή|f}}
{{werger-bin}}
cm3q7v7b2v830lfrtfxskl906vx84df
6347602
6347530
2026-09-01T11:12:14Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347602
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[daxwaz|Daxwazên]] ku mirov ji [[Xwedê]] dike bi taybetî [[stran]]ên [[dînî]], [[neşîde]], [[îlahî]].
#: {{hevmane|ku|lava|dua}}
#* {{J:Mele Mehmûdê Bayezîdî:Adat û Rusûmatnameê Ekradiye|r=112|jêgirtin=Wekû mirovek fewt bûyî (miriye), feryad û girîn peyda dibi. îcarê ehlê (kesên) mala meyyitî (yê mirî) berhev cihekî dikin û jinêd dengbêj heyîn, '''Lawjok''' û Siwaro dibêjin û dikine quri (hawar û gazî)}}
# {{kontrol|rêz=erê|[[daxwaz]], [[hewîş]], [[parîn]], [[niyaz]], [[hêvî]]}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|lawij kirin<crz:lêker>
|lawijkirin<crz:navdêr><c:m>
|lawijkar
|lawijkarî
|lawijker
|lawijkerî
|lawijî
}}
==== Etîmolojî ====
Herwiha [[lavij]], [[lawje]], gengazkî hevreha [[lava]], {{q|ku|law|w=kurr}}, {{q|ku|law|w=stran}}, [[lawir]]; bi ramana "''deng derxistin''". Dibe ku ji lêkerek berê a {{jinûvesazî|ku|lawijîn}}/{{jinûvesazî|ku|lavijîn}} (wek [[kelij]] < [[kelijîn]]). Dibe ku [[nimêj]] (devokî [[limêj]], [[livêj]]) jî hevreh bibe lê ev bi pirsgirêkên dengnasîkî tê.
==== Bide ber ====
{{kol3|ku
|lawik
}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: [[Gebet]] {{nt}} [[Beten]] {{nt}}, {{W|de|Gottesdienst|m}}, {{W|de|Lied|m}}
* {{Z|fi}}: {{W+|fi|rukous}}
* {{Z|fr}}: {{W|fr|prière|f}}, [[prières]] ''f pl''
* {{Z|nl}}: {{W|nl|gebed|n}}
* {{Z|ang}}: {{W+|ang|gebed}}
* {{Z|en}}: {{W-|en|prayer}}, {{W+|en|anthem}}, {{W|en|heroic song|guman=erê}}, {{W|en|love song|guman=erê}}
* {{Z|la}}: {{W|la|molitva|f}}, {{W|la|molba|f}}
* {{Z|pl}}: {{W|pl|modlitwa|f}}
* {{Z|ro}}: {{W|ro|rugăciune|f}}, [[rugăciuni]] {{p}}
* {{Z|sh}}: {{W|sh|molitva|f}}, {{W|sh|molba|f}}, [[молитва]] {{mê}}, [[молба]] {{mê}}
* {{Z|sl}}: {{W|sl|molitev|f}}
* {{Z|es}}: {{W+|es|rezo}}, {{W+|es|oración}}
* {{Z|tr}}: {{W+|tr|dua#Tirkî}}, {{W+|tr|deyiş}}, {{W+|tr|ilâhî}}, {{W+|tr|litürji}}
* {{Z|grc}}: {{W|grc|προσευχή|f}}
* {{Z|el}}: {{W|el|προσευχή|f}}
{{werger-bin}}
t95tr0uui0uevue9gb6q1potb2er8lt
Behra Reş
0
29085
6347355
6132949
2026-08-31T12:52:30Z
Wikihez
7344
+nimûneya bikaranînê bi amûra « [[Mediawiki:Gadget-wikt.add-examples|Nimûne zêde bike]] » (v2.0).
6347355
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Serenav ===
[[Wêne:Black Sea map ku.png|thumb|Behra Reş]]
{{serenav|ku|z=m|[[behr|Behra]] [[reş|Reş]]}}
# {{e|ku|behr}} Behra [[navber]]a [[Tirkiye]], [[Ukrayna]] û [[Rusya]]yê.
#: {{hevmane|ku|Deryaya Reş}}
#* {{jêder-websîte|ku|nivîskar=Rohat Alakom|websîte=Kovara Bîr|sernav=Behra Reş Dibe Goristan (1942)|url=https://www.kovarabir.com/505/rohat-alakom-behra-res-dibe-goristan-1942/kmr/|tarîx=17.05.2021|jêgirtin=Lê belê wek me jorê li qala wê kir, keştî tê binavkirin û Nadia jî wek wan 759 kesên din di '''Behra Reş''' da dixeniqin.}}
==== Binêre herwiha ====
{{kol3|ku
|Behra Sor
}}
* {{wpedî}}
==== Werger ====
{{werger-ser|Behra navbera Tirkiye û Rusyayê}}
* {{Z|ab}}: {{W-|ab|Амшын Еиқәа|sc=Cyrl}}
* {{Z|ady}}: {{W-|ady|Хы Шӏуцӏ}}
* {{Z|af}}: {{W+|af|Swartsee}}
* {{Z|sq}}: {{W-|sq|Deti i Zi|n}}
* {{Z|de}}: {{W+|de|Schwarzes Meer|nt}}
* {{Z|alt}}: {{W-|alt|Кара талай}}, {{W-|alt|Кара теҥис}}
* {{Z|am}}: {{W-|am|ጥቁር ባሕር|sc=Ethi}}
* {{Z|an}}: {{W-|an|Mar Negro|n}}
* {{Z|aii}}: {{W-|aii|ܝܵܡܵܐ ܐ݇ܟܘܿܡܵܐ|n}}
* {{Z|ast}}: {{W-|ast|Mar Negru|n}}
* {{Z|az}}: {{W+|az|Qara dəniz}}
* {{Z|eu}}: {{W-|eu|Itsaso Beltza}}
* {{Z|ba}}: {{W-|ba|Ҡара диңгеҙ|sc=Cyrl}}
* {{Z|bar}}: {{W-|bar|Schwoazz Meea}}
* {{Z|be}}: {{W-|be|Чо́рнае мо́ра|nt}}
* {{Z|bn}}: {{W-|bn|কালা দরিয়া}}
* {{Z|br}}: {{W-|br|Mor Du}}
* {{Z|bg}}: {{W-|bg|Че́рно море́|nt}}
* {{Z|my}}: {{W-|my|ပင်လယ်နက်|sc=Mymr}}
* {{Z|ce}}: {{W-|ce|Ӏаьржа хӀорд}}
* {{Z|cs}}: {{W+|cs|Černé moře|nt}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|黑海|tr=Hēihǎi}}
* {{Z|cv}}: {{W-|cv|Хура тинӗс}}
* {{Z|da}}: {{W+|da|Sortehavet|nt}}
* {{Z|id}}: {{W-|id|Laut Hitam}}
* {{Z|ar}}: {{W-|ar|الْبَحْر الْأَسْوَد|n}}
* {{Z|hy}}: {{W-|hy|Սեւ ծով}}
* {{Z|eo}}: {{W+|eo|Nigra Maro}}
* {{Z|et}}: {{W-|et|Must meri}}
* {{Z|pal}}: {{W-|pal|𐭮𐭩𐭠𐭡𐭭|ts=siyābun}}
* {{Z|fa}}: {{W+|fa|دریای سیاه|tr=daryâ-ye siyâh}}
* {{Z|fo}}: {{W-|fo|Svartahavið|nt}}
* {{Z|fi}}: {{W+|fi|Mustameri}}
* {{Z|fr}}: {{W+|fr|mer Noire|m}}
* {{Z|fy}}: {{W+|fy|Swarte See|nt}}
* {{Z|gd}}: {{W-|gd|Am Muir Dubh}}
* {{Z|gl}}: {{W-|gl|Mar Negro|n}}
* {{Z|gu}}: {{W-|gu|કાળો સમુદ્ર}}
* {{Z|ka}}: {{W+|ka|შავი ზღვა|sc=Geor}}
* {{Z|gn}}: {{W-|gn|Para Hũ}}
* {{Z|hi}}: {{W-|hi|कृष्ण सागर|n}}, {{W-|hi|काला समुद्र|n}}, {{W-|hi|काला समुंदर|n}}, {{W-|hi|काला सागर|n}}
* {{Z|nl}}: {{W+|nl|Zwarte Zee|m}}
* {{Z|he}}: {{W-|he|הים השחור|n|tr=ha-yam ha-shakhór|cuda=הַיָּם הַשָּׁחֹר \ הים השחור}}
* {{Z|io}}: {{W+|io|Nigra Maro}}
* {{Z|en}}: {{W+|en|Black Sea}}
* {{Z|izh}}: {{W-|izh|Musta meri}}
* {{Z|inh}}: {{W-|inh|Ӏаьржа форд}}
* {{Z|ga}}: {{W-|ga|an Mhuir Dhubh|m}}
* {{Z|it}}: {{W-|it|Mar Nero|n}}
* {{Z|is}}: {{W-|is|Svartahaf|nt}}
* {{Z|ja}}: {{W+|ja|黒海|tr=こっかい, Kokkai}}
* {{Z|kbd}}: {{W-|kbd|Хы Фӏыцӏэ}}
* {{Z|xal}}: {{W-|xal|Хар теңгс}}
* {{Z|kn}}: {{W-|kn|ಕಪ್ಪು ಸಮುದ್ರ|sc=Knda}}
* {{Z|csb}}: {{W-|csb|Czôrné Mòrze|nt}}
* {{Z|ca}}: {{W-|ca|mar Negra|cuda=Mar Negra|m}}
* {{Z|qu}}: {{W-|qu|Yana hatun qucha}}
* {{Z|ky}}: {{W-|ky|Кара деңиз}}
* {{Z|si}}: {{W+|si|කළු මුහුද|sc=Sinh}}, {{W-|si|කම්ඵ මුහුද|sc=Sinh}}
* {{Z|ko}}: {{W-|ko|^흑해}}, {{W-|ko|黑海}}
* {{Z|lad}}: {{W-|lad|Mar Preta}}
* {{Z|lbe}}: {{W-|lbe|Лухӏи хьхьири}}
* {{Z|la}}: {{W-|la|Pontus Euxinus|n}}, {{W-|la|Pontus|n}}
* {{Z|lv}}: {{W-|lv|Melnā jūra}}
* {{Z|lo}}: {{W+|lo|ທະເລດຳ}}
* {{Z|lez}}: {{W-|lez|Чӏулав гьуьл|sc=Cyrl}}
* {{Z|li}}: {{W-|li|Zwarte Zie}}
* {{Z|lt}}: {{W+|lt|Juodoji jūra}}
* {{Z|lmo}}: {{W-|lmo|Mar Negher}}
* {{Z|lb}}: {{W-|lb|Schwaarzt Mier}}
* {{Z|mk}}: {{W-|mk|Црно Море|nt}}
* {{Z|ml}}: {{W-|ml|കരിങ്കടല്|sc=Mlym}}
* {{Z|ms}}: {{W-|ms|Laut Hitam}}
* {{Z|mt}}: {{W-|mt|Baħar l-Iswed}}
* {{Z|gv}}: {{W-|gv|Mooir Ghoo|m}}
* {{Z|mr}}: {{W-|mr|काळा समुद्र}}
* {{Z|hu}}: {{W+|hu|Fekete-tenger}}
* {{Z|xmf}}: {{W-|xmf|უჩა ზუღა}}
* {{Z|mwl}}: {{W-|mwl|Mar Negro}}
* {{Z|mdf}}: {{W-|mdf|Равжа иневедь}}
* {{Z|mn}}:
*: Kirîlî: {{W-|mn|Хар тэнгис|sc=Cyrl}}
*: Mongolî: {{W-|mn|ᠬᠠᠷᠠ ᠲᠡᠩᠭᠢᠰ|sc=Mong}}
* {{Z|nv}}: {{W-|nv|Tónteel diłhił}}
* {{Z|nrf}}: {{W-|nrf|Néthe Mé|m}}
* {{Z|non}}: {{W-|non|Svartahaf|nt}}
* {{Z|no}}: {{W+|no|Svartehavet|nt}}
* {{Z|oc}}: {{W-|oc|Mar Negra|m}}, {{W-|oc|Mar Nêra|m}}
* {{Z|os}}: {{W-|os|Сау денджыз|sc=Cyrl}}
* {{Z|ota}}: {{W-|ota|بحر سیاه|tr=Bahr-i Siyah|sc=ota-Arab}}, {{W-|ota|قره دڭز|tr=Kara deñiz|sc=ota-Arab}}
* {{Z|ug}}: {{W-|ug|قارا دېڭىز}}
* {{Z|xwo}}: {{W-|xwo|ᡍᠠᠷᠠ ᡐᡄᡊᡎᡄᠰ}}
* {{Z|uz}}: {{W-|uz|Qora dengiz}}
* {{Z|pms}}: {{W-|pms|Mar Nèir}}
* {{Z|pl}}: {{W+|pl|Morze Czarne|nt}}
* {{Z|pt}}: {{W-|pt|Mar Negro|n}}
* {{Z|pa}}: {{W-|pa|ਕਾਲ਼ਾ ਸਮੁੰਦਰ}}
* {{Z|kk}}: {{W-|kk|Қара теңіз|sc=Cyrl}}
* {{Z|rom}}: {{W-|rom|Kali Deryav}}
* {{Z|ro}}: {{W+|ro|Marea Neagră|m}}
* {{Z|ru}}: {{W-|ru|Чёрное мо́ре|nt}}
* {{Z|scn}}: {{W-|scn|Mari Nìguru|n}}
* {{Z|sd}}: {{W-|sd|ڪارو سمنڊ|n}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|Црно море|nt|sc=Cyrl}}
*: Latînî: {{W+|sh|Crno more|nt}}
* {{Z|sk}}: {{W-|sk|Čierne more|nt}}
* {{Z|sl}}: {{W+|sl|Čŕno mórje|nt}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|Carne mórjo|nt}}
*: {{Z|hsb}}: {{W-|hsb|Čorne morjo|nt}}
* {{Z|es}}: {{W-|es|Mar Negro|n}}
* {{Z|sw}}: {{W-|sw|Bahari Nyeusi}}
* {{Z|sv}}: {{W+|sv|Svarta havet|nt}}
* {{Z|tab}}: {{W-|tab|Кӏару гьюл}}
* {{Z|tg}}: {{W-|tg|Баҳри Сиёҳ|sc=Cyrl}}
* {{Z|tl}}: {{W-|tl|Dagat Itim}}
* {{Z|ta}}: {{W-|ta|கருங்கடல்|sc=Taml}}
* {{Z|th}}: {{W-|th|ทะเลดำ|tr=tá-lee dam}}
* {{Z|te}}: {{W+|te|నల్ల సముద్రం}}
* {{Z|tt}}: {{W-|tt|Кара диңгез|sc=Cyrl}}
* {{Z|tr}}: {{W+|tr|Karadeniz}}
* {{Z|tk}}: {{W-|tk|Gara deňiz}}
* {{Z|tyv}}: {{W-|tyv|Кара далай}}
* {{Z|ur}}: {{W-|ur|بحیرہ اسود}}
* {{Z|uk}}: {{W-|uk|Чо́рне мо́ре|nt}}
* {{Z|vec}}: {{W-|vec|Mar Néro|n}}
* {{Z|vi}}: {{W-|vi|Biển Đen}}, {{W-|vi|Hắc Hải}}
* {{Z|cy}}: {{W-|cy|Môr Du|n}}
* {{Z|km}}: {{W-|km|សមុទ្រខ្មៅ|tr=saʼmot khmaw}}
* {{Z|sah}}: {{W-|sah|Хара байҕал|sc=Cyrl}}
* {{Z|yi}}: {{W-|yi|שווארצער ים|n|tr=shvartser yam}}
* {{Z|pnt}}: {{W-|pnt|Μαύρον Θάλασσα}}
* {{Z|el}}: {{W+|el|Μαύρη Θάλασσα|m}}, {{W+|el|Εύξεινος Πόντος|n|sc=Grek}}
*: Kevn: {{W-|grc|Εὔξεινος Πόντος|n}}
{{werger-bin}}
r3gyw1ae0x42ji6epysu6c7e5kbves3
6347356
6347355
2026-08-31T12:52:46Z
Wikihez
7344
/* Serenav */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347356
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Serenav ===
[[Wêne:Black Sea map ku.png|thumb|Behra Reş]]
{{serenav|ku|z=m|[[behr|Behra]] [[reş|Reş]]}}
# {{e|ku|behr}} Behra [[navber]]a [[Tirkiye]], [[Ukrayna]] û [[Rusya]]yê.
#: {{hevmane|ku|Deryaya Reş}}
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Behra Reş Dibe Goristan (1942)|url=https://www.kovarabir.com/505/rohat-alakom-behra-res-dibe-goristan-1942/kmr/|tarîx=17.05.2021|jêgirtin=Lê belê wek me jorê li qala wê kir, keştî tê binavkirin û Nadia jî wek wan 759 kesên din di '''Behra Reş''' da dixeniqin.}}
==== Binêre herwiha ====
{{kol3|ku
|Behra Sor
}}
* {{wpedî}}
==== Werger ====
{{werger-ser|Behra navbera Tirkiye û Rusyayê}}
* {{Z|ab}}: {{W-|ab|Амшын Еиқәа|sc=Cyrl}}
* {{Z|ady}}: {{W-|ady|Хы Шӏуцӏ}}
* {{Z|af}}: {{W+|af|Swartsee}}
* {{Z|sq}}: {{W-|sq|Deti i Zi|n}}
* {{Z|de}}: {{W+|de|Schwarzes Meer|nt}}
* {{Z|alt}}: {{W-|alt|Кара талай}}, {{W-|alt|Кара теҥис}}
* {{Z|am}}: {{W-|am|ጥቁር ባሕር|sc=Ethi}}
* {{Z|an}}: {{W-|an|Mar Negro|n}}
* {{Z|aii}}: {{W-|aii|ܝܵܡܵܐ ܐ݇ܟܘܿܡܵܐ|n}}
* {{Z|ast}}: {{W-|ast|Mar Negru|n}}
* {{Z|az}}: {{W+|az|Qara dəniz}}
* {{Z|eu}}: {{W-|eu|Itsaso Beltza}}
* {{Z|ba}}: {{W-|ba|Ҡара диңгеҙ|sc=Cyrl}}
* {{Z|bar}}: {{W-|bar|Schwoazz Meea}}
* {{Z|be}}: {{W-|be|Чо́рнае мо́ра|nt}}
* {{Z|bn}}: {{W-|bn|কালা দরিয়া}}
* {{Z|br}}: {{W-|br|Mor Du}}
* {{Z|bg}}: {{W-|bg|Че́рно море́|nt}}
* {{Z|my}}: {{W-|my|ပင်လယ်နက်|sc=Mymr}}
* {{Z|ce}}: {{W-|ce|Ӏаьржа хӀорд}}
* {{Z|cs}}: {{W+|cs|Černé moře|nt}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|黑海|tr=Hēihǎi}}
* {{Z|cv}}: {{W-|cv|Хура тинӗс}}
* {{Z|da}}: {{W+|da|Sortehavet|nt}}
* {{Z|id}}: {{W-|id|Laut Hitam}}
* {{Z|ar}}: {{W-|ar|الْبَحْر الْأَسْوَد|n}}
* {{Z|hy}}: {{W-|hy|Սեւ ծով}}
* {{Z|eo}}: {{W+|eo|Nigra Maro}}
* {{Z|et}}: {{W-|et|Must meri}}
* {{Z|pal}}: {{W-|pal|𐭮𐭩𐭠𐭡𐭭|ts=siyābun}}
* {{Z|fa}}: {{W+|fa|دریای سیاه|tr=daryâ-ye siyâh}}
* {{Z|fo}}: {{W-|fo|Svartahavið|nt}}
* {{Z|fi}}: {{W+|fi|Mustameri}}
* {{Z|fr}}: {{W+|fr|mer Noire|m}}
* {{Z|fy}}: {{W+|fy|Swarte See|nt}}
* {{Z|gd}}: {{W-|gd|Am Muir Dubh}}
* {{Z|gl}}: {{W-|gl|Mar Negro|n}}
* {{Z|gu}}: {{W-|gu|કાળો સમુદ્ર}}
* {{Z|ka}}: {{W+|ka|შავი ზღვა|sc=Geor}}
* {{Z|gn}}: {{W-|gn|Para Hũ}}
* {{Z|hi}}: {{W-|hi|कृष्ण सागर|n}}, {{W-|hi|काला समुद्र|n}}, {{W-|hi|काला समुंदर|n}}, {{W-|hi|काला सागर|n}}
* {{Z|nl}}: {{W+|nl|Zwarte Zee|m}}
* {{Z|he}}: {{W-|he|הים השחור|n|tr=ha-yam ha-shakhór|cuda=הַיָּם הַשָּׁחֹר \ הים השחור}}
* {{Z|io}}: {{W+|io|Nigra Maro}}
* {{Z|en}}: {{W+|en|Black Sea}}
* {{Z|izh}}: {{W-|izh|Musta meri}}
* {{Z|inh}}: {{W-|inh|Ӏаьржа форд}}
* {{Z|ga}}: {{W-|ga|an Mhuir Dhubh|m}}
* {{Z|it}}: {{W-|it|Mar Nero|n}}
* {{Z|is}}: {{W-|is|Svartahaf|nt}}
* {{Z|ja}}: {{W+|ja|黒海|tr=こっかい, Kokkai}}
* {{Z|kbd}}: {{W-|kbd|Хы Фӏыцӏэ}}
* {{Z|xal}}: {{W-|xal|Хар теңгс}}
* {{Z|kn}}: {{W-|kn|ಕಪ್ಪು ಸಮುದ್ರ|sc=Knda}}
* {{Z|csb}}: {{W-|csb|Czôrné Mòrze|nt}}
* {{Z|ca}}: {{W-|ca|mar Negra|cuda=Mar Negra|m}}
* {{Z|qu}}: {{W-|qu|Yana hatun qucha}}
* {{Z|ky}}: {{W-|ky|Кара деңиз}}
* {{Z|si}}: {{W+|si|කළු මුහුද|sc=Sinh}}, {{W-|si|කම්ඵ මුහුද|sc=Sinh}}
* {{Z|ko}}: {{W-|ko|^흑해}}, {{W-|ko|黑海}}
* {{Z|lad}}: {{W-|lad|Mar Preta}}
* {{Z|lbe}}: {{W-|lbe|Лухӏи хьхьири}}
* {{Z|la}}: {{W-|la|Pontus Euxinus|n}}, {{W-|la|Pontus|n}}
* {{Z|lv}}: {{W-|lv|Melnā jūra}}
* {{Z|lo}}: {{W+|lo|ທະເລດຳ}}
* {{Z|lez}}: {{W-|lez|Чӏулав гьуьл|sc=Cyrl}}
* {{Z|li}}: {{W-|li|Zwarte Zie}}
* {{Z|lt}}: {{W+|lt|Juodoji jūra}}
* {{Z|lmo}}: {{W-|lmo|Mar Negher}}
* {{Z|lb}}: {{W-|lb|Schwaarzt Mier}}
* {{Z|mk}}: {{W-|mk|Црно Море|nt}}
* {{Z|ml}}: {{W-|ml|കരിങ്കടല്|sc=Mlym}}
* {{Z|ms}}: {{W-|ms|Laut Hitam}}
* {{Z|mt}}: {{W-|mt|Baħar l-Iswed}}
* {{Z|gv}}: {{W-|gv|Mooir Ghoo|m}}
* {{Z|mr}}: {{W-|mr|काळा समुद्र}}
* {{Z|hu}}: {{W+|hu|Fekete-tenger}}
* {{Z|xmf}}: {{W-|xmf|უჩა ზუღა}}
* {{Z|mwl}}: {{W-|mwl|Mar Negro}}
* {{Z|mdf}}: {{W-|mdf|Равжа иневедь}}
* {{Z|mn}}:
*: Kirîlî: {{W-|mn|Хар тэнгис|sc=Cyrl}}
*: Mongolî: {{W-|mn|ᠬᠠᠷᠠ ᠲᠡᠩᠭᠢᠰ|sc=Mong}}
* {{Z|nv}}: {{W-|nv|Tónteel diłhił}}
* {{Z|nrf}}: {{W-|nrf|Néthe Mé|m}}
* {{Z|non}}: {{W-|non|Svartahaf|nt}}
* {{Z|no}}: {{W+|no|Svartehavet|nt}}
* {{Z|oc}}: {{W-|oc|Mar Negra|m}}, {{W-|oc|Mar Nêra|m}}
* {{Z|os}}: {{W-|os|Сау денджыз|sc=Cyrl}}
* {{Z|ota}}: {{W-|ota|بحر سیاه|tr=Bahr-i Siyah|sc=ota-Arab}}, {{W-|ota|قره دڭز|tr=Kara deñiz|sc=ota-Arab}}
* {{Z|ug}}: {{W-|ug|قارا دېڭىز}}
* {{Z|xwo}}: {{W-|xwo|ᡍᠠᠷᠠ ᡐᡄᡊᡎᡄᠰ}}
* {{Z|uz}}: {{W-|uz|Qora dengiz}}
* {{Z|pms}}: {{W-|pms|Mar Nèir}}
* {{Z|pl}}: {{W+|pl|Morze Czarne|nt}}
* {{Z|pt}}: {{W-|pt|Mar Negro|n}}
* {{Z|pa}}: {{W-|pa|ਕਾਲ਼ਾ ਸਮੁੰਦਰ}}
* {{Z|kk}}: {{W-|kk|Қара теңіз|sc=Cyrl}}
* {{Z|rom}}: {{W-|rom|Kali Deryav}}
* {{Z|ro}}: {{W+|ro|Marea Neagră|m}}
* {{Z|ru}}: {{W-|ru|Чёрное мо́ре|nt}}
* {{Z|scn}}: {{W-|scn|Mari Nìguru|n}}
* {{Z|sd}}: {{W-|sd|ڪارو سمنڊ|n}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|Црно море|nt|sc=Cyrl}}
*: Latînî: {{W+|sh|Crno more|nt}}
* {{Z|sk}}: {{W-|sk|Čierne more|nt}}
* {{Z|sl}}: {{W+|sl|Čŕno mórje|nt}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|Carne mórjo|nt}}
*: {{Z|hsb}}: {{W-|hsb|Čorne morjo|nt}}
* {{Z|es}}: {{W-|es|Mar Negro|n}}
* {{Z|sw}}: {{W-|sw|Bahari Nyeusi}}
* {{Z|sv}}: {{W+|sv|Svarta havet|nt}}
* {{Z|tab}}: {{W-|tab|Кӏару гьюл}}
* {{Z|tg}}: {{W-|tg|Баҳри Сиёҳ|sc=Cyrl}}
* {{Z|tl}}: {{W-|tl|Dagat Itim}}
* {{Z|ta}}: {{W-|ta|கருங்கடல்|sc=Taml}}
* {{Z|th}}: {{W-|th|ทะเลดำ|tr=tá-lee dam}}
* {{Z|te}}: {{W+|te|నల్ల సముద్రం}}
* {{Z|tt}}: {{W-|tt|Кара диңгез|sc=Cyrl}}
* {{Z|tr}}: {{W+|tr|Karadeniz}}
* {{Z|tk}}: {{W-|tk|Gara deňiz}}
* {{Z|tyv}}: {{W-|tyv|Кара далай}}
* {{Z|ur}}: {{W-|ur|بحیرہ اسود}}
* {{Z|uk}}: {{W-|uk|Чо́рне мо́ре|nt}}
* {{Z|vec}}: {{W-|vec|Mar Néro|n}}
* {{Z|vi}}: {{W-|vi|Biển Đen}}, {{W-|vi|Hắc Hải}}
* {{Z|cy}}: {{W-|cy|Môr Du|n}}
* {{Z|km}}: {{W-|km|សមុទ្រខ្មៅ|tr=saʼmot khmaw}}
* {{Z|sah}}: {{W-|sah|Хара байҕал|sc=Cyrl}}
* {{Z|yi}}: {{W-|yi|שווארצער ים|n|tr=shvartser yam}}
* {{Z|pnt}}: {{W-|pnt|Μαύρον Θάλασσα}}
* {{Z|el}}: {{W+|el|Μαύρη Θάλασσα|m}}, {{W+|el|Εύξεινος Πόντος|n|sc=Grek}}
*: Kevn: {{W-|grc|Εὔξεινος Πόντος|n}}
{{werger-bin}}
l87abzuq7spmzeriqbz294yc8sj7xgb
6347357
6347356
2026-08-31T12:54:56Z
Wikihez
7344
/* Binêre herwiha */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347357
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Serenav ===
[[Wêne:Black Sea map ku.png|thumb|Behra Reş]]
{{serenav|ku|z=m|[[behr|Behra]] [[reş|Reş]]}}
# {{e|ku|behr}} Behra [[navber]]a [[Tirkiye]], [[Ukrayna]] û [[Rusya]]yê.
#: {{hevmane|ku|Deryaya Reş}}
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Behra Reş Dibe Goristan (1942)|url=https://www.kovarabir.com/505/rohat-alakom-behra-res-dibe-goristan-1942/kmr/|tarîx=17.05.2021|jêgirtin=Lê belê wek me jorê li qala wê kir, keştî tê binavkirin û Nadia jî wek wan 759 kesên din di '''Behra Reş''' da dixeniqin.}}
==== Binêre herwiha ====
{{kol3|ku
|Behra Sor
}}
==== Bêhtir bixwîne ====
* {{wpedî}}
==== Werger ====
{{werger-ser|Behra navbera Tirkiye û Rusyayê}}
* {{Z|ab}}: {{W-|ab|Амшын Еиқәа|sc=Cyrl}}
* {{Z|ady}}: {{W-|ady|Хы Шӏуцӏ}}
* {{Z|af}}: {{W+|af|Swartsee}}
* {{Z|sq}}: {{W-|sq|Deti i Zi|n}}
* {{Z|de}}: {{W+|de|Schwarzes Meer|nt}}
* {{Z|alt}}: {{W-|alt|Кара талай}}, {{W-|alt|Кара теҥис}}
* {{Z|am}}: {{W-|am|ጥቁር ባሕር|sc=Ethi}}
* {{Z|an}}: {{W-|an|Mar Negro|n}}
* {{Z|aii}}: {{W-|aii|ܝܵܡܵܐ ܐ݇ܟܘܿܡܵܐ|n}}
* {{Z|ast}}: {{W-|ast|Mar Negru|n}}
* {{Z|az}}: {{W+|az|Qara dəniz}}
* {{Z|eu}}: {{W-|eu|Itsaso Beltza}}
* {{Z|ba}}: {{W-|ba|Ҡара диңгеҙ|sc=Cyrl}}
* {{Z|bar}}: {{W-|bar|Schwoazz Meea}}
* {{Z|be}}: {{W-|be|Чо́рнае мо́ра|nt}}
* {{Z|bn}}: {{W-|bn|কালা দরিয়া}}
* {{Z|br}}: {{W-|br|Mor Du}}
* {{Z|bg}}: {{W-|bg|Че́рно море́|nt}}
* {{Z|my}}: {{W-|my|ပင်လယ်နက်|sc=Mymr}}
* {{Z|ce}}: {{W-|ce|Ӏаьржа хӀорд}}
* {{Z|cs}}: {{W+|cs|Černé moře|nt}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|黑海|tr=Hēihǎi}}
* {{Z|cv}}: {{W-|cv|Хура тинӗс}}
* {{Z|da}}: {{W+|da|Sortehavet|nt}}
* {{Z|id}}: {{W-|id|Laut Hitam}}
* {{Z|ar}}: {{W-|ar|الْبَحْر الْأَسْوَد|n}}
* {{Z|hy}}: {{W-|hy|Սեւ ծով}}
* {{Z|eo}}: {{W+|eo|Nigra Maro}}
* {{Z|et}}: {{W-|et|Must meri}}
* {{Z|pal}}: {{W-|pal|𐭮𐭩𐭠𐭡𐭭|ts=siyābun}}
* {{Z|fa}}: {{W+|fa|دریای سیاه|tr=daryâ-ye siyâh}}
* {{Z|fo}}: {{W-|fo|Svartahavið|nt}}
* {{Z|fi}}: {{W+|fi|Mustameri}}
* {{Z|fr}}: {{W+|fr|mer Noire|m}}
* {{Z|fy}}: {{W+|fy|Swarte See|nt}}
* {{Z|gd}}: {{W-|gd|Am Muir Dubh}}
* {{Z|gl}}: {{W-|gl|Mar Negro|n}}
* {{Z|gu}}: {{W-|gu|કાળો સમુદ્ર}}
* {{Z|ka}}: {{W+|ka|შავი ზღვა|sc=Geor}}
* {{Z|gn}}: {{W-|gn|Para Hũ}}
* {{Z|hi}}: {{W-|hi|कृष्ण सागर|n}}, {{W-|hi|काला समुद्र|n}}, {{W-|hi|काला समुंदर|n}}, {{W-|hi|काला सागर|n}}
* {{Z|nl}}: {{W+|nl|Zwarte Zee|m}}
* {{Z|he}}: {{W-|he|הים השחור|n|tr=ha-yam ha-shakhór|cuda=הַיָּם הַשָּׁחֹר \ הים השחור}}
* {{Z|io}}: {{W+|io|Nigra Maro}}
* {{Z|en}}: {{W+|en|Black Sea}}
* {{Z|izh}}: {{W-|izh|Musta meri}}
* {{Z|inh}}: {{W-|inh|Ӏаьржа форд}}
* {{Z|ga}}: {{W-|ga|an Mhuir Dhubh|m}}
* {{Z|it}}: {{W-|it|Mar Nero|n}}
* {{Z|is}}: {{W-|is|Svartahaf|nt}}
* {{Z|ja}}: {{W+|ja|黒海|tr=こっかい, Kokkai}}
* {{Z|kbd}}: {{W-|kbd|Хы Фӏыцӏэ}}
* {{Z|xal}}: {{W-|xal|Хар теңгс}}
* {{Z|kn}}: {{W-|kn|ಕಪ್ಪು ಸಮುದ್ರ|sc=Knda}}
* {{Z|csb}}: {{W-|csb|Czôrné Mòrze|nt}}
* {{Z|ca}}: {{W-|ca|mar Negra|cuda=Mar Negra|m}}
* {{Z|qu}}: {{W-|qu|Yana hatun qucha}}
* {{Z|ky}}: {{W-|ky|Кара деңиз}}
* {{Z|si}}: {{W+|si|කළු මුහුද|sc=Sinh}}, {{W-|si|කම්ඵ මුහුද|sc=Sinh}}
* {{Z|ko}}: {{W-|ko|^흑해}}, {{W-|ko|黑海}}
* {{Z|lad}}: {{W-|lad|Mar Preta}}
* {{Z|lbe}}: {{W-|lbe|Лухӏи хьхьири}}
* {{Z|la}}: {{W-|la|Pontus Euxinus|n}}, {{W-|la|Pontus|n}}
* {{Z|lv}}: {{W-|lv|Melnā jūra}}
* {{Z|lo}}: {{W+|lo|ທະເລດຳ}}
* {{Z|lez}}: {{W-|lez|Чӏулав гьуьл|sc=Cyrl}}
* {{Z|li}}: {{W-|li|Zwarte Zie}}
* {{Z|lt}}: {{W+|lt|Juodoji jūra}}
* {{Z|lmo}}: {{W-|lmo|Mar Negher}}
* {{Z|lb}}: {{W-|lb|Schwaarzt Mier}}
* {{Z|mk}}: {{W-|mk|Црно Море|nt}}
* {{Z|ml}}: {{W-|ml|കരിങ്കടല്|sc=Mlym}}
* {{Z|ms}}: {{W-|ms|Laut Hitam}}
* {{Z|mt}}: {{W-|mt|Baħar l-Iswed}}
* {{Z|gv}}: {{W-|gv|Mooir Ghoo|m}}
* {{Z|mr}}: {{W-|mr|काळा समुद्र}}
* {{Z|hu}}: {{W+|hu|Fekete-tenger}}
* {{Z|xmf}}: {{W-|xmf|უჩა ზუღა}}
* {{Z|mwl}}: {{W-|mwl|Mar Negro}}
* {{Z|mdf}}: {{W-|mdf|Равжа иневедь}}
* {{Z|mn}}:
*: Kirîlî: {{W-|mn|Хар тэнгис|sc=Cyrl}}
*: Mongolî: {{W-|mn|ᠬᠠᠷᠠ ᠲᠡᠩᠭᠢᠰ|sc=Mong}}
* {{Z|nv}}: {{W-|nv|Tónteel diłhił}}
* {{Z|nrf}}: {{W-|nrf|Néthe Mé|m}}
* {{Z|non}}: {{W-|non|Svartahaf|nt}}
* {{Z|no}}: {{W+|no|Svartehavet|nt}}
* {{Z|oc}}: {{W-|oc|Mar Negra|m}}, {{W-|oc|Mar Nêra|m}}
* {{Z|os}}: {{W-|os|Сау денджыз|sc=Cyrl}}
* {{Z|ota}}: {{W-|ota|بحر سیاه|tr=Bahr-i Siyah|sc=ota-Arab}}, {{W-|ota|قره دڭز|tr=Kara deñiz|sc=ota-Arab}}
* {{Z|ug}}: {{W-|ug|قارا دېڭىز}}
* {{Z|xwo}}: {{W-|xwo|ᡍᠠᠷᠠ ᡐᡄᡊᡎᡄᠰ}}
* {{Z|uz}}: {{W-|uz|Qora dengiz}}
* {{Z|pms}}: {{W-|pms|Mar Nèir}}
* {{Z|pl}}: {{W+|pl|Morze Czarne|nt}}
* {{Z|pt}}: {{W-|pt|Mar Negro|n}}
* {{Z|pa}}: {{W-|pa|ਕਾਲ਼ਾ ਸਮੁੰਦਰ}}
* {{Z|kk}}: {{W-|kk|Қара теңіз|sc=Cyrl}}
* {{Z|rom}}: {{W-|rom|Kali Deryav}}
* {{Z|ro}}: {{W+|ro|Marea Neagră|m}}
* {{Z|ru}}: {{W-|ru|Чёрное мо́ре|nt}}
* {{Z|scn}}: {{W-|scn|Mari Nìguru|n}}
* {{Z|sd}}: {{W-|sd|ڪارو سمنڊ|n}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|Црно море|nt|sc=Cyrl}}
*: Latînî: {{W+|sh|Crno more|nt}}
* {{Z|sk}}: {{W-|sk|Čierne more|nt}}
* {{Z|sl}}: {{W+|sl|Čŕno mórje|nt}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|Carne mórjo|nt}}
*: {{Z|hsb}}: {{W-|hsb|Čorne morjo|nt}}
* {{Z|es}}: {{W-|es|Mar Negro|n}}
* {{Z|sw}}: {{W-|sw|Bahari Nyeusi}}
* {{Z|sv}}: {{W+|sv|Svarta havet|nt}}
* {{Z|tab}}: {{W-|tab|Кӏару гьюл}}
* {{Z|tg}}: {{W-|tg|Баҳри Сиёҳ|sc=Cyrl}}
* {{Z|tl}}: {{W-|tl|Dagat Itim}}
* {{Z|ta}}: {{W-|ta|கருங்கடல்|sc=Taml}}
* {{Z|th}}: {{W-|th|ทะเลดำ|tr=tá-lee dam}}
* {{Z|te}}: {{W+|te|నల్ల సముద్రం}}
* {{Z|tt}}: {{W-|tt|Кара диңгез|sc=Cyrl}}
* {{Z|tr}}: {{W+|tr|Karadeniz}}
* {{Z|tk}}: {{W-|tk|Gara deňiz}}
* {{Z|tyv}}: {{W-|tyv|Кара далай}}
* {{Z|ur}}: {{W-|ur|بحیرہ اسود}}
* {{Z|uk}}: {{W-|uk|Чо́рне мо́ре|nt}}
* {{Z|vec}}: {{W-|vec|Mar Néro|n}}
* {{Z|vi}}: {{W-|vi|Biển Đen}}, {{W-|vi|Hắc Hải}}
* {{Z|cy}}: {{W-|cy|Môr Du|n}}
* {{Z|km}}: {{W-|km|សមុទ្រខ្មៅ|tr=saʼmot khmaw}}
* {{Z|sah}}: {{W-|sah|Хара байҕал|sc=Cyrl}}
* {{Z|yi}}: {{W-|yi|שווארצער ים|n|tr=shvartser yam}}
* {{Z|pnt}}: {{W-|pnt|Μαύρον Θάλασσα}}
* {{Z|el}}: {{W+|el|Μαύρη Θάλασσα|m}}, {{W+|el|Εύξεινος Πόντος|n|sc=Grek}}
*: Kevn: {{W-|grc|Εὔξεινος Πόντος|n}}
{{werger-bin}}
nma5zuxvwl45aqlusva10o9gwa2ttil
6347382
6347357
2026-08-31T13:41:07Z
Balyozbot
7867
[[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan
6347382
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Serenav ===
[[Wêne:Black Sea map ku.png|thumb|Behra Reş]]
{{serenav|ku|z=m|[[behr|Behra]] [[reş|Reş]]}}
# {{e|ku|behr}} Behra [[navber]]a [[Tirkiye]], [[Ukrayna]] û [[Rusya]]yê.
#: {{hevmane|ku|Deryaya Reş}}
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Behra Reş Dibe Goristan (1942)|url=https://www.kovarabir.com/505/rohat-alakom-behra-res-dibe-goristan-1942/kmr/|tarîx=17.05.2021|jêgirtin=Lê belê wek me jorê li qala wê kir, keştî tê binavkirin û Nadia jî wek wan 759 kesên din di '''Behra Reş''' da dixeniqin.}}
==== Herwiha binêre ====
{{kol3|ku
|Behra Sor
}}
==== Bêhtir bixwîne ====
* {{wpedî}}
==== Werger ====
{{werger-ser|Behra navbera Tirkiye û Rusyayê}}
* {{Z|ab}}: {{W-|ab|Амшын Еиқәа|sc=Cyrl}}
* {{Z|ady}}: {{W-|ady|Хы Шӏуцӏ}}
* {{Z|af}}: {{W+|af|Swartsee}}
* {{Z|sq}}: {{W-|sq|Deti i Zi|n}}
* {{Z|de}}: {{W+|de|Schwarzes Meer|nt}}
* {{Z|alt}}: {{W-|alt|Кара талай}}, {{W-|alt|Кара теҥис}}
* {{Z|am}}: {{W-|am|ጥቁር ባሕር|sc=Ethi}}
* {{Z|an}}: {{W-|an|Mar Negro|n}}
* {{Z|aii}}: {{W-|aii|ܝܵܡܵܐ ܐ݇ܟܘܿܡܵܐ|n}}
* {{Z|ast}}: {{W-|ast|Mar Negru|n}}
* {{Z|az}}: {{W+|az|Qara dəniz}}
* {{Z|eu}}: {{W-|eu|Itsaso Beltza}}
* {{Z|ba}}: {{W-|ba|Ҡара диңгеҙ|sc=Cyrl}}
* {{Z|bar}}: {{W-|bar|Schwoazz Meea}}
* {{Z|be}}: {{W-|be|Чо́рнае мо́ра|nt}}
* {{Z|bn}}: {{W-|bn|কালা দরিয়া}}
* {{Z|br}}: {{W-|br|Mor Du}}
* {{Z|bg}}: {{W-|bg|Че́рно море́|nt}}
* {{Z|my}}: {{W-|my|ပင်လယ်နက်|sc=Mymr}}
* {{Z|ce}}: {{W-|ce|Ӏаьржа хӀорд}}
* {{Z|cs}}: {{W+|cs|Černé moře|nt}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|黑海|tr=Hēihǎi}}
* {{Z|cv}}: {{W-|cv|Хура тинӗс}}
* {{Z|da}}: {{W+|da|Sortehavet|nt}}
* {{Z|id}}: {{W-|id|Laut Hitam}}
* {{Z|ar}}: {{W-|ar|الْبَحْر الْأَسْوَد|n}}
* {{Z|hy}}: {{W-|hy|Սեւ ծով}}
* {{Z|eo}}: {{W+|eo|Nigra Maro}}
* {{Z|et}}: {{W-|et|Must meri}}
* {{Z|pal}}: {{W-|pal|𐭮𐭩𐭠𐭡𐭭|ts=siyābun}}
* {{Z|fa}}: {{W+|fa|دریای سیاه|tr=daryâ-ye siyâh}}
* {{Z|fo}}: {{W-|fo|Svartahavið|nt}}
* {{Z|fi}}: {{W+|fi|Mustameri}}
* {{Z|fr}}: {{W+|fr|mer Noire|m}}
* {{Z|fy}}: {{W+|fy|Swarte See|nt}}
* {{Z|gd}}: {{W-|gd|Am Muir Dubh}}
* {{Z|gl}}: {{W-|gl|Mar Negro|n}}
* {{Z|gu}}: {{W-|gu|કાળો સમુદ્ર}}
* {{Z|ka}}: {{W+|ka|შავი ზღვა|sc=Geor}}
* {{Z|gn}}: {{W-|gn|Para Hũ}}
* {{Z|hi}}: {{W-|hi|कृष्ण सागर|n}}, {{W-|hi|काला समुद्र|n}}, {{W-|hi|काला समुंदर|n}}, {{W-|hi|काला सागर|n}}
* {{Z|nl}}: {{W+|nl|Zwarte Zee|m}}
* {{Z|he}}: {{W-|he|הים השחור|n|tr=ha-yam ha-shakhór|cuda=הַיָּם הַשָּׁחֹר \ הים השחור}}
* {{Z|io}}: {{W+|io|Nigra Maro}}
* {{Z|en}}: {{W+|en|Black Sea}}
* {{Z|izh}}: {{W-|izh|Musta meri}}
* {{Z|inh}}: {{W-|inh|Ӏаьржа форд}}
* {{Z|ga}}: {{W-|ga|an Mhuir Dhubh|m}}
* {{Z|it}}: {{W-|it|Mar Nero|n}}
* {{Z|is}}: {{W-|is|Svartahaf|nt}}
* {{Z|ja}}: {{W+|ja|黒海|tr=こっかい, Kokkai}}
* {{Z|kbd}}: {{W-|kbd|Хы Фӏыцӏэ}}
* {{Z|xal}}: {{W-|xal|Хар теңгс}}
* {{Z|kn}}: {{W-|kn|ಕಪ್ಪು ಸಮುದ್ರ|sc=Knda}}
* {{Z|csb}}: {{W-|csb|Czôrné Mòrze|nt}}
* {{Z|ca}}: {{W-|ca|mar Negra|cuda=Mar Negra|m}}
* {{Z|qu}}: {{W-|qu|Yana hatun qucha}}
* {{Z|ky}}: {{W-|ky|Кара деңиз}}
* {{Z|si}}: {{W+|si|කළු මුහුද|sc=Sinh}}, {{W-|si|කම්ඵ මුහුද|sc=Sinh}}
* {{Z|ko}}: {{W-|ko|^흑해}}, {{W-|ko|黑海}}
* {{Z|lad}}: {{W-|lad|Mar Preta}}
* {{Z|lbe}}: {{W-|lbe|Лухӏи хьхьири}}
* {{Z|la}}: {{W-|la|Pontus Euxinus|n}}, {{W-|la|Pontus|n}}
* {{Z|lv}}: {{W-|lv|Melnā jūra}}
* {{Z|lo}}: {{W+|lo|ທະເລດຳ}}
* {{Z|lez}}: {{W-|lez|Чӏулав гьуьл|sc=Cyrl}}
* {{Z|li}}: {{W-|li|Zwarte Zie}}
* {{Z|lt}}: {{W+|lt|Juodoji jūra}}
* {{Z|lmo}}: {{W-|lmo|Mar Negher}}
* {{Z|lb}}: {{W-|lb|Schwaarzt Mier}}
* {{Z|mk}}: {{W-|mk|Црно Море|nt}}
* {{Z|ml}}: {{W-|ml|കരിങ്കടല്|sc=Mlym}}
* {{Z|ms}}: {{W-|ms|Laut Hitam}}
* {{Z|mt}}: {{W-|mt|Baħar l-Iswed}}
* {{Z|gv}}: {{W-|gv|Mooir Ghoo|m}}
* {{Z|mr}}: {{W-|mr|काळा समुद्र}}
* {{Z|hu}}: {{W+|hu|Fekete-tenger}}
* {{Z|xmf}}: {{W-|xmf|უჩა ზუღა}}
* {{Z|mwl}}: {{W-|mwl|Mar Negro}}
* {{Z|mdf}}: {{W-|mdf|Равжа иневедь}}
* {{Z|mn}}:
*: Kirîlî: {{W-|mn|Хар тэнгис|sc=Cyrl}}
*: Mongolî: {{W-|mn|ᠬᠠᠷᠠ ᠲᠡᠩᠭᠢᠰ|sc=Mong}}
* {{Z|nv}}: {{W-|nv|Tónteel diłhił}}
* {{Z|nrf}}: {{W-|nrf|Néthe Mé|m}}
* {{Z|non}}: {{W-|non|Svartahaf|nt}}
* {{Z|no}}: {{W+|no|Svartehavet|nt}}
* {{Z|oc}}: {{W-|oc|Mar Negra|m}}, {{W-|oc|Mar Nêra|m}}
* {{Z|os}}: {{W-|os|Сау денджыз|sc=Cyrl}}
* {{Z|ota}}: {{W-|ota|بحر سیاه|tr=Bahr-i Siyah|sc=ota-Arab}}, {{W-|ota|قره دڭز|tr=Kara deñiz|sc=ota-Arab}}
* {{Z|ug}}: {{W-|ug|قارا دېڭىز}}
* {{Z|xwo}}: {{W-|xwo|ᡍᠠᠷᠠ ᡐᡄᡊᡎᡄᠰ}}
* {{Z|uz}}: {{W-|uz|Qora dengiz}}
* {{Z|pms}}: {{W-|pms|Mar Nèir}}
* {{Z|pl}}: {{W+|pl|Morze Czarne|nt}}
* {{Z|pt}}: {{W-|pt|Mar Negro|n}}
* {{Z|pa}}: {{W-|pa|ਕਾਲ਼ਾ ਸਮੁੰਦਰ}}
* {{Z|kk}}: {{W-|kk|Қара теңіз|sc=Cyrl}}
* {{Z|rom}}: {{W-|rom|Kali Deryav}}
* {{Z|ro}}: {{W+|ro|Marea Neagră|m}}
* {{Z|ru}}: {{W-|ru|Чёрное мо́ре|nt}}
* {{Z|scn}}: {{W-|scn|Mari Nìguru|n}}
* {{Z|sd}}: {{W-|sd|ڪارو سمنڊ|n}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|Црно море|nt|sc=Cyrl}}
*: Latînî: {{W+|sh|Crno more|nt}}
* {{Z|sk}}: {{W-|sk|Čierne more|nt}}
* {{Z|sl}}: {{W+|sl|Čŕno mórje|nt}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|Carne mórjo|nt}}
*: {{Z|hsb}}: {{W-|hsb|Čorne morjo|nt}}
* {{Z|es}}: {{W-|es|Mar Negro|n}}
* {{Z|sw}}: {{W-|sw|Bahari Nyeusi}}
* {{Z|sv}}: {{W+|sv|Svarta havet|nt}}
* {{Z|tab}}: {{W-|tab|Кӏару гьюл}}
* {{Z|tg}}: {{W-|tg|Баҳри Сиёҳ|sc=Cyrl}}
* {{Z|tl}}: {{W-|tl|Dagat Itim}}
* {{Z|ta}}: {{W-|ta|கருங்கடல்|sc=Taml}}
* {{Z|th}}: {{W-|th|ทะเลดำ|tr=tá-lee dam}}
* {{Z|te}}: {{W+|te|నల్ల సముద్రం}}
* {{Z|tt}}: {{W-|tt|Кара диңгез|sc=Cyrl}}
* {{Z|tr}}: {{W+|tr|Karadeniz}}
* {{Z|tk}}: {{W-|tk|Gara deňiz}}
* {{Z|tyv}}: {{W-|tyv|Кара далай}}
* {{Z|ur}}: {{W-|ur|بحیرہ اسود}}
* {{Z|uk}}: {{W-|uk|Чо́рне мо́ре|nt}}
* {{Z|vec}}: {{W-|vec|Mar Néro|n}}
* {{Z|vi}}: {{W-|vi|Biển Đen}}, {{W-|vi|Hắc Hải}}
* {{Z|cy}}: {{W-|cy|Môr Du|n}}
* {{Z|km}}: {{W-|km|សមុទ្រខ្មៅ|tr=saʼmot khmaw}}
* {{Z|sah}}: {{W-|sah|Хара байҕал|sc=Cyrl}}
* {{Z|yi}}: {{W-|yi|שווארצער ים|n|tr=shvartser yam}}
* {{Z|pnt}}: {{W-|pnt|Μαύρον Θάλασσα}}
* {{Z|el}}: {{W+|el|Μαύρη Θάλασσα|m}}, {{W+|el|Εύξεινος Πόντος|n|sc=Grek}}
*: Kevn: {{W-|grc|Εὔξεινος Πόντος|n}}
{{werger-bin}}
frqpb7xlw8vwxy2wbnmbyjloya3ann0
çavdêrî
0
29582
6347614
6322560
2026-09-01T11:30:26Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347614
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-çavdêrî.wav|dever=Bidlîs}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# Lê[[nerîn]] û [[parastin]]; lê[[nerîn]] û [[şirove]]kirin.
#: {{hevmane|ku|sereguhî|venerîn|raçavî|nezaret|ragirî|binçavî}}
#* {{bêmînak|ku}}
# {{kontrol|rêz=erê|[[pişkinîn]], [[dîqet]], [[serqorî]], [[xwedankirin]], [[lêmiqatebûn]]}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Bi alfabeyên din ====
* {{ku-ar|چاڤدێری}}
==== Formên alternatîv ====
{{kol3|ku
|çavnerî
|çavnêrî
}}
==== Jê ====
{{kol3|ku
|çavdêrî kirin<crz:lêker>
|çavdêrîkirin<crz:navdêr>
|çavdêrîkirî<crz:rengdêr>
}}
==== Etîmolojî ====
Ji {{paş|ku|çavdêr|-î}} yan ji {{qertaf|ku|çav|-dêrî}}.
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W-|af|opmerking}}
* {{Z|de}}: {{W+|de|Bemerkung|f}}, {{W+|de|Beobachtung|f}}, {{W+|de|Vermerk|m}}, {{W+|de|Anschauung|f}}, {{W+|de|Aufsicht|f}}, {{W+|de|Posten|m}}, {{W+|de|Augenschein|m|guman=erê}}, {{W-|de|Beaufsichtigung|f|guman=erê}}, {{W+|de|Bewachung|f|guman=erê}}
* {{Z|da}}: {{W+|da|iagttagelse}}
* {{Z|ar}}: {{W-|ar|مراقبة}}, {{W-|ar|حراسة}}, {{W-|ar|دقة}}, {{W-|ar|مبالاة}}, {{W-|ar|اهتمام}}, {{W-|ar|عناية}}, {{W-|ar|اكتراث}}, {{W-|ar|العنایة|guman=erê}}, {{W-|ar|العین|guman=erê}}
* {{Z|eo}}: {{W-|eo|rimarko}}, {{W-|eo|observo}}, {{W-|eo|observado}}
* {{Z|fa}}: {{W+|fa|مراقبت}}, {{W+|fa|نظارت}}, {{W+|fa|مشاهده}}, {{W+|fa|تفتیش}}, {{W+|fa|بازرسی}}
* {{Z|fo}}: {{W-|fo|viðmerking}}, {{W-|fo|eygleiðing}}
* {{Z|fi}}: {{W+|fi|tarkkailu}}, {{W+|fi|valvonta}}, {{W+|fi|tarkastelu}}
* {{Z|fr}}: {{W+|fr|observation}}, {{W+|fr|surveillance}}
* {{Z|nl}}: {{W+|nl|opmerking}}, {{W+|nl|waarneming}}, {{W+|nl|inachtneming}}, {{W+|nl|naleving}}, {{W+|nl|observatie}}
* {{Z|en}}: {{W+|en|supervision}}, {{W+|en|observation}}, {{W+|en|observance}}, {{W+|en|watch}}, {{W+|en|custody}}, {{W+|en|guard}}, {{W+|en|oversight}}, {{W+|en|superintendence}}, {{W+|en|surveillance}}, {{W+|en|ward}}, {{W+|en|care}}, {{W+|en|invigilation}}, {{W+|en|patronage}}, {{W+|en|censorship|guman=erê}}, {{W+|en|inspection|guman=erê}}, {{W+|en|observing|guman=erê}}, {{W+|en|watching|guman=erê}}
* {{Z|it}}: {{W+|it|osservazione}}
* {{Z|pap}}: {{W-|pap|opservashon}}
* {{Z|pl}}: {{W+|pl|uwaga}}, {{W+|pl|spostrzeżenie}}
* {{Z|pt}}: {{W+|pt|nota}}, {{W+|pt|observação}}, {{W+|pt|reparo}}
* {{Z|es}}: {{W+|es|advertencia}}, {{W+|es|nota}}
* {{Z|tr}}: {{W+|tr|gözetim}}, {{W+|tr|gözlem}}, {{W-|tr|gözleyicilik}}, {{W+|tr|izlenim}}, {{W+|tr|erkete}}, {{W+|tr|erketecilik}}, {{W+|tr|gözcülük}}, {{W+|tr|kolaçan}}, {{W+|tr|müşahade}}, {{W-|tr|dikizcilik}}, {{W+|tr|intiba}}, {{W+|tr|nezaret}}, {{W+|tr|gözetlemek}}, {{W+|tr|tarassut|guman=erê}}, {{W+|tr|gözleyiş|guman=erê}}
{{werger-bin}}
prep5bqfrif4hd8zobi58uhz1smr57j
ejdeha
0
30184
6347373
6339033
2026-08-31T13:20:27Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes); guhartina pêşketî (DefSideBoxes)
6347373
wikitext
text/x-wiki
{{bnr-h|Ejdeha}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}, ئەژدەها
=== Navdêr ===
[[Wêne:Nibelungendrache.jpg|thumb|250px|ejdehayek (1)]]
{{navdêr|ku|z=n}}
# {{e|ku|mîtolojî}} Li gor [[çîrok]]an [[cinawir]]ek pirr [[gir]] û [[tirsnak]] yê wek [[mar]]an e lê bi [[ling]] û [[çeng]] e û dikare [[agir]]î jî ji devê xwe [[barandin|bibarîne]].
#: {{hevmane|ku|ziya|ejdiyar|ejder|dragon}}
#* {{J:Melayê Cizîrî:Dîwana Melayê Cizîrî|jêgirtin=Can biret mi d' vê 'ezabê</br>Ev siyahreng '''ejdeha''' ye</br>Çendekê sadiq cema bin}}
==== Tewandin ====
{{ku-tewîn-nav/nû|nêr|guherto=2}}
==== Bi alfabeyên din ====
* {{ku-ar|ئهژدهها}}
==== Formên alternatîv ====
{{stûn|
* [[ejdehar]]
* [[ejder]]
* [[ejderha]]
* [[ejdiha]]
* [[ejdirha]]
* [[ejdiya]]
* [[ejdiyaq]]
* [[ijdeha]]
* [[ijderha]]
}}
==== Jê ====
* [[ejdehayî]]
==== Etîmolojî ====
Ji {{mîr|ine-pro|ku|*h₂engʷʰ-|w=[[mar]]}}. Hevreha {{hv|fa|اژدها|tr=ejdeha}}, {{hv|pal|tr=ejdehaeji-dehak}}, {{hv|ae|tr=eji-dehake}}, {{hv|sa|अहि|tr=ehi}}, {{hv|hy|օձ|tr=oç|w=[[mar]]}}, [[уж]] (uj: [[mar]]) ya rusî, [[ὄφις]] (ofis: mar) ya yûnanî, [[anguis]] (mar)ya latînî, [[angis]] (mar) ya lîtwanî, [[unc]] ya almaniya kevn. Ji eynî rehî [[ejî]] (2).
==== Werger ====
{{werger-ser}}
* {{Z|ab}}: {{W-|ab|аблаҩа}}, {{W-|ab|агәылшьаԥ}}
* {{Z|af}}: {{W+|af|draak}}
* {{Z|sq}}: {{W+|sq|kuçedër|m}}, {{W-|sq|dragoi}}
* {{Z|goh}}: {{W-|goh|trahho}}
* {{Z|de}}: {{W+|de|Drache|n}}
* {{Z|alt}}: {{W-|alt|улуу}}
* {{Z|an}}: {{W-|an|dragón}}
* {{Z|arc}}: {{W-|arc|תנינא|sc=Hebr}}
* {{Z|ast}}: {{W+|ast|cuélebre|n}}
* {{Z|av}}: {{W-|av|аздагьо|sc=Cyrl}}
* {{Z|ae}}: {{W-|ae|𐬀𐬲𐬌}}, {{W-|ae|𐬀𐬲𐬌⸱𐬛𐬀𐬵𐬁𐬐𐬀}}
* {{Z|az}}: {{W+|az|əjdəha}}
* {{Z|eu}}: {{W-|eu|herensuge}}
* {{Z|ba}}: {{W-|ba|аждаһа|sc=Cyrl}}, {{W-|ba|дракон|sc=Cyrl}}
* {{Z|be}}: {{W-|be|цмок|n|sc=Cyrl}}, {{W-|be|драко́н|n|sc=Cyrl}}, {{W-|be|змей|n|sc=Cyrl}}, {{W-|be|смок|n}}
* {{Z|bn}}: {{W+|bn|আজদাহা|tr=ajdaha}}
* {{Z|bcl}}: {{W-|bcl|dragon}}
* {{Z|bg}}: {{W+|bg|драко́н|n|sc=Cyrl}}, {{W+|bg|змей|n|sc=Cyrl}}
* {{Z|my}}: {{W+|my|နဂါး|sc=Mymr}}
* {{Z|kac}}: {{W-|kac|baren}}
* {{Z|dz}}: {{W-|dz|འབྲུག}}
* {{Z|ce}}: {{W-|ce|саьрмик}}
* {{Z|cs}}: {{W+|cs|drak|n}}
* {{Z|chr}}: {{W-|chr|ᎤᎦᏖᎾ|tr=ugatena}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|龍|tr=lóng}}
* {{Z|cv}}: {{W-|cv|аҫтаха}}
* {{Z|da}}: {{W+|da|drage|g}}, {{W-|da|lindorm|g}}
* {{Z|dar}}: {{W-|dar|аждагьа}}
* {{Z|ovd}}: {{W-|ovd|dratji|n}}
* {{Z|id}}: {{W+|id|naga}}
* {{Z|ar}}: {{W-|ar|تِنِّين|n}}
*: {{Z|acw}}: {{W-|acw|تِنِّين|n|tr=tinnīn}}
* {{Z|hy}}: {{W+|hy|դրակոն}}, {{W+|hy|վիշապ}}
* {{Z|eo}}: {{W-|eo|drako}}
* {{Z|et}}: {{W-|et|lohe}}, {{W-|et|draakon}}, {{W-|et|lohemadu}}, {{W-|et|lendmadu}}
* {{Z|pal}}: {{W-|pal|𐭠𐭰𐭩𐭣𐭤𐭠𐭪𐭩}}, {{W-|pal|𐭠𐭰}}
* {{Z|fa}}: {{W+|fa|اژدها|tr=eždehâ}}, {{W+|fa|اژدر|tr=aždar}}
* {{Z|fo}}: {{W-|fo|dreki|n}}, {{W-|fo|lindormur|n}}
* {{Z|fi}}: {{W+|fi|lohikäärme}}
* {{Z|fr}}: {{W+|fr|dragon|n}}
* {{Z|fur}}: {{W-|fur|dragon|n}}
* {{Z|fy}}: {{W-|fy|draak|g}}
* {{Z|gd}}: {{W-|gd|nathair-sgiathach|m}}
* {{Z|gl}}: {{W+|gl|dragón}}
* {{Z|ka}}: {{W+|ka|დრაკონი}}
* {{Z|hi}}: {{W-|hi|अज़दहा|sc=Deva}}, {{W+|hi|अजदहा|n}}, {{W+|hi|अजदाह|n}}
* {{Z|nl}}: {{W+|nl|draak|n}}, {{W+|nl|lintworm}}
* {{Z|he}}: {{W+|he|דְּרָקוֹן|n|tr=drakón}}, {{W+|he|רַהַב|n|tr=ráhav}}
* {{Z|io}}: {{W+|io|drako}}
* {{Z|ang}}: {{W-|ang|draca|n}}
* {{Z|en}}: {{W+|en|dragon}}
* {{Z|ga}}: {{W-|ga|dragan|n}}, {{W-|ga|dragún|n}}
* {{Z|it}}: {{W+|it|drago|n}}, {{W+|it|dragone|n}}, {{W-|it|viverna}}
* {{Z|is}}: {{W+|is|dreki|n}}, {{W-|is|lindormur|n}}
* {{Z|ja}}: {{W+|ja|竜|tr=りゅう, ryū; りょう, ryō; たつ, tatsu}}, {{W+|ja|ドラゴン|tr=doragon}}
* {{Z|kl}}: {{W-|kl|uumasorujuk}}, {{W-|kl|aassissuaq}}, {{W-|kl|kuukkooriaasarsuaq}}
* {{Z|xal}}: {{W-|xal|лу}}
* {{Z|ca}}: {{W+|ca|drac|n}}, {{W-|ca|víbria|m}}
* {{Z|ky}}: {{W+|ky|ажыдаар|sc=Cyrl}}, {{W+|ky|улу|sc=Cyrl}}
* {{Z|ko}}: {{W+|ko|용}}, {{W-|ko|룡}}, {{W+|ko|미르}}
* {{Z|lbe}}: {{W-|lbe|аждагьа}}
* {{Z|ltg}}: {{W-|ltg|pyučs|n}}, {{W-|ltg|pyukuļs}}
* {{Z|la}}: {{W+|la|draco|n}}
* {{Z|lv}}: {{W+|lv|pūķis|n}}, {{W-|lv|drakons|n}}
* {{Z|lo}}: {{W+|lo|ມັງກອນ}}, {{W-|lo|ນາກ}}
* {{Z|lez}}: {{W-|lez|аждагьан}}
* {{Z|lt}}: {{W+|lt|drakonas|n}}, {{W+|lt|slibinas|n}}
* {{Z|lb}}: {{W+|lb|Draach}}
* {{Z|mk}}: {{W-|mk|змеј|n|sc=Cyrl}}, {{W-|mk|а́ждер|n|sc=Cyrl}}, {{W-|mk|а́ла|m|sc=Cyrl}}, {{W-|mk|ла́мја|m|sc=Cyrl}}, {{W-|mk|а́ждаја|m|sc=Cyrl}}, {{W-|mk|дра́кон|n}}
* {{Z|ms}}: {{W+|ms|naga}}
* {{Z|mt}}: {{W-|mt|dragun|n}}
* {{Z|mnc}}: {{W-|mnc|ᠮᡠᡩᡠ᠋ᡵᡳ}}
* {{Z|gv}}: {{W-|gv|dragan|n}}, {{W-|gv|dragane|n}}
* {{Z|mi}}: {{W-|mi|tarākona}}, {{W-|mi|taniwha}}, {{W-|mi|mokoahi}}
* {{Z|mr}}: {{W-|mr|ड्रॅगन}}
* {{Z|hu}}: {{W+|hu|sárkány}}
* {{Z|mn}}: {{W+|mn|луу|sc=Cyrl}}
* {{Z|gld}}: {{W-|gld|мудур}}
* {{Z|nv}}: {{W-|nv|naʼashǫ́ʼiitsoh}}, {{W-|nv|tłʼiishtsoh}}
* {{Z|niu}}: {{W-|niu|tarākoni}}
* {{Z|nog}}: {{W-|nog|аздаа}}
* {{Z|nrf}}: {{W-|nrf|dragon|n}}
* {{Z|non}}: {{W-|non|dreki|n}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|drage|n}}, {{W+|nb|drake|n}}
*: {{Z|nn}}: {{W-|nn|drake|n}}
* {{Z|oc}}: {{W+|oc|dragon}}
* {{Z|ota}}: {{W-|ota|اژدرها|tr=ejderha}}, {{W-|ota|ثعبان|tr=suʿban}}, {{W-|ota|غول|tr=ğul}}
* {{Z|ug}}: {{W-|ug|ئەجدىھا}}, {{W-|ug|ئەجدىھار}}
* {{Z|xwo}}: {{W-|xwo|ᠯᡇᡇ᠋}}
* {{Z|uz}}: {{W+|uz|ajdar}}
* {{Z|pi}}: {{W-|pi|nāga|n}}
* {{Z|xpr}}: {{W-|xpr|𐫀𐫋𐫅𐫍𐫀𐫃}}
* {{Z|ps}}: {{W+|ps|ښامار|n|tr=ӽāmãr}}
* {{Z|pdt}}: {{W-|pdt|Droak|n}}
* {{Z|pl}}: {{W+|pl|smok|n}}, {{W+|pl|żmij|n}}
* {{Z|pt}}: {{W+|pt|dragão|n}}
* {{Z|kk}}: {{W-|kk|айдаһар|sc=Cyrl}}, {{W-|kk|аждаһа}}
* {{Z|rgn}}: {{W-|rgn|drêgh|n}}
* {{Z|rm}}: {{W-|rm|dragun|n}}
* {{Z|ro}}: {{W+|ro|balaur|n}}, {{W+|ro|dragon}}, {{W+|ro|zmeu}}
* {{Z|ru}}: {{W+|ru|драко́н|n}}, {{W+|ru|змей|n}}, {{W+|ru|смок|n}}
* {{Z|sa}}: {{W+|sa|उरङ्ग|n}}, {{W+|sa|नाग|n}}
* {{Z|scn}}: {{W+|scn|dragu|n}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|змај|n|m|sc=Cyrl}}, {{W-|sh|аждаја|m|sc=Cyrl}}, {{W-|sh|аждаха|n|sc=Cyrl}}, {{W-|sh|aлa|m|sc=Cyrl}}, {{W-|sh|змајица|m|sc=Cyrl}}, {{W-|sh|змајеви|p|sc=Cyrl}}
*: Latînî: {{W+|sh|zmaj|n}}, {{W+|sh|aždaja|m}}, {{W-|sh|aždaha|n}}, {{W+|sh|ala|m}}, {{W+|sh|zmajica|m}}, {{W-|sh|zmajevi|p}}
* {{Z|sco}}: {{W-|sco|Draigon}}
* {{Z|cu}}:
*: Kirîlî: {{W-|cu|смокъ|n}}
* {{Z|orv}}: {{W-|orv|смокъ|n}}
* {{Z|sk}}: {{W+|sk|drak|n}}, {{W-|sk|šarkan|n}}
* {{Z|sl}}: {{W+|sl|zmaj|m-an}}
* Sorbî:
*: {{Z|dsb}}: {{W-|dsb|plon|n}}, {{W-|dsb|paliwaka|m}}
*: {{Z|hsb}}: {{W-|hsb|zmij|n}}
* {{Z|es}}: {{W+|es|dragón|n}}, {{W+|es|guiverno|n}}
* {{Z|sw}}: {{W-|sw|joka}}, {{W-|sw|dragoni}}
* {{Z|sv}}: {{W+|sv|drake|g}}, {{W+|sv|lindorm}}
* {{Z|xsr}}: {{W-|xsr|འབྲུག|tr=druk}}
* {{Z|tg}}: {{W+|tg|аждаҳо|sc=Cyrl}}
* {{Z|tl}}: {{W-|tl|dragon}}
* {{Z|ta}}: {{W-|ta|டிராகன்|sc=Taml}}
* {{Z|th}}: {{W+|th|มังกร}}, {{W+|th|นาค}}, {{W+|th|อุรค}}
* {{Z|crh}}: {{W-|crh|ajderha}}
* {{Z|tt}}: {{W+|tt|аждаһа|sc=Cyrl}}, {{W+|tt|ләү}}
* {{Z|tr}}: {{W+|tr|ejderha}}, {{W+|tr|ejder}}, {{W+|tr|dragon}}, {{W+|tr|büke}}, {{W-|tr|suban}}
* {{Z|tk}}: {{W-|tk|ajdarha}}
* {{Z|bo}}: {{W-|bo|འབྲུག}}
* {{Z|ddo}}: {{W-|ddo|аждагь}}
* {{Z|tyv}}: {{W-|tyv|улу}}
* {{Z|uga}}: {{W-|uga|𐎚𐎐𐎐}}
* {{Z|ur}}: {{W-|ur|اژدہا|tr=eždeha|sc=ur-Arab}}
* {{Z|uby}}: {{W-|uby|чыгьыблы}}
* {{Z|uk}}: {{W-|uk|змій|n|sc=Cyrl}}, {{W-|uk|змії́ха|m|sc=Cyrl}}, {{W+|uk|драко́н|n|sc=Cyrl}}, {{W-|uk|смок|n}}
* {{Z|vec}}: {{W-|vec|dragon}}
* {{Z|vi}}: {{W+|vi|rồng}}
* {{Z|vo}}: {{W+|vo|drak}}
* {{Z|cy}}: {{W-|cy|draig|m}}
* {{Z|km}}: {{W+|km|នាគ}}, {{W+|km|ឧរគ}}
* {{Z|yi}}: {{W-|yi|דראַקאָן|n|sc=Hebr}}, {{W-|yi|פּיפּערנאָטער|n}}
* {{Z|yo}}: {{W-|yo|dírágónì}}
* {{Z|el}}: {{W+|el|δράκος|n}}, {{W+|el|δράκαινα|m}}, {{W+|el|δράκοντας|n}}
*: Kevn: {{W-|grc|δράκων|n}}, {{W-|grc|δράκαινα|m}}
{{werger-bin}}
:{{werger çavkanî|en|dragon|beş=Ev qismê Wergerê|oldid=76333155}}
dwjlxbe8vejwr2u9duy3dt5tqoiz90f
kafî
0
30201
6347534
6340182
2026-09-01T09:38:18Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347534
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Rengdêr ===
{{rengdêr|ku}}
# [[bes]], [[têr]]
#: {{nm|ku|Ev '''kafî''' me ye.|Ev têra me dike. Ew bo me bes e.|rêz=1}}
# {{kontrol|rêz=erê|[[hew]]}}
==== Ji wêjeya klasîk ====
* {{J:Melayê Cizîrî:Dîwana Melayê Cizîrî|jêgirtin=Li-yetme'inne qelbî 'eynu l-yeqîn dibexşit</br>'Eynu l-'iyan divêtin '''kafî''' nehin dirayet</br>Mîrî yû padişahî mûyek li nik Melayî}}
==== Jê ====
{{kol3|ku
|kafîtî
|kafî bûn<crz:lêker>
|kafîbûn<crz:navdêr>
}}
==== Etîmolojî ====
Ji {{ji|ar|ku}}
==== Bide ber ====
{{kol3|ku
|kaf
|kefî
}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|ausreichend}}, {{W|de|genug}}, {{W|de|genügend}}
* {{Z|fa}}: {{W|fa|کافی}}
* {{Z|tr}}: {{W|tr|kâfi}}, {{W|tr|yeter}}
{{werger-bin}}
heixu112iavtsb5yvzqjewwpb57gpny
pelamar
0
30591
6347524
6325457
2026-09-01T09:00:25Z
Balyozbot
7867
sererastkirina nimûneyên edebiyatê (bi destî) [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347524
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[bikaranîn|Bikaranîna]] [[hêz]]ê bo [[ziyan]]danê; çûn [[der]]ekê yan nêzî kesekî daku [[ziyan]]ê bigihîniyê (bi taybetî di [[ceng]]ê de).
#: {{hevmane|ku|êriş|hicûm|şalaw|suîqest}}
#* {{jêder|ku|jêgirtin=''Pirsa êzidiya, hizir û serinca dîrokzanan ne rakêşaye û gelek bi kêmî û kurtî basî wan hatiye kirin. Basî wan( belku ji bo cara yekê) di pirtûka Şaristanî de, yê ku di sala 1153 Z de, koç kirî, hatiye kirin û careka din jî, di pirtûka Siyahetnama Olya Çelebî de, ku ew jî, di sala 1680 Z de, miriye, hatiye kirin. Jiber hindê jî, dema şêx Adî dest daye ser ola Êzidiya, êdî wan nekarî roleka giring bilîzin û cihên tiliyên xwe di dîrokê de çêkin. Lê ew li Kurdistanê jiyan û xwe ji hêriş û '''pelamarên''' musilmanan parastin. Çinku bi hizra musilmanan, ew kafir û gawir bûn û Şeytan diperistin. Bo cara dawiyê jî, di destpêka çerxê 19 ê Z de, ew ketine ber hêrişa Mehemed Paşayê Rewandizî, ku bi Mîrê Kore nav dikirin. Jiber hindê jî, roj li pey rojê, ew kêm dibûn û her hind mabû bêne qirrkirin.|Pîr Memo Osman: ''Felsefa ola êzidiyan û koka wî'', wergerrandin: Xelîl Duhokî, Newroz.com, jêwergirtin: 1/2006}}
#* {{bênimûne|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|[[pelamar birin]] (ser)<crz:lêker>
|[[pelamar kirin]] (ser)<crz:lêker>
|pelamar sekinandin<crz:lêker>
|ketin ber pelamaran<crz:lêker>
|ketin ber pelamarê<crz:lêker>
|rê li pelamarê girtin<crz:lêker>
|rê li pelamaran girtin<crz:lêker>
|pelamarber
|pelamarberî
|pelamarbir
|pelamargir
|pelamargirî
|pelamarker
|pelamarkerî
|pelamarkir
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W-|af|aanval}}
* {{Z|de}}: {{W+|de|Anfall|m}}, {{W+|de|Angriff|m}}, {{W+|de|Offensive|f}}
* {{Z|da}}: {{W+|da|angreb}}
* {{Z|ar}}: {{W-|ar|هجوم}}, {{W-|ar|مباغتة}}
* {{Z|eo}}: {{W-|eo|atako}}
* {{Z|fa}}: {{W+|fa|تجاوز کردن}}, {{W-|fa|حمله ناگهانی|guman=erê}}, {{W-|fa|فرصت کمیاب|guman=erê}}, {{W+|fa|یورش|guman=erê}}
* {{Z|fi}}: {{W+|fi|hyökkäys}}
* {{Z|fr}}: {{W+|fr|attaque}}
* {{Z|fy}}: {{W-|fy|oanfal}}, {{W-|fy|oerhaal}}, {{W-|fy|raam}}
* {{Z|nl}}: {{W+|nl|aanval}}, {{W+|nl|offensief}}, {{W+|nl|vlaag}}, {{W+|nl|attaque}}
* {{Z|en}}: {{W+|en|attack}}, {{W+|en|aggression}}, {{W+|en|assault}}, {{W+|en|strike}}, {{W+|en|offensive}}, {{W+|en|crusade}}, {{W+|en|incursion|guman=erê}}, {{W+|en|swoop|guman=erê}}
* {{Z|it}}: {{W+|it|assalto}}, {{W+|it|attacco}}, {{W+|it|aggressione}}
* {{Z|hu}}: {{W+|hu|attak}}, {{W+|hu|roham}}, {{W+|hu|támadás}}
* {{Z|pap}}: {{W-|pap|ataka}}
* {{Z|pt}}: {{W+|pt|crise}}, {{W+|pt|agressão}}, {{W+|pt|ataque}}
* {{Z|ru}}: {{W+|ru|атака}}
* {{Z|es}}: {{W+|es|ataque}}, {{W+|es|agresión}}
* {{Z|sv}}: {{W+|sv|anfall}}, {{W+|sv|angrepp}}, {{W+|sv|attack}}
* {{Z|tl}}: {{W-|tl|paglúsob}}
* {{Z|tr}}: {{W+|tr|hücum}}, {{W+|tr|saldırış}}, {{W+|tr|kampanya}}, {{W+|tr|saldırı|guman=erê}}
{{werger-bin}}
h0y8qgxzmerh5dil4y8sriu8wfwj6xa
pêşbirk
0
30862
6347613
6315166
2026-09-01T11:28:09Z
Wikihez
7344
/* Etîmolojî */ [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin
6347613
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[kêbirrkê]], [[pêşbazî]], [[hevrikî]], [[berebezî]], [[berêkane]], [[hawirkanî]], [[riberiz]], [[kêbirk]], [[milmilane]], [[dijberî]], [[reqabet]], [[misabiqe]], [[sîbaq]], <br>[[yarî|yariya]] yan [[kar]]ê ku du yan zêdetir kes dikin daku [[diyar]] bibe ka [[kîjan]] [[zîrek]]tir e
#:''pêşbirka bezînê, <br>pêşbirka helbestan''
# {{kontrol|rêz=erê|[[tirat]], [[berebazî]], [[hawirkan]], [[hevberî]], [[berberî]], [[ixtilaf]], [[lec]]}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Jê ====
* [[pêşbirkane]]
* [[pêşbirkî]]
* [[pêşbirkvan]]
* [[pêşbirkvanî]]
==== Etîmolojî ====
Ji {{qf|ku|pêş-|birîn|-k}}. Bide ber {{hv|ckb|پێشبڕک}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Konkurrenz|f}}, {{W+|de|Konkurrenzkampf}}, {{W+|de|Rivalität|f}}, {{W+|de|Wettbewerb|m}}
* {{Z|fa}}: {{W+|fa|مسابقه}}
* {{Z|fi}}: {{W+|fi|kilpailu}}, {{W+|fi|kisa}}
* {{Z|fr}}: {{W+|fr|concours|m}}, {{W+|fr|compétition|f}}
* {{Z|nl}}: {{W+|nl|competitie|f}}, {{W+|nl|toernooi|n}}
* {{Z|en}}: {{W+|en|competition}}, {{W+|en|contest}}, {{W+|en|emulation}}, {{W+|en|opposition}}, {{W+|en|race}}, {{W+|en|rivalry}}, {{W+|en|rencounter}}, {{W+|en|bout|guman=erê}}
* {{Z|it}}: {{W+|it|concorso|m}}, {{W+|it|competizione|f}}, {{W+|it|gara|f}}
* {{Z|ca}}: {{W+|ca|competició}}
* {{Z|ml}}: [[മത്സരം]] (malsaram)
* {{Z|pt}}: {{W+|pt|concurso|m}}, {{W+|pt|competição|f}}
* {{Z|es}}: {{W+|es|concurso}}, {{W+|es|competición}}
* {{Z|sv}}: {{W+|sv|tävling|c}}
* {{Z|tr}}: {{W+|tr|müsabaka}}, {{W+|tr|yarış}}, {{W+|tr|konkur}}, {{W+|tr|koşun}}, {{W+|tr|rekabet}}, {{W+|tr|yarışma}}, {{W+|tr|maç}}, {{W+|tr|karşılaşma}}
{{werger-bin}}
6qubff6u80ebnr9omdqh0s13ctgxcb7
biwêj
0
30995
6347434
6302117
2026-08-31T19:05:32Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347434
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{deng|ku|LL-Q36368 (kur)-Dildadil-biwêj.wav|dever=Amed}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# {{f|ku|purîzm|kevnbûyî}} [[şair]]<ref>{{ferhenga kurdî-rûsî|r=124}}</ref><ref>{{Musa Anter|r=25}}</ref>
#* {{jêder-kovar|ku|sal=1944|nivîskar=Dilbikulê Doskî|sernav=Serbestî|r=27|kovar=Ronahî|hj=26|jêgirtin=Gelê serbest dê behsê bab û bapîr û mêrçak û '''biwêjêt''' (şair) xwe ket û xûnit.}}
#* {{jêder-kitêb|ku|jêgirtin=Çi gava ku mirovek, têkoşer û şoreşgerên kurd bîne ber çavên xwe, bê guman, navê '''biwêj''' (şair) ê mezin Cigerxwin di nav wande wê bê êjmartin.|nivîskar=Hemîd Derwêş|sernav=Pêşgotina Kîme Ez ya Cigerxwîn|sal=1973|rûpel=3}}
# {{f|ku|rêziman}} Çend [[kelîme]]yên [[li gel hev]] yên ku [[mane]]yeke [[xisûsî]] didin, ne maneya her yek ji wan kelîmeyan.
#: {{hevmane|ku|tebîr|fraz|îdyom}}
#: {{nm|ku|"Emrê Xwedê kirin" '''biwêjek''' e ku wateya "mirin"ê dide.}}
#* {{jêder-kitêb|ku|jêgirtin={{zim|fr|Locution adverbiale}} — '''biwêja''' rengpîşe|r=164|sernav=Langue Kurde|url=https://bnk.institutkurde.org/catalogue/detail.php?pirtuk=619|cih=Parîs|nivîskar=Kamiran Alî Bedirxan|çap=2|sal=1965}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Notên bikaranînê ====
Maneya 2an ya ''fraz, tebîr'' ji aliyê [[dariştin]]ê ve xelet e.{{eref|nav=Ergun2021}} Bide ber {{q|ku|bikir|t=ê ku dikirre}}.
==== Bi alfabeyên din ====
* {{ku-ar|بوێژ}}
* {{ku-kr|бьԝеж}}
==== Jê ====
{{kol3|ku
|biwêjî
}}
==== Etîmolojî ====
{{neo|ku}}eke {{deyn|ckb|ku|بوێژ<tr:biwêj><t:şair>}} ye ku {{coinage|ku|Gîw Mukriyanî|nocap=1}}.{{eref|{{kitêb|sal=2024|nivîskar=Zülküf Ergün|sernav=Plandanîna Zimanê Kurdî (Kurmancî-Soranî) di Mînakên Korî Zanyarî Kurd û Enstîtuya Kurdî ya Parîsê da|url=https://acikerisim.dicle.edu.tr/server/api/core/bitstreams/21ff11fc-bab3-4b39-8e49-4649c22f56be/content|r=57}} "dariştina bêjeyan tiştekî asayî dibîne û di nivîsareke xwe da dîyar dike ku bêjeyên “wêje” û “biwêj” ê ji alîyê wî ve hatine dariştin (Hetaw: 1958: 4-5) û bêjeya “kovar” ê jî cara pêşî wan di Zarî Kirmancîyê da dahênaye (G.M., 1958: 23)"}} ji {{qe|ckb|ب<tr:bi-><crz:pêşgira failî, bide ber {{q+|ku|bikir|t=mişterî}}>|وێژ<tr:-wêj-><crz:rehê dema niha ya fiîla {{q|ckb|ۋاتەی|tr=watey|t=gotin}}>|nekat=1}}.{{eref|nav=Ergun2021|{{kovar|kovar=Nûbihar Akademî|nivîskar=Zülküf Ergün|url=https://dergipark.org.tr/tr/pub/nubihar/issue/65156/954951|sernav=Çend Kêşeyên Veguhestinê ji Kurdîya Soranî bo Kurdîya Kurmancî|cild=4|hejmar=15|sal=2021|r=40}}}} Bide ber {{q|ku|wêje}}.
Maneya 2an ya ''fraz, tebîr'' ji eynî rehî {{coinage|ku|Kamiran Alî Bedirxan|nocap=1}}.
{{çavkanî-etîm}}
==== Bide ber ====
{{kol3|ku
|bêje
}}
==== Werger ====
{{werger-bnr|şair}}
{{werger-bnr|tebîr|id=îdyom}}
=== Formeke lêkerê ===
{{lêker|ku|form=erê}}
# {{f|ku|Semsûr/Kolik}} {{guharto|ku|bibêje}}
=== Çavkanî ===
{{çavkanî}}
os39w31steve4ni3bsviugwjaec2hj9
kerb
0
32302
6347509
6341220
2026-09-01T03:30:15Z
~2026-47348-87
15312
/* Etîmolojî */ Çima ji peyva Erebi [[كَرْب]]=[[kerb]] nîne?
6347509
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[kîn]], [[rik]], [[nefret]], [[nifir]], [[neyarî]], [[dijminatî]], [[qîn]], [[xezeb]]<br>jê[[hez]]nekirin û [[dij]]î bûn
#* {{J:Yaşar Kemal:Çiyayê Agirî|jêgirtin='''Kerba''' Sofî rabûbû, ne west dihat bîra wî, ne jî rawest. Her lêdixist.}}
# {{kontrol|rêz=erê|[[xezeb]], [[înat]], [[israr]], [[dijberî]]}}
==== Ji wêjeya klasîk ====
* {{J:Mem û Zîn:1692|jêgirtin=Dinya hemî bûye 'eyş û 'uşret</br>Zala felekê ji '''kerb''' û hesret</br>Çu j'dest nedihat û maye 'aciz}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Bi alfabeyên din ====
* {{ku-ar|كهرب}}
==== Jê ====
* [[kerb jê vebûn]]
* [[kerb u kîn]]
==== Etîmolojî ====
Ji {{ji|ar|ku|كلب|tr=keleb}} yan ji aramî [[ܟܠܒܐ]] (kelba/kelva) herdu bi maneya "[[harî]], [[har]]bûn", têkilî erebî {{g|ar|كلب}} (kelb: [[se]], [[kûçik]]) û aramî [[ܟܠܒܐ]] (kelba/kelva[[se]], [[kûçik]]). Binêre: [[kelb]]
[[Baş e, bi heman wateyê jixwe peyvek erebî wek [[kerb]]=[[كَرْب]] heye gelo ew jî ji [[keleb]] hatiye der? Himmm, bavêje....]]
==== Werger ====
{{werger-ser}}
* {{Z|sq}}: {{W+|sq|urrejtje}}
* {{Z|de}}: {{W|de|Haß|m}}, {{W|de|Hass|m}}, {{W|de|Angst|f}}, {{W|de|Aufwallung|f}}, {{W|de|Wut|f}}, {{W|de|Zorn|m}}, {{W|de|Böse|guman=erê}}
* {{Z|az}}: {{W+|az|nifrәt}}
* {{Z|eu}}: {{W+|eu|herra}}
* {{Z|br}}: {{W|br|kas|m}}
* {{Z|bg}}: {{W+|bg|омраза}}
* {{Z|cs}}: {{W|cs|nenávist|f}}, {{W|cs|zášť|f}}
* {{Z|zh}}: [[仇恨]] (chóuhèn)
* {{Z|id}}: {{W+|id|kebencian}}
* {{Z|ar}}: [[كراهية]] (kerahiye), {{W|ar|الإحاح|guman=erê}}
* {{Z|eo}}: {{W+|eo|malamo}}
* {{Z|et}}: {{W+|et|viha}}
* {{Z|fa}}: [[دشمنی]] (došmenî), [[نفرت]] (nefret), {{W+|fa|شدت عصبانیت}}
* {{Z|fi}}: {{W+|fi|viha}}
* {{Z|fr}}: {{W|fr|haine|f}}
* {{Z|hi}}: [[घृणा]] (gh.ri.nā), [[घिन]] (ghin), [[दुश्मनी]] (dušmanī), [[नफ़रत]] (nefret)
* {{Z|nl}}: {{W|nl|haat|m}}
* {{Z|he}}: [[שנאה]] (siná)
* {{Z|en}}: {{W+|en|hatred}}, {{W+|en|ire}}, {{W+|en|outrage}}, {{W+|en|rage}}, {{W+|en|spite}}, {{W+|en|wrath}}, {{W+|en|anger}}, {{W+|en|botheration|guman=erê}}
* {{Z|it}}: {{W|it|odio|m}}
* {{Z|ja}}: {{W+|ja|憎悪}}
* {{Z|ca}}: {{W|ca|odi|m}}
* {{Z|ko}}: {{W+|ko|증오심}}
* {{Z|lv}}: {{W+|lv|ienaids}}
* {{Z|lt}}: {{W+|lt|neapykanta}}
* {{Z|ms}}: {{W+|ms|benci}}
* {{Z|hu}}: {{W+|hu|gyűlölet}}
* {{Z|no}}: {{W|no|hat|n}}
* {{Z|pl}}: {{W|pl|nienawiść|f}}
* {{Z|pt}}: {{W|pt|ódio|m}}
* [[pygurî]]: [[bolmaq]]
* {{Z|ro}}: {{W+|ro|ură}}
* {{Z|ru}}: {{W|ru|ненависть|f}}
* {{Z|sh}}: {{W|sh|mržnja#Bosnian|f}}
* {{Z|sh}}: {{W|sh|mržnja#Croatian|f}}
* {{Z|sh}}:
*: Kirîlî: [[мржња#Serbian|мржња]] {{mê}}
*: Latînî: {{W|la|mržnja#Serbian|f}}
* {{Z|sk}}: {{W|sk|zášť|f}}
* {{Z|sl}}: {{W|sl|sovraštvo|n}}
* {{Z|es}}: {{W|es|odio|m}}
* {{Z|sw}}: {{W+|sw|chuki}}
* {{Z|sv}}: {{W|sv|hat|n}}
* {{Z|tr}}: {{W+|tr|nefret}}, {{W+|tr|hasret}}, {{W+|tr|keder}}, {{W+|tr|üzünç}}, {{W+|tr|üzüntü}}, {{W+|tr|çeki}}
* {{Z|ur}}: {{W|ur|گھرنا|f}}, {{W|ur|گھن|f}}, {{W|ur|دشمنی|f}}, [[نفرت]] (nefret)
* {{Z|cy}}: {{W|cy|casineb|m}}
* {{Z|el}}: {{W|el|μίσος|n}}, {{W|el|έχθρα|f}}
* [[yidîşî]]: [[האַס]] (has) {{mê}}
{{werger-bin}}
gex3v7eluufxbag044ztnh606td0a2b
6347562
6347509
2026-09-01T10:12:15Z
Wikihez
7344
/* Etîmolojî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347562
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[kîn]], [[rik]], [[nefret]], [[nifir]], [[neyarî]], [[dijminatî]], [[qîn]], [[xezeb]]<br>jê[[hez]]nekirin û [[dij]]î bûn
#* {{J:Yaşar Kemal:Çiyayê Agirî|jêgirtin='''Kerba''' Sofî rabûbû, ne west dihat bîra wî, ne jî rawest. Her lêdixist.}}
# {{kontrol|rêz=erê|[[xezeb]], [[înat]], [[israr]], [[dijberî]]}}
==== Ji wêjeya klasîk ====
* {{J:Mem û Zîn:1692|jêgirtin=Dinya hemî bûye 'eyş û 'uşret</br>Zala felekê ji '''kerb''' û hesret</br>Çu j'dest nedihat û maye 'aciz}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Bi alfabeyên din ====
* {{ku-ar|كهرب}}
==== Jê ====
* [[kerb jê vebûn]]
* [[kerb u kîn]]
==== Etîmolojî ====
Ji {{ji|ar|ku|كلب|tr=keleb}} yan ji aramî [[ܟܠܒܐ]] (kelba/kelva) herdu bi maneya "[[harî]], [[har]]bûn", têkilî erebî {{g|ar|كلب}} (kelb: [[se]], [[kûçik]]) û aramî [[ܟܠܒܐ]] (kelba/kelva[[se]], [[kûçik]]). Binêre: [[kelb]]
Herwiha bide ber {{nh|ar|كَرْب|t=kerb}}.
==== Werger ====
{{werger-ser}}
* {{Z|sq}}: {{W+|sq|urrejtje}}
* {{Z|de}}: {{W|de|Haß|m}}, {{W|de|Hass|m}}, {{W|de|Angst|f}}, {{W|de|Aufwallung|f}}, {{W|de|Wut|f}}, {{W|de|Zorn|m}}, {{W|de|Böse|guman=erê}}
* {{Z|az}}: {{W+|az|nifrәt}}
* {{Z|eu}}: {{W+|eu|herra}}
* {{Z|br}}: {{W|br|kas|m}}
* {{Z|bg}}: {{W+|bg|омраза}}
* {{Z|cs}}: {{W|cs|nenávist|f}}, {{W|cs|zášť|f}}
* {{Z|zh}}: [[仇恨]] (chóuhèn)
* {{Z|id}}: {{W+|id|kebencian}}
* {{Z|ar}}: [[كراهية]] (kerahiye), {{W|ar|الإحاح|guman=erê}}
* {{Z|eo}}: {{W+|eo|malamo}}
* {{Z|et}}: {{W+|et|viha}}
* {{Z|fa}}: [[دشمنی]] (došmenî), [[نفرت]] (nefret), {{W+|fa|شدت عصبانیت}}
* {{Z|fi}}: {{W+|fi|viha}}
* {{Z|fr}}: {{W|fr|haine|f}}
* {{Z|hi}}: [[घृणा]] (gh.ri.nā), [[घिन]] (ghin), [[दुश्मनी]] (dušmanī), [[नफ़रत]] (nefret)
* {{Z|nl}}: {{W|nl|haat|m}}
* {{Z|he}}: [[שנאה]] (siná)
* {{Z|en}}: {{W+|en|hatred}}, {{W+|en|ire}}, {{W+|en|outrage}}, {{W+|en|rage}}, {{W+|en|spite}}, {{W+|en|wrath}}, {{W+|en|anger}}, {{W+|en|botheration|guman=erê}}
* {{Z|it}}: {{W|it|odio|m}}
* {{Z|ja}}: {{W+|ja|憎悪}}
* {{Z|ca}}: {{W|ca|odi|m}}
* {{Z|ko}}: {{W+|ko|증오심}}
* {{Z|lv}}: {{W+|lv|ienaids}}
* {{Z|lt}}: {{W+|lt|neapykanta}}
* {{Z|ms}}: {{W+|ms|benci}}
* {{Z|hu}}: {{W+|hu|gyűlölet}}
* {{Z|no}}: {{W|no|hat|n}}
* {{Z|pl}}: {{W|pl|nienawiść|f}}
* {{Z|pt}}: {{W|pt|ódio|m}}
* [[pygurî]]: [[bolmaq]]
* {{Z|ro}}: {{W+|ro|ură}}
* {{Z|ru}}: {{W|ru|ненависть|f}}
* {{Z|sh}}: {{W|sh|mržnja#Bosnian|f}}
* {{Z|sh}}: {{W|sh|mržnja#Croatian|f}}
* {{Z|sh}}:
*: Kirîlî: [[мржња#Serbian|мржња]] {{mê}}
*: Latînî: {{W|la|mržnja#Serbian|f}}
* {{Z|sk}}: {{W|sk|zášť|f}}
* {{Z|sl}}: {{W|sl|sovraštvo|n}}
* {{Z|es}}: {{W|es|odio|m}}
* {{Z|sw}}: {{W+|sw|chuki}}
* {{Z|sv}}: {{W|sv|hat|n}}
* {{Z|tr}}: {{W+|tr|nefret}}, {{W+|tr|hasret}}, {{W+|tr|keder}}, {{W+|tr|üzünç}}, {{W+|tr|üzüntü}}, {{W+|tr|çeki}}
* {{Z|ur}}: {{W|ur|گھرنا|f}}, {{W|ur|گھن|f}}, {{W|ur|دشمنی|f}}, [[نفرت]] (nefret)
* {{Z|cy}}: {{W|cy|casineb|m}}
* {{Z|el}}: {{W|el|μίσος|n}}, {{W|el|έχθρα|f}}
* [[yidîşî]]: [[האַס]] (has) {{mê}}
{{werger-bin}}
lm91v11p0nzyuc1bx1wallm96ki7xad
mircan
0
33425
6347413
6339141
2026-08-31T17:11:47Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes)
6347413
wikitext
text/x-wiki
{{bnr-h|Mircan}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/mɪɾˈd͡ʒɑːn/}}
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:White_pearl_necklace.jpg|thumb|'''Mircan''']]
{{navdêr|ku|z=n}}
# Hin [[cure]]yê [[canewer]]ên [[hûrik]] yên [[avî]] ne
#* {{bêmînak|ku}}
# [[xişir]]ek [[bihagiran]] e ji wan [[heywan]]an çêbûye
#* {{J:Melayê Cizîrî:Dîwana Melayê Cizîrî|jêgirtin=Ke'be û Beytu l-heram e lê bi nûr bêtin receb</br>Suftiyên pir le'l û '''mircanan''' bi mujganan heta</br>Dîde rewşen bûn bi dîna dêmdurê sîmînxebeb}}
==== Tewandin ====
{{ku-tewîn-nav/nû|nêr}}
==== Bi alfabeyên din ====
* {{ku-ar|مرجان}}
==== Formên alternatîv ====
* [[mercan]]
==== Jê ====
* [[mircanfiroş]]
* [[mircanfiroşgeh]]
* [[mircanfiroşî]]
* [[mircanî]]
* [[mircanvan]]
* [[mircanvanî]]
==== Etîmolojî ====
Ji {{ji|ar|ku|مرجان|tr=mercan}} ji {{ji|arc|ku|מרגנא|tr=mergûna}} ji {{ji|el|ku|μαργαρίτης|tr=margarîtas}} ji {{ji|ira}}, [[hevreh]]a sanskrîtî [[मञ्यरी]] (mañjarī), kurdî [[mirwarî]], farisî {{g|fa|مروارید}} (mervarîd).
==== Bide ber ====
* [[mirarî]]
* [[morî]]
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W+|af|koraal}}
* {{Z|de}}: {{W|de|Koralle|f}}
* {{Z|da}}: {{W+|da|koral}}
* {{Z|ar}}: [[مرجان]] (mercan)
* {{Z|eo}}: {{W+|eo|koralo}}
* {{Z|fa}}: {{W+|fa|بسد}}, {{W+|fa|مرجان}}, {{W+|fa|نامی دخترانه}}, {{W+|fa|نام دختر}}
* {{Z|fi}}: {{W+|fi|koralli}}
* {{Z|fr}}: {{W+|fr|corail}}
* {{Z|nl}}: {{W+|nl|koraal}}
* {{Z|en}}: {{W+|en|coral}}, {{W+|en|coracoid|guman=erê}}
* {{Z|pap}}: {{W+|pap|koral}}
* {{Z|es}}: {{W+|es|coral}}
* {{Z|sv}}: {{W+|sv|korall}}
* {{Z|tr}}: {{W+|tr|mercan}}
{{werger-bin}}
l31miulkuoui8o1skhlsdyd7qxue9oo
rû dan
0
35049
6347569
6337310
2026-09-01T10:19:56Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347569
wikitext
text/x-wiki
{{bnr-n|rûdan}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Lêker ===
{{lêker|ku|c=h-gh}}
# [[qewimîn]], ([[bûyer]]ek) [[çêbûn]] yan [[bi serî hatin|bi serê kesekî hatin]]
#* {{J:Mîran Janbar:Qolyeya Cecileê|r=99|jêgirtin=Raymond hindik mabû hiş biavêta. Vê dîmena ku li ber çavên wî '''rû dabû''', ew xistibû nava şokeke mezin.}}
# {{kontrol|rêz=erê|[[çêbûn]], [[bûn]], [[peyda bûn]]}}
# rû badan
#* {{jêder-kovar|ku|jêgirtin=No ... Ne bi gora gotina wan e . Heçî ko bi dilpakî '''rùyê xwe dane'''. Xwedê û dest bi qenciyê kirine , li nik, Xwedê sewaba wan heye û ji bo wan tirsa ezabî nîne û ew xemdar na bin.|kovar=Hawar |sernav=Tefsîra Quranê |nivîskar= |weşanxane=Nûdem|hejmar=30|sal=1932-1933|rûpel=746|cîld=1}}
==== Bi alfabeyên din ====
* {{ku-ar|ڕوو دان}}
==== Jê ====
{{kol3|ku
|rûdav
|rûdaw
|rûdayî
|rûdan<crz:navdêr>
}}
==== Etîmolojî ====
Ji {{heve|ku|rû|dan}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|geschehen}}, {{W+|de|passieren}}, {{W+|de|stattfinden}}, {{W+|de|erfolgen}}, {{W-|de|sich ereignen}}, {{W+|de|ereignen}}, {{W+|de|verwöhnen}}, {{W+|de|unterlaufen}}
* {{Z|zh}}: {{W+|zh|發生}}, {{W-|zh|发生|tr=fāshēng}}
* {{Z|da}}: {{W+|da|ske}}
* {{Z|ar}}: {{W-|ar|استقبل|guman=erê}}
* {{Z|fa}}: {{W+|fa|رخ دادن}}, {{W+|fa|روی دادن}}
* {{Z|fi}}: {{W+|fi|tapahtua}}, {{W+|fi|sattua}}
* {{Z|fr}}: {{W+|fr|arriver}}, {{W+|fr|se produire}}, {{W+|fr|se passer}}
* {{Z|nl}}: {{W+|nl|gebeuren}}
* {{Z|he}}: {{W-|he|הלך|tr=halak}}
* {{Z|ang}}: {{W-|ang|weorþan}}, {{W-|ang|geweorþan}}
* {{Z|en}}: to {{W+|en|happen}}, to {{W+|en|occur}}, to {{W+|en|take place}}, {{W+|en|happen}}, {{W+|en|pamper|guman=erê}}
* {{Z|it}}: {{W+|it|accadere}}
* {{Z|pt}}: {{W+|pt|acontecer}}, {{W+|pt|suceder}}
* {{ru}} : [[случиться]] (slučït’sja)
* [[serî]]: [[aaha]]
* {{Z|es}}: {{W+|es|suceder}}, {{W+|es|ocurrir}}, {{W+|es|pasar}}
* {{Z|sv}}: {{W+|sv|hända}}, {{W+|sv|ske}}
* {{Z|tr}}: {{W+|tr|gelişmek}}, {{W+|tr|yüz vermek}}, {{W+|tr|yüzlü yüzlü|guman=erê}}
* {{Z|el}}: {{W-|el|συμβαίνω|tr=simvéno}}, {{W-|el|τυχαίνω|tr=tiçéno}}, {{W-|el|λαχαίνω|tr=laçéno}}, {{W-|el|τυγχάνω|tr=tiŋxáno}}, {{W-|el|διαδραματίζομαι|tr=ðiaðramatízome}}, {{W-|el|σημειώνομαι|tr=simiónome}}
{{werger-bin}}
nud8k41e0wemy7b8ew3sxe8t8fd54xk
hîbe
0
36338
6347539
6309033
2026-09-01T09:43:07Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347539
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/hiːˈbɛː/}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[bexş]], [[şabaş]], [[sexawet]], [[teberih]], [[diyarî]], [[hediye]], [[berarî]], [[bexşîn]], [[xêr]]kirin, <br>tiştek [[belaş]] dan
#* {{bênimûne|ku}}
#* {{jêder|ku|Netkurd.com, 3/2007|jêgirtin=Di hefteya '''hîbekirina''' organan de serokê şarediya Sûrê Abdullah Demirbaş jî ji bo '''hîbekirina''' organan bi kurdî û tirkî broşur belav kir}}
==== Tewandin ====
{{ku-tewîn-nav|mê|guherto=hemû}}
==== Formên alternatîv ====
{{kol3|ku
|hîba
}}
==== Jê ====
{{kol3|ku
|hîbe kirin<crz:lêker>
|hîbekirin<crz:navdêr>
|hîbekirî<crz:rengdêr>
|hîbeker
|hîbekirî
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|sq}}: {{W+|sq|dhurim}}
* {{Z|de}}: {{W|de|Spende|f}}, {{W|de|Beitrag|m}}
* {{Z|az}}: {{W+|az|bağışlama}}
* {{Z|bg}}: {{W+|bg|подаряване}}
* {{Z|cs}}: {{W+|cs|dar}}
* {{Z|zh}}: {{W+|zh|捐赠}}
* {{Z|id}}: {{W+|id|sumbangan}}
* {{Z|ar}}: {{W+|ar|التبرّع}}
* {{Z|eo}}: {{W+|eo|donaco}}
* {{Z|et}}: {{W+|et|annetamine}}
* {{Z|fa}}: {{W+|fa|دهش}}
* {{Z|fi}}: {{W+|fi|lahjoitus}}
* {{Z|fr}}: {{W|fr|donation|f}}, {{W|fr|don|m}}
* {{Z|ka}}: {{W+|ka|შენაწირი}}
* {{Z|nl}}: {{W|nl|donatie|f}}, {{W+|nl|schenking}}
* {{Z|en}}: {{W+|en|donation}}
* {{Z|it}}: {{W+|it|donazione}}
* {{Z|is}}: {{W+|is|framlag}}
* {{Z|ja}}: [[寄付]] ([[きふ]])
* {{Z|ko}}: {{W+|ko|기부금}}
* {{Z|lv}}: {{W+|lv|dāvana}}
* {{Z|hu}}: {{W+|hu|adomány}}
* {{Z|no}}: {{W+|no|donasjon}}
* {{Z|ug}}: {{W+|ug|iane}}
* {{Z|pl}}: {{W+|pl|dar}}
* {{Z|pt}}: {{W+|pt|doação}}
* {{Z|ro}}: {{W+|ro|donare}}
* {{Z|ru}}: {{W+|ru|пожертвование}}
* {{Z|sh}}: {{W+|sh|poklon}}
* {{Z|sh}}: {{W+|sh|поклон}}
* {{Z|sk}}: {{W+|sk|dar}}
* {{Z|es}}: {{W|es|donación|f}}
* {{Z|sw}}: {{W+|sw|kipaji}}
* {{Z|sv}}: {{W+|sv|donation}}
* {{Z|tr}}: {{W+|tr|bağişlama}}, {{W+|tr|hibe}}, {{W+|tr|bağış}}
* {{Z|vi}}: {{W+|vi|sự tặng}}
* {{Z|cy}}: {{W+|cy|cyfraniad}}
* {{Z|el}}: {{W+|el|δωρεά}}
{{werger-bin}}
d3puumv6wvus0bypw4p08t7bd8ey86d
zûl
0
36405
6347538
6346262
2026-09-01T09:42:24Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347538
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=n}}
# [[tîfşe]], [[teqal]], [[ker]], [[qed]], [[qaş]], [[parçe]], [[par]]
#: {{nm|ku|'''zûlek''' gundorî / pirteqalê}}
#: {{nm|ku|'''zûl-zûl''' kirin}}
#* {{jêder-websîte|ku|jêgirtin=Dema ko serok tûşek ('''zûl''') tenê porteqal bixwe dikare rewşa aboriya dinyayê têkbiçe an jî bo wî tenê destûra yek çemçikek berfeşîr (dondurma) bêd dayin, dikare hemî çiyayên berfê bihelin, rewşa ekolojîk têkbiçe. (Têbînî: Di rewşeka wiha de pêwîstî bi tedbîrên cidî hene, lewma dikare hemî agirbest biqedin û şerek dom û dirêj ji nû ve destpê bike.)|nivîskar=Mihemed Evdile|sernav=Fantastîk-polîtîka û kuna doşeka Ocalan|websîte=Nefel.com|sal=3/2007}}
# {{kontrol|rêz=erê|[[par]]}}
==== Formên alternatîv ====
{{kol3|ku
|zwîl
|zîl
}}
==== Jê ====
{{kol3|ku
|zûl kirin<crz:lêker>
|zûlkirin<crz:navdêr>
|zûlkirî<crz:rengdêr>
|zûlik
|zûl-zûl
|zûlî
|zûlker
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Bide ber ====
{{kol3|ku
|zal
|zil
|zîl
}}
==== Werger ====
{{werger-ser}}
* {{Z|ar}}: {{W-|ar|الكتلة|guman=erê}}
* {{Z|en}}: {{W+|en|oni}}, {{W+|en|thong}}, {{W+|en|come along|guman=erê}}
* {{Z|tr}}: {{W+|tr|dilim}}, {{W+|tr|sıyrıntı}}, {{W+|tr|şerha}}, {{W+|tr|taban}}
{{werger-bin}}
hawvvbg8s99kpehywuzujmg8zsxen5p
lasa
0
37032
6347532
6311061
2026-09-01T09:36:34Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347532
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/lɑːˈsɑː/}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[texlîd]], [[çavlêkirin]], [[zarî]]kirin, [[zehrî]]vekirin, [[demelaske]], <br>[[mîna]] kesekî yan tiştekî kirin, [[wek]] kesekî yan tiştekî kirin
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Bi alfabeyên din ====
* {{ku-ar|لاسا}}
==== Jê ====
{{kol3|ku
|lasaker
|lasa kirin<crz:lêker>
|lasakirin<crz:navdêr>
|lasakirî<crz:rengdêr>
}}
==== Etîmolojî ====
Ji {{deyn|ckb|ku|لاسایی}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|Imitation|f}}
* {{Z|fa}}: {{W+|fa|کارناروا}}, {{W+|fa|کار نادرست}}
* {{Z|en}}: {{W|en|imitation}}, {{W+|en|tradition}}, {{W+|en|dummy}}, {{W+|en|mimesis}}, {{W|en|keeping up with the Joneses|guman=erê}}
* {{Z|tr}}: {{W+|tr|kopya}}, {{W+|tr|taklit}}, {{W+|tr|imitasyon}}, {{W+|tr|sıradan}}, {{W+|tr|taklidî}}
{{werger-bin}}
85q0gpqtygtqy9otbqm3p1dm6oozowg
keşf
0
38290
6347520
6339200
2026-09-01T08:56:24Z
Balyozbot
7867
sererastkirina nimûneyên edebiyatê (bi destî) [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347520
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[dozîn]], [[vedîtin]], [[venasîn]], [[deranderî]], [[norîn]], [[dahênan]], [[danîn]], [[peyda]]kirin,
#* {{bêmînak|ku}}
# [[çêkirin]]a tiştekî nû
#: {{nm|ku|Televizyon kengî hatiye '''keşfkirin'''?|Yekem televizyon kengî hatiye çêkirin?|rêz=1}}
#: {{nm|ku|Firoke ji alî birayan Wright ve hatiye '''keşf'''kirin.}}
# [[peydakirin]]a cihekî nû
#: {{nm|ku|'''Keşfa''' Amerîkayê}}
# {{f|ku|hiqûq}} lêkolîna li cihê bûyerê
#* {{bêmînak|ku}}
# der barê tiştekî de bi awayekî nehênî agahî bi dest xistin
#* {{bêmînak|ku}}
==== Ji wêjeya klasîk ====
* {{J:Melayê Cizîrî:Dîwana Melayê Cizîrî|jêgirtin=Dê li nik sahibdilan hetta ebed bit serferaz</br>'''Keşfa''' esrarê sifatan bêmehebbet nabitin</br>Sûretê esma divêtin da bikîn jê fehim raz}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Formên alternatîv ====
{{kol3|ku
|keşif
}}
==== Jê ====
{{kol3|ku
|keşfî
|keşfvan
|keşfvanî
|keşf kirin<crz:lêker>
|keşfkirin<crz:navdêr>
|keşfkirî<crz:rengdêr>
}}
==== Etîmolojî ====
Ji {{deyn|ar|ku}}, têkildarî [[keşaf]]
==== Bide ber ====
{{kol3|ku
|kefş
}}
==== Werger ====
{{werger-ser}}
* {{Z|en}}: {{W+|en|discovery}}
* {{Z|tr}}: {{W+|tr|keşif}}
{{werger-bin}}
e3jq396ryy32ekohbmhfaksjupctrti
neqeb
0
39822
6347523
6336020
2026-09-01T08:58:35Z
Balyozbot
7867
sererastkirina nimûneyên edebiyatê (bi destî) [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347523
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[newal]], [[nihal]], [[kend]], [[dol]], [[gelî]], [[teht]], [[lat]], [[talde]], [[kanyon]], [[zinar]], [[rizde]], [[gêdûk]], [[gewer]], [[derbend]], [[zûr]], [[zûrik]], [[zeqir]], [[ziqre]], [[zixur]], [[xirînc]]
#* {{bênimûne|ku}}
# [[navber]]
#* {{J:Mîran Janbar:Qolyeya Cecileê|r=75|jêgirtin=Destê xwe dirêjî bişkokên gomlekê wê yên spîboz kiribû û ji jorê ve hêdî hêdî vekiribû. Di bişkoka duduyan de, rastî '''neqeba''' pêsîrên Cécileê hatibû.}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|neqeb kirin<crz:lêker>
|neqebî
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Bresche}} {{mê}}, {{W+|de|Spalt|guman=erê}} {{n}}, {{W+|de|Defilee|m|guman=erê}}, {{W+|de|Durchbruch|m|guman=erê}}
* {{Z|ar}}: {{W-|ar|ممر|guman=erê}}
* {{Z|fa}}: {{W+|fa|نقب}}, {{W+|fa|حفره}}
* {{Z|en}}: {{W+|en|between}}
* {{Z|tr}}: {{W+|tr|geçit}}, {{W+|tr|kanyon}}, {{W+|tr|tokat}}, {{W+|tr|ara}}, {{W+|tr|aralık}}, {{W+|tr|gedik}}, {{W+|tr|kapuz|guman=erê}}
{{werger-bin}}
80t37s0ax9oroedtoa4q54obw9c23l0
bûme
0
40037
6347580
6335084
2026-09-01T10:35:05Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes); +Etîmolojî (DefSideBoxes)
6347580
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[lerizîn|Lerizîn]]a bi[[hêz]] ya [[erd]]ê ku [[carine]] dibe [[sedem]]a [[ruxîn]]a [[avahî|avahiyan]] jî.
#: {{hevmane|ku|zelzele|erdhejî|erdlerzî}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê|guherto=hemû}}
==== Jê ====
* [[bûmeyî]]
* [[bûmelerz]]
==== Etîmolojî ====
{{ji?}}
==== Bide ber ====
* [[bûm]]
==== Werger ====
{{werger-ser}}
{{werger-bin}}
=== Formeke lêkerê ===
{{lêker|ku|form=erê}}
# ''Binêre'': '''[[bûn]]'''
#* {{J:Mem û Zîn:1692|jêgirtin=Ez jî ji zelîl û bênesîbî<br />Zer '''bûme''' ji hicr-i 'endelîbî<br />Dêma min e sor e erxewanî}}
k3vazs9wbfgkkabhrq1qirbzu4z64al
6347581
6347580
2026-09-01T10:35:24Z
Wikihez
7344
/* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347581
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[lerizîn|Lerizîn]]a bi[[hêz]] ya [[erd]]ê ku [[carine]] dibe [[sedem]]a [[ruxîn]]a [[avahî|avahiyan]] jî.
#: {{hevmane|ku|zelzele|erdhejî|erdlerzî}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê|guherto=hemû}}
==== Jê ====
* [[bûmeyî]]
* [[bûmelerz]]
==== Etîmolojî ====
{{ji?|ku}}
==== Bide ber ====
* [[bûm]]
==== Werger ====
{{werger-ser}}
{{werger-bin}}
=== Formeke lêkerê ===
{{lêker|ku|form=erê}}
# ''Binêre'': '''[[bûn]]'''
#* {{J:Mem û Zîn:1692|jêgirtin=Ez jî ji zelîl û bênesîbî<br />Zer '''bûme''' ji hicr-i 'endelîbî<br />Dêma min e sor e erxewanî}}
j4g6jbwhqp0btu5g0oujmjag7z2ays7
veto
0
40089
6347533
6319808
2026-09-01T09:37:53Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347533
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[red]]kirin, ne[[pejirandin]], [[pesind]]nekirin, [[qebûl]]nekirin
#* {{jêder|ku|Netkurd.com, 6/2007|jêgirtin=Serokkomarê Tirkiyeyê qanûna referandûmê '''veto''' kir.}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Formên alternatîv ====
{{kol3|ku
|vêto
|vîto
}}
==== Jê ====
{{kol3|ku
|veto kirin<crz:lêker>
|vetokirin<crz:navdêr>
|vetokirî<crz:rengdêr>
|vetoker
|vetoyî
}}
==== Etîmolojî ====
Taliyê ji {{ji|la|ku|veto|t=ez qedexe dikim}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Veto|nt}}
* {{Z|en}}: {{W+|en|veto}}
{{werger-bin}}
== {{ziman|en}} ==
=== Bilêvkirin ===
* {{deng|en|LL-Q1860 (eng)-Vealhurl-veto.wav|Deng|dever=Başûrê Îngilistanê, QY}}
=== Navdêr ===
{{navdêr|en}}
# [[veto]], [[qedexe kirin]], mafê helweşînê, yan mandelkirinê<ref>Ferhenga Kurdî-Îngîlîzî ya Salah Sadallah</ref>
== {{ziman|la}} ==
=== Formeke lêkerê ===
{{lêker|la|form=erê}}
# {{la-dema-niha|vetare|yekem|yekjimar}}
=== Çavkanî ===
{{çavkanî}}
t7rnebs6nbebd5cgkgo9g5kvwf2cmy9
înfaz
0
42250
6347637
6322439
2026-09-01T11:51:42Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347637
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[bicihanîn]], [[çespandin]], [[encamdan]], [[pêkanîn]], [[kirin]], [[îcra]]
#* {{bêmînak|ku}}
# [[sêdaredan]], [[darvekirin]], [[îdam]], [[şenq]]
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Formên alternatîv ====
{{kol3|ku
|infaz
}}
==== Jê ====
{{kol3|ku
|înfaz kirin<crz:lêker>
|înfazkirin<crz:navdêr>
|înfazkirî<crz:rengdêr>
|înfazî
|înfazker
}}
==== Etîmolojî ====
Ji {{ji|ar|ku|إِنْفَاذ}}.
==== Werger ====
{{werger-ser|înfaz kirin}}
* {{Z|af}}: {{W+|af|bedryf}}, {{W+|af|bedrywe}}, {{W+|af|begaan}}
* {{Z|de}}: {{W+|de|ausführen}}, {{W+|de|bestellen}}, {{W+|de|erfüllen}}, {{W+|de|leisten}}, {{W|de|Vollzug|m}}
* {{Z|eo}}: {{W+|eo|plenumi}}
* {{Z|fo}}: {{W+|fo|fullføra}}
* {{Z|fi}}: {{W+|fi|toteuttaa}}, {{W+|fi|panna toimeen}}, {{W+|fi|suoirttaa}}
* {{Z|nl}}: {{W+|nl|nakomen}}, {{W+|nl|naleven}}, {{W+|nl|uitvoeren}}, {{W+|nl|verrichten}}, {{W+|nl|vervullen}}, {{W+|nl|voltrekken}}
* {{Z|ang}}: {{W+|ang|gefyllan}}
* {{Z|en}}: {{W+|en|accomplish}}, {{W+|en|achieve}}, {{W+|en|keep}}, {{W+|en|observe}}, {{W+|en|perform}}, {{W+|en|exercise}}, {{W+|en|fulfil}}, {{W+|en|meet}}, {{W+|en|execute}}, {{W+|en|abide}}, {{W+|en|abide by}}, {{W+|en|execution}}, {{W+|en|performance}}
* {{Z|it}}: {{W+|it|compiere}}, {{W+|it|eseguire}}
* {{Z|ca}}: {{W+|ca|acomplir}}, {{W+|ca|realitzar}}, {{W+|ca|portar a cap}}
* {{Z|hu}}: {{W+|hu|teljesít}}
* {{Z|pap}}: {{W+|pap|kumpli}}
* {{Z|pl}}: {{W+|pl|wykonać}}, {{W+|pl|spełnić}}
* {{Z|pt}}: {{W+|pt|cumprir}}, {{W+|pt|desempenhar}}
* {{Z|ru}}: {{W+|ru|выполнять}}
* {{Z|es}}: {{W+|es|cumplir}}, {{W+|es|llevar a cabo}}, {{W+|es|ejecutar}}
* {{Z|tr}}: [[infaz]] etmek, {{W+|tr|yürütüm}}
{{werger-bin}}
awg0gaetn6i5j2drwng1kuaxcagm107
qefes
0
42941
6347522
6339284
2026-09-01T08:58:14Z
Balyozbot
7867
sererastkirina nimûneyên edebiyatê (bi destî) [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347522
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Vogelkäfig 18-19 Jh.jpg|thumb|qefesek]]
{{navdêr|ku|z=m}}
# [[rekeh|Rekeha]] ku ji [[darik]]ên yan [[şifşe]]yên [[zirav]] hatiye çêkirin û [[firinde]] tê de tên [[girtin]].
#* {{bêmînak|ku}}
# {{f|ku|mecazî}} [[girtîgeh]], [[girtîxane]], [[zîndan]], [[bendîxane]], [[bendîtî]]
#* {{bêmînak|ku}}
# [[perasû]], [[parsû]]
#* {{bêmînak|ku}}
==== Ji wêjeya klasîk ====
* {{J:Melayê Cizîrî:Dîwana Melayê Cizîrî|jêgirtin=Yexma ji me can kir ko tecellayê li dil da</br>Min rûhê di qalib tu yî tenha '''qefes''' im ez</br>Hubba te ye min radihejînî ko binalim}}
==== Bi alfabeyên din ====
* {{ku-ar|قهفهس}}
==== Formên alternatîv ====
{{kol3|ku
|qafes<qq:di bin tesîra tirkî de>
}}
==== Jê ====
{{kol3|ku
|qesef kirin<crz:lêker>
|qefeskirin<crz:navdêr>
|qefeskirî<crz:rengdêr>
|bêqefes
|biqefes
|qefeskirî
}}
==== Etîmolojî ====
Ji {{ji|ar|ku|قفص}} (qefeṣ: [[rekeh]], qefes; [[zembîl]], [[selik]]) ji {{ji|arc|ku|ܩܦܣܐ}} (qepsa: [[hw]]) ji {{ji|la|ku|capsa}} ([[sindoq]]) ji [[capere]] ([[zeft]] kirin, [[girtin]]) ji {{ji|ine-pro|ku|-}} [[keh₂p-]] ([[hw]]), hevreha yûnanî [[κάπτω]] (kapto: [[daqurtandin]], [[daûrandin]], [[daqurçandin]]). Ji heman rehê latînî: [[qase]], [[qaset]], [[qepsûl]], [[kapasîte]]...
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W-|de|Brustkorb(parsû)}}, {{W+|de|Käfig|m}}, {{W+|de|Bauer|n}}, {{W+|de|Brustkorb|m}}, {{W+|de|Fachwerk|n}}, {{W+|de|Gitter|n}}, {{W+|de|Vogelbauer|n}}
* {{Z|da}}: {{W+|da|bur|n}}
* {{Z|ar}}: {{W-|ar|قفص|cuda=قَفَص|tr=qefes}}, {{W+|ar|صدر|guman=erê}}
* {{Z|fa}}: {{W+|fa|قفس|tr=qefes}}, {{W+|fa|قفس}}, {{W+|fa|سینه}}
* {{Z|fi}}: {{W+|fi|häkki}}
* {{Z|fr}}: {{W+|fr|cage|f}}
* {{Z|hi}}: {{W-|hi|क़फ़स|tr=qafas}}
* {{Z|he}}: {{W-|he|כלוב|tr=kluv}}
* {{Z|io}}: {{W+|io|kajo}}
* {{Z|en}}: [[cage]] /keyc/, {{W+|en|cage}}
* {{Z|it}}: {{W+|it|gabbia|f}}
* {{Z|la}}: {{W-|la|cavea|f}}
* {{Z|pl}}: {{W+|pl|klatka|f}}
* {{Z|sh}}: {{W+|sh|kavez|m}}
* {{Z|sh}}:
*: Kirîlî: [[кавез]] {{mê}}
*: Latînî: {{W-|la|kavez|m}}
* {{Z|es}}: {{W+|es|jaula|f}}
* {{Z|tr}}: {{W+|tr|kafes}}
* {{Z|ur}}: {{W-|ur|قفس|tr=qefes}}
{{werger-bin}}
68rejgxt989a4izulp2q5f4uwh1mr2j
navûdeng
0
43638
6347521
6313057
2026-09-01T08:56:56Z
Balyozbot
7867
sererastkirina nimûneyên edebiyatê (bi destî) [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347521
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[nasîn|Nasîna]] tiştek [[an jî]] [[kesayetî|kesayetekî]] ji layê [[herkes]]ê ve
#* {{bêmînak|ku}}
# [[navdar|Navdar]]bûn, [[meşhûr]]bûn, [[rewş]]a kesên [[meşhûr]].
#: {{hevmane|ku|navdarî|meşhûrî|nasî|niyasî|nasdarî|popûlerî|binavûdengî}}
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Formên alternatîv ====
{{kol3|ku
|nav-û-deng
|nav û deng
}}
==== Hevmane ====
{{kol3|ku
|nam
}}
==== Jê ====
{{kol3|ku
|navûdeng dan<crz:lêker>
|navûdengdan<crz:navdêr>
|bênavûdeng
|bênavûdengî
|bênavûdengîtî
|bênavûdengt
|binavûdeng
|navûdengdar
}}
==== Etîmolojî ====
Ji {{qertaf|ku|nav|-û-|deng}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|Ruhm|m}}, {{W|de|Ruf|m|guman=erê}}
* {{Z|fi}}: {{W+|fi|kuuluisuus}}
* {{Z|en}}: {{W+|en|famous}}, {{W|en|popular}}, {{W|en|well-known}}, {{W+|en|fame}}, {{W+|en|kudos}}, {{W+|en|reputation}}, {{W+|en|appellation|guman=erê}}, {{W|en|famousness|guman=erê}}
* {{Z|tr}}: {{W+|tr|san}}, {{W+|tr|meşhurluk}}, {{W+|tr|ünlülük}}, {{W+|tr|çav}}, {{W+|tr|şan}}, {{W+|tr|anlı şanlı}}, {{W|tr|nam|guman=erê}}
{{werger-bin}}
5a4qb3y19ruk1jynyxe9omhg6al6pm0
6347563
6347521
2026-09-01T10:12:15Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347563
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[nasîn|Nasîna]] tiştek [[an jî]] [[kesayetî|kesayetekî]] ji layê [[herkes]]ê ve
#* {{bêmînak|ku}}
# [[navdar|Navdarbûn]], [[meşhûr]]bûn, [[rewş]]a kesên [[meşhûr]].
#: {{hevmane|ku|navdarî|meşhûrî|nasî|niyasî|nasdarî|popûlerî|binavûdengî}}
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Formên alternatîv ====
{{kol3|ku
|nav-û-deng
|nav û deng
}}
==== Hevmane ====
{{kol3|ku
|nam
}}
==== Jê ====
{{kol3|ku
|navûdeng dan<crz:lêker>
|navûdengdan<crz:navdêr>
|bênavûdeng
|bênavûdengî
|bênavûdengîtî
|bênavûdengt
|binavûdeng
|navûdengdar
}}
==== Etîmolojî ====
Ji {{qertaf|ku|nav|-û-|deng}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|Ruhm|m}}, {{W|de|Ruf|m|guman=erê}}
* {{Z|fi}}: {{W+|fi|kuuluisuus}}
* {{Z|en}}: {{W+|en|famous}}, {{W|en|popular}}, {{W|en|well-known}}, {{W+|en|fame}}, {{W+|en|kudos}}, {{W+|en|reputation}}, {{W+|en|appellation|guman=erê}}, {{W|en|famousness|guman=erê}}
* {{Z|tr}}: {{W+|tr|san}}, {{W+|tr|meşhurluk}}, {{W+|tr|ünlülük}}, {{W+|tr|çav}}, {{W+|tr|şan}}, {{W+|tr|anlı şanlı}}, {{W|tr|nam|guman=erê}}
{{werger-bin}}
4uegit2v68br8o30tys0qrh4tazjllh
temsîl
0
44705
6347525
6318732
2026-09-01T09:27:40Z
Balyozbot
7867
sererastkirina nimûneyên edebiyatê (bi destî) [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347525
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA|t(h)emsîl}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[nimandin]], [[nûnerî|nûneriya]] kesekî kirin
#: {{nm|ku|Ew partî '''temsîla''' gelê kurd nake.}}
# [[pêşkêş]]kirin, [[araste]]kirin, [[raber]]kirin, [[nîşan]]dan
#* {{bêmînak|ku}}
# [[nimûne]] bûn, [[mînak]] bûn
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Bi alfabeyên din ====
* {{ku-ar|تەمسیل}}
==== Jê ====
{{kol3|ku
|temsîlî
|temsîlkar
|temsîlker
|temsîlvan
|temsîl kirin<crz:lêker>
|temsîlkirin<crz:navdêr>
|temsîlkirî<crz:rengdêr>
}}
==== Etîmolojî ====
Ji {{deyn|ar|ku|تمثيل}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W-|de|Repräsentation|f}}, {{W+|de|Vertretung|f}}
* {{Z|fa}}: {{W+|fa|تمثیل}}
* {{Z|en}}: {{W+|en|representation}}
{{werger-bin}}
eeyqkbgvnwym4a6nda5n8g7huf6u5h8
talîmat
0
45110
6347572
6318386
2026-09-01T10:22:06Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347572
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[şîret]], [[nesîhet]]
#* {{bêmînak|ku}}
# [[rahênan]], [[prove]], [[ceribandin]], [[pratîk]], [[antreman]], [[îdman]], [[egzersîz]], [[tetbîqat]], [[temrîn]]
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Notên bikaranînê ====
{{kol3|ku
|talîmatdan<crz:navdêr>
}}
==== Formên alternatîv ====
{{kol3|ku
|tehlîm
|tahlîm
|te'lîm
|ta'lîm
}}
==== Etîmolojî ====
Ji {{deyn|ar|ku}}, têkildarî [[ilm]], [[elimîn]], [[elimandin]], [[mielim]], [[talîm]], [[malûmat]]
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Anleitung|m}}, {{W+|de|Anordnung|f|guman=erê}}, {{W+|de|Verfügung|f|guman=erê}}
* {{Z|fa}}: {{W+|fa|آموزش}}, {{W-|fa|دستورات}}
* {{Z|en}}: {{W+|en|regulation|guman=erê}}, {{W+|en|instruction|guman=erê}}
* {{Z|tr}}: {{W+|tr|talimat}}, {{W+|tr|direktif|guman=erê}}
{{werger-bin}}
53f3s1nqcn8m2n4n9kysfj7gveappjz
bergirî
0
45387
6347360
6298928
2026-08-31T12:57:43Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes)
6347360
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[rê dan|Rênedan]] ku kesek yan tiştek [[ziyan]]ê li kesekî yan tiştekî bike
#: {{hevmane|ku|berevanî|berhingarî|parastin|dîfa'}}
#* {{bêmînak|ku}}
# [[asteng]]kirin, [[rê dan|rênedan]]
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Formên alternatîv ====
* {{g|ku|bergirîtî}}
==== Jê ====
{{kol3|ku|cure=Jê
|bergirî kirin<pos:lêker>
|bergirîkirin<pos:navdêr>
|bergirîdan<pos:navdêr>
|bergirîkirî<pos:rengdêr>
}}
==== Etîmolojî ====
Ji {{paş|ku|bergir|-î}}
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W-|af|afweer}}
* {{Z|sq}}: {{W+|sq|mbrójtje}}
* {{Z|de}}: {{W+|de|Interdikt}}, {{W+|de|Verbot|nt}}, {{W+|de|Abwehr|m}}, {{W+|de|Wehr|m}}, {{W+|de|Verteidigung|m}}, {{W+|de|Defensive|m}}, {{W+|de|defensiv}}, {{W+|de|Vorsichtsmaßnahme|f|guman=erê}}
* {{Z|cs}}: {{W+|cs|obrana}}
* {{Z|da}}: {{W-|da|forbud}}, {{W-|da|forsvar}}
* {{Z|eo}}: {{W-|eo|pravigo}}, {{W-|eo|malpermeso}}, {{W-|eo|defendo}}
* {{Z|fa}}: {{W+|fa|احتیاط}}, {{W+|fa|اخطار}}, {{W+|fa|جلوگیری}}, {{W+|fa|دفاع}}
* {{Z|fo}}: {{W-|fo|forboð}}
* {{Z|fi}}: {{W+|fi|puolustus}}
* {{Z|fr}}: {{W+|fr|défense}}
* {{Z|fy}}: {{W-|fy|ferbod}}, {{W-|fy|definsje}}, {{W-|fy|ferdigening}}, {{W-|fy|ferwar}}
* {{Z|nl}}: {{W+|nl|motivering}}, {{W+|nl|rechtvaardiging}}, {{W+|nl|wettiging}}, {{W+|nl|interdict}}, {{W+|nl|verbod}}, {{W+|nl|afweer}}, {{W+|nl|defensie}}, {{W+|nl|verdediging}}, {{W+|nl|weer}}, {{W+|nl|verweer}}
* {{Z|en}}: {{W+|en|defense}}, {{W+|en|defence}}, {{W+|en|protection}}, {{W+|en|caution}}, {{W+|en|discreetness}}, {{W+|en|steadfastness}}, {{W+|en|impregnability|guman=erê}}, {{W+|en|endurance|guman=erê}}, {{W+|en|renitency|guman=erê}}, {{W+|en|immunity|guman=erê}}, {{W+|en|objecting|guman=erê}}
* {{Z|it}}: {{W+|it|difesa}}
* {{Z|pap}}: {{W-|pap|hustifikashon}}, {{W-|pap|prohibishon}}, {{W-|pap|defensa}}
* {{Z|pt}}: {{W+|pt|defesa}}
* {{Z|es}}: {{W+|es|prohibición}}, {{W+|es|defensa}}
* {{Z|sv}}: {{W+|sv|försvar}}, {{W+|sv|värn}}
* {{Z|tr}}: {{W+|tr|savunma}}, {{W+|tr|korunum}}, {{W+|tr|önlem}}, {{W+|tr|tedbir}}, {{W+|tr|savunuculuk}}, {{W-|tr|antipad}}, {{W+|tr|önleme}}
{{werger-bin}}
s53kit28kctn5n9qb8b9sq6z5dt6rfg
xepar
0
45999
6347527
6320364
2026-09-01T09:29:33Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347527
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[kêlan]]a [[zevî]] û [[bûstan]]an daku [[giya]]yên [[zîwan]] bên [[jêkirin]]
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Formên alternatîv ====
{{kol3|ku
|xepare
}}
==== Jê ====
{{kol3|ku
|xepirandin
|xepirandî
|xepirîner
|xeparker
|xepar kirin<crz:lêker>
|xeparkirin<crz:navdêr>
|xeparkirî<crz:rengdêr>
}}
==== Etîmolojî ====
Ji {{ji|arc}} [[ܚܦܪܐ]] ([[ḥ]]ipara: [[kolan]], karê kolandinê) ji [[ܚܦܪ]] ([[ḥ]]ipar: [[kolandin]], [[kêlan]], [[kun]] kirin), hevreha îbranî [[חפר]] ([[ḥ]]a[[ᵽ]]er) û erebî {{g|ar|حفر}} (ḥefere), hemû ji [[proto-samî]] *ḥ-ᵽ-r-.
==== Bide ber ====
{{kol3|ku
|eşêf kirin
}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Anker|m}}
* {{Z|en}}: {{W+|en|anchor}}
* {{Z|tr}}: {{W+|tr|çapa}}, {{W+|tr|çapalama}}, {{W+|tr|eşme}}
{{werger-bin}}
4krz8vmh0awj8nnsr5795c19h4xnd3x
kupeşte
0
46188
6347415
6310736
2026-08-31T17:19:50Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes)
6347415
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[dîwar|Dîwar]]ê yan [[şîş]]ên ku li [[balkon]]an yan [[ban]]an yan [[pir]]an hene daku mirov jê nekeve.
#: {{hevmane|ku|parapet|cax|şifşe}}
#* {{bênimûne|ku}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê|guherto=hemû}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|fi}}: {{W+|fi|kaide}}
* {{Z|en}}: {{W+|en|parapet}}, {{W+|en|bulwark}}
* {{Z|tr}}: {{W+|tr|parmaklık}}, {{W+|tr|korkuluk}}, {{W+|tr|parapet}}, {{W+|tr|küpeşte}}
{{werger-bin}}
5vvab07xo55ru6fzpig2dt8gxgkj9b6
6347441
6347415
2026-08-31T19:12:10Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347441
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[dîwar|Dîwarê]] yan [[şîş]]ên ku li [[balkon]]an yan [[ban]]an yan [[pir]]an hene daku mirov jê nekeve.
#: {{hevmane|ku|parapet|cax|şifşe}}
#* {{bênimûne|ku}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê|guherto=hemû}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|fi}}: {{W+|fi|kaide}}
* {{Z|en}}: {{W+|en|parapet}}, {{W+|en|bulwark}}
* {{Z|tr}}: {{W+|tr|parmaklık}}, {{W+|tr|korkuluk}}, {{W+|tr|parapet}}, {{W+|tr|küpeşte}}
{{werger-bin}}
qjtmaspibua96uxqhp4a4ympwm58ejm
komîk
0
46806
6347465
6239459
2026-08-31T20:38:54Z
Wikihez
7344
/* Rengdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347465
wikitext
text/x-wiki
{{bnr-h|komik}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Rengdêr ===
{{ku-tewîn-rd|komîk}}
{{rengdêr|ku}}
# [[pêkenok]], [[qirdik]], [[qeşmer]]
#* {{jêder-kovar|ku|jêgirtin=Lê Şiro mirîdekî seyr e. mirîdekî{{sic}} pir reng û pir '''komîk''' e.|kovar=Dugir|sernav=Berf û wêran|nivîskar=Selîm Berekat|sal=1995|rûpel=13}}
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026|jêgirtin=Dema mirov bi rêya înternetê îfadeya “Dêra Sorê” gogla dike, wek nimûne mirov wergerên tirkî yên '''komîk''' dibîne{{...}}}}
==== Jê ====
{{kol3|ku
|komîk bûn<pos:lêker>
|komîk kirin<pos:lêker>
|komîkbûn<pos:navdêr>
|komîkkirin<pos:navdêr>
|komîkbûyî<pos:rengdêr>
|komîkkirî<pos:rengdêr>
|komîkî
|trajî-komîk
}}
==== Têkildar ====
* {{g|ku|komedî}}
==== Etîmolojî ====
Ji {{deyn|tr|ku|komik}} ji {{ji|fr|ku|comique}} ji {{ji|la|ku|cōmicus}}, ji {{ji|grc|ku|κωμικός}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|komisch}}, {{W|de|lächerlich}}, {{W|de|lustig}}, {{W|de|unterhaltend}}, {{W|de|läppisch|guman=erê}}, {{W|de|aberwitzig|guman=erê}}, {{W|de|drollig|guman=erê}}
* {{Z|fa}}: {{W+|fa|خنده آور}}, {{W+|fa|خنده دار}}
* {{Z|en}}: {{W+|en|risible}}
* {{Z|tr}}: {{W+|tr|güldürücü}}, {{W+|tr|kepaze}}, {{W+|tr|gülünç}}, {{W+|tr|komik}}
{{werger-bin}}
=== Çavkanî ===
* {{Zana Farqînî|r=1045}}
* {{Ç:ku:Çeko Kocadag:2010|r=789}}
os8e63mr7k8qt4h6dc4vwhxxkx3uj0b
peroş
0
48671
6347636
6336137
2026-09-01T11:51:25Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347636
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[heyecan]], [[kelecan]], [[coş]], [[heyranî]]
#* {{jêder|ku|jêgirtin=Diyarbekir bibû stûdyoya Radyoya Dengê Êrîvanê û beşdar jî wekî ku li gundên xwe, li ber roniya çirayê Radyoya Êrîvanê guhdarî bikin dixuyan. Hest û raman, coş û '''peroş''' rih û giyaneke kurdewar di konserê de afirand.|Peyamner.com, 2/2008}}
#* {{J:Mîran Janbar:Qolyeya Cecileê|r=23|jêgirtin=Bi du mehan piştî serlêdana wê, piştî ku hemû referansên xwe bo têketina vê akademiyê bi kar anîbû, hatibû qebûlkirin û vê qebûlbûnê bi wê re coş û '''peroşeke''' mezin çekiribû.}}
# [[axûn]], [[şewq]], [[azwerî]], [[azgînî]], [[hewes]], [[arezû]], [[xasma]] ji bo [[huner]]ê.
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Notên bikaranînê ====
* Nêzî hergav xasma digel ''[[coş]]'' li kar dibe, wek ''coş û peroş''. Peyvek [[dêrîn]]/[[archaic]] e.
* Bi hin [[zarava]] û [[ziman]]ên [[kurdî]] [[wate]]ya [[perîşanî|perîşaniyê]] dide, li ''Etîmolojî'' binêre.
==== Jê ====
{{kol3|ku
|bêperoş
|bêperoşî
|biperoş
|peroşandin
|peroşdar
|peroşder
|peroşî
|peroşîn
|peroşîner
}}
==== Etîmolojî ====
Hevreha {{hv|ckb|پەرۆش|w=perîşanî, xem}}, {{hv|ku|perîşan}}, {{hv|fa|پریشیدن|tr=perêşîden|w=[[belawela kirin]], [[belav kirin]]; [[hiş]] [[belav kirin]], [[bal]]a yekî [[belav kirin]]}}. [[wate|Wateya]] [[resen]] ''[[belav]] bûn/kirin'' bûye û [[paşê]] bûye [[hiş]]î [[belav bûn]] ku bi [[farisî]] û [[soranî]] bo [[mebest]]a [[konsept]]a ''[[xemgînî]]'' û bi [[kurmancî|badînî]] jî [[mane]]ya ''ji [[kelecan]]ê [[hiş]] [[belav bûn]]'' wergirtiye. Bo [[guherîn]]ên di [[navber]]a [[mane]]yên ''[[gurmijîn]]-[[berketin]]-[[qîrîn]]-[[kelecan]]-[[şa bûn]]'' binêre {{q|ku|heyecan}}, {{q|ku|xiroş}} û {{q|en|excite}}, {{q|en|outburst}}... Divê ji ''{{g|ku|peroşîn}}'' çêbûbe. Ev [[herwiha]] [[peytandin|dipeyitîne]] ku ''[[perîşan]]'' ji [[farisî]] ye. [[guherîn|Guherîna]] [[deng]]ên /ê/-/û/ di [[kurdî]] de [[berbelav]] e. Herçend bi [[wekhevî|wekheviya]] [[dengî]], bi [[gengazî]] hevreha {{q|ku|xiroş}} nîne.
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W-|af|geesdrif}}, {{W-|af|besieling}}
* {{Z|de}}: {{W-|de|begeisterung}}, {{W+|de|Begeisterung|f}}, {{W+|de|Enthusiasmus|m}}, {{W+|de|Schwung|m}}, {{W+|de|Rührung|f}}
* {{Z|cs}}: {{W+|cs|entuziazmus|m}}
* {{Z|da}}: {{W-|da|begejstring}}
* {{Z|eo}}: {{W+|eo|entuziasmo}}
* {{Z|fa}}: {{W+|fa|سوزان}}
* {{Z|fo}}: {{W-|fo|eldhugi}}
* {{Z|fi}}: {{W+|fi|innostus}}
* {{Z|fr}}: {{W+|fr|enthousiasme}}
* {{Z|nl}}: {{W+|nl|enthousiasme}}, {{W+|nl|geestdrift}}, {{W+|nl|uitbundigheid}}
* {{Z|io}}: {{W+|io|entuziasmo}}
* {{Z|en}}: {{W+|en|enthusiasm}}, {{W+|en|zest}}, {{W+|en|ardent}}, {{W+|en|excitement}}, {{W+|en|ardently}}, {{W+|en|ebullient}}, {{W+|en|bouncy|guman=erê}}, {{W+|en|fervent|guman=erê}}, {{W+|en|enthusiast|guman=erê}}, {{W+|en|hair raising|guman=erê}}, {{W+|en|maudlin|guman=erê}}, {{W+|en|pressing|guman=erê}}, {{W+|en|raring|guman=erê}}
* {{Z|it}}: {{W+|it|entusiasmo}}
* {{Z|ca}}: {{W+|ca|entusiasme}}
* {{Z|pl}}: {{W+|pl|entuzjazm}}
* {{Z|pt}}: {{W+|pt|entusiasmo}}, {{W+|pt|furor}}, {{W+|pt|vida}}
* {{Z|es}}: {{W+|es|entusiasmo}}
* {{Z|sv}}: {{W+|sv|entusiasm}}, {{W+|sv|hänförelse}}
* {{Z|tr}}: {{W+|tr|coşku}}, {{W+|tr|heyecan}}, {{W-|tr|sanat aşkı}}, {{W+|tr|şevk}}
{{werger-bin}}
nwtm7791z0hawpz0frso15he28vbltd
teme
0
48859
6347553
6337280
2026-09-01T09:52:53Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347553
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Lêker ===
{{lêker|ku|c=}}
# [[şandin|Şandin]]a [[gotin]]ekê an jî [[şandin]]a [[tişt]]ekî din bi [[rê]]ya rêwiyeke an [[kes]]eke din.
#: {{nm|ku|Min [[Barîn]] [[teme]] kir ku [[rewş]]a me ji [[Zelal]]ê re bibêje.}}
#* {{bênimûne|ku}}
# Ji [[der]]eke [[din]] ji [[kes]]ekî [[tişt]]ek [[xwestin]].
#: {{nm|ku|Min [[Bengîn]] [[bo]] [[girtin]]a sê [[kîlo]] [[xiyar]] [[teme]] kir.}}
#* {{bênimûne|ku}}
==== Ji wêjeya klasîk ====
* {{J:Mem û Zîn:1692|jêgirtin=Ye'nî ji '''teme'''' dirav û dînar</br>Heryek ji me ra we bûne dildar}}
==== Jê ====
{{kol3|ku
|teme bûn<crz:lêker>
|teme kirin<crz:lêker>
|temebûn<crz:navdêr>
|temekirin<crz:navdêr>
|temebûyî<crz:rengdêr>
|temekirî<crz:rengdêr>
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Bitte|f}}
* {{Z|fa}}: {{W+|fa|تنبیه}}, {{W+|fa|نصیحت}}
* {{Z|tr}}: {{W+|tr|uyan}}, {{W+|tr|tembih}}
{{werger-bin}}
== {{ziman|ro}} ==
=== Lêker ===
{{lêker|ro}}
# {{g|ku|tirsîn}}
#* {{bênimûne|ro}}
=== Çavkanî ===
{{rûpela wergerê|ro|tirsîn}}
dwfajim7sjnpk8zaf2byj0va29fhdi2
6347601
6347553
2026-09-01T11:12:11Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347601
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Lêker ===
{{lêker|ku|c=}}
# [[şandin|Şandina]] [[gotin]]ekê an jî [[şandin]]a [[tişt]]ekî din bi [[rê]]ya rêwiyeke an [[kes]]eke din.
#: {{nm|ku|Min [[Barîn]] [[teme]] kir ku [[rewş]]a me ji [[Zelal]]ê re bibêje.}}
#* {{bênimûne|ku}}
# Ji [[der]]eke [[din]] ji [[kes]]ekî [[tişt]]ek [[xwestin]].
#: {{nm|ku|Min [[Bengîn]] [[bo]] [[girtin]]a sê [[kîlo]] [[xiyar]] [[teme]] kir.}}
#* {{bênimûne|ku}}
==== Ji wêjeya klasîk ====
* {{J:Mem û Zîn:1692|jêgirtin=Ye'nî ji '''teme'''' dirav û dînar</br>Heryek ji me ra we bûne dildar}}
==== Jê ====
{{kol3|ku
|teme bûn<crz:lêker>
|teme kirin<crz:lêker>
|temebûn<crz:navdêr>
|temekirin<crz:navdêr>
|temebûyî<crz:rengdêr>
|temekirî<crz:rengdêr>
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Bitte|f}}
* {{Z|fa}}: {{W+|fa|تنبیه}}, {{W+|fa|نصیحت}}
* {{Z|tr}}: {{W+|tr|uyan}}, {{W+|tr|tembih}}
{{werger-bin}}
== {{ziman|ro}} ==
=== Lêker ===
{{lêker|ro}}
# {{g|ku|tirsîn}}
#* {{bênimûne|ro}}
=== Çavkanî ===
{{rûpela wergerê|ro|tirsîn}}
bx1mirhe14o04q8s4qfxtpt4fw8g5w3
miştax
0
48889
6347374
6312594
2026-08-31T13:21:35Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347374
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# Cihê ku [[tirî]] lê tê [[hişk]]kirin daku bibe [[mewîj]].
#* {{jêder|ku|jêgirtin=Heyva tebaxê, tirî ket '''miştaxê'''.|metelokek kurdî ye|tarîxna=1}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Etîmolojî ====
Ji {{ji|arc}}.
==== Werger ====
{{werger-ser}}
* {{Z|en}}: {{W-|en|[[tray]] for [[drying]] [[fruit]]}}
{{werger-bin}}
7r1qlgranu5mamjndkfvd0gibp2vdzc
6347375
6347374
2026-08-31T13:21:47Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347375
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# Cihê ku [[tirî]] lê tê [[hişk]]kirin daku bibe [[mewîj]].
#* {{jêder|ku|jêgirtin=Heyva tebaxê, tirî ket '''miştaxê'''.|Metelokek kurdî|tarîxna=1}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Etîmolojî ====
Ji {{ji|arc}}.
==== Werger ====
{{werger-ser}}
* {{Z|en}}: {{W-|en|[[tray]] for [[drying]] [[fruit]]}}
{{werger-bin}}
e3d0sp36c8ldxfm21skbglenk1l0140
tesfiye
0
49031
6347548
6318962
2026-09-01T09:48:48Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347548
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[safî]]kirin, [[xwerû]]kirin, [[zelilandin]], [[zelal]]kirin, [[paqij]]kirin, [[pak]]kirin, [[arî]]kirin, [[sade]]kirin
#* {{bêmînak|ku}}
# [[jiholêrakirin]], [[îmha]]kirin, ne[[hêlan]]
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav|mê|guherto=hemû}}
==== Formên alternatîv ====
{{kol3|ku
|tasfiye
}}
==== Jê ====
{{kol3|ku
|tesfiye bûn<crz:lêker>
|tesfiye kirin<crz:lêker>
|tesfiyebûn<crz:navdêr>
|tesfiyekirin<crz:navdêr>
|tesfiyebûyî<crz:rengdêr>
|tesfiyekirî<crz:rengdêr>
|resfiyeker
}}
==== Etîmolojî ====
Ji {{deyn|ar|ku}}. {{anlz|ku|te-|safî}}.
==== Werger ====
{{werger-ser}}
* {{Z|en}}: {{W+|en|refinement}}
* {{Z|it}}: {{W+|it|liquidare}}, {{W+|it|liquidazione}}
* {{Z|tr}}: {{W+|tr|likidasyon}}, {{W+|tr|tasfiye}}
{{werger-bin}}
hvnomis17zem69r3dumefg20iwd38gg
li bendê man
0
49294
6347573
6336168
2026-09-01T10:22:38Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347573
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Lêker ===
{{ku-tewîn-lk|li bendê man|form=negerguhêz|niha=mîn|borî=ma|pêşgir= li bendê|valahî=erê}}
{{lêker|ku|c=b-ngh}}
# [[rawestîn|Rawestîn]] ta ku tiştek [[qewimîn|biqewime]] yan kesek bêt.
#: {{hevmane|ku|payîn|li hêviyê man|li bendê bûn|li hêviyê bûn|lê [[sekinîn]]}}
#: {{nm|ku|Ez seetekê '''li''' '''benda te mam''' lê tu nehatî.}}
#* {{J:Bavê Nazê:1986|jêgirtin=Remo mîna rêwiyên din di rêzê de '''li bendî''' dora xwe '''ma'''.}}
==== Jê ====
{{kol3|ku
|libendêman<crz:navdêr>
}}
==== Formên alternatîv ====
{{kol3|ku
|li bendê mayîn
}}
==== Etîmolojî ====
Ji {{qertaf|ku|li|bendê|man}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|erwarten}}, {{W|de|entgegensehen|guman=erê}}, {{W|de|gewärtigen|guman=erê}}, {{W|de|harren|guman=erê}}, {{W|de|rechnen auf|guman=erê}}, {{W|de|warten auf|guman=erê}}
* {{Z|ar}}: {{W|ar|انتظار}}, {{W|ar|ترقب}}, {{W|ar|رصد}}, {{W|ar|ارتقاب}}, {{W|ar|ترصد}}
* {{Z|fa}}: {{W+|fa|منتظر ماندن}}, {{W|fa|منتظر شدن|guman=erê}}
* {{Z|en}}: {{W+|en|abide}}, {{W+|en|anticipate}}, {{W+|en|wait}}, {{W+|en|hold your horses|guman=erê}}, {{W+|en|watch for|guman=erê}}, {{W|en|wait on|guman=erê}}
* {{Z|tr}}: {{W+|tr|beklemek}}, {{W+|tr|intizar etmek}}, {{W+|tr|aylamak}}, {{W+|tr|yolunu beklemek|guman=erê}}
{{werger-bin}}
3k9pnikm60ac8z5suxqeyrpokvayqj2
6347584
6347573
2026-09-01T10:41:11Z
Balyozbot
7867
[[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan
6347584
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Lêker ===
{{ku-tewîn-lk|li bendê man|form=negerguhêz|niha=mîn|borî=ma|pêşgir= li bendê|valahî=erê}}
{{lêker|ku|c=b-ngh}}
# [[rawestîn|Rawestîn]] ta ku tiştek [[qewimîn|biqewime]] yan kesek bêt.
#: {{hevmane|ku|payîn|li hêviyê man|li bendê bûn|li hêviyê bûn|lê [[sekinîn]]}}
#: {{nm|ku|Ez seetekê '''li''' '''benda te mam''' lê tu nehatî.}}
#* {{J:Bavê Nazê:1986|jêgirtin=Remo mîna rêwiyên din di rêzê de '''li bendî''' dora xwe '''ma'''.}}
==== Formên alternatîv ====
{{kol3|ku
|li bendê mayîn
}}
==== Jê ====
{{kol3|ku
|libendêman<crz:navdêr>
}}
==== Etîmolojî ====
Ji {{qertaf|ku|li|bendê|man}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|erwarten}}, {{W|de|entgegensehen|guman=erê}}, {{W|de|gewärtigen|guman=erê}}, {{W|de|harren|guman=erê}}, {{W|de|rechnen auf|guman=erê}}, {{W|de|warten auf|guman=erê}}
* {{Z|ar}}: {{W|ar|انتظار}}, {{W|ar|ترقب}}, {{W|ar|رصد}}, {{W|ar|ارتقاب}}, {{W|ar|ترصد}}
* {{Z|fa}}: {{W+|fa|منتظر ماندن}}, {{W|fa|منتظر شدن|guman=erê}}
* {{Z|en}}: {{W+|en|abide}}, {{W+|en|anticipate}}, {{W+|en|wait}}, {{W+|en|hold your horses|guman=erê}}, {{W+|en|watch for|guman=erê}}, {{W|en|wait on|guman=erê}}
* {{Z|tr}}: {{W+|tr|beklemek}}, {{W+|tr|intizar etmek}}, {{W+|tr|aylamak}}, {{W+|tr|yolunu beklemek|guman=erê}}
{{werger-bin}}
kcr82mubahjc87w7unrav50h1iz0htf
ji nav birin
0
49814
6347575
6346277
2026-09-01T10:23:17Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347575
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Lêker ===
{{lêker|ku|c=}}
# ne[[hêlan]], [[ji holê rakirin]], [[birhandin]], [[hilweşandin]], [[qir]] kirin, [[îmha]] kirin, [[ladan]]
#: {{nm|ku|hewla terorîstan hate '''ji nav birin'''.}}
#* {{jêder-websîte|ku|jêgirtin=Berî çend salan rêxistinên mafên mirovî eşkere kirin ku diyardeya "xetenekirinê" li Başûrê Kurdistanê heye. Paşî hejmareke kêm a saziyên medyayê hinek gutar û raport belav kirin û ew mijar azirand. Di encam de deshelatdarên deverê diyarkirin ku ewê wê diyardeya nemirovane '''ji nav bibin''' û wê zulmê li ser keçên herêmê rakin.|nivîskar=Silêman Alîxan|sernav=Ev gotar li Badînan hat qedexekirin|websîte=Avestakurd.net|sal=7/2010}}
==== Formên alternatîv ====
{{kol3|ku
|ji nêv birin
|ji navê rakirin
}}
==== Jê ====
{{kol3|ku
|jinavkirin<crz:navdêr>
|jinavêkirin<crz:navdêr>
|jinavraker
|jinavrakirî
}}
==== Etîmolojî ====
Ji {{qertaf|ku|ji|nav|birin}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|räumen|guman=erê}}, {{W|de|abstreifen|guman=erê}}, {{W|de|verwischen|guman=erê}}
* {{Z|ar}}: {{W|ar|أبعد|guman=erê}}
* {{Z|fa}}: {{W+|fa|از میان برداشتن}}, {{W+|fa|از بین بردن}}, {{W+|fa|نابود کردن}}
* {{Z|en}}: to {{W+|en|remove}}, to {{W+|en|annihilate}}, to {{W+|en|end}}, {{W+|en|remotion}}, {{W+|en|dislodge|guman=erê}}, {{W|en|perish|guman=erê}}
* {{Z|tr}}: {{W+|tr|ilga etmek|guman=erê}}, {{W+|tr|imha etmek|guman=erê}}, {{W+|tr|kovmak|guman=erê}}, {{W+|tr|ortadan kaldırmak|guman=erê}}, {{W+|tr|toz duman etmek|guman=erê}}, {{W+|tr|vücudunu ortadan kaldırmak|guman=erê}}, {{W|tr|künyesini silmek|guman=erê}}
{{werger-bin}}
lzwe9iiaawap1mftfi7iath9xdfs99e
tertîb
0
50018
6347531
6339430
2026-09-01T09:36:05Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347531
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[rêz]], [[rêz]]kirin, [[durist]]kirin, [[birêk]]kirin
#* {{bêmînak|ku}}
==== Ji wêjeya klasîk ====
* {{J:Melayê Cizîrî:Dîwana Melayê Cizîrî|jêgirtin=Here eslê xwe we '''tertîb'''a qiyasê jê ke</br>Ger nizanî çi ye yekcarê berê darê hudûs}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|tertîb kirin<crz:lêker>
|tertîbkirin<crz:navdêr>
|tertîbkirî<crz:rengdêr>
|tertîbî
|tertîbker
}}
==== Etîmolojî ====
Ji {{deyn|ar|ku|ترتيب}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Regelung|f}}, {{W-|de|Aussinnen|guman=erê}}
* {{Z|fa}}: {{W+|fa|ترتیب}}
* {{Z|en}}: {{W+|en|array|guman=erê}}
* {{Z|tr}}: {{W+|tr|tertip}}, {{W+|tr|mürettep|guman=erê}}, {{W+|tr|dizgi|guman=erê}}, {{W+|tr|düzen|guman=erê}}, {{W+|tr|düzenlemek|guman=erê}}, {{W+|tr|tertip etmek|guman=erê}}, {{W+|tr|tertiplemek|guman=erê}}
{{werger-bin}}
rkra3njkcwhhkhjy52kpxrwzuxciamc
bedreng
0
50143
6347411
6334996
2026-08-31T16:55:19Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes)
6347411
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Rengdêr ===
{{ku-tewîn-rd|bedreng}}
{{rengdêr|ku}}
# Kesa/ê yan tişta/ê ku [[reng]]ê wî [[guherîn|guheriye]] yan [[xirab]] bûye.
#: {{hevmane|ku|spîçolkî|zerik|zerhimî}}
#* {{bêmînak|ku}}
==== Ji wêjeya klasîk ====
* {{J:Mem û Zîn:1692|jêgirtin=Wey xawiyê de'weya kemalê<br />Ey xameyê serteraş-i '''bedreng'''<br />Bes nameyê xweşqumaş-i xweşreng}}
==== Formên alternatîv ====
* [[betreng]]
==== Jê ====
* [[bedrengî]]
* [[bedrengîtî]]
==== Etîmolojî ====
Ji {{qertaf|ku|bed|reng}}.
==== Werger ====
{{werger-ser}}
* {{Z|fa}}: {{W-|fa|بد رنگ}}
{{werger-bin}}
==== Çavkanî ====
* Têmûrê Xelîl: ''Gotinên kurdî ko di nav kurdên Ermenistanê da mane'', Nefel.com, 7/2008
pofak72urpjotuzz3diby0eqxknwjp7
angorî
0
51123
6347492
6247055
2026-08-31T21:13:33Z
Wikihez
7344
/* Hoker */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347492
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Hoker ===
{{hoker|ku}}
# li [[gor]], [[gorekî]], bi [[gotin]]a kesekî, wek ku kesek dibêje
#: ''Angorî tirkan, kurd ne milet in.'' (Tirk dibêjin ku kurd ne milet in.)
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|urlya-arşîvê=https://web.archive.org/web/20260831205557/https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026
|jêgirtin=Kincên (cil, çek, libas…) jinan û mêran '''angorî''' herêmên Kurdistanê gelek cudatiyan nîşan didin.
}}
==== Formên alternatîv ====
* [[anegorî]]
==== Etîmolojî ====
herwiha [[anegorî]] ji {{ji|tr|ku|-}} "[[on]]a [[göre]]" (li gor wê / wî)
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|entsprechend}}, {{W+|de|vergleichsweise}}, {{W+|de|ähnlich}}
* {{Z|fi}}: ([[joku|jonkun]] kertoman) [[mukaan]]
* {{Z|fr}}: {{W+|fr|selon}}
* {{Z|en}}: {{W+|en|according to}}
* {{Z|tr}}: {{W+|tr|göre}}
{{werger-bin}}
5ze531qp1eyvaddpss84akrh6p89sq5
6347493
6347492
2026-08-31T21:14:24Z
Wikihez
7344
/* Etîmolojî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347493
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Hoker ===
{{hoker|ku}}
# li [[gor]], [[gorekî]], bi [[gotin]]a kesekî, wek ku kesek dibêje
#: ''Angorî tirkan, kurd ne milet in.'' (Tirk dibêjin ku kurd ne milet in.)
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|urlya-arşîvê=https://web.archive.org/web/20260831205557/https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026
|jêgirtin=Kincên (cil, çek, libas…) jinan û mêran '''angorî''' herêmên Kurdistanê gelek cudatiyan nîşan didin.
}}
==== Formên alternatîv ====
* [[anegorî]]
==== Etîmolojî ====
Herwiha [[anegorî]] ji {{ji|tr|ku|[[ona]] [[göre]]|t=li gor wê / wî}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|entsprechend}}, {{W+|de|vergleichsweise}}, {{W+|de|ähnlich}}
* {{Z|fi}}: ([[joku|jonkun]] kertoman) [[mukaan]]
* {{Z|fr}}: {{W+|fr|selon}}
* {{Z|en}}: {{W+|en|according to}}
* {{Z|tr}}: {{W+|tr|göre}}
{{werger-bin}}
irw83hn6fymu33koxxy9x0a0ve7z17v
yol
0
51248
6347639
6321023
2026-09-01T11:54:16Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347639
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[rê]], [[rêk]]
#* {{mewlûd|jêgirtin=Zivistanê evê '''yolê''', evê beriyê evê çolê<br> Mijê avête der dolê, xunavê girtî kîstanê}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Notên bikaranînê ====
: Tenê di [[tirkmancî]] de û di klasîkan de
==== Etîmolojî ====
Ji {{deyn|tr|ku|yol}} ([[rê]]) ku herwiha serekaniya peyva "[[ol]]" ([[rê]] > [[terîqet]] > [[dîn]] / [[diyanet]]) e jî.
==== Werger ====
{{werger-bnr|rê}}
== {{ziman|az}} ==
=== Navdêr ===
{{navdêr|az}}
# {{f|az|erdnîgarî}} {{g|ku|rê}}
#* {{bêmînak|az}}
=== Çavkanî ===
{{rûpela wergerê|az|rê}}
== {{ziman|crh}} ==
=== Navdêr ===
{{navdêr|crh}}
# {{f|crh|erdnîgarî}} {{g|ku|rê}}
#* {{bêmînak|crh}}
=== Çavkanî ===
{{rûpela wergerê|crh|rê}}
== {{ziman|tr}} ==
=== Bilêvkirin ===
* {{deng|tr|LL-Q256 (tur)-ToprakM-yol.wav|Deng|dever=}}
* {{deng|tr|LL-Q256 (tur)-Veravi95-yol.wav|Deng|dever=}}
=== Navdêr ===
{{navdêr|tr}}
# [[rê]], [[ra]], [[rêk]], [[ray]]
#* {{bêmînak|tr}}
# [[şivîle]], [[şiverê]]
#: {{nm|tr|keçiyolu şiverê}}
# [[ra]]
#: {{nm|tr|'''yolda''' çocuklar oynuyordu|rêz=1|li ser rê zarok dileyîstin}}
# [[ra]]
#: {{nm|tr|su '''yolu'''|rêz=1|riya avê}}
# [[rêwîtî]], [[rêwingî]]
#: {{nm|tr|'''yola''' çıkmak|rêz=1|ketin rê}}
# [[lez]], [[sur'et]]
#: {{nm|tr|bu geminin '''yolu''' az|rêz=1|leza vê keştiyê hindik e}}
# [[rê]]
#: {{nm|tr|bu işi yapmanın bir '''yolu''' vardır|rêz=1|riyeke kirina vî karî heye}}
# [[rê]]
#: {{nm|tr|tuttuğu '''yolu''' beğenmedim|rêz=1|min ew riya ku te pê girtiye neeciband}}
# [[şêwe]], [[terz]], [[sîstem]]
#* {{bêmînak|tr}}
# [[mebest]], [[xaye]]
#: {{nm|tr|bu '''yolda''' çok emek harcadı|rêz=1|di vê rê de gelek ked da}}
# [[şift]], [[xet]]
#: {{nm|tr|kumaşın '''yolları'''|rêz=1|şiftên qumaş}}
# [[car]], [[dor]], [[neql]]
#* {{bêmînak|tr}}
5vjokwukvw2b44x8418pybdnxobixox
6347642
6347639
2026-09-01T11:57:14Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347642
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[rê]], [[rêk]]
#* {{mewlûd|jêgirtin=Zivistanê evê '''yolê''', evê beriyê evê çolê<br> Mijê avête der dolê, xunavê girtî kîstanê}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Notên bikaranînê ====
: Tenê di [[tirkmancî]] de û di klasîkan de
==== Etîmolojî ====
Ji {{deyn|tr|ku|yol}} ([[rê]]) ku herwiha serekaniya peyva "[[ol]]" ([[rê]] > [[terîqet]] > [[dîn]] / [[diyanet]]) e jî.
==== Werger ====
{{werger-bnr|rê}}
== {{ziman|az}} ==
=== Navdêr ===
{{navdêr|az}}
# {{f|az|erdnîgarî}} {{g|ku|rê}}
#* {{bêmînak|az}}
=== Çavkanî ===
{{rûpela wergerê|az|rê}}
== {{ziman|crh}} ==
=== Navdêr ===
{{navdêr|crh}}
# {{f|crh|erdnîgarî}} {{g|ku|rê}}
#* {{bêmînak|crh}}
=== Çavkanî ===
{{rûpela wergerê|crh|rê}}
== {{ziman|tr}} ==
=== Bilêvkirin ===
* {{deng|tr|LL-Q256 (tur)-ToprakM-yol.wav|Deng|dever=}}
* {{deng|tr|LL-Q256 (tur)-Veravi95-yol.wav|Deng|dever=}}
=== Navdêr ===
{{navdêr|tr}}
# [[rê]], [[ra]], [[rêk]], [[ray]]
#* {{bêmînak|tr}}
# [[şivîle]], [[şiverê]]
#: {{nm|tr|keçiyolu|rêz=1şiverê}}
# [[ra]]
#: {{nm|tr|'''yolda''' çocuklar oynuyordu|rêz=1|li ser rê zarok dileyîstin}}
# [[ra]]
#: {{nm|tr|su '''yolu'''|rêz=1|riya avê}}
# [[rêwîtî]], [[rêwingî]]
#: {{nm|tr|'''yola''' çıkmak|rêz=1|ketin rê}}
# [[lez]], [[sur'et]]
#: {{nm|tr|bu geminin '''yolu''' az|rêz=1|leza vê keştiyê hindik e}}
# [[rê]]
#: {{nm|tr|bu işi yapmanın bir '''yolu''' vardır|rêz=1|riyeke kirina vî karî heye}}
# [[rê]]
#: {{nm|tr|tuttuğu '''yolu''' beğenmedim|rêz=1|min ew riya ku te pê girtiye neeciband}}
# [[şêwe]], [[terz]], [[sîstem]]
#* {{bêmînak|tr}}
# [[mebest]], [[xaye]]
#: {{nm|tr|bu '''yolda''' çok emek harcadı|rêz=1|di vê rê de gelek ked da}}
# [[şift]], [[xet]]
#: {{nm|tr|kumaşın '''yolları'''|rêz=1|şiftên qumaş}}
# [[car]], [[dor]], [[neql]]
#* {{bêmînak|tr}}
daom2opl0dajck2tnnwxic3729x32gk
6347643
6347642
2026-09-01T11:57:23Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347643
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[rê]], [[rêk]]
#* {{mewlûd|jêgirtin=Zivistanê evê '''yolê''', evê beriyê evê çolê<br> Mijê avête der dolê, xunavê girtî kîstanê}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Notên bikaranînê ====
: Tenê di [[tirkmancî]] de û di klasîkan de
==== Etîmolojî ====
Ji {{deyn|tr|ku|yol}} ([[rê]]) ku herwiha serekaniya peyva "[[ol]]" ([[rê]] > [[terîqet]] > [[dîn]] / [[diyanet]]) e jî.
==== Werger ====
{{werger-bnr|rê}}
== {{ziman|az}} ==
=== Navdêr ===
{{navdêr|az}}
# {{f|az|erdnîgarî}} {{g|ku|rê}}
#* {{bêmînak|az}}
=== Çavkanî ===
{{rûpela wergerê|az|rê}}
== {{ziman|crh}} ==
=== Navdêr ===
{{navdêr|crh}}
# {{f|crh|erdnîgarî}} {{g|ku|rê}}
#* {{bêmînak|crh}}
=== Çavkanî ===
{{rûpela wergerê|crh|rê}}
== {{ziman|tr}} ==
=== Bilêvkirin ===
* {{deng|tr|LL-Q256 (tur)-ToprakM-yol.wav|Deng|dever=}}
* {{deng|tr|LL-Q256 (tur)-Veravi95-yol.wav|Deng|dever=}}
=== Navdêr ===
{{navdêr|tr}}
# [[rê]], [[ra]], [[rêk]], [[ray]]
#* {{bêmînak|tr}}
# [[şivîle]], [[şiverê]]
#: {{nm|tr|keçiyolu|rêz=1|şiverê}}
# [[ra]]
#: {{nm|tr|'''yolda''' çocuklar oynuyordu|rêz=1|li ser rê zarok dileyîstin}}
# [[ra]]
#: {{nm|tr|su '''yolu'''|rêz=1|riya avê}}
# [[rêwîtî]], [[rêwingî]]
#: {{nm|tr|'''yola''' çıkmak|rêz=1|ketin rê}}
# [[lez]], [[sur'et]]
#: {{nm|tr|bu geminin '''yolu''' az|rêz=1|leza vê keştiyê hindik e}}
# [[rê]]
#: {{nm|tr|bu işi yapmanın bir '''yolu''' vardır|rêz=1|riyeke kirina vî karî heye}}
# [[rê]]
#: {{nm|tr|tuttuğu '''yolu''' beğenmedim|rêz=1|min ew riya ku te pê girtiye neeciband}}
# [[şêwe]], [[terz]], [[sîstem]]
#* {{bêmînak|tr}}
# [[mebest]], [[xaye]]
#: {{nm|tr|bu '''yolda''' çok emek harcadı|rêz=1|di vê rê de gelek ked da}}
# [[şift]], [[xet]]
#: {{nm|tr|kumaşın '''yolları'''|rêz=1|şiftên qumaş}}
# [[car]], [[dor]], [[neql]]
#* {{bêmînak|tr}}
5cn2qz6vfoxqcnpomzeej01bt6pca3h
xane
0
51257
6347568
6339461
2026-09-01T10:19:26Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347568
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-xane.wav|dever=Bidlîs}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# {{f|ku|biyolojî}} Xane yekeya bingehîn a zîndewer e. Ango tiştekî zîndewer be, herî kêm xwediyê xaneyek e. Ji ber ku piraniya xaneyan pir piçûk in, bi çavê tazî nayên dîtin. Ji bo dîtina xaneyan mîkroskob tên bikaranîn.
#* {{bênimûne|ku}}
# [[xanî|Xanî]], [[mal]], [[çavik]].
#* {{bênimûne|ku}}
# [[malbat|Malbat]], [[mal]].
#* {{bênimûne|ku}}
# [[cih|Cih]], [[şûn]]<ref name="spi">{{Fer:kur-ar:spîrêz|r=229}}</ref>.
#* {{bênimûne|ku}}
# [[refik|Refika]] pirtûkan an ya tiştan.<ref name="spi" />
#* {{bênimûne|ku}}
==== Ji wêjeya klasîk ====
* {{J:Melayê Cizîrî:Dîwana Melayê Cizîrî|jêgirtin=Eqdê ihramê di 'işqê da ko pîrê 'işqê best</br>Dê çi xem ger xerqe rehnê '''xane''''ê xemmar-i bit</br>Gezmeyek qewsê şevên 'aşiq bi nîva dil kevit}}
==== Tewandin ====
{{ku-tewîn-nav|mê|guherto=hemû}}
==== Têkildar ====
{{kol3|ku
|xanedan<crz:navdêr>
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser|yekeya zîndeweran (biyolojî)}}
* {{Z|en}}: {{W+|en|cell}}
* {{Z|tr}}: {{W+|tr|hücre}}, {{W+|tr|hane}}
{{werger-bin}}
{{werger-ser|xanî, mal, çavik}}
* {{Z|de}}: {{W+|de|Daheim|m}}
* {{Z|ar}}: {{W-|ar|الدار}}
* {{Z|en}}: {{W+|en|inn}}
* {{Z|tr}}: {{W+|tr|konut}}, {{W+|tr|hane}}
{{werger-bin}}
=== Çavkanî ===
{{çavkanî}}
hn5xt5063uieszgy118dcpix58tum3m
tê derxistin
0
52186
6347570
6326829
2026-09-01T10:20:55Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347570
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Lêker ===
{{lêker|ku|c=}}
# [[şitirîn]], [[texmîn]] kirin, [[ji ber xwe ve]] [[gotin]], [[derc]] kirin, [[fam]] kirin, [[tê gihiştin]], [[kifş]] kirin, [[pê hesîn]]
#* {{bêmînak|ku}}
# {{kontrol|rêz=erê|[[mezandin]], [[pêşbînî kirin]]}}
==== Bi alfabeyên din ====
* {{ku-ar|تێ دهرخستن}}
==== Jê ====
{{kol3|ku
|têderxistî
|têderxistin<c:m><crz:navdêr>
}}
==== Etîmolojî ====
Ji {{heve|ku|tê|derxistin}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|schätzen}}, {{W+|de|raten}}, {{W+|de|schließen}}, {{W+|de|herausfinden}}, {{W+|de|entnehmen|guman=erê}}, {{W+|de|heraushören|guman=erê}}, {{W+|de|durchschauen|guman=erê}}, {{W-|de|herausgelesen|guman=erê}}
* {{Z|cs}}: {{W-|cs|hádat}}
* {{Z|da}}: {{W-|da|gætte}}
* {{Z|ar}}: {{W-|ar|خمن|tr=xemmene}}
* {{Z|eo}}: {{W+|eo|diveni}}
* {{Z|fo}}: {{W-|fo|gita}}
* {{Z|fi}}: {{W+|fi|arvata}}
* {{Z|fr}}: {{W+|fr|devenir}}
* {{Z|nl}}: {{W+|nl|veronderstellen}}, {{W+|nl|gissen}}, {{W+|nl|raden}}
* {{Z|io}}: {{W+|io|divinar}}
* {{Z|en}}: to {{W+|en|guess}}* {{Z|he}}: {{W+|he|נחש|cuda=נחשׁ}} {{mf}}, {{W+|en|unriddle}}, {{W+|en|untie}}
* {{Z|it}}: {{W+|it|indovinare}}
* {{Z|ja}}: {{W-|ja|推測する|tr=suisoku-suru}}, {{W-|ja|察する|tr=sassuru}}, {{W-|ja|憶測する|tr=okusoku-suru}}
* {{Z|ca}}: {{W+|ca|endevinar}}
* {{Z|no}}: {{W-|no|gjette}}
* {{Z|pap}}: {{W-|pap|rei}}
* {{Z|pt}}: {{W+|pt|acertar}}, {{W+|pt|adivinhar}}, {{W+|pt|decifrar}}
* {{Z|ro}}: {{W+|ro|bănui}}
* {{Z|ru}}: {{W-|ru|угадать|tr=ugadát'}}, {{W-|ru|угадывать|tr=ugádyvat'}}
* {{Z|sl}}: {{W-|sl|uganiti}}
* {{Z|es}}: {{W+|es|adivinar}}, {{W+|es|conjeturar}}
* {{Z|sv}}: {{W+|sv|gissa}}
* {{Z|tr}}: {{W+|tr|ayrımsamak}}, {{W+|tr|duyumsamak}}, {{W+|tr|zannetmek}}, {{W+|tr|kestirmek}}, [[tahmin]] etmek, {{W+|tr|sezmek}}, {{W+|tr|bilmece çözmek}}, {{W+|tr|çakmak}}, {{W+|tr|çıkarmak}}, {{W+|tr|çözmek}}, {{W+|tr|fark etmek}}, {{W+|tr|hissetmek}}, {{W+|tr|karine ile anlamak}}, {{W+|tr|okumak}}, {{W+|tr|varmak}}, {{W+|tr|duymak|guman=erê}}
* {{Z|el}}: {{W+|el|υποθέσει}}
{{werger-bin}}
p3dw1bgg8qwshhjs2o4fwiqpw34jn4m
serdozger
0
52208
6347412
6246639
2026-08-31T16:56:55Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes)
6347412
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku}}
# Kesa/ê ku li ser navê dewletê [[doz]]ê dijî [[tawanbar]]ên mezin [[vekirin|vedike]].
#* {{jêder|ku|jêgirtin='''Serdozgerê''' Dadgeha Bilind Abdurrahman Yalçinkaya bi hinceta ku DTP li gorî rêz û rêçikên qanûnî yên ji bo partiyên siyasî hatine diyarkirin tevnagere doz li DTP’ê vekir.|Peyamner.com, 11/2007}}
==== Formên alternatîv ====
* [[serdozgêr]]
* [[serdozgêrr]]
==== Jê ====
* [[serdozgerî]]
==== Etîmolojî ====
Ji {{qertaf|ku|ser-|dozger}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Generalstaatsanwalt}}
* {{Z|fi}}: {{W-|fi|yleinen syyttäjä}}
* {{Z|fr}}: {{W+|fr|procureur général}}
* {{Z|nl}}: {{W+|nl|procureur-generaal}}
* {{Z|en}}: {{W-|en|public prosecutor}}
* {{Z|tr}}: {{W+|tr|başsavcı}}
{{werger-bin}}
plxu77wk3qsy6j5uj431t5rrjzr5t7g
rebît
0
52526
6347549
6346321
2026-09-01T09:49:10Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347549
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Rengdêr ===
{{ku-tewîn-rd|rebît}}
{{rengdêr|ku}}
# [[xurt]], [[saxlem]], [[qayîm]], [[qewî]], [[çist]], [[rep]]
#* {{jêder|ku|Zeynelabidîn Zinar di hevpeyivînekê de li gel Gabar Çiyan, Netkurd.com, 7/2009|jêgirtin=Min li çend deveran li simbilê zad nihêrî, bereketa Xwedê tê de be, wisa '''rebît''' û qebilî bûn ku êdî hew tê gotin. Min sedemê vê başiya zad ji çend gundiyên kal pirsî, weha gotin: "Ji xwe îsal şilî zêde bû, lê ew toza ku ji aliyê Erebistanê ve wek ewran dihat, ji zadên me re hemû bûye wek zibl û derman.}}
==== Jê ====
{{kol3|ku
|rebît bûn<crz:lêker>
|rebît kirin<crz:lêker>
|rebîtbûn<crz:navdêr>
|rebîtkirin<crz:navdêr>
|rebîtbûyî<crz:rengdêr>
|rebîtkirî<crz:rengdêr>
|rebîtane
|rebîtî
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|rabiat}}, {{W+|de|gesund}}, {{W+|de|kräftig}}
* {{Z|fi}}: {{W+|fi|elinvoimainen}}, {{W+|fi|terve}}
* {{Z|fr}}: {{W+|fr|dru|m}}, {{W+|fr|drue|f}}, {{W+|fr|robuste}}, {{W+|fr|râblé|m}}, {{W+|fr|râblée|f}}
* {{Z|en}}: {{W+|en|robust}}, {{W+|en|sturdy}}, {{W+|en|bouncing}}, {{W+|en|bonny}}, {{W+|en|cornfed}}, {{W+|en|healthy}}, {{W+|en|strong}}
* {{Z|tr}}: {{W+|tr|gürbüz}}
{{werger-bin}}
rowuf382j8ji3o0muajisra2hor2i2c
lîberalîzm
0
52588
6347587
6311437
2026-09-01T10:46:19Z
Wikihez
7344
/* Binêre herwiha */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347587
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# {{f|ku|îdeolojî}} [[bawerî|Baweriyên]] [[lîberal]].
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Têkildar ====
{{kol3|ku|cure=Têkildar
|antîlîberal
|antîlîberal
|antîlîberalane
|îlîberal
|îllîberal
|lîberal
|lîberalane
|lîberaldemokrat
|lîberalî
|lîberalîtî
|lîberalîst
|lîberalîstî
|lîberalîstîk
|lîberaltî
|lîberasyon
|lîbertar
|lîbertarane
|lîbertarî
|lîbertarîtî
|lîbertartî
|lîbertaryan
|Partiya Lîberal
}}
==== Etîmolojî ====
Bi riya {{ji|fr|ku|libéralisme}} ji {{q|fr|libéral}} yan ji {{ji|en|ku|liberalism}} ji [[liberal]] ji {{ji|la|ku|liberalis}} ji {{q|la|liber|w=[[azad]], [[serbest]]}}. Wekheva {{paş|ku|lîberal|-îzm}}.
==== Bêhtir bixwîne ====
* {{wpedî}}
==== Werger ====
{{werger-ser}}
* {{Z|sq}}: {{W+|sq|liberalizëm|n}}
* {{Z|de}}: {{W+|de|Liberalismus|n}}
* {{Z|an}}: {{W-|an|liberalismo|n}}
* {{Z|ast}}: {{W-|ast|lliberalismu|n}}
* {{Z|az}}: {{W-|az|liberalizm}}
* {{Z|be}}: {{W-|be|лібералі́зм|n}}
* {{Z|bn}}: {{W-|bn|উদারনীতিবাদ}}
* {{Z|bg}}: {{W+|bg|либерали́зъм|n}}
* {{Z|my}}: {{W-|my|လစ်ဘရယ်ဝါဒ}}
* {{Z|cs}}: {{W+|cs|liberalizmus|n}}
* {{Z|zh}}:
*: {{Z|hak}}: {{W-|hak|自由主義|tr=chhṳ-yù chú-ngi}}
*: {{Z|cmn}}: {{W+|cmn|自由主義|tr=zìyóuzhǔyì}}
*: {{Z|nan}}: {{W-|nan|自由主義|tr=chū-iû chú-gī}}
* {{Z|da}}: {{W+|da|liberalisme}}
* {{Z|id}}: {{W+|id|liberalisme}}
* {{Z|ar}}: {{W-|ar|لِيبْرَالِيَّة|m|tr=librāliyya}}
* {{Z|hy}}: {{W+|hy|լիբերալիզմ}}, {{W+|hy|ազատականություն}}
* {{Z|eo}}: {{W+|eo|liberalismo}}
* {{Z|et}}: {{W+|et|liberalism}}
* {{Z|fa}}: {{W+|fa|لیبرالیسم|tr=liberâlism}}
* {{Z|fo}}: {{W-|fo|liberalisma|m}}
* {{Z|fi}}: {{W+|fi|liberalismi}}
* {{Z|fr}}: {{W+|fr|libéralisme|n}}
* {{Z|gl}}: {{W+|gl|liberalismo|n}}
* {{Z|ka}}: {{W+|ka|ლიბერალიზმი}}
* {{Z|hi}}: {{W-|hi|उदारतावाद|n}}
* {{Z|nl}}: {{W+|nl|liberalisme|nt}}
* {{Z|he}}: {{W+|he|לִיבֶּרָלִיזְם|n|tr=liberalízm}}
* {{Z|io}}: {{W+|io|liberalismo}}
* {{Z|en}}: {{W+|en|liberalism}}
* {{Z|ga}}: {{W-|ga|liobrálachas|n}}
* {{Z|it}}: {{W+|it|liberalismo|n}}
* {{Z|is}}: {{W-|is|frjálshyggja|m}}
* {{Z|ja}}: {{W+|ja|自由主義|tr=じゆうしゅぎ, jiyūshugi|sc=Jpan}}
* {{Z|ca}}: {{W-|ca|liberalisme|n}}
* {{Z|ky}}: {{W-|ky|либерализм}}
* {{Z|ko}}: {{W+|ko|자유주의}}
* {{Z|jam}}: {{W-|jam|liberalizim}}
* {{Z|la}}: {{W-|la|līberālismus|n}}
* {{Z|lv}}: {{W-|lv|liberālisms|n}}
* {{Z|lo}}: {{W-|lo|ເສຣີນິຍົມ}}, {{W-|lo|ເສລີນິຍົມ}}
* {{Z|lt}}: {{W+|lt|liberalizmas|n}}
* {{Z|mk}}: {{W-|mk|либерализам|n}}
* {{Z|mg}}: {{W+|mg|liberalisma}}
* {{Z|ms}}: {{W-|ms|liberalisme}}
* {{Z|hu}}: {{W+|hu|liberalizmus}}
* {{Z|mwl}}: {{W-|mwl|liberalismo|n}}
* {{Z|mn}}: {{W+|mn|либерализм}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|liberalisme|n}}
*: {{Z|nn}}: {{W-|nn|liberalisme}}
* {{Z|uz}}: {{W+|uz|liberalizm}}
* {{Z|pl}}: {{W+|pl|liberalizm|n}}
* {{Z|pt}}: {{W+|pt|liberalismo|n}}
* {{Z|kk}}: {{W-|kk|либерализм}}
* {{Z|ro}}: {{W+|ro|liberalism|nt}}
* {{Z|ru}}: {{W+|ru|либерали́зм|n}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|либералѝзам|n}}
*: Latînî: {{W+|sh|liberalìzam|n}}
* {{Z|sk}}: {{W-|sk|liberalizmus|n}}
* {{Z|sl}}: {{W+|sl|liberalizem|n}}
* {{Z|es}}: {{W+|es|liberalismo|n}}
* {{Z|sv}}: {{W+|sv|liberalism|g}}
* {{Z|tg}}: {{W-|tg|либерализм}}
* {{Z|th}}: {{W+|th|เสรีนิยม}}
* {{Z|tr}}: {{W+|tr|liberalizm}}
* {{Z|tk}}: {{W-|tk|liberalizm}}
* {{Z|uk}}: {{W+|uk|лібералі́зм|n}}
* {{Z|vi}}: {{W+|vi|chủ nghĩa tự do}}
* {{Z|km}}: {{W-|km|សេរីនិយម}}
* {{Z|yi}}: {{W-|yi|ליבעראַליזם|sc=Hebr}}
* {{Z|el}}: {{W+|el|φιλελευθερισμός|n}}
{{werger-bin}}
:{{werger çavkanî|en|liberalism|beş=Ev qismê Wergerê|oldid=75679670}}
h1et4l7s9y993re95tnuw8e80okoza0
raje
0
52627
6347545
6316210
2026-09-01T09:47:54Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347545
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{IPA|ku|/rɑːˈʒɛː/}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# Tişta/ê bo kesek din têt kirin.
#: {{hevmane|ku|xizmet|servîs}}
#: {{nm|ku|Celadet Bedirxan '''rajeyek''' hêja bo zimanê kurdî kiriye.}}
#* {{jêder|ku|jêgirtin=Wek akam, Reşîd dixweze du regezên sereke ên ku gelê Kurd wek gelekî resen û zimanê wî dara û dewlemend biselimîne, û ev jî bixwe ji pêdiviyên çespandina fereziya netewî a li gorî demê diviyabû bihata damezirandin ta bikarîba şûd û kelkê ji rewşa heyîn werbigire. Reşîd pêşniyar dike ku xebatên der barê metelokan de bûne, divê der barê Mûzîk, fêr, dab, cil, çîrok, efsane de û hwd bê kirin, çimkî ev hêmanên navborî dê hem asoyên heyîna Kurdî ronîtir bikin û hem jî têkevin '''rajeya''' (xizmeta) kesayetiya netewî ya miletê Kurd.|Mihemed Elî: ''Belgeyek dîrokî'', Geocities.com/kurdistanclub, jêwergirtin: 7/2009}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|raje kirin<crz:lêker>
|rajekirin<crz:navdêr>
|rajekirî<crz:rengdêr>
|rajegeh
|rajekar
|rajkarî
|rajeker
|rajevan
|rajevanî
|rajevanîtî
|rajevantî
|rajexane
|rajexwaz
|rajexwazî
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Bide ber ====
{{kol3|ku
|rade
|rêje
}}
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W+|af|diens}}
* {{Z|de}}: {{W+|de|Dienst}}, {{W+|de|Service|n}}
* {{Z|da}}: {{W+|da|tjeneste}}, {{W+|da|service}}
* {{Z|eo}}: {{W-|eo|servo}}, {{W-|eo|servico}}
* {{Z|fo}}: {{W-|fo|borðbúnaður}}, {{W-|fo|deild}}, {{W-|fo|starv}}
* {{Z|fi}}: {{W+|fi|palvelu}}
* {{Z|fr}}: {{W+|fr|service}}
* {{Z|fur}}: {{W-|fur|tsjinst}}, {{W-|fur|ôfdieling}}, {{W-|fur|amt}}
* {{Z|fy}}: {{W-|fy|tsjinst}}, {{W-|fy|ôfdieling}}, {{W-|fy|amt}}
* {{Z|nl}}: {{W+|nl|dienst}}, {{W+|nl|servies}}
* {{Z|io}}: {{W+|io|servo}}
* {{Z|en}}: {{W+|en|service}}, {{W+|en|favor}}, {{W+|en|favour}}
* {{Z|it}}: {{W+|it|servizio}}
* {{Z|la}}: {{W+|la|officium}}
* {{Z|ms}}: {{W+|ms|bagian}}
* {{Z|no}}: {{W+|no|servise}}
* {{Z|pap}}: {{W-|pap|servisio}}, {{W-|pap|puesto}}
* {{Z|pl}}: {{W+|pl|serwis}}, {{W+|pl|zastawa}}
* {{Z|pt}}: {{W+|pt|serviço}}
* {{Z|es}}: {{W+|es|servicio}}
* {{Z|sv}}: {{W+|sv|tjänst}}
* {{Z|tr}}: {{W+|tr|hizmet}}
{{werger-bin}}
9yylp368plhal0h3ous5o6oz4xgvf4b
sorax
0
52632
6347542
6317959
2026-09-01T09:46:05Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347542
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[lêkolîn]], [[vekolîn]], [[pişkinîn]], [[teftîş]], [[ezmûn]], [[ceribandin]]
#* {{jêder|ku|7/2009, (cara dawî hate gihiştin), Mihemed Elî: ''Belgeyek dîrokî'', Geocities.com/kurdistanclub|jêgirtin=Îro piştî rûxandina sazûmana Sedam Hûsên li Îraqê û guhertinên ku hêdî hêdî li rojhilata derdikevin holê, bi baweriya min rewşa wê dişibînin heyama piştî rûxandina Împeretoriya Osmaniyan. Îro dîsa pêla netewî li rojhilar xedar e, û wek berî sed salî Kurd dîsa bazneya vê tevgerê ne û pêdiviya wan bi raberkirina çand, dîrok, ziman û kesayetiya cuda û puxte heye, nemaze li bakur, başûr rojava û rojhilatî Kurdistanê. Îro konfêransa aşitiyê careke din rûniştiye, ema vê carê ne li Parîsê lê li Washingotin’ê, vaye dîsa şandeyên arezûya serxwebûna gelan '''sorax''' dikin dîsa li rojhilata navîn in, û mîna destpêka sedsala borî dîsa netewe tên gurkirin û piştgirtin.}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|sorax kirin<crz:lêker>
|soraxkirin<crz:navdêr>
|soraxkirî<crz:rengdêr>
|soraxî
|soraxvan
|soraxvanî
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Bide ber ====
{{kol3|ku
|sorav
}}
==== Werger ====
{{werger-ser}}
* {{Z|en}}: {{W+|en|inspection}}
* {{Z|tr}}: {{W+|tr|teftiş}}
{{werger-bin}}
gwqv0dajal8oqu4quayvcfg51ymdjiw
qubalek
0
53770
6347410
6315985
2026-08-31T16:47:30Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes)
6347410
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[pencere|Pencere]]ya [[hundirîn]] ya ku berê ji dêvla [[dolab]]a cilan dihat bikaranîn
#: {{hevmane|ku|stêrrk}}
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
4vkez8le2ae53dr8ui3drae6ckumacr
6347418
6347410
2026-08-31T18:12:15Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347418
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[pencere|Pencereya]] [[hundirîn]] ya ku berê ji dêvla [[dolab]]a cilan dihat bikaranîn
#: {{hevmane|ku|stêrrk}}
#* {{bêmînak|ku}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
mprmmlbuhuqou2dyjs74yzt4bfjw0u7
quncik
0
53967
6347593
6336409
2026-09-01T11:02:54Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes); guhartina pêşketî (DefSideBoxes)
6347593
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[goşe]], [[qunc]], [[kujî]], [[zawî]], [[qulaç]]
#* {{J:Firat Cewerî:Girtî:1986|jêgirtin=Ew ji cihê xwe rabû û çû li '''quncika''' herî dawiyê rûnişt.}}
# [[amûr|Amûra]] ku [[qulpik]]ên [[cil|cilan]] [[gihandin|digihîne]] [[hev|hev]].
#: {{hevmane|ku|quncok}}
#* {{bênimûne|ku}}
==== Tewandin ====
{{ku-tewîn-nav/nû|nêr}}
==== Bi alfabeyên din ====
* {{ku-ar|قونجک}}
==== Hevmane ====
* [[kunc]]
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Ecke|f}}, {{W+|de|Eckchen|m|guman=erê}}
* {{Z|ar}}: {{W-|ar|ركن}}, {{W-|ar|زاوية}}
* {{Z|fa}}: {{W-|fa|گوشه تنگ}}
* {{Z|en}}: {{W+|en|corner}}, {{W+|en|angle}}
* {{Z|tr}}: {{W+|tr|bucak}}, {{W+|tr|köşe}}, {{W+|tr|ufak|guman=erê}}
{{werger-bin}}
irlupkwq3sbnq4401na49864ht5duyd
sefar
0
54010
6347399
6245361
2026-08-31T16:33:48Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes)
6347399
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku}}
[[Wêne:Sefar-qelaker, Mêrdîn, Kurdistan.jpg|thumb|200px|Sefarek li Mêrdînê]]
# Kesa/ê ku [[firaq]]ên [[sifrî]] ji [[tenî]] yan [[qilêr]]ê [[paqij]] dike.
#: {{hevmane|ku|misger}}
#* {{bêmînak|ku}}
==== Formên alternatîv ====
* [[stefar]]
====Bide ber====
* [[sefer]]
==== Têkildar ====
* [[sifir]]
==== Etîmolojî ====
Ji {{ji|ar}}.
==== Jê ====
* [[sefarçî]]
* [[sefarî]]
* [[sefarîtî]]
* [[sefartî]]
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W-|de|Verzinner|m}}
* {{Z|en}}: {{W+|en|tinsmith}}
* {{Z|tr}}: {{W+|tr|bakırcı}}, {{W+|tr|kalaycı}}
{{werger-bin}}
3li4iq4n5z2cfge4k42jemu2w2ags37
6347405
6347399
2026-08-31T16:41:19Z
Balyozbot
7867
[[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan
6347405
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku}}
[[Wêne:Sefar-qelaker, Mêrdîn, Kurdistan.jpg|thumb|200px|Sefarek li Mêrdînê]]
# Kesa/ê ku [[firaq]]ên [[sifrî]] ji [[tenî]] yan [[qilêr]]ê [[paqij]] dike.
#: {{hevmane|ku|misger}}
#* {{bêmînak|ku}}
==== Formên alternatîv ====
* [[stefar]]
==== Jê ====
* [[sefarçî]]
* [[sefarî]]
* [[sefarîtî]]
* [[sefartî]]
==== Têkildar ====
* [[sifir]]
==== Etîmolojî ====
Ji {{ji|ar}}.
====Bide ber====
* [[sefer]]
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W-|de|Verzinner|m}}
* {{Z|en}}: {{W+|en|tinsmith}}
* {{Z|tr}}: {{W+|tr|bakırcı}}, {{W+|tr|kalaycı}}
{{werger-bin}}
5uaegerka7905nuvu6nzl28akm4twkj
qab
0
54041
6347567
6339528
2026-09-01T10:19:03Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347567
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[hawe|Haweyek]] [[avahî]]yan [[ku]] [[ji]] [[hundur]] [[ve]] [[qat]]ê wê [[gulover]] e.
#: {{nm|ku|'''Qaba''' me ji hêwanê hêniktir e.}}
==== Ji wêjeya klasîk ====
* {{J:Melayê Cizîrî:Dîwana Melayê Cizîrî|jêgirtin=Mecalê dê bixwazim jê dibê deynê te »fewqe l-'eyn«</br>Bi remza '''qab'''ê qewseyn-i ji wan birhan xeberdar în</br>»Fe-ati l-qewse barîha ela ya ramîye l-qewseyn«}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|qabkirin<crz:navdêr>
|qabkirî<crz:rengdêr>
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W-|de|Buchhülle}}, {{W+|de|Buchdeckel}}, {{W+|de|Bucheinband|m}}, {{W+|de|Büchse|f}}, {{W+|de|Futteral}}, {{W+|de|Gehäuse|m}}, {{W+|de|Teller|m}}
* {{Z|fa}}: {{W+|fa|قاب}}
* {{Z|en}}: {{W+|en|urn}}
* {{Z|tr}}: {{W+|tr|kap}}, {{W+|tr|kapak}}, {{W+|tr|kemer}}, {{W+|tr|zarf}}, {{W+|tr|kubbe}}
{{werger-bin}}
t426d16n0fgz37qqbmdwpun7ivb5vyd
pirtû
0
54716
6347481
6285941
2026-08-31T21:00:22Z
Wikihez
7344
Cureyê rêzimanî hate diyarkirin: Navdêr (DefSideBoxes)
6347481
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Navdêr ===
{{navdêr|ku}}
# [[caw]], [[cang]], [[qumaş]], [[çît]], [[pate]], [[fason]]
# {{kontrol|rêz=erê|[[kemxe]], [[kisûr]], [[pirtî]], [[xak]]}}
{{kontrolWergerr}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|en}}: {{W+|en|dry goods}}
* {{Z|tr}}: {{W+|tr|manifatura}}, {{W+|tr|mensucat}}, {{W+|tr|tekstil}}, {{W+|tr|dokuma|guman=erê}}, {{W-|tr|elbiselik kumaş|guman=erê}}
{{werger-bin}}
jsatd2u5vsi4eejuqepp2129x3ctlsx
6347484
6347481
2026-08-31T21:04:09Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347484
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Navdêr ===
{{navdêr|ku}}
# [[caw]], [[cang]], [[qumaş]], [[çît]], [[pate]], [[fason]]
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|urlya-arşîvê=https://web.archive.org/web/20260831205557/https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026
|jêgirtin=Baş tê bîra min, berî pêncî salan li Qaxizmanê dikaneke me ya manîfaturayê hebû. Gelek cure '''pirtu''' û qumaş li wir dihatin firotan.
}}
# {{kontrol|rêz=erê|[[kemxe]], [[kisûr]], [[pirtî]], [[xak]]}}
{{kontrolWergerr}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|en}}: {{W+|en|dry goods}}
* {{Z|tr}}: {{W+|tr|manifatura}}, {{W+|tr|mensucat}}, {{W+|tr|tekstil}}, {{W+|tr|dokuma|guman=erê}}, {{W-|tr|elbiselik kumaş|guman=erê}}
{{werger-bin}}
n6ewih4uuhj40z6ldslf8wzuwb8tipk
6347485
6347484
2026-08-31T21:04:46Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347485
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Navdêr ===
{{navdêr|ku}}
# [[caw]], [[cang]], [[qumaş]], [[çît]], [[pate]], [[fason]]
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|urlya-arşîvê=https://web.archive.org/web/20260831205557/https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026
|jêgirtin=Baş tê bîra min, berî pêncî salan li Qaxizmanê dikaneke me ya manîfaturayê hebû. Gelek cure '''pirtu''' û qumaş li wir dihatin firotan. Yek ji wan jî çît bû, '''pirtukî''' gulgulî û rengîn bû.
}}
# {{kontrol|rêz=erê|[[kemxe]], [[kisûr]], [[pirtî]], [[xak]]}}
{{kontrolWergerr}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|en}}: {{W+|en|dry goods}}
* {{Z|tr}}: {{W+|tr|manifatura}}, {{W+|tr|mensucat}}, {{W+|tr|tekstil}}, {{W+|tr|dokuma|guman=erê}}, {{W-|tr|elbiselik kumaş|guman=erê}}
{{werger-bin}}
9uipuzh4oqqiruv5zuovvpgm9gnd1lz
spîker
0
55137
6347469
6138083
2026-08-31T20:46:06Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes)
6347469
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku}}
# {{K|ku|kes}} {{e|ku|meslek|televîzyon}} Kesa/ê ku [[bername]]yek [[televizyon]]ê yan [[radyo]]yê [[pêşkêş]] dike.
#: {{hevmane|ku|bêjer|pêşkêşker}}
#* {{jêder|ku|jêgirtin=Sara Carbonero bi xweşikbûna xwe li Îtalya naskirî ye, weke spîkera herî seksî tê naskirin. Ew zêdetir bi ken û çavên xwe meşhûr e.'' |Avestakurd.net, 7/2010}}
#* {{jêder|ku|jêgirtin=Hecîyê Cindî û kevaniya wî Zeyneva Îvo Cewarî salên 1930-1937-a radîoya Yêrêvanê ya beşa kurdîda çawa sipîkêr kar kirine.|''[[w:Bîranînên Min|Bîranînên Min]]'', [[w:Frîda Hecî Cewarî|Frîda Hecî Cewarî]], Weşanên [[w:Lîmûş|Lîmûş]]}}
==== Etîmolojî ====
Ji îngilîzî [[speaker]] ([[axiver]], [[peyiver]])
==== Jê ====
* [[spîkerane]]
* [[spîkerî]]
* [[spîkerîtî]]
* [[spîkertî]]
==== Werger ====
{{werger-ser}}
* {{Z|fa}}: {{W+|fa|گوینده}}
* {{Z|fi}}: {{W+|fi|juontaja}}
* {{Z|en}}: {{W+|en|speaker}}, {{W+|en|announcer}}, {{W+|en|fuller}}, {{W+|en|whitewasher|guman=erê}}
* {{Z|tr}}: {{W+|tr|beyazlatıcı}}, {{W+|tr|spiker}}
{{werger-bin}}
99ap9rkijrg34ikbk4svdf4cbvx5800
6347470
6347469
2026-08-31T20:46:53Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347470
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|c=mn}}
# {{K|ku|kes}} {{e|ku|meslek|televîzyon}} Kesa/ê ku [[bername]]yek [[televizyon]]ê yan [[radyo]]yê [[pêşkêş]] dike.
#: {{hevmane|ku|bêjer|pêşkêşker}}
#* {{jêder|ku|jêgirtin=Sara Carbonero bi xweşikbûna xwe li Îtalya naskirî ye, weke spîkera herî seksî tê naskirin. Ew zêdetir bi ken û çavên xwe meşhûr e.'' |Avestakurd.net, 7/2010}}
#* {{jêder|ku|jêgirtin=Hecîyê Cindî û kevaniya wî Zeyneva Îvo Cewarî salên 1930-1937-a radîoya Yêrêvanê ya beşa kurdîda çawa sipîkêr kar kirine.|''[[w:Bîranînên Min|Bîranînên Min]]'', [[w:Frîda Hecî Cewarî|Frîda Hecî Cewarî]], Weşanên [[w:Lîmûş|Lîmûş]]}}
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026|jêgirtin='''Spîkerê''' Radyoya Rewanê Keremê Seyad, di sala 1971an li ser hunermendiya Zadîna Şekir nivîseke gelek hewaskar weşandiye. }}
==== Etîmolojî ====
Ji îngilîzî [[speaker]] ([[axiver]], [[peyiver]])
==== Jê ====
* [[spîkerane]]
* [[spîkerî]]
* [[spîkerîtî]]
* [[spîkertî]]
==== Werger ====
{{werger-ser}}
* {{Z|fa}}: {{W+|fa|گوینده}}
* {{Z|fi}}: {{W+|fi|juontaja}}
* {{Z|en}}: {{W+|en|speaker}}, {{W+|en|announcer}}, {{W+|en|fuller}}, {{W+|en|whitewasher|guman=erê}}
* {{Z|tr}}: {{W+|tr|beyazlatıcı}}, {{W+|tr|spiker}}
{{werger-bin}}
bg7z94w18t6x03fcbslr7btxkcw00at
6347471
6347470
2026-08-31T20:47:32Z
Wikihez
7344
+Tewandin (DefSideBoxes)
6347471
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|c=mn}}
# {{K|ku|kes}} {{e|ku|meslek|televîzyon}} Kesa/ê ku [[bername]]yek [[televizyon]]ê yan [[radyo]]yê [[pêşkêş]] dike.
#: {{hevmane|ku|bêjer|pêşkêşker}}
#* {{jêder|ku|jêgirtin=Sara Carbonero bi xweşikbûna xwe li Îtalya naskirî ye, weke spîkera herî seksî tê naskirin. Ew zêdetir bi ken û çavên xwe meşhûr e.'' |Avestakurd.net, 7/2010}}
#* {{jêder|ku|jêgirtin=Hecîyê Cindî û kevaniya wî Zeyneva Îvo Cewarî salên 1930-1937-a radîoya Yêrêvanê ya beşa kurdîda çawa sipîkêr kar kirine.|''[[w:Bîranînên Min|Bîranînên Min]]'', [[w:Frîda Hecî Cewarî|Frîda Hecî Cewarî]], Weşanên [[w:Lîmûş|Lîmûş]]}}
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026|jêgirtin='''Spîkerê''' Radyoya Rewanê Keremê Seyad, di sala 1971an li ser hunermendiya Zadîna Şekir nivîseke gelek hewaskar weşandiye. }}
==== Tewandin ====
{{ku-tewîn-nav|mê û nêr}}
==== Etîmolojî ====
Ji îngilîzî [[speaker]] ([[axiver]], [[peyiver]])
==== Jê ====
* [[spîkerane]]
* [[spîkerî]]
* [[spîkerîtî]]
* [[spîkertî]]
==== Werger ====
{{werger-ser}}
* {{Z|fa}}: {{W+|fa|گوینده}}
* {{Z|fi}}: {{W+|fi|juontaja}}
* {{Z|en}}: {{W+|en|speaker}}, {{W+|en|announcer}}, {{W+|en|fuller}}, {{W+|en|whitewasher|guman=erê}}
* {{Z|tr}}: {{W+|tr|beyazlatıcı}}, {{W+|tr|spiker}}
{{werger-bin}}
q8a1p6dedsbu9vei81d1zblojyd4dax
6347472
6347471
2026-08-31T20:47:56Z
Wikihez
7344
/* Werger */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347472
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|c=mn}}
# {{K|ku|kes}} {{e|ku|meslek|televîzyon}} Kesa/ê ku [[bername]]yek [[televizyon]]ê yan [[radyo]]yê [[pêşkêş]] dike.
#: {{hevmane|ku|bêjer|pêşkêşker}}
#* {{jêder|ku|jêgirtin=Sara Carbonero bi xweşikbûna xwe li Îtalya naskirî ye, weke spîkera herî seksî tê naskirin. Ew zêdetir bi ken û çavên xwe meşhûr e.'' |Avestakurd.net, 7/2010}}
#* {{jêder|ku|jêgirtin=Hecîyê Cindî û kevaniya wî Zeyneva Îvo Cewarî salên 1930-1937-a radîoya Yêrêvanê ya beşa kurdîda çawa sipîkêr kar kirine.|''[[w:Bîranînên Min|Bîranînên Min]]'', [[w:Frîda Hecî Cewarî|Frîda Hecî Cewarî]], Weşanên [[w:Lîmûş|Lîmûş]]}}
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026|jêgirtin='''Spîkerê''' Radyoya Rewanê Keremê Seyad, di sala 1971an li ser hunermendiya Zadîna Şekir nivîseke gelek hewaskar weşandiye. }}
==== Tewandin ====
{{ku-tewîn-nav|mê û nêr}}
==== Etîmolojî ====
Ji îngilîzî [[speaker]] ([[axiver]], [[peyiver]])
==== Jê ====
* [[spîkerane]]
* [[spîkerî]]
* [[spîkerîtî]]
* [[spîkertî]]
==== Werger ====
{{werger-ser}}
* {{Z|fa}}: {{W+|fa|گوینده}}
* {{Z|fi}}: {{W+|fi|juontaja}}
* {{Z|en}}: {{W+|en|speaker}}, {{W+|en|announcer}}, {{W+|en|fuller}}, {{W+|en|whitewasher|guman=erê}}
* {{Z|tr}}: {{W+|tr|spiker}}
{{werger-bin}}
5y4a6zy9ej7g4mep5umnntnpc9md4dc
6347501
6347472
2026-08-31T21:41:10Z
Balyozbot
7867
[[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan
6347501
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|c=mn}}
# {{K|ku|kes}} {{e|ku|meslek|televîzyon}} Kesa/ê ku [[bername]]yek [[televizyon]]ê yan [[radyo]]yê [[pêşkêş]] dike.
#: {{hevmane|ku|bêjer|pêşkêşker}}
#* {{jêder|ku|jêgirtin=Sara Carbonero bi xweşikbûna xwe li Îtalya naskirî ye, weke spîkera herî seksî tê naskirin. Ew zêdetir bi ken û çavên xwe meşhûr e.'' |Avestakurd.net, 7/2010}}
#* {{jêder|ku|jêgirtin=Hecîyê Cindî û kevaniya wî Zeyneva Îvo Cewarî salên 1930-1937-a radîoya Yêrêvanê ya beşa kurdîda çawa sipîkêr kar kirine.|''[[w:Bîranînên Min|Bîranînên Min]]'', [[w:Frîda Hecî Cewarî|Frîda Hecî Cewarî]], Weşanên [[w:Lîmûş|Lîmûş]]}}
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026|jêgirtin='''Spîkerê''' Radyoya Rewanê Keremê Seyad, di sala 1971an li ser hunermendiya Zadîna Şekir nivîseke gelek hewaskar weşandiye. }}
==== Tewandin ====
{{ku-tewîn-nav|mê û nêr}}
==== Jê ====
* [[spîkerane]]
* [[spîkerî]]
* [[spîkerîtî]]
* [[spîkertî]]
==== Etîmolojî ====
Ji îngilîzî [[speaker]] ([[axiver]], [[peyiver]])
==== Werger ====
{{werger-ser}}
* {{Z|fa}}: {{W+|fa|گوینده}}
* {{Z|fi}}: {{W+|fi|juontaja}}
* {{Z|en}}: {{W+|en|speaker}}, {{W+|en|announcer}}, {{W+|en|fuller}}, {{W+|en|whitewasher|guman=erê}}
* {{Z|tr}}: {{W+|tr|spiker}}
{{werger-bin}}
ihcqqhaf1stbjbhx9u4dvjoc0528v2m
li sêdarê dan
0
57860
6347577
6346555
2026-09-01T10:24:49Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347577
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Lêker ===
{{lêker|ku|c=h-gh|nd=lisêdarêdan}}
# [[bi dar ve kirin]], [[daliqandin]], [[xeniqandin]], bi [[dar]]ekê ve [[kuştin]]
#* {{jêder|ku|jêgirtin=Demê Siltan Selîm zanî ku Hisên begê şerr dorandiye, mîrgeh ji destê wî deranîn, gelek lê bi hêrs bû, şand pey wî, ew çû Stembolê û li wê derê '''li sêdarê dan'''. Jiyana Hisên begê mezin bi vî awayê tirajedî bi dûmahî hat.|Dr.Khalil J. Rashow: ''Mirgeha [[Şêxan]] û [[Şengal]] û [[Kilîs]]'', 9/2003}}
==== Jê ====
{{kol3|ku
|lisêdarêdan<crz:navdêr>
|lisêdarêdayî
|lisêdarêder
}}
==== Etîmolojî ====
Ji {{qertaf|ku|li|sêdare|dan}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|hängen}}, {{W-|de|henken}}
* {{Z|cs}}: {{W+|cs|oběsit}}
* {{Z|fi}}: {{W+|fi|hirttää}}
* {{Z|fr}}: {{W+|fr|pendre}}
* {{Z|gd}}: {{W|gd|croch|xs=Scottish Gaelic}}
* {{Z|nl}}: {{W+|nl|hangen}}, {{W+|nl|ophangen}}
* {{Z|io}}: {{W|io|pendar|xs=Ido}}
* {{Z|en}}: to [[hang]] (to execute by hanging), {{W|en|put somebody to death|guman=erê}}
* {{Z|it}}: {{W+|it|impiccare}}, {{W+|it|essere impiccato}}
* {{Z|hu}}: {{W+|hu|felakaszt}}
* {{Z|pt}}: {{W+|pt|enforcar}}
* {{Z|ro}}: {{W+|ro|spânzura}}
* {{Z|ru}}: {{W|ru|вешать|tr=véšat'}}, {{W|ru|повесить|tr=pov'ésit'}}
* {{Z|scn}}: {{W+|scn|penniri}}, {{W+|scn|pinnuliari}}
* {{Z|sl}}: {{W+|sl|obesiti}}, {{W+|sl|obesiti se}}, {{W+|sl|viseti}}
* {{Z|es}}: {{W+|es|colgarse}}, {{W+|es|tildarse}}
* {{Z|sv}}: {{W+|sv|hänga}}
* {{Z|te}}: {{W-|te|ఉరితీయు|tr=uriteeyu}}, {{W-|te|ఉరితీయబడు|tr=uriteeyabaDu}}
* {{Z|tr}}: {{W+|tr|berdar etmek}}, {{W+|tr|irileşmek}}
{{werger-bin}}
sb32ux2nb6i1u2j3xvqow37m47sqewt
dawidê dunikil
0
62296
6347606
6138762
2026-09-01T11:16:43Z
Wikihez
7344
/* Werger */ xelet (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347606
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Upupa epops 1 Luc Viatour.jpg|thumb|dawidê dunikil]]
{{navdêr|ku|z=}}
# [[dîksilêman]], [[hudhud]], [[silêmanê dunikil]], [[dîkilê silêmanî]], [[dîkê silêman]], [[hophopk]]
# {{kontrol|rêz=erê|[[hepûşk]], [[dunikil]]}}
==== Navê zanistî ====
* ''Upupa epops''
==== Etîmolojî ====
Ji {{heve|ku|dawidê|dunikil}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Wiedehopf|m}}
* {{Z|cs}}: {{W+|cs|dudek}}
* {{Z|ar}}: {{W-|ar|هدهد|R=hudhud}}
* {{Z|hy}}: {{W+|hy|հոպոպ|R=hopop}}
* {{Z|eo}}: {{W-|eo|upupo}}
* {{Z|fa}}: {{W+|fa|پوپک|R=pupak}} ; {{W+|fa|هدهد|R=hod hod}}
* {{Z|ka}}: {{W-|ka|ოფოფი|R=opʻopʻi}}
* {{Z|nl}}: {{W+|nl|hop}}
* {{Z|en}}: {{W+|en|hoopoe}}
* {{Z|it}}: {{W+|it|upupa}}
* {{Z|ca}}: {{W+|ca|puput}} ; {{W+|ca|palput}}
* {{Z|la}}: {{W-|la|upupa}}
* {{Z|oc}}: {{W-|oc|upa}}
* {{Z|pl}}: {{W+|pl|dudek}}
* {{Z|pt}}: {{W+|pt|poupa}}
* {{Z|ro}}: {{W+|ro|pupăză}}
* {{Z|ru}}: {{W+|ru|удод|R=udód}}
* {{Z|ses}}: {{W-|ses|zunbu}}
* {{Z|es}}: {{W-|es|abulilla}}
* {{Z|tr}}: {{W+|tr|ibibik}} ; {{W+|tr|hüthüt}}
* {{Z|el}}: {{W+|el|τσαλαπετεινός|R=tsalapetinós}}
{{werger-bin}}
{{mijar|ku|balinde}}
pdd5je0hwzpghl5i9b28w9rp8vg70z8
rûçik
0
63152
6347459
6336540
2026-08-31T19:48:03Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347459
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{kîte|ku|rû|çik}}
=== Navdêr ===
[[Wêne:Chica cachetona.jpg|thumb|250px]]
{{navdêr|ku|z=m}}
# Herdu [[rex]]ên [[rû]] yên li herdu [[al]]ên [[difin]]ê; [[cih]]ê [[rih]]ên [[zelam]]an lê [[şên]] dibin.
#: {{hevmane|ku|alek|gep|sîmet|lam|lamik|sûret|dêm|hinarik|lem|lemik|alişk}}
#* {{J:Mîran Janbar:Qolyeya Cecileê|r=93|jêgirtin=Lê gava ku çav pê ketibû, rengê '''rûçikê''' wî hatibû guhestin û çavên wî ji şermê qudûmên xwe şikênandibûn, wer li erdê nihêrîbûn.}}
# {{f|ku|mecazî}} [[maske]]
#* {{jêder|ku|jêgirtin=Orfeyîzm û Pîsagorasî ya Yûnana kevin, batinîtî û hurûfîtî yên îranî ya bisilman dûvajoyên vê ne, lêbelê di nav herikîna zeman de hin reng û '''rûçikên''' nû wergirtine.|Rojen Barnas: ''Bi kurmanciya gewr'', Enstîtuya kurdî ya Parîsê, ISBN: 2-908416-19-0, r.56}}
#* {{jêder|ku|jêgirtin=Her ku şev çû, sir û sermayê '''rûçikên''' xwe derxistin holê û bayekî gurr li wan rabû.|Zeynelabidîn Zinar: ''Kadîna Mişkan'', Weşanxaneya Çanda Kurdî, 1993, r.40}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|rûçikgirtî<crz:rengdêr>
}}
==== Bi alfabeyên din ====
* {{ku-ar|رووچک}}
==== Herwiha binêre ====
{{kol3|ku
|lamk
}}
==== Etîmolojî ====
Ji {{qertaf|ku|rû|-çik}}.
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W+|af|wang}}
* {{Z|sq}}: {{W+|sq|faqe}}
* {{Z|de}}: {{W+|de|Dreistigkeit}}, {{W+|de|Backe|f}}, {{W+|de|Wange|f}}
* {{Z|bm}}: {{W-|bm|dafuruku}}
* {{Z|eu}}: {{W-|eu|belarrondo}}, {{W-|eu|ahutz}}, {{W-|eu|masail}}, {{W-|eu|masaila}}, {{W-|eu|matela}}, {{W-|eu|mazela}}
* {{Z|br}}: {{W+|br|boc’h}}
* {{Z|bg}}: {{W+|bg|буза}}
* {{Z|tso-lya}}: {{W-|tso-lya|üpǘkh}}
* {{Z|da}}: {{W+|da|kind}}
* {{Z|ar}}: {{W-|ar|خد}} (xedd)
* {{Z|eo}}: {{W+|eo|vango}}
* {{Z|fa}}: {{W+|fa|گونه|tr=gûnê}}, {{fa}}: {{W+|fa|لپ|tr=lup}}, {{W+|fa|اخم}}, {{W+|fa|چهره}}, {{W+|fa|قیافه}}
* {{Z|fo}}: {{W-|fo|vangi}}
* {{Z|fi}}: {{W+|fi|poski}}
* {{Z|fr}}: {{W+|fr|joue}}
* {{Z|fy}}: {{W-|fy|wang}}
* {{Z|gd}}: {{W-|gd|gruaidh}}
* {{Z|nl}}: {{W+|nl|wang}}, {{W+|nl|kaak}}, {{W+|nl|koon}}
* {{Z|io}}: {{W+|io|vango}}
* {{Z|en}}: {{W+|en|cheek}}, {{W+|en|surface}}, {{W+|en|facies|guman=erê}}, {{W+|en|lineament|guman=erê}}, {{W+|en|quale|guman=erê}}, {{W+|en|trait|guman=erê}}
* {{Z|iu}}: {{W-|iu|ᐅᓗᐊᖅ|R=[[uluaq]]}}
* {{Z|it}}: {{W+|it|ganascia}} ; {{W+|it|gota}} ; {{W+|it|guancia}}
* {{Z|ca}}: {{W+|ca|galta}}
* {{Z|kw}}: {{W-|kw|bogh}}
* {{Z|hu}}: {{W+|hu|orca}}
* {{Z|no}}: {{W+|no|kinn}}
* {{Z|oc}}: {{W+|oc|gauta}}
* {{Z|pt}}: {{W+|pt|bochecha}}, {{W+|pt|face}}
* {{Z|ro}}: {{W+|ro|obraz}}
* {{Z|se}}: {{W-|se|muohtu}}
* {{Z|ses}}: {{W-|ses|garbe}}
* {{Z|es}}: {{W+|es|mejilla}}
* {{Z|sv}}: {{W+|sv|kind}}
* {{Z|tr}}: {{W+|tr|yanak}}, {{W+|tr|beniz}}, {{W+|tr|didar}}, {{W+|tr|sıfat}}, {{W+|tr|duluk}}, {{W+|tr|bet}}
* {{Z|uk}}: {{W-|uk|щока}}
* {{Z|cy}}: {{W-|cy|boch}}
{{werger-bin}}
3a4toofso7zkstmsjpz4u3m4vevv2gz
6347466
6347459
2026-08-31T20:41:11Z
Balyozbot
7867
[[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan
6347466
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{kîte|ku|rû|çik}}
=== Navdêr ===
[[Wêne:Chica cachetona.jpg|thumb|250px]]
{{navdêr|ku|z=m}}
# Herdu [[rex]]ên [[rû]] yên li herdu [[al]]ên [[difin]]ê; [[cih]]ê [[rih]]ên [[zelam]]an lê [[şên]] dibin.
#: {{hevmane|ku|alek|gep|sîmet|lam|lamik|sûret|dêm|hinarik|lem|lemik|alişk}}
#* {{J:Mîran Janbar:Qolyeya Cecileê|r=93|jêgirtin=Lê gava ku çav pê ketibû, rengê '''rûçikê''' wî hatibû guhestin û çavên wî ji şermê qudûmên xwe şikênandibûn, wer li erdê nihêrîbûn.}}
# {{f|ku|mecazî}} [[maske]]
#* {{jêder|ku|jêgirtin=Orfeyîzm û Pîsagorasî ya Yûnana kevin, batinîtî û hurûfîtî yên îranî ya bisilman dûvajoyên vê ne, lêbelê di nav herikîna zeman de hin reng û '''rûçikên''' nû wergirtine.|Rojen Barnas: ''Bi kurmanciya gewr'', Enstîtuya kurdî ya Parîsê, ISBN: 2-908416-19-0, r.56}}
#* {{jêder|ku|jêgirtin=Her ku şev çû, sir û sermayê '''rûçikên''' xwe derxistin holê û bayekî gurr li wan rabû.|Zeynelabidîn Zinar: ''Kadîna Mişkan'', Weşanxaneya Çanda Kurdî, 1993, r.40}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Bi alfabeyên din ====
* {{ku-ar|رووچک}}
==== Jê ====
{{kol3|ku
|rûçikgirtî<crz:rengdêr>
}}
==== Etîmolojî ====
Ji {{qertaf|ku|rû|-çik}}.
==== Herwiha binêre ====
{{kol3|ku
|lamk
}}
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W+|af|wang}}
* {{Z|sq}}: {{W+|sq|faqe}}
* {{Z|de}}: {{W+|de|Dreistigkeit}}, {{W+|de|Backe|f}}, {{W+|de|Wange|f}}
* {{Z|bm}}: {{W-|bm|dafuruku}}
* {{Z|eu}}: {{W-|eu|belarrondo}}, {{W-|eu|ahutz}}, {{W-|eu|masail}}, {{W-|eu|masaila}}, {{W-|eu|matela}}, {{W-|eu|mazela}}
* {{Z|br}}: {{W+|br|boc’h}}
* {{Z|bg}}: {{W+|bg|буза}}
* {{Z|tso-lya}}: {{W-|tso-lya|üpǘkh}}
* {{Z|da}}: {{W+|da|kind}}
* {{Z|ar}}: {{W-|ar|خد}} (xedd)
* {{Z|eo}}: {{W+|eo|vango}}
* {{Z|fa}}: {{W+|fa|گونه|tr=gûnê}}, {{fa}}: {{W+|fa|لپ|tr=lup}}, {{W+|fa|اخم}}, {{W+|fa|چهره}}, {{W+|fa|قیافه}}
* {{Z|fo}}: {{W-|fo|vangi}}
* {{Z|fi}}: {{W+|fi|poski}}
* {{Z|fr}}: {{W+|fr|joue}}
* {{Z|fy}}: {{W-|fy|wang}}
* {{Z|gd}}: {{W-|gd|gruaidh}}
* {{Z|nl}}: {{W+|nl|wang}}, {{W+|nl|kaak}}, {{W+|nl|koon}}
* {{Z|io}}: {{W+|io|vango}}
* {{Z|en}}: {{W+|en|cheek}}, {{W+|en|surface}}, {{W+|en|facies|guman=erê}}, {{W+|en|lineament|guman=erê}}, {{W+|en|quale|guman=erê}}, {{W+|en|trait|guman=erê}}
* {{Z|iu}}: {{W-|iu|ᐅᓗᐊᖅ|R=[[uluaq]]}}
* {{Z|it}}: {{W+|it|ganascia}} ; {{W+|it|gota}} ; {{W+|it|guancia}}
* {{Z|ca}}: {{W+|ca|galta}}
* {{Z|kw}}: {{W-|kw|bogh}}
* {{Z|hu}}: {{W+|hu|orca}}
* {{Z|no}}: {{W+|no|kinn}}
* {{Z|oc}}: {{W+|oc|gauta}}
* {{Z|pt}}: {{W+|pt|bochecha}}, {{W+|pt|face}}
* {{Z|ro}}: {{W+|ro|obraz}}
* {{Z|se}}: {{W-|se|muohtu}}
* {{Z|ses}}: {{W-|ses|garbe}}
* {{Z|es}}: {{W+|es|mejilla}}
* {{Z|sv}}: {{W+|sv|kind}}
* {{Z|tr}}: {{W+|tr|yanak}}, {{W+|tr|beniz}}, {{W+|tr|didar}}, {{W+|tr|sıfat}}, {{W+|tr|duluk}}, {{W+|tr|bet}}
* {{Z|uk}}: {{W-|uk|щока}}
* {{Z|cy}}: {{W-|cy|boch}}
{{werger-bin}}
6v4ykjauh99iv961k4n4grkjvwti9kx
taxûk
0
63284
6347369
6318493
2026-08-31T13:16:22Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes); guhartina pêşketî (DefSideBoxes); guhartina pêşketî (DefSideBoxes)
6347369
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Stiga rattikelkka.JPG|thumb|250px|taxûkek (2)]]
{{navdêr|ku|z=m}}
# [[alav|Alava]] [[li ser]] [[berf|berfê]], [[mirov|mirov]] pê [[xwe|xwe]] [[xuşkêl dike|xuşkêl dike]].
# [[alav|Alava]] [[li ser]] [[berf|berfê]], [[tişt|tişt]] pê [[têne|têne]] [[kêşandin|kêşandin]] û [[xuşikandin|xuşikandin]].
#: {{hevmane|ku|kaş}}
# [[navgîn|Navgîn]]ek e ku [[bar]] lê tên [[siwar]]kirin yan jî [[mirov]] lê siwar dibin û li ser [[berf]]ê tê [[kişandin]].
#: {{hevmane|ku|kêşe<crz:2>|kole<crz:2>|tawûg}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Schlitten|m}}
* {{Z|ar}}: {{W-|ar|مزلقة}}
* {{Z|eo}}: {{W-|eo|glitveturilo}}
* {{Z|fa}}: {{W+|fa|سورتمه}}
* {{Z|fi}}: {{W+|fi|kelkka}}
* {{Z|fr}}: {{W+|fr|traîneau}}
* {{Z|io}}: {{W+|io|glit-veturo}}
* {{Z|en}}: {{W+|en|sled}}, {{W-|en|seldge}}, {{W+|en|sleigh}}
* {{Z|iu}}: {{W-|iu|ᖃᒧᑏᒃ|R=[[qamutiik]]}}
* {{Z|it}}: {{W+|it|slitta|f}}
* {{Z|ja}}: {{W-|ja|ソリ|R=sori}}
* {{Z|ca}}: {{W+|ca|trineu|m}}
* {{Z|oj}}: {{W-|oj|zhooshkodaabaan}}
* {{Z|pt}}: {{W+|pt|trenó|m}}
* {{Z|se}}: {{W-|se|gielká}}
* {{Z|es}}: {{W+|es|trineo|m}}
* {{Z|tr}}: {{W+|tr|kızak}}
* {{Z|el}}: {{W+|el|έλκηθρο|R=élkithro}}
{{werger-bin}}
424jijpwt2ku4ctb7tv8ljz6gp7i88p
6347370
6347369
2026-08-31T13:17:57Z
Wikihez
7344
+nimûneya bikaranînê bi amûra « [[Mediawiki:Gadget-wikt.add-examples|Nimûne zêde bike]] » (v2.0).
6347370
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Stiga rattikelkka.JPG|thumb|250px|taxûkek (2)]]
{{navdêr|ku|z=m}}
# [[alav|Alava]] [[li ser]] [[berf|berfê]], [[mirov|mirov]] pê [[xwe|xwe]] [[xuşkêl dike|xuşkêl dike]].
#* {{jêder-websîte|ku|nivîskar=Zinarê Xamo|websîte=HINDIK - RINDIK|sernav=Dil dîsa hat zimên...|url=https://zinarexamo.blogspot.com/2014/01/dil-disa-hat-zimen.html|tarîx=2014-01-19|jêgirtin=Li ser gir û kaşan çend dê û bavan bi zarokên xwe ra dilîstin, bi '''taxûkan'''(kaşkaşokan) xwe dişemitandin, zarok tot dikirin, şûş dikirin…}}
# [[alav|Alava]] [[li ser]] [[berf|berfê]], [[tişt|tişt]] pê [[têne|têne]] [[kêşandin|kêşandin]] û [[xuşikandin|xuşikandin]].
#: {{hevmane|ku|kaş}}
# [[navgîn|Navgîn]]ek e ku [[bar]] lê tên [[siwar]]kirin yan jî [[mirov]] lê siwar dibin û li ser [[berf]]ê tê [[kişandin]].
#: {{hevmane|ku|kêşe<crz:2>|kole<crz:2>|tawûg}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Schlitten|m}}
* {{Z|ar}}: {{W-|ar|مزلقة}}
* {{Z|eo}}: {{W-|eo|glitveturilo}}
* {{Z|fa}}: {{W+|fa|سورتمه}}
* {{Z|fi}}: {{W+|fi|kelkka}}
* {{Z|fr}}: {{W+|fr|traîneau}}
* {{Z|io}}: {{W+|io|glit-veturo}}
* {{Z|en}}: {{W+|en|sled}}, {{W-|en|seldge}}, {{W+|en|sleigh}}
* {{Z|iu}}: {{W-|iu|ᖃᒧᑏᒃ|R=[[qamutiik]]}}
* {{Z|it}}: {{W+|it|slitta|f}}
* {{Z|ja}}: {{W-|ja|ソリ|R=sori}}
* {{Z|ca}}: {{W+|ca|trineu|m}}
* {{Z|oj}}: {{W-|oj|zhooshkodaabaan}}
* {{Z|pt}}: {{W+|pt|trenó|m}}
* {{Z|se}}: {{W-|se|gielká}}
* {{Z|es}}: {{W+|es|trineo|m}}
* {{Z|tr}}: {{W+|tr|kızak}}
* {{Z|el}}: {{W+|el|έλκηθρο|R=élkithro}}
{{werger-bin}}
hkxif5r7jg6vfkqjae2kz0vbzdejmz4
6347386
6347370
2026-08-31T15:12:16Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347386
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Stiga rattikelkka.JPG|thumb|250px|taxûkek (2)]]
{{navdêr|ku|z=m}}
# [[alav|Alava]] [[li ser]] [[berf]]ê, [[mirov]] pê [[xwe]] [[xuşkêl dike]].
#* {{jêder-websîte|ku|nivîskar=Zinarê Xamo|websîte=HINDIK - RINDIK|sernav=Dil dîsa hat zimên...|url=https://zinarexamo.blogspot.com/2014/01/dil-disa-hat-zimen.html|tarîx=2014-01-19|jêgirtin=Li ser gir û kaşan çend dê û bavan bi zarokên xwe ra dilîstin, bi '''taxûkan'''(kaşkaşokan) xwe dişemitandin, zarok tot dikirin, şûş dikirin…}}
# [[alav|Alava]] [[li ser]] [[berf]]ê, [[tişt]] pê [[têne]] [[kêşandin]] û [[xuşikandin]].
#: {{hevmane|ku|kaş}}
# [[navgîn|Navgînek]] e ku [[bar]] lê tên [[siwar]]kirin yan jî [[mirov]] lê siwar dibin û li ser [[berf]]ê tê [[kişandin]].
#: {{hevmane|ku|kêşe<crz:2>|kole<crz:2>|tawûg}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Schlitten|m}}
* {{Z|ar}}: {{W-|ar|مزلقة}}
* {{Z|eo}}: {{W-|eo|glitveturilo}}
* {{Z|fa}}: {{W+|fa|سورتمه}}
* {{Z|fi}}: {{W+|fi|kelkka}}
* {{Z|fr}}: {{W+|fr|traîneau}}
* {{Z|io}}: {{W+|io|glit-veturo}}
* {{Z|en}}: {{W+|en|sled}}, {{W-|en|seldge}}, {{W+|en|sleigh}}
* {{Z|iu}}: {{W-|iu|ᖃᒧᑏᒃ|R=[[qamutiik]]}}
* {{Z|it}}: {{W+|it|slitta|f}}
* {{Z|ja}}: {{W-|ja|ソリ|R=sori}}
* {{Z|ca}}: {{W+|ca|trineu|m}}
* {{Z|oj}}: {{W-|oj|zhooshkodaabaan}}
* {{Z|pt}}: {{W+|pt|trenó|m}}
* {{Z|se}}: {{W-|se|gielká}}
* {{Z|es}}: {{W+|es|trineo|m}}
* {{Z|tr}}: {{W+|tr|kızak}}
* {{Z|el}}: {{W+|el|έλκηθρο|R=élkithro}}
{{werger-bin}}
murm51fpf475bzyq3e04k0gdgaoguzg
Begreifen
0
116457
6347595
5848409
2026-09-01T11:08:50Z
Wikihez
7344
Cureyê rêzimanî hate diyarkirin: Navdêr (DefSideBoxes)
6347595
wikitext
text/x-wiki
{{bnr-h|begreifen}}
== {{ziman|de}} ==
=== Navdêr ===
{{navdêr|de}}
# [[têgehiştin]], [[pêhîzkirin]], [[firaset]]
fs2xozs1iqwf5bm56ju8kiklh4sh0ht
diğer
0
132743
6347351
6347173
2026-08-31T12:47:50Z
Wikihez
7344
([[m:Special:MyLanguage/User:Jon Harald Søby/diffedit|diffedit]])
6347351
wikitext
text/x-wiki
== {{ziman|tr}} ==
=== Daçek ===
{{daçek|tr}}
# [[din]]
# [[dîtir]], [[diğer]], [[dike]], [[dîtirk]], [[a din]], ê din, [[dî]]
#: {{mk|tr|sen değil '''diğeri''' gelsin|rêz=1| tu na, bila yê din bê }}
9a8lmvplsuhlapd8ce2ayg5c451xo2g
6347352
6347351
2026-08-31T12:48:19Z
Wikihez
7344
6347352
wikitext
text/x-wiki
== {{ziman|tr}} ==
=== Bilêvkirin ===
* {{deng|tr|LL-Q256 (tur)-ToprakM-diğer.wav|Deng|dever=Îzmîr, Tirkiye}}
=== Daçek ===
{{daçek|tr}}
# [[din]]
# [[dîtir]], [[diğer]], [[dike]], [[dîtirk]], [[a din]], ê din, [[dî]]
#: {{mk|tr|sen değil '''diğeri''' gelsin|rêz=1|tu na, bila yê din bê}}
p9nixgfev9gj60epvuxznby5x9j1drk
6347353
6347352
2026-08-31T12:48:49Z
Wikihez
7344
/* Daçek */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347353
wikitext
text/x-wiki
== {{ziman|tr}} ==
=== Bilêvkirin ===
* {{deng|tr|LL-Q256 (tur)-ToprakM-diğer.wav|Deng|dever=Îzmîr, Tirkiye}}
=== Daçek ===
{{daçek|tr}}
# [[din]], [[dîtir]], [[dîtirk]], [[a din]], ê din, [[dî]]
#: {{mk|tr|sen değil '''diğeri''' gelsin|rêz=1|tu na, bila yê din bê}}
8l26nr67ngmlryxysjr0e1xz19kmh4q
kafa kâğıdı
0
145318
6347612
4614992
2026-09-01T11:26:39Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347612
wikitext
text/x-wiki
== {{ziman|tr}} ==
=== Navdêr ===
{{navdêr|tr}}
# [[nasname]], cizdanê nifûsê, [[huwiyet]]
qt5bfv6v66yz5nff344ebv3xv0w7a68
barname
0
178269
6347376
6298162
2026-08-31T13:22:26Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes)
6347376
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[kaxez|Kaxeza]] ku [[naverok|naveroka]] wê di [[heq|heqê]] [[bar|bar]] û [[xwedî|xwediyê]] wî de [[agahî|agahiyê]] [[dan|dide]].
==== Tewandin ====
{{ku-tewîn-nav/nû|mê|guherto=hemû}}
==== Hevmane ====
* [[îrsaliye]]
* [[fatûra]]
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|fa}}: {{W+|fa|بارنامه}}
* {{Z|tr}}: {{W+|tr|fatura}}, {{W+|tr|irsaliye}}
{{werger-bin}}
dod3i22i6z001klrft5yu02uzkyjj57
6347384
6347376
2026-08-31T15:12:10Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347384
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[kaxez|Kaxeza]] ku [[naverok]]a wê di [[heq]]ê [[bar]] û [[xwedî|xwediyê]] wî de [[agahî|agahiyê]] [[dan|dide]].
==== Tewandin ====
{{ku-tewîn-nav/nû|mê|guherto=hemû}}
==== Hevmane ====
* [[îrsaliye]]
* [[fatûra]]
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|fa}}: {{W+|fa|بارنامه}}
* {{Z|tr}}: {{W+|tr|fatura}}, {{W+|tr|irsaliye}}
{{werger-bin}}
4f7x908zqhh2vh5n4wt2u4t6kyt710z
dêre
0
179048
6347494
6305691
2026-08-31T21:20:08Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347494
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# {{e|ku|cilûberg|serhedî}} [[kiras|Kiras]]ekî [[ser]]ê [[bervekirî]].
#* {{jêder-pirtûk|ku|jêgirtin=Gelek '''dêre''', fanorî, saqoyên ku ji bo cejnan, rojên taybet dîlan û dawetan di nav baxçeyên gulgulî de, di sandoqên quzanî de hatibûn veşartin, bûn para diranên min yên xirab tûj.|nivîskar=Mihemed Şarman|sernav=Pirça Winda|cîh=Stembol|weşanxane={{w|Weşanên Avesta|Avesta}}|sal=2016, Çapa Duyem|rûpel=41|isbn=978-605-5585-41-9}}
#* {{jêder-pirtûk|ku|jêgirtin=Ez jî dixwazim ji xwe re '''dêreyeke''' sor bikirim.|nivîskar=Samî Tan|sernav=HÎNKER:Asta Yekemîn|weşanxane=ENSTÎTUYA KURDÎ YA STENBOLÊ|rûpel=50}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê|guherto=hemû}}
==== Notên bikaranînê ====
{{agadarî}} Jêre li navçeya Behdînan û Hekarê [[fîstan]] dibêjin. Li nav koçeran û li aliyê Serhedê ji vî kirasê serê bervekirî re '''dêre''', li hin navçeyên din jî [[taqî]] dibêjin. Li piraniya navçeyên Kurdistanê fîstan bi mana kirasê ser bi kar tînin.<br><small>'''Çavkanî: '''Muzaffer BEGZADE: ''Cil û Berg'', Kurmancî, Hj. 11, 1992, r. 97</small>
==== Hevmane ====
* [[fîstan]]
* [[taqî]]
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Kleid}}
* {{Z|fa}}: {{W|fa|لباس زنان کرد}}
* {{Z|en}}: {{W|en|dress}}
* {{Z|tr}}: {{W|tr|fistan}}, {{W|tr|entari}}
{{werger-bin}}
mtywj290ooy8jbm76lyeqaf2dteh8lk
6347495
6347494
2026-08-31T21:20:22Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347495
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# {{e|ku|cilûberg|Serhedî}} [[kiras|Kiras]]ekî [[ser]]ê [[bervekirî]].
#* {{jêder-pirtûk|ku|jêgirtin=Gelek '''dêre''', fanorî, saqoyên ku ji bo cejnan, rojên taybet dîlan û dawetan di nav baxçeyên gulgulî de, di sandoqên quzanî de hatibûn veşartin, bûn para diranên min yên xirab tûj.|nivîskar=Mihemed Şarman|sernav=Pirça Winda|cîh=Stembol|weşanxane={{w|Weşanên Avesta|Avesta}}|sal=2016, Çapa Duyem|rûpel=41|isbn=978-605-5585-41-9}}
#* {{jêder-pirtûk|ku|jêgirtin=Ez jî dixwazim ji xwe re '''dêreyeke''' sor bikirim.|nivîskar=Samî Tan|sernav=HÎNKER:Asta Yekemîn|weşanxane=ENSTÎTUYA KURDÎ YA STENBOLÊ|rûpel=50}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê|guherto=hemû}}
==== Notên bikaranînê ====
{{agadarî}} Jêre li navçeya Behdînan û Hekarê [[fîstan]] dibêjin. Li nav koçeran û li aliyê Serhedê ji vî kirasê serê bervekirî re '''dêre''', li hin navçeyên din jî [[taqî]] dibêjin. Li piraniya navçeyên Kurdistanê fîstan bi mana kirasê ser bi kar tînin.<br><small>'''Çavkanî: '''Muzaffer BEGZADE: ''Cil û Berg'', Kurmancî, Hj. 11, 1992, r. 97</small>
==== Hevmane ====
* [[fîstan]]
* [[taqî]]
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Kleid}}
* {{Z|fa}}: {{W|fa|لباس زنان کرد}}
* {{Z|en}}: {{W|en|dress}}
* {{Z|tr}}: {{W|tr|fistan}}, {{W|tr|entari}}
{{werger-bin}}
2dn4xwc83auddtle48hf6bk5k1gctq5
6347507
6347495
2026-08-31T23:12:15Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347507
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# {{e|ku|cilûberg|Serhedî}} [[kiras|Kirasekî]] [[ser]]ê [[bervekirî]].
#* {{jêder-pirtûk|ku|jêgirtin=Gelek '''dêre''', fanorî, saqoyên ku ji bo cejnan, rojên taybet dîlan û dawetan di nav baxçeyên gulgulî de, di sandoqên quzanî de hatibûn veşartin, bûn para diranên min yên xirab tûj.|nivîskar=Mihemed Şarman|sernav=Pirça Winda|cîh=Stembol|weşanxane={{w|Weşanên Avesta|Avesta}}|sal=2016, Çapa Duyem|rûpel=41|isbn=978-605-5585-41-9}}
#* {{jêder-pirtûk|ku|jêgirtin=Ez jî dixwazim ji xwe re '''dêreyeke''' sor bikirim.|nivîskar=Samî Tan|sernav=HÎNKER:Asta Yekemîn|weşanxane=ENSTÎTUYA KURDÎ YA STENBOLÊ|rûpel=50}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê|guherto=hemû}}
==== Notên bikaranînê ====
{{agadarî}} Jêre li navçeya Behdînan û Hekarê [[fîstan]] dibêjin. Li nav koçeran û li aliyê Serhedê ji vî kirasê serê bervekirî re '''dêre''', li hin navçeyên din jî [[taqî]] dibêjin. Li piraniya navçeyên Kurdistanê fîstan bi mana kirasê ser bi kar tînin.<br><small>'''Çavkanî: '''Muzaffer BEGZADE: ''Cil û Berg'', Kurmancî, Hj. 11, 1992, r. 97</small>
==== Hevmane ====
* [[fîstan]]
* [[taqî]]
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Kleid}}
* {{Z|fa}}: {{W|fa|لباس زنان کرد}}
* {{Z|en}}: {{W|en|dress}}
* {{Z|tr}}: {{W|tr|fistan}}, {{W|tr|entari}}
{{werger-bin}}
prhdz01f2ktsc82mevbrxgjlk0fzcdx
heweskar
0
179893
6347476
6282486
2026-08-31T20:52:20Z
Wikihez
7344
Cureyê rêzimanî hate diyarkirin: Rengdêr (DefSideBoxes)
6347476
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Rengdêr ===
{{rengdêr|ku}}
# [[dilxwaz]]
# {{kontrol|rêz=erê|[[arezûdar]], [[bidil]]}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|ehrgeizig}}, {{W|de|begierig}}
* {{Z|fa}}: {{W|fa|خواستنی}}, {{W|fa|دارای هوس}}, {{W|fa|آماتور|guman=erê}}, {{W|fa|منطقی|guman=erê}}
* {{Z|en}}: {{W|en|avid}}, {{W|en|juicy}}, {{W|en|responsive}}
* {{Z|tr}}: {{W|tr|heveskâr}}, {{W|tr|hevesli}}, {{W|tr|özentici}}
{{werger-bin}}
szyo3uzycsjpqhyc54g61nmxa7p9l8k
6347477
6347476
2026-08-31T20:52:47Z
Wikihez
7344
+Formên alternatîv (DefSideBoxes)
6347477
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Rengdêr ===
{{rengdêr|ku}}
# [[dilxwaz]]
# {{kontrol|rêz=erê|[[arezûdar]], [[bidil]]}}
==== Formên alternatîv ====
{{kol3|ku|cure=Formên alternatîv
|hewaskar
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|ehrgeizig}}, {{W|de|begierig}}
* {{Z|fa}}: {{W|fa|خواستنی}}, {{W|fa|دارای هوس}}, {{W|fa|آماتور|guman=erê}}, {{W|fa|منطقی|guman=erê}}
* {{Z|en}}: {{W|en|avid}}, {{W|en|juicy}}, {{W|en|responsive}}
* {{Z|tr}}: {{W|tr|heveskâr}}, {{W|tr|hevesli}}, {{W|tr|özentici}}
{{werger-bin}}
jhhtgbn7ydve5bkznk5o1qcen4rx0tb
6347478
6347477
2026-08-31T20:53:18Z
Wikihez
7344
/* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347478
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Rengdêr ===
{{rengdêr|ku}}
# [[dilxwaz]]
# {{kontrol|rêz=erê|[[arezûdar]], [[bidil]]}}
==== Formên alternatîv ====
{{kol3|ku|cure=Formên alternatîv
|hewaskar
}}
==== Etîmolojî ====
Ji {{qf|ku|hewes|-kar}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|ehrgeizig}}, {{W|de|begierig}}
* {{Z|fa}}: {{W|fa|خواستنی}}, {{W|fa|دارای هوس}}, {{W|fa|آماتور|guman=erê}}, {{W|fa|منطقی|guman=erê}}
* {{Z|en}}: {{W|en|avid}}, {{W|en|juicy}}, {{W|en|responsive}}
* {{Z|tr}}: {{W|tr|heveskâr}}, {{W|tr|hevesli}}, {{W|tr|özentici}}
{{werger-bin}}
0fflcfriqesdncsnyrww74fyw250p9h
texsî
0
188638
6347366
6336753
2026-08-31T13:08:48Z
Wikihez
7344
+nimûneya bikaranînê bi amûra « [[Mediawiki:Gadget-wikt.add-examples|Nimûne zêde bike]] » (v2.0).
6347366
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Navdêr ===
{{navdêr|ku|z=m}}
# {{guharto|ku|taksî}}
#* {{J:Firat Cewerî:Girtî:1986|jêgirtin=Ez li bendî '''texsiyê''' me!...}}
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Behra Reş Dibe Goristan (1942)|url=https://www.kovarabir.com/505/rohat-alakom-behra-res-dibe-goristan-1942/kmr/|tarîx=17.05.2021|jêgirtin=Wagner ligel Mayayê '''texsîyekê''' sîyar dibe di orta zivistanê da bi kemana xwe û tacegulekê (çeleng) berê xwe dide Şîleyê, bajarokekî ku li qiraxa Behra Reş e.}}
1ehzgeg0e8et4q1gko7tq8fmvsmkfn1
lasakirin
0
243394
6347425
6311063
2026-08-31T18:33:20Z
~2026-47410-60
15308
/* Navdêr */
6347425
wikitext
text/x-wiki
{{bnr-l|lasa kirin}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# {{teqlîdkirin|ku}}
#* {{bênimûne|ku}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Etîmolojî ====
Ji {{pêk|ku|lasa|kirin}}.
==== Werger ====
{{werger-ser}}
{{werger-bin}}
jlne6g34pa81hyuahizyrwv4xh8uh9h
6347426
6347425
2026-08-31T18:35:02Z
~2026-47410-60
15308
/* Navdêr */
6347426
wikitext
text/x-wiki
{{bnr-l|lasa kirin}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
[[texlîd]], [[çavlêkirin]], [[zarî]]kirin
#* {{bênimûne|ku}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Etîmolojî ====
Ji {{pêk|ku|lasa|kirin}}.
==== Werger ====
{{werger-ser}}
{{werger-bin}}
9akiu62svc8r97r19mg99vtt207ynxp
6347427
6347426
2026-08-31T18:35:48Z
~2026-47410-60
15308
Werger: +erebî : [[تقليد]] (bi alîkarî)
6347427
wikitext
text/x-wiki
{{bnr-l|lasa kirin}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
[[texlîd]], [[çavlêkirin]], [[zarî]]kirin
#* {{bênimûne|ku}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Etîmolojî ====
Ji {{pêk|ku|lasa|kirin}}.
==== Werger ====
{{werger-ser}}
* {{Z|ar}}: {{W-|ar|تقليد}}
{{werger-bin}}
372stmqmmyd55vj8piyrsfxwi3xngl8
6347428
6347427
2026-08-31T18:55:18Z
Wikihez
7344
([[m:Special:MyLanguage/User:Jon Harald Søby/diffedit|diffedit]])
6347428
wikitext
text/x-wiki
{{bnr-l|lasa kirin}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[texlîd]], [[çavlêkirin]], [[zarî]]kirin
#* {{bênimûne|ku}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Etîmolojî ====
Ji {{pêk|ku|lasa|kirin}}.
==== Werger ====
{{werger-ser}}
* {{Z|ar}}: {{W-|ar|تقليد}}
{{werger-bin}}
9f76mhnj7j8r1cw0aub9hhx944amdgj
6347429
6347428
2026-08-31T18:59:21Z
Wikihez
7344
+nimûneya bikaranînê bi amûra « [[Mediawiki:Gadget-wikt.add-examples|Nimûne zêde bike]] » (v2.0).
6347429
wikitext
text/x-wiki
{{bnr-l|lasa kirin}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[texlîd]], [[çavlêkirin]], [[zarî]]kirin
#* {{jêder-websîte|ku|nivîskar=Beşîr Taha Silêman|websîte=ronahi.net|sernav=Perwerde û dûrayiyên wê|url=https://ronahi.net/ku/?p=48298|urlya-arşîvê=https://web.archive.org/web/20220417010013/https://ronahi.net/ku/?p=48298|tarîx=2022-03-30|jêgirtin=Di sîstemên perwerdeyê de, li gelek welatan lawaziyeke berbiçav heye; gava mirov li minhacên van welatan dinêre, dibîne ku pirtûkên wan mîna hev in û hem '''lasakirineke''' (teqlîd) berbiçav di wan de heye.}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Etîmolojî ====
Ji {{pêk|ku|lasa|kirin}}.
==== Werger ====
{{werger-ser}}
* {{Z|ar}}: {{W-|ar|تقليد}}
{{werger-bin}}
off99rn12vj5c8nlpgwrz351wj61lvd
6347430
6347429
2026-08-31T19:00:16Z
Wikihez
7344
6347430
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m|lk=lasa kirin}}
# [[texlîd]], [[çavlêkirin]], [[zarî]]kirin
#* {{jêder-websîte|ku|nivîskar=Beşîr Taha Silêman|websîte=ronahi.net|sernav=Perwerde û dûrayiyên wê|url=https://ronahi.net/ku/?p=48298|urlya-arşîvê=https://web.archive.org/web/20220417010013/https://ronahi.net/ku/?p=48298|tarîx=2022-03-30|jêgirtin=Di sîstemên perwerdeyê de, li gelek welatan lawaziyeke berbiçav heye; gava mirov li minhacên van welatan dinêre, dibîne ku pirtûkên wan mîna hev in û hem '''lasakirineke''' (teqlîd) berbiçav di wan de heye.}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Etîmolojî ====
Ji {{pêk|ku|lasa|kirin}}.
==== Werger ====
{{werger-ser}}
* {{Z|ar}}: {{W-|ar|تقليد}}
{{werger-bin}}
s3m68c6xctq18nk3gfw8vaz5svx469i
خياط
0
254086
6347420
5188398
2026-08-31T18:22:34Z
Wikihez
7344
/* Navdêr */
6347420
wikitext
text/x-wiki
{{bnr-h|خیاط}}
== {{ziman|ar}} ==
=== Navdêr ===
[[File:Tailor sewing a Somaliland flag, Berbera.jpg|thumb|right|270px|{{l-self|ar|خَيَّاط|tr=-}}]]
{{navdêr|ar|خَيَّاط|z=n|m=خَيَّاطَة|p=خَيَّاطُون}}
# [[terzî]], [[dirûnkar]]
keuk8n61uroa8t2r52tcvxsvulwtbho
6347462
6347420
2026-08-31T20:12:06Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Valahiya nav rast kir, Kelîmeyên sihirî rast kir.)
6347462
wikitext
text/x-wiki
{{bnr-h|خیاط}}
== {{ziman|ar}} ==
=== Navdêr ===
[[Wêne:Tailor sewing a Somaliland flag, Berbera.jpg|thumb|rast|270px|{{l-self|ar|خَيَّاط|tr=-}}]]
{{navdêr|ar|خَيَّاط|z=n|m=خَيَّاطَة|p=خَيَّاطُون}}
# [[terzî]], [[dirûnkar]]
rbj07nma17qinvsb2y7q827yqlclisd
6347463
6347462
2026-08-31T20:21:45Z
Wikihez
7344
([[m:Special:MyLanguage/User:Jon Harald Søby/diffedit|diffedit]])
6347463
wikitext
text/x-wiki
{{bnr-h|خیاط}}
== {{ziman|ar}} ==
=== Navdêr ===
[[Wêne:Tailor sewing a Somaliland flag, Berbera.jpg|thumb|270px|{{l-self|ar|خَيَّاط|tr=-}}]]
{{navdêr|ar|خَيَّاط|z=n|m=خَيَّاطَة|p=خَيَّاطُون}}
# [[terzî]], [[dirûnkar]]
79ku8bpyyzw4i8wwe6taq2pykpiwjou
ھەڵفلیقاندن
0
269701
6347594
5878754
2026-09-01T11:04:56Z
Wikihez
7344
Cureyê rêzimanî hate diyarkirin: Lêker (DefSideBoxes)
6347594
wikitext
text/x-wiki
== {{ziman|ckb}} ==
=== Bilêvkirin ===
:hellfilîqandin
=== Lêker ===
{{lêker|ckb}}
# [[meriçandin]], [[merçiqandin]], [[zirviçandin]], [[perçiqandin]]
ies38rm1g1jvs8fnid3h9jpvbs5kt0v
کەزاخە
0
270577
6347629
5874470
2026-09-01T11:44:07Z
Wikihez
7344
Cureyê rêzimanî hate diyarkirin: Navdêr (DefSideBoxes)
6347629
wikitext
text/x-wiki
== {{ziman|ckb}} ==
=== Bilêvkirin ===
:kezaxe
=== Navdêr ===
{{navdêr|ckb}}
# [[kezaxe]], qusandina / kurrkirina mêwên tirî
3cjmieea6en9iisayr2irp976y27w0w
6347630
6347629
2026-09-01T11:44:43Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes)
6347630
wikitext
text/x-wiki
== {{ziman|ckb}} ==
=== Bilêvkirin ===
:kezaxe
=== Navdêr ===
{{navdêr|ckb}}
# {{g|ku|kezaxe}} {{îzah|[[qusandin|qusandina]] / [[kurrkirin|kurrkirina]] [[mêw|mêwên]] [[tirî|tirî]]}}
fqfw5ll06agmk0z8ijoctydo2bjf3at
dryer
0
275609
6347596
6256660
2026-09-01T11:09:40Z
Wikihez
7344
/* Binêre herwiha */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347596
wikitext
text/x-wiki
== {{ziman|en}} ==
=== Bilêvkirin ===
* {{mj|DYA}} {{IPA|en|/ˈdɹaɪɚ/}}
* {{mj|KY}} {{IPA|en|/ˈdɹaɪə/}}
* {{deng|en|LL-Q1860 (eng)-Persent101-dryer.wav|Deng|dever=}}
=== Navdêr ===
[[Wêne:modern front load tumble dryer.JPG|thumb|150px|A modern front-load tumble clothes dryer for home application]]
[[Image:Hairdryer 20101109.jpg|thumb|130px|A '''hair dryer''']]
{{en-navdêr}}
# [[mekîn]]a [[ziwakirin]]ê
==== Formên alternatîv ====
* {{g|en|drier}}
==== Etîmolojî ====
Ji {{paş|en|dry|-er}}.
==== Bêhtir bixwîne ====
{{wpedî|ziman=en}}
041kvl968wap3ycqwor4ydmlutczpls
6347597
6347596
2026-09-01T11:10:11Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347597
wikitext
text/x-wiki
== {{ziman|en}} ==
=== Bilêvkirin ===
* {{mj|DYA}} {{IPA|en|/ˈdɹaɪɚ/}}
* {{mj|KY}} {{IPA|en|/ˈdɹaɪə/}}
* {{deng|en|LL-Q1860 (eng)-Persent101-dryer.wav|Deng|dever=}}
=== Navdêr ===
[[Wêne:modern front load tumble dryer.JPG|thumb|150px|{{zim|en|A modern front-load tumble clothes dryer for home application}}]]
[[Image:Hairdryer 20101109.jpg|thumb|130px|{{zim|en|A '''hair dryer'''}}]]
{{en-navdêr}}
# [[makîna|mekîn]]a [[ziwakirin]]ê
==== Formên alternatîv ====
* {{g|en|drier}}
==== Etîmolojî ====
Ji {{paş|en|dry|-er}}.
==== Bêhtir bixwîne ====
{{wpedî|ziman=en}}
hjk634t0t2o2kfo26t7yt64w5klbvrp
6347598
6347597
2026-09-01T11:10:48Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347598
wikitext
text/x-wiki
== {{ziman|en}} ==
=== Bilêvkirin ===
* {{mj|DYA}} {{IPA|en|/ˈdɹaɪɚ/}}
* {{mj|KY}} {{IPA|en|/ˈdɹaɪə/}}
* {{deng|en|LL-Q1860 (eng)-Persent101-dryer.wav|Deng|dever=}}
=== Navdêr ===
[[Wêne:modern front load tumble dryer.JPG|thumb|150px|{{zim|en|A modern front-load tumble clothes dryer for home application}}]]
[[Image:Hairdryer 20101109.jpg|thumb|130px|{{zim|en|A '''hair dryer'''}}]]
{{en-navdêr}}
# [[makîne|makîneya]] [[ziwakirin]]ê
==== Formên alternatîv ====
* {{g|en|drier}}
==== Etîmolojî ====
Ji {{paş|en|dry|-er}}.
==== Bêhtir bixwîne ====
{{wpedî|ziman=en}}
py8y4nk4ngan6r9hmclrtjhuqcu7vzj
saccharimeter
0
276818
6347343
6347334
2026-08-31T12:12:07Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347343
wikitext
text/x-wiki
== {{ziman|en}} ==
=== Navdêr ===
{{navdêr|en}}
# [[halet]]a ku [[rêje]]ya [[şekir]] ya di [[nav|nêv]] [[têkelang]]ekî de [[dipîve]]
8zaalr63olbftau4l3u48nqaadwlxu7
sewgir
0
279474
6347555
6327480
2026-09-01T09:54:39Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347555
wikitext
text/x-wiki
{{ds|sewgur|sewgûr|sewgir|sewgor}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Rengdêr ===
{{rengdêr|ku}}
# [[temîn]], [[ekîd]], [[garantî]]kirî, [[bêguman]], [[eseh]], [[bivê-nevê]]
#: {{nm|ku|Ez '''sewgir''' im ku neteweyê kurd dê serkeftinê bidest bixe .|Kurd dê [[île]] bi ser bikevin.|rêz=1}}
# {{kontrol|rêz=erê|[[bêşik]], [[piştrast]], [[tekîdkirî]], [[diyar]], [[esehî]], [[dabîn]]}}
==== Formên alternatîv ====
{{kol3|ku
|misoger
}}
==== Jê ====
{{kol3|ku
|sewgirî
|sewgir bûn<crz:lêker>
|sewgir kirin<crz:lêker>
|sewgirandin<crz:navdêr><crz:m>
|sewgirîn<crz:navdêr><crz:m>
|sewgirane<crz:rengdêr>
|sewgirandî<crz:rengdêr>
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|sicher}}
* {{Z|zh}}: {{W+|zh|確定}}, {{W-|zh|确定|tr=quèdìng}}, {{W-|zh|当然|tr=dāngrán}}
* {{Z|ar}}: {{W-|ar|اكيد|tr=ekîd}}
* {{Z|fa}}: {{W+|fa|حتمی}}, {{W-|fa|تضمینی}}
* {{Z|fi}}: {{W+|fi|varma}}
* {{Z|fr}}: {{W+|fr|sûr}} {{n}}, {{W+|fr|sûre}} {{mê}}
* {{Z|gu}}: {{W-|gu|biztos}}
* {{Z|nl}}: {{W+|nl|zeker}}
* {{Z|en}}: {{W+|en|sure}}, {{W+|en|certain}}, {{W+|en|guaranteed}}, {{W+|en|secure}}, {{W+|en|surely}}
* {{Z|it}}: {{W+|it|sicuro}} {{n}}, {{W+|it|sicura}} {{mê}}, {{W+|it|certo}} {{n}}, {{W+|it|certa}} {{mê}}
* {{Z|ja}}: [[確か]]な (たしかな, tashika na)
* {{Z|ko}}: {{W-|ko|확실한|tr=hwaksilhan}}
* {{Z|pl}}: {{W+|pl|pewny}}, {{W+|pl|pewien}} {{n}}, {{W-|pl|pewna}} {{mê}}, {{W-|pl|pewne}} {{nt}}
* {{Z|pt}}: {{W+|pt|certo}}, {{W+|pt|seguro}}
* {{Z|ru}}: {{W-|ru|уверенный|tr=uvérennyj}}
* {{Z|es}}: {{W+|es|seguro}}
* {{Z|sv}}: {{W+|sv|säker}}
* {{Z|tr}}: {{W+|tr|radikal}}, {{W+|tr|kesin}}, {{W+|tr|kaçınılmaz}}, {{W+|tr|muhakkak}}
{{werger-bin}}
5j09l2om2s639jfzq4go5xh31in7td4
خرم
0
297495
6347368
5621861
2026-08-31T13:13:07Z
Wikihez
7344
/* Erebî */ heqê telîfê (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347368
wikitext
text/x-wiki
{{bnr-h|حرم|جرم|خرم|حزم|چرم}}
== {{ziman|fa}} ==
=== Bilêvkirin ===
: {{ku-tîp|xorm}}
=== Navdêr ===
{{navdêr|fa|tr=}}
# [[şînkatî]]
501od8g58mmsg9k7pc1xgjey03x9utx
xirecir
0
298434
6347454
6336910
2026-08-31T19:42:55Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347454
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{kîte|ku|xi|re|cir}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# {{f|ku|dengê siriştî}} [[bihevketin]], [[şer]], [[qerqeşe]], [[cedel]], [[gengeşe]], [[nîqaş]]
# [[teqereq]]
#* {{J:Mîran Janbar:Qolyeya Cecileê|r=66|jêgirtin=Piştî '''xirecira''' ku li hêwanê kiribû, Cécileê berê xwe dabû odeyê.}}
#* {{J:Robert Louis Stevenson:Meseleya Seyr a Dr. Jekyll û Mr. Hyde|r=50|jêgirtin=...çaxa gihiştin kolaneke li wê nêzîkê, yeke ku roja yekşemê jî hîne '''xirecira''' jiyanê lê hebû}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|xirecir kirin<crz:lêker>
|bixirecir<crz:rengdêr>
}}
==== Bi alfabeyên din ====
* {{ku-ar|خرەجر}}
==== Formên alternatîv ====
{{kol3|ku
|xirexir
|qirecir
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Durcheinander|m}}, {{W+|de|Geräusch|m}}, {{W+|de|Getöse|m}}, {{W+|de|Rabatz|m}}, {{W+|de|Rummel|m}}, {{W+|de|Tumult}}, {{W+|de|Unruhe|f}}, {{W+|de|Zank|m}}, {{W+|de|Störung|f}}
* {{Z|ar}}: {{W+|ar|اضطراب}}, {{W-|ar|مشاجرة}}, {{W-|ar|مخانقة}}, {{W-|ar|خشخشة}}
* {{Z|fa}}: {{W+|fa|مشاجره}}, {{W+|fa|دعوا}}, {{W+|fa|جروبحث}}
* {{Z|en}}: {{W+|en|clamor}}, {{W+|en|disorder}}, {{W+|en|disturbance}}, {{W+|en|jangle}}, {{W+|en|racket}}, {{W+|en|ruffle}}, {{W+|en|uproariousness}}, {{W+|en|bluster|guman=erê}}, {{W+|en|roughhouse|guman=erê}}, {{W+|en|bedlam|guman=erê}}
* {{Z|tr}}: {{W+|tr|arbede}}, {{W+|tr|gürültü}}, {{W+|tr|haraza}}, {{W+|tr|hengame}}, {{W+|tr|hırgür}}, {{W+|tr|hırıltı}}, {{W+|tr|kavara}}, {{W+|tr|konser}}, {{W+|tr|patırtı}}, {{W+|tr|takatuka}}, {{W+|tr|zırıltı}}, {{W+|tr|dağdağa}}, {{W+|tr|şamata|guman=erê}}, {{W+|tr|har gür|guman=erê}}
{{werger-bin}}
plmsqgs1przg0a82ni7p7xd4lvg4mkt
6347467
6347454
2026-08-31T20:41:14Z
Balyozbot
7867
[[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan
6347467
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{kîte|ku|xi|re|cir}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# {{f|ku|dengê siriştî}} [[bihevketin]], [[şer]], [[qerqeşe]], [[cedel]], [[gengeşe]], [[nîqaş]]
# [[teqereq]]
#* {{J:Mîran Janbar:Qolyeya Cecileê|r=66|jêgirtin=Piştî '''xirecira''' ku li hêwanê kiribû, Cécileê berê xwe dabû odeyê.}}
#* {{J:Robert Louis Stevenson:Meseleya Seyr a Dr. Jekyll û Mr. Hyde|r=50|jêgirtin=...çaxa gihiştin kolaneke li wê nêzîkê, yeke ku roja yekşemê jî hîne '''xirecira''' jiyanê lê hebû}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Bi alfabeyên din ====
* {{ku-ar|خرەجر}}
==== Formên alternatîv ====
{{kol3|ku
|xirexir
|qirecir
}}
==== Jê ====
{{kol3|ku
|xirecir kirin<crz:lêker>
|bixirecir<crz:rengdêr>
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Durcheinander|m}}, {{W+|de|Geräusch|m}}, {{W+|de|Getöse|m}}, {{W+|de|Rabatz|m}}, {{W+|de|Rummel|m}}, {{W+|de|Tumult}}, {{W+|de|Unruhe|f}}, {{W+|de|Zank|m}}, {{W+|de|Störung|f}}
* {{Z|ar}}: {{W+|ar|اضطراب}}, {{W-|ar|مشاجرة}}, {{W-|ar|مخانقة}}, {{W-|ar|خشخشة}}
* {{Z|fa}}: {{W+|fa|مشاجره}}, {{W+|fa|دعوا}}, {{W+|fa|جروبحث}}
* {{Z|en}}: {{W+|en|clamor}}, {{W+|en|disorder}}, {{W+|en|disturbance}}, {{W+|en|jangle}}, {{W+|en|racket}}, {{W+|en|ruffle}}, {{W+|en|uproariousness}}, {{W+|en|bluster|guman=erê}}, {{W+|en|roughhouse|guman=erê}}, {{W+|en|bedlam|guman=erê}}
* {{Z|tr}}: {{W+|tr|arbede}}, {{W+|tr|gürültü}}, {{W+|tr|haraza}}, {{W+|tr|hengame}}, {{W+|tr|hırgür}}, {{W+|tr|hırıltı}}, {{W+|tr|kavara}}, {{W+|tr|konser}}, {{W+|tr|patırtı}}, {{W+|tr|takatuka}}, {{W+|tr|zırıltı}}, {{W+|tr|dağdağa}}, {{W+|tr|şamata|guman=erê}}, {{W+|tr|har gür|guman=erê}}
{{werger-bin}}
sg2pcc7evp9p7evip24k4wb3lc8wu6f
dilşewatkirî
0
305117
6347354
6146291
2026-08-31T12:49:57Z
Wikihez
7344
/* Çavkanî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347354
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Rengdêr ===
{{rengdêr|ku}}
# ya / yê ku hatiye [[dilşewat kirin]]
==== Etîmolojî ====
Ji {{qertaf|ku|dilşewat|kirî}}.
==== Werger ====
{{werger-ser}}
* {{Z|en}}: {{W+|en|afflicted}}
{{werger-bin}}
jm2xc6smi0hiuj6mra6bmmpkiueohmv
recycle
0
315145
6347383
6028317
2026-08-31T14:43:20Z
Joseph Hemê
2610
/* Lêker */
6347383
wikitext
text/x-wiki
== {{ziman|en}} ==
=== Lêker ===
{{lêker|en}}
# [[cardin]] [[bikaranîn]], [[rîsaykil kirin]], [[veçerxandin]], [[veçerxîn]]<ref>Ferhenga Îngilîzî-Kurdî, Musa Altun</ref> <br> (madeyên bikarhatî) [[ji nû ve]] [[kar pê kirin]] û ji bo bikaranînê [[berdest kirin]]
==== Çavkanî ====
{{çavkanî}}
80gyfm1dr8ojhyeaw2dkbzrnduz02ya
revolving light
0
315910
6347416
5855853
2026-08-31T17:21:42Z
Wikihez
7344
Cureyê rêzimanî hate diyarkirin: Navdêr (DefSideBoxes)
6347416
wikitext
text/x-wiki
== {{ziman|en}} ==
=== Navdêr ===
{{navdêr|en}}
# fenera fetlok
lqom69j7ohithsyowl8849qajz861yy
6347417
6347416
2026-08-31T17:21:51Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes)
6347417
wikitext
text/x-wiki
== {{ziman|en}} ==
=== Navdêr ===
{{navdêr|en}}
# [[fener|fenera]] [[fetlok|fetlok]]
rgw40tdfx5ocmdvpol7tv6x7yszd0dq
6347440
6347417
2026-08-31T19:12:07Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347440
wikitext
text/x-wiki
== {{ziman|en}} ==
=== Navdêr ===
{{navdêr|en}}
# [[fener]]a [[fetlok]]
4anvbgu6ektm8wk4it2d7ff7kle4buw
mexles
0
322805
6347560
6312133
2026-09-01T10:03:45Z
~2026-47359-08
15314
Werger: +fînî : [[lempinimi]] (bi alîkarî)
6347560
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|c=m}}
# [[penageh]], [[sitare]]
# [[bernav]], [[nav]]ê [[nepenî]]
#* {{jêder|ku|jêgirtin=Wek gelek nivîskar û şairên wê demê Fuzûlî jî navê '''mahlas''' bi kar anîye. Navê wî yê eslî Mehmed e û navê bavê wî jî Silêman e.|Seîd Veroj, Nefel.com 5/2014}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Formên alternatîv ====
* {{g|ku|mahlas}} {{i|di bin tesîra tirkî de}}
* {{hw|ku|mehles}}
==== Etîmolojî ====
Ji {{ji|ar|ku|مَخْلَص}} binêre {{qf|ku|me-|xilas}}.
==== Werger ====
{{werger-ser|penageh, sitare|1}}
{{werger-bin}}
{{werger-ser|navê nepenî|2}}
* {{Z|fi}}: {{W+|fi|lempinimi}}
* {{Z|tr}}: {{W|tr|mahlas}}
{{werger-bin}}
ihdvvnmmytye7ly5j5hwvdmmi5m9ajo
nepakî
0
323518
6347544
6313195
2026-09-01T09:47:22Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347544
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# Rewşa [[nepak]]bûnê.
# {{kontrol|rêz=erê|[[neçêtî]], [[netûyî]], [[fenatî]], [[bedîtî]], [[qirêj]], [[pîsî]], [[gemar]]}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|nepakî kirin<crz:lêker>
|nepakîkirin<crz:navdêr>
}}
==== Etîmolojî ====
Ji {{paş|ku|nepak|-î}}.
==== Werger ====
{{kontrolWergerr}}
{{werger-ser}}
* {{Z|ar}}: {{W-|ar|نجاسة}}, {{W-|ar|خبث}}, {{W+|ar|شر}}
* {{Z|en}}: {{W+|en|impurity}}, {{W+|en|evil}},{{W+|en|godlessness}},{{W+|en|viciousness}}, {{W+|en|improbity|guman=erê}}, {{W+|en|perfidiousness|guman=erê}}
* {{Z|tr}}: {{W+|tr|fenalık}}, {{W+|tr|fesat|guman=erê}}
{{werger-bin}}
2cvjvvl2jhaij0ob70n1mxr8c106zmg
sextî
0
323589
6347547
6317661
2026-09-01T09:48:15Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347547
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# rewşa [[sext]]bûnê
#* {{jêder-pirtûk|ku|jêgirtin=Pêlavên '''sextiyan''' hatin hildan.|nivîskar=Eyüp Kiran| sernav=Dewrêşê Evdî Kulîlka Bilbizêk û Rim|cîh=Stenbol|weşanxane={{w|Nûbihar}}|sal=2018|çap=4|rûpel=31|isbn=978-9944-360-95-1}}
# {{kontrol|rêz=erê|[[tundî]], [[hişkahî]], [[raqî]], [[sirtî]], [[zîwanî]], [[tenikî]], [[reqîtî]], [[notî]], [[tûjî]], [[çorsî]], [[çêkirî]]}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|sextî kirin<crz:lêker>
|sextîkirin<crz:navdêr>
}}
==== Bi alfabeyên din ====
* {{ku-ar|سهختی}}
==== Etîmolojî ====
Ji {{paş|ku|sext|-î}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|unecht}}
* {{Z|ar}}: {{W-|ar|التكلفة|guman=erê}}, {{W-|ar|الزیف|guman=erê}}, {{W-|ar|الصعوبة|guman=erê}}, {{W-|ar|الكره|guman=erê}}, {{W-|ar|الوعورة|guman=erê}}, {{W-|ar|مشقة|guman=erê}}
* {{Z|en}}: {{W+|en|awkwardness|guman=erê}}, {{W+|en|abstrusity|guman=erê}}, {{W+|en|inaccessibility|guman=erê}}, {{W+|en|inexpugnableness|guman=erê}}, {{W+|en|ruggedness|guman=erê}}, {{W+|en|severity|guman=erê}}
* {{Z|tr}}: {{W+|tr|katılık}}, {{W+|tr|sertlik}}
{{werger-bin}}
se1t571jm0vpkkpj8cluqopouetyeji
6347585
6347547
2026-09-01T10:41:14Z
Balyozbot
7867
[[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan
6347585
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# rewşa [[sext]]bûnê
#* {{jêder-pirtûk|ku|jêgirtin=Pêlavên '''sextiyan''' hatin hildan.|nivîskar=Eyüp Kiran| sernav=Dewrêşê Evdî Kulîlka Bilbizêk û Rim|cîh=Stenbol|weşanxane={{w|Nûbihar}}|sal=2018|çap=4|rûpel=31|isbn=978-9944-360-95-1}}
# {{kontrol|rêz=erê|[[tundî]], [[hişkahî]], [[raqî]], [[sirtî]], [[zîwanî]], [[tenikî]], [[reqîtî]], [[notî]], [[tûjî]], [[çorsî]], [[çêkirî]]}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Bi alfabeyên din ====
* {{ku-ar|سهختی}}
==== Jê ====
{{kol3|ku
|sextî kirin<crz:lêker>
|sextîkirin<crz:navdêr>
}}
==== Etîmolojî ====
Ji {{paş|ku|sext|-î}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|unecht}}
* {{Z|ar}}: {{W-|ar|التكلفة|guman=erê}}, {{W-|ar|الزیف|guman=erê}}, {{W-|ar|الصعوبة|guman=erê}}, {{W-|ar|الكره|guman=erê}}, {{W-|ar|الوعورة|guman=erê}}, {{W-|ar|مشقة|guman=erê}}
* {{Z|en}}: {{W+|en|awkwardness|guman=erê}}, {{W+|en|abstrusity|guman=erê}}, {{W+|en|inaccessibility|guman=erê}}, {{W+|en|inexpugnableness|guman=erê}}, {{W+|en|ruggedness|guman=erê}}, {{W+|en|severity|guman=erê}}
* {{Z|tr}}: {{W+|tr|katılık}}, {{W+|tr|sertlik}}
{{werger-bin}}
0to2n0ohg4210c970t4471ezyzc1r20
wehşîtî
0
323636
6347546
6319962
2026-09-01T09:48:05Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347546
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# rewşa [[wehşî]]bûnê
# {{kontrol|rêz=erê|[[hovîtî]], [[xinzîrî]], [[beraztî]]}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|wehşîtî kirin<crz:lêker>
|wehşîtîkirin<crz:navdêr>
}}
==== Etîmolojî ====
Ji {{qertaf|ku|wehşî|-î}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Bestialität|f|guman=erê}}, {{W+|de|Barbarei|f|guman=erê}}
* {{Z|en}}: {{W+|en|barbarism}}, {{W+|en|bestiality}}, {{W+|en|ferocity|guman=erê}}
* {{Z|tr}}: {{W+|tr|domuzluk}}, {{W+|tr|hınzırlık}}, {{W+|tr|vahşilik}}, {{W+|tr|yamyamlık}}
{{werger-bin}}
0kaisgxh1eq5t3zoy9iwiba8fgb3w8i
zanatî
0
323666
6347543
6321059
2026-09-01T09:46:31Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347543
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# rewşa [[zana]]bûnê
# {{kontrol|rêz=erê|[[ferzanetî]], [[zanyarî]], [[alimî]], [[hîn]], [[fêr]], [[biaqilî]], [[bîrbirî]], [[arifî]]}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|zanatî kirin<crz:lêker>
|zanatîkirin<crz:navdêr>
}}
==== Etîmolojî ====
Ji {{qertaf|ku|zana|-î}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W-|de|Altklugheit|f|guman=erê}}, {{W+|de|Gelehrsamkeit|f|guman=erê}}
* {{Z|fa}}: {{W+|fa|فطنت}}
* {{Z|en}}: {{W+|en|sagaciousness}}, {{W+|en|knowledgeability|guman=erê}}
* {{Z|tr}}: {{W+|tr|bilgelik}}, {{W+|tr|hikmet}}, {{W+|tr|allâmelik}}, {{W+|tr|bilecenlik}}, {{W+|tr|bilgiçlik}}, {{W+|tr|bilginlik}}, {{W+|tr|uyanıklık}}
{{werger-bin}}
hponvo3c8fsh758e7601k6mfma0dvyg
paçvevanî
0
326949
6347552
6314111
2026-09-01T09:51:35Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347552
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# karê [[paçvevan]]an
# {{kontrol|rêz=erê|[[wergêrî]], [[paçvanî]], [[dilbendî]]}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|paçvevanî kirin<crz:lêker>
|paçvevanîkirin<crz:navdêr>
}}
==== Etîmolojî ====
Ji {{paş|ku|paçvevan|-î}}.
==== Werger ====
{{werger-ser}}
* {{Z|tr}}: {{W+|tr|dilmaçlık}}, {{W+|tr|tercümanlık}}, {{W+|tr|mütercimlik|guman=erê}}, {{W+|tr|çeviricilik|guman=erê}}
{{werger-bin}}
3eo2cvrd7z1a2vft2rexgj4ne814xmp
biehliyet
0
336947
6347401
6159473
2026-08-31T16:38:24Z
Wikihez
7344
6347401
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Rengdêr ===
{{rengdêr|ku}}
# # {{mane?|ku}}
==== Etîmolojî ====
Ji {{qertaf|ku|bi-|ehliyet}}.
==== Jê ====
* [[biehliyetî]]
* [[biehliyetîtî]]
* [[biehliyettî]]
==== Werger ====
{{werger-ser}}
* {{Z|tr}}: {{W+|tr|ehliyetli}}, {{W+|tr|yeterli}}
{{werger-bin}}
5hiwg1ozk1w2skfkl0q4tlqz8pgqfy4
6347402
6347401
2026-08-31T16:38:31Z
Wikihez
7344
/* Rengdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347402
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Rengdêr ===
{{rengdêr|ku}}
# {{mane?|ku}}
==== Etîmolojî ====
Ji {{qertaf|ku|bi-|ehliyet}}.
==== Jê ====
* [[biehliyetî]]
* [[biehliyetîtî]]
* [[biehliyettî]]
==== Werger ====
{{werger-ser}}
* {{Z|tr}}: {{W+|tr|ehliyetli}}, {{W+|tr|yeterli}}
{{werger-bin}}
1c2bsgnmf9r4n9yh3zzx1l1bz26kph4
6347403
6347402
2026-08-31T16:41:13Z
Balyozbot
7867
[[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan
6347403
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Rengdêr ===
{{rengdêr|ku}}
# {{mane?|ku}}
==== Jê ====
* [[biehliyetî]]
* [[biehliyetîtî]]
* [[biehliyettî]]
==== Etîmolojî ====
Ji {{qertaf|ku|bi-|ehliyet}}.
==== Werger ====
{{werger-ser}}
* {{Z|tr}}: {{W+|tr|ehliyetli}}, {{W+|tr|yeterli}}
{{werger-bin}}
f3fxpqat6v3ikshmyttn65s8d3bqqpe
6347406
6347403
2026-08-31T16:41:35Z
Wikihez
7344
[[Bikarhêner:Wikihez/skrîpt/js/şablon-lêke.js|T]]: +{{bêçavkanî}}
6347406
wikitext
text/x-wiki
{{bêçavkanî}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Rengdêr ===
{{rengdêr|ku}}
# {{mane?|ku}}
==== Jê ====
* [[biehliyetî]]
* [[biehliyetîtî]]
* [[biehliyettî]]
==== Etîmolojî ====
Ji {{qertaf|ku|bi-|ehliyet}}.
==== Werger ====
{{werger-ser}}
* {{Z|tr}}: {{W+|tr|ehliyetli}}, {{W+|tr|yeterli}}
{{werger-bin}}
g2gngvclgf8xbo836pwd7rdcjjgqrql
ehliyetdar
0
336948
6347400
6159474
2026-08-31T16:38:15Z
Wikihez
7344
6347400
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Rengdêr ===
{{rengdêr|ku}}
# {{mane?|ku}}
==== Etîmolojî ====
Ji {{qertaf|ku|ehliyet|-dar}}.
==== Jê ====
* [[ehliyetdarî]]
* [[ehliyetdarîtî]]
* [[ehliyetdartî]]
==== Werger ====
{{werger-ser}}
* {{Z|tr}}: {{W+|tr|ehliyetli}}
{{werger-bin}}
65k5alfu7qhz8agp7ked2umrj4zfz47
6347404
6347400
2026-08-31T16:41:16Z
Balyozbot
7867
[[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan
6347404
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Rengdêr ===
{{rengdêr|ku}}
# {{mane?|ku}}
==== Jê ====
* [[ehliyetdarî]]
* [[ehliyetdarîtî]]
* [[ehliyetdartî]]
==== Etîmolojî ====
Ji {{qertaf|ku|ehliyet|-dar}}.
==== Werger ====
{{werger-ser}}
* {{Z|tr}}: {{W+|tr|ehliyetli}}
{{werger-bin}}
gsyeheh49k7qguxmjp17jhnq6npap8y
xeberdan
0
341798
6347631
6336867
2026-09-01T11:46:44Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347631
wikitext
text/x-wiki
{{bnr-l|xeber dan}}
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[çêr]], [[suhbet]], [[axiftin]], [[qese]], [[gotin]], [[peyv]], [[peyivîn]], [[axivîn]]
* {{J:Mem û Zîn:1692|jêgirtin=Sihdan nediket ji wî li 'erdan</br>Vêk ra dibihîst sed '''xeberdan'''</br>Goyende dibûn digel cemadat}}
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|xeberdan kirin<crz:lêker>
|xeberdankirin<crz:navdêr>
}}
==== Etîmolojî ====
Ji {{pêk|ku|xeber|dan}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Gespräch|m}}, {{W+|de|Meldung|f}}
* {{Z|fa}}: {{W+|fa|بحث}}, {{W+|fa|حرف زدن}}
* {{Z|en}}: {{W+|en|annunciation}}, {{W+|en|report}}
* {{Z|tr}}: {{W+|tr|konuşma}}, {{W+|tr|laf}}, {{W+|tr|nutuk}}
{{werger-bin}}
fmfment2b0xnrbqbujfhxqsi56xmcpz
giyamêş
0
342419
6347607
6281767
2026-09-01T11:16:52Z
Wikihez
7344
/* Werger */ xelet (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347607
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[guldawidî]], [[dawûdek]], [[gulmêş]], [[giyadawidî]], [[dawidî]], [[zêrrgul]], [[zêrgul]], [[krîsantem]]
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|tr}}: {{W+|tr|kasım patı}}
{{werger-bin}}
ez5t1tm2916m2kmk94nhr7yu9l2rq7q
kulik
0
343399
6347496
6163666
2026-08-31T21:24:04Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes); guhartina pêşketî (DefSideBoxes); guhartina pêşketî (DefSideBoxes)
6347496
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[pirsik|Pirsik]]eka ku [[hecim]]ê wê mezin be.
#: {{hevmane|ku|peqik|vilik}}
#: '''''Kulikên''' pîsatiyê li hevalê min hatbûn. ''
# [[bi taybetî|Bi taybetî]] [[şeweyekî|şeweyekî]] [[endezyarî|endezyariyê]]
# [[cih|Cihê]] ku [[nan|nan]] û [[şîv|şîv]] lê [[tê çêkirin]].
#: {{hevmane|ku|metbex}}
==== Bi alfabeyên din ====
* {{ku-ar|کولک}}
==== Pend ====
* [[kulka qunêye ne dêr dibît û ne zer dibît]]
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|Häubchen|m}}, {{W|de|Haube|f}}, {{W|de|Kalotte|f}}, {{W|de|Kappe|f}}, {{W|de|Kopfbedeckung|f}}, {{W|de|Mütze|f}}, {{W|de|Baskenmütze|f|guman=erê}}
* {{Z|ar}}: {{W|ar|بثرة}}, {{W|ar|مطبخ}}, {{W|ar|مخروط}}
* {{Z|fa}}: {{W+|fa|سرپوش}}, {{W+|fa|کلاه}}, {{W+|fa|کلاهک}}
* {{Z|en}}: {{W+|en|sore}}, {{W+|en|barret}}, {{W+|en|beret}}, {{W+|en|blisters}}, {{W+|en|bonnet|guman=erê}}, {{W+|en|inflammation|guman=erê}}
* {{Z|tr}}: {{W+|tr|kukuleta}}, {{W+|tr|külah}}, {{W+|tr|küllük}}, {{W+|tr|tuğ}}, {{W+|tr|sorguç}}
{{werger-bin}}
qo73enb2scx8fhgvx7mph1tq717unng
6347497
6347496
2026-08-31T21:24:36Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347497
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[pirsik|Pirsik]]eka ku [[hecim]]ê wê mezin be.
#: {{hevmane|ku|peqik|vilik}}
#: '''''Kulikên''' pîsatiyê li hevalê min hatbûn. ''
# [[bi taybetî|Bi taybetî]] [[şêwe|şêweyekî]] [[endezyarî|endezyariyê]]
# [[cih|Cihê]] ku [[nan|nan]] û [[şîv|şîv]] lê [[tê çêkirin]].
#: {{hevmane|ku|metbex}}
==== Bi alfabeyên din ====
* {{ku-ar|کولک}}
==== Pend ====
* [[kulka qunêye ne dêr dibît û ne zer dibît]]
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|Häubchen|m}}, {{W|de|Haube|f}}, {{W|de|Kalotte|f}}, {{W|de|Kappe|f}}, {{W|de|Kopfbedeckung|f}}, {{W|de|Mütze|f}}, {{W|de|Baskenmütze|f|guman=erê}}
* {{Z|ar}}: {{W|ar|بثرة}}, {{W|ar|مطبخ}}, {{W|ar|مخروط}}
* {{Z|fa}}: {{W+|fa|سرپوش}}, {{W+|fa|کلاه}}, {{W+|fa|کلاهک}}
* {{Z|en}}: {{W+|en|sore}}, {{W+|en|barret}}, {{W+|en|beret}}, {{W+|en|blisters}}, {{W+|en|bonnet|guman=erê}}, {{W+|en|inflammation|guman=erê}}
* {{Z|tr}}: {{W+|tr|kukuleta}}, {{W+|tr|külah}}, {{W+|tr|küllük}}, {{W+|tr|tuğ}}, {{W+|tr|sorguç}}
{{werger-bin}}
c1c7ygxyhgsubl9zjp4dsz5pablcsft
6347498
6347497
2026-08-31T21:25:03Z
Wikihez
7344
+Etîmolojî (DefSideBoxes)
6347498
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[pirsik|Pirsik]]eka ku [[hecim]]ê wê mezin be.
#: {{hevmane|ku|peqik|vilik}}
#: '''''Kulikên''' pîsatiyê li hevalê min hatbûn. ''
# [[bi taybetî|Bi taybetî]] [[şêwe|şêweyekî]] [[endezyarî|endezyariyê]]
# [[cih|Cihê]] ku [[nan|nan]] û [[şîv|şîv]] lê [[tê çêkirin]].
#: {{hevmane|ku|metbex}}
==== Bi alfabeyên din ====
* {{ku-ar|کولک}}
==== Pend ====
* [[kulka qunêye ne dêr dibît û ne zer dibît]]
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|Häubchen|m}}, {{W|de|Haube|f}}, {{W|de|Kalotte|f}}, {{W|de|Kappe|f}}, {{W|de|Kopfbedeckung|f}}, {{W|de|Mütze|f}}, {{W|de|Baskenmütze|f|guman=erê}}
* {{Z|ar}}: {{W|ar|بثرة}}, {{W|ar|مطبخ}}, {{W|ar|مخروط}}
* {{Z|fa}}: {{W+|fa|سرپوش}}, {{W+|fa|کلاه}}, {{W+|fa|کلاهک}}
* {{Z|en}}: {{W+|en|sore}}, {{W+|en|barret}}, {{W+|en|beret}}, {{W+|en|blisters}}, {{W+|en|bonnet|guman=erê}}, {{W+|en|inflammation|guman=erê}}
* {{Z|tr}}: {{W+|tr|kukuleta}}, {{W+|tr|külah}}, {{W+|tr|küllük}}, {{W+|tr|tuğ}}, {{W+|tr|sorguç}}
{{werger-bin}}
==== Etîmolojî ====
{{ji?|ku}}
222148jk3xu74mqa2pfol4aj5q05iko
6347500
6347498
2026-08-31T21:41:06Z
Balyozbot
7867
[[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan
6347500
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[pirsik|Pirsik]]eka ku [[hecim]]ê wê mezin be.
#: {{hevmane|ku|peqik|vilik}}
#: '''''Kulikên''' pîsatiyê li hevalê min hatbûn. ''
# [[bi taybetî|Bi taybetî]] [[şêwe|şêweyekî]] [[endezyarî|endezyariyê]]
# [[cih|Cihê]] ku [[nan|nan]] û [[şîv|şîv]] lê [[tê çêkirin]].
#: {{hevmane|ku|metbex}}
==== Bi alfabeyên din ====
* {{ku-ar|کولک}}
==== Etîmolojî ====
{{ji?|ku}}
==== Pend ====
* [[kulka qunêye ne dêr dibît û ne zer dibît]]
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|Häubchen|m}}, {{W|de|Haube|f}}, {{W|de|Kalotte|f}}, {{W|de|Kappe|f}}, {{W|de|Kopfbedeckung|f}}, {{W|de|Mütze|f}}, {{W|de|Baskenmütze|f|guman=erê}}
* {{Z|ar}}: {{W|ar|بثرة}}, {{W|ar|مطبخ}}, {{W|ar|مخروط}}
* {{Z|fa}}: {{W+|fa|سرپوش}}, {{W+|fa|کلاه}}, {{W+|fa|کلاهک}}
* {{Z|en}}: {{W+|en|sore}}, {{W+|en|barret}}, {{W+|en|beret}}, {{W+|en|blisters}}, {{W+|en|bonnet|guman=erê}}, {{W+|en|inflammation|guman=erê}}
* {{Z|tr}}: {{W+|tr|kukuleta}}, {{W+|tr|külah}}, {{W+|tr|küllük}}, {{W+|tr|tuğ}}, {{W+|tr|sorguç}}
{{werger-bin}}
8hvcfllapw6bqmfx5ymyhe3etskqv4x
6347505
6347500
2026-08-31T23:12:09Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347505
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[pirsik|Pirsikeka]] ku [[hecim]]ê wê mezin be.
#: {{hevmane|ku|peqik|vilik}}
#: '''''Kulikên''' pîsatiyê li hevalê min hatbûn. ''
# [[bi taybetî|Bi taybetî]] [[şêwe]]yekî [[endezyarî|endezyariyê]]
# [[cih|Cihê]] ku [[nan]] û [[şîv]] lê [[tê çêkirin]].
#: {{hevmane|ku|metbex}}
==== Bi alfabeyên din ====
* {{ku-ar|کولک}}
==== Etîmolojî ====
{{ji?|ku}}
==== Pend ====
* [[kulka qunêye ne dêr dibît û ne zer dibît]]
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|Häubchen|m}}, {{W|de|Haube|f}}, {{W|de|Kalotte|f}}, {{W|de|Kappe|f}}, {{W|de|Kopfbedeckung|f}}, {{W|de|Mütze|f}}, {{W|de|Baskenmütze|f|guman=erê}}
* {{Z|ar}}: {{W|ar|بثرة}}, {{W|ar|مطبخ}}, {{W|ar|مخروط}}
* {{Z|fa}}: {{W+|fa|سرپوش}}, {{W+|fa|کلاه}}, {{W+|fa|کلاهک}}
* {{Z|en}}: {{W+|en|sore}}, {{W+|en|barret}}, {{W+|en|beret}}, {{W+|en|blisters}}, {{W+|en|bonnet|guman=erê}}, {{W+|en|inflammation|guman=erê}}
* {{Z|tr}}: {{W+|tr|kukuleta}}, {{W+|tr|külah}}, {{W+|tr|küllük}}, {{W+|tr|tuğ}}, {{W+|tr|sorguç}}
{{werger-bin}}
jbf8w3v9luljxr5gbarr32kpng740ks
varrêbûn
0
344130
6347554
6319672
2026-09-01T09:53:08Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347554
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[vederî]], [[vederbûn]], [[tecrîd]], [[îzolasyon]]
# {{f|ku|mecazî}} [[xirab bûn]], [[dîr bûn]], ji [[rêk]]ê [[derkeftin]]
==== Tewandin ====
{{ku-tewîn-nav|mê}}
==== Jê ====
{{kol3|ku
|varê bûn<crz:lêker>
|varê kirin<crz:lêker>
|varêbûn<crz:navdêr>
|varêkirin<crz:navdêr>
|varêbûyî<crz:rengdêr>
|varêkirî<crz:rengdêr>
}}
==== Etîmolojî ====
Ji {{qertaf|ku|varê|bûn}}.
==== Werger ====
{{werger-ser}}
* {{Z|en}}: to {{W+|en|turn away}}, (metaphorically) {{W+|en|corrupt}}
{{werger-bin}}
fwhv35o4u5cw4vlk623qf6ujy3zflo6
kemêl
0
362069
6347390
6309882
2026-08-31T15:23:41Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347390
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# rîxa/rêxa bi hiriya pez ve dimîne û hişk dibe
#* {{J:Sadiq Ûskan:Şampaz|jêgirtin={{...}} di berdêla malê min da, kulavên kevn û cilikên hirî û '''kemêlên''' mîhan didan min.}}
==== Tewandin ====
{{ku-tewîn-nav/nû|mê}}
==== Formên alternatîv ====
* [[kemmêl]]
==== Têkildar ====
* [[kerme]]
* [[kuşkûr]]
* [[keşkûr]]
* [[tezeg]]
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
{{werger-bin}}
shwn2xnor6odyy0talsyldizwrprpg6
doğruya doğru
0
363407
6347362
5803282
2026-08-31T13:00:55Z
Wikihez
7344
Cureyê rêzimanî hate diyarkirin: Hoker (DefSideBoxes)
6347362
wikitext
text/x-wiki
== {{ziman|tr}} ==
=== Hoker ===
# raste rast
py2p7fdderh2ouv99i4waa640pl5pb5
6347363
6347362
2026-08-31T13:01:12Z
Wikihez
7344
/* Hoker */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347363
wikitext
text/x-wiki
== {{ziman|tr}} ==
=== Hoker ===
{{hoker|tr}}
# [[rasterast]]
mw9skoyyaej91dpbju9f5wp7klm410s
6347364
6347363
2026-08-31T13:01:43Z
Wikihez
7344
/* Hoker */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347364
wikitext
text/x-wiki
== {{ziman|tr}} ==
=== Hoker ===
{{hoker|tr}}
# [[raste]] [[rast]]
9w18hfk4jdjkcd5ujwbliyvlloj9o24
pêşgirî
0
379615
6347358
6169209
2026-08-31T12:56:29Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes)
6347358
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[bergirî]], [[tedbîr]]
# {{f|ku|rêzimanî}} [[rewş|Rewşa]] [[pêşgirbûn|pêşgirbûnê]].
==== Etîmolojî ====
Ji {{paş|ku|pêş|-girî}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Umsicht}}, {{W+|de|Vorsichtsmaßnahme|f|guman=erê}}
* {{Z|fa}}: {{W+|fa|پیشگیری}}, {{W+|fa|جلوگیری}}
* {{Z|en}}: {{W+|en|prepositive|guman=erê}}, {{W+|en|prefixion|guman=erê}}
* {{Z|tr}}: {{W+|tr|önlem}}, {{W+|tr|tedbir}}
{{werger-bin}}
i899m1hluyzlssjyr098e7uirw6c26f
6347359
6347358
2026-08-31T12:56:53Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347359
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[bergirî]], [[tedbîr]]
# {{f|ku|rêzimanî}} [[rewş|Rewşa]] [[pêşgir]]bûnê.
==== Etîmolojî ====
Ji {{paş|ku|pêş|-girî}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W+|de|Umsicht}}, {{W+|de|Vorsichtsmaßnahme|f|guman=erê}}
* {{Z|fa}}: {{W+|fa|پیشگیری}}, {{W+|fa|جلوگیری}}
* {{Z|en}}: {{W+|en|prepositive|guman=erê}}, {{W+|en|prefixion|guman=erê}}
* {{Z|tr}}: {{W+|tr|önlem}}, {{W+|tr|tedbir}}
{{werger-bin}}
ai9s0qx3ga9ub473agu1u6na18lq81g
şilokî
0
384319
6347588
6171393
2026-09-01T10:50:10Z
Wikihez
7344
~Etîmolojî (DefSideBoxes)
6347588
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[şilok]]
==== Etîmolojî ====
Ji {{paş|ku|şilok|-î}}.
==== Werger ====
{{werger-ser}}
* {{Z|tr}}: {{W-|tr|suluca}}
{{werger-bin}}
s5wsg2oejisl1tpn4entbykzalwrg4l
tiştek
0
424463
6347624
6249757
2026-09-01T11:39:17Z
Wikihez
7344
6347624
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bi alfabeyên din ===
* {{ku-ar|تشتهک}}
=== Formên alternatîv ===
* [[tiştik]]
* [[tişk]]
=== Etîmolojî ===
Ji {{qertaf|ku|tişt|-ek}}.
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Cînav ===
{{cînav|ku|z=mn}}
# {{înm|Wek [[cînav]]ekî li [[cih]]ê [[peyv]]eke din ya [[negotî]]/[[diyar kirin|diyarnekirî]] tê bikaranîn.}}
#: {{nm|ku|Divê em tiştekî bikin.}}
#: {{nm|ku|Xwendin tiştekî baş e.}}
==== Têkildar ====
*[[çi tişt]]
*[[her tişt]]
*[[ti tişt]]
*[[hin tişt]]
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W+|af|iets}}
* {{Z|gmw-ecg}}: {{W-|gmw-ecg|was}}, {{W-|gmw-ecg|aawoss}}
* {{Z|de}}: {{W+|de|etwas}}
*: {{Z|gsw}}: {{W-|gsw|öppis}}, {{W-|gsw|ebbes}}, {{W-|gsw|ebbis}}, {{W-|gsw|öbbis}}
* {{Z|ast}}: {{W+|ast|daqué}}
* {{Z|az}}: {{W+|az|nəsə}}, {{W+|az|nə isə}}
* {{Z|bar}}: {{W-|bar|eps}}
* {{Z|be}}: {{W-|be|што́сьці}}, {{W-|be|штось|sc=Cyrl}}, {{W-|be|не́шта|sc=Cyrl}}
* {{Z|bn}}: {{W+|bn|কিছু একটা|sc=Beng}}
* {{Z|bg}}: {{W+|bg|не́що|sc=Cyrl}}
* {{Z|my}}: {{W-|my|တစ်ခုခု}}, {{W+|my|တစ်စုံတစ်ခု}}
* {{Z|ccc}}: {{W-|ccc|anaskajneye}}
* {{Z|cs}}: {{W+|cs|něco}}
* {{Z|chr}}: {{W-|chr|ᎦᎱᏍᏗ}}
* {{Z|zh}}:
*: {{Z|cmn}}: {{W+|cmn|某事|tr=mǒushì}}, {{W+|cmn|某物|tr=mǒuwù}}, {{W-|cmn|某東西|tr=mǒudōngxi}}
*: {{Z|yue}}: {{W-|yue|啲嘢|tr=di1 je5}}, {{W-|yue|某啲嘢|tr=mau5 di1 je5}}
* {{Z|dlm}}: {{W-|dlm|nosko}}
* {{Z|da}}: {{W+|da|noget}}, {{W-|da|et eller andet|nt}}
* {{Z|ar}}: {{W+|ar|شَيْء|n}}
*: {{Z|arz}}: {{W-|arz|حاجة|m|tr=ḥāga|sc=Arab}}
*: {{Z|acw}}: {{W-|acw|شي|n|tr=šay}}, {{W-|acw|حاجة|m|tr=ḥāja|sc=Arab}}
*: {{Z|ary}}: {{W-|ary|شي حاجة|tr=ši ḥāja}}
*: {{Z|apc}}: {{W-|apc|شي|n|tr=šī}}
*: {{Z|ajp}}: {{W-|ajp|شي|tr=šī}} {{W-|ajp|إشي|tr=ʔiši}}
* {{Z|eo}}: {{W+|eo|io}}
* {{Z|et}}: {{W-|et|midagi}}
* {{Z|fa}}: {{W+|fa|چیزی|tr=čizi}}
* {{Z|fi}}: {{W+|fi|jokin}}, {{W+|fi|jokin|cuda=jotakin}}
* {{Z|fr}}: {{W+|fr|quelque chose}}
* {{Z|fy}}: {{W+|fy|wat}}, {{W-|fy|eat}}
* {{Z|gd}}: {{W-|gd|rudeigin}}
* {{Z|gl}}: {{W+|gl|algo}}, {{W-|gl|algunha cousa|m}}
* {{Z|ka}}: {{W-|ka|რაღაც}}
* {{Z|hi}}: {{W+|hi|कुछ|sc=Deva}}
* {{Z|nl}}: {{W+|nl|iets}}
* {{Z|he}}: {{W+|he|מַשֶּׁהוּ|n|tr=máshehu}}
* {{Z|io}}: {{W+|io|ulo}}, {{W+|io|kelko}}
* {{Z|ang}}: {{W-|ang|hwæthwugu}}
* {{Z|en}}: {{W+|en|somthing}}
* {{Z|ga}}: {{W-|ga|rud éigin}}
* {{Z|it}}: {{W+|it|qualcosa}}
* {{Z|is}}: {{W+|is|eitthvað}}
* {{Z|ja}}: {{W-|ja|何か|tr=なにか, nanika}}
* {{Z|ca}}: {{W+|ca|alguna cosa}}, {{W+|ca|quelcom}}, {{W+|ca|qualque cosa}}
* {{Z|qu}}: {{W+|qu|ima}}
* {{Z|ko}}: {{W-|ko|무언가}}, {{W-|ko|뭔가}}, {{W-|ko|무엇인가}}
* {{Z|kw}}: {{W-|kw|neppyth}}
* {{Z|co}}: {{W-|co|qualcosa}}
* {{Z|mfe}}: {{W-|mfe|kiksoz}}
* {{Z|lld}}: {{W-|lld|zech}}
* {{Z|lad}}: {{W-|lad|alguna koza}}, {{W-|lad|algune koze}}
* {{Z|ltg}}: {{W-|ltg|nazkas}}, {{W-|ltg|kas naviņ}}, {{W-|ltg|kazyn kas}}
* {{Z|la}}: {{W-|la|aliquid|nt}}, {{W-|la|quiddam|nt}}
* {{Z|lv}}: {{W-|lv|kaut kas}}
* {{Z|li}}: {{W+|li|get}}
* {{Z|mk}}: {{W-|mk|нешто|nt}}
* {{Z|ms}}: {{W+|ms|sesuatu}}
* {{Z|mt}}: {{W-|mt|xi ħaġa}}
* {{Z|gv}}: {{W-|gv|nhee ennagh}}
* {{Z|gun}}: {{W-|gun|mba'emo}}
* {{Z|hu}}: {{W+|hu|valami}}
* {{Z|mvi}}: {{W-|mvi|ノーガラー|tr=nōgarā}}
* {{Z|nrf}}: {{W-|nrf|quique seit}}
* {{Z|no}}:
*: {{Z|nb}}: {{W+|nb|noe}}
*: {{Z|nn}}: {{W-|nn|noko}}, {{W-|nn|eitkvart}}
* {{Z|pl}}: {{W+|pl|coś}}
* {{Z|pt}}: {{W+|pt|algo|n}}, {{W-|pt|[[alguma]] [[coisa]]|m}}
* {{Z|ro}}: {{W+|ro|ceva}}
* {{Z|ru}}: {{W+|ru|что́-то|nt}}, {{W+|ru|не́что|nt}}, {{W+|ru|кое-что́|nt}}
* {{Z|se}}: {{W-|se|juoga}}
* {{Z|sh}}:
*: Kirîlî: {{W-|sh|нешто|nt|sc=Cyrl}}
*: Latînî: {{W+|sh|nešto|nt}}
* {{Z|sco}}: {{W-|sco|sumthin}}, {{W-|sco|somethin}}
* {{Z|sk}}: {{W+|sk|niečo}}
* {{Z|sl}}: {{W+|sl|nekaj}}
* {{Z|so}}: {{W+|so|wax}}
* {{Z|es}}: {{W+|es|algo}}, {{W-|es|alguna cosa}}
* {{Z|sv}}: {{W+|sv|något}}, {{W+|sv|någonting}}, {{W+|sv|någon|g}}
* Talysh:
*: {{Z|tly}}: {{W-|tly|ای چییی|tr=i cii|sc=fa-Arab}}
* {{Z|zdj}}: {{W-|zdj|ndrongoo}}
* {{Z|ta}}: {{W+|ta|ஏதோ}}
* {{Z|th}}: {{W-|th|บางสิ่ง}}
* {{Z|te}}: {{W-|te|ఏదో}}
* {{Z|tr}}: {{W+|tr|bir şey}}
* {{Z|tpi}}: {{W-|tpi|wanpela samting}}
* {{Z|tn}}: {{W-|tn|sengwe}}
* {{Z|ur}}: {{W-|ur|کچھ|tr=kuch|sc=ur-Arab}}
* {{Z|uk}}: {{W+|uk|щось|sc=Cyrl}}, {{W-|uk|де́що|sc=Cyrl}}, {{W+|uk|що-не́будь|sc=Cyrl}}, {{W+|uk|чого́-не́будь|sc=Cyrl}}
* {{Z|vi}}: {{W-|vi|cái gì}}, {{W+|vi|gì}}, {{W-|vi|một cái gì đó}}
* {{Z|vo}}: {{W+|vo|bos}}
* {{Z|cy}}: {{W+|cy|rhywbeth|n}}
* {{Z|kjh}}: {{W-|kjh|пір ниме|sc=Cyrl}}
* {{Z|km}}: {{W-|km|អី}}
* {{Z|yi}}: {{W-|yi|עפּעס|sc=Hebr}}
* {{Z|el}}: {{W+|el|κάτι|nt}}
*: Kevn: {{W-|grc|[[τις|τι]]}}
* {{Z|ase}}: {{W-|ase|1@InsideNeckhigh-FingerUpPalmBack CirclesHoriz}}
{{werger-bin}}
:{{werger çavkanî|en|somthing|beş=Ev qismê Wergerê|oldid=75819373}}
=== Navdêr ===
{{navdêr|ku|z=n|j=y}}
# [[yek]] [[tişt]]
#: {{nm|ku|Ev tiştek e, ne du tişt in.}}
mabtnvx8rewqlnhvu0xy1rw3frld0qy
anîn rojevê
0
431800
6347468
5732715
2026-08-31T20:43:27Z
Wikihez
7344
/* Lêker */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347468
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
=== Lêker ===
{{lêker|ku}}
# avêtin rastê, [[anîn rastê]], [[anîn holê]], [[qal kirin]]
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026|jêgirtin=Min ev mijara hê di sala 2009an de di xebateke xwe de '''anîbû rojevê'''.}}
==== Etîmolojî ====
Ji ''[[anîn]] +[[rojev]]ê''.
==== Werger ====
{{werger-ser}}
* {{Z|fa}}: {{W+|fa|مطرح کردن}}, {{W-|fa|بحث روزکردن|guman=erê}}
* {{Z|tr}}: {{W+|tr|gündeme getirmek}}
{{werger-bin}}
q7dmsbmpe1izdsh1awgkba07mmuuexs
hewaskar
0
451197
6347474
1279985
2026-08-31T20:51:53Z
Wikihez
7344
([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +ku:rengdêr:{{guharto|ku|heweskar}}
6347474
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Rengdêr ===
{{rengdêr|ku}}
# {{guharto|ku|heweskar}}
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026|jêgirtin=Spîkerê Radyoya Rewanê Keremê Seyad, di sala 1971an li ser hunermendiya Zadîna Şekir nivîseke gelek '''hewaskar''' weşandiye.}}
8bm6zxx5ow2xbe96295ktxq3bh8kpg5
6347475
6347474
2026-08-31T20:52:00Z
Wikihez
7344
/* Rengdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347475
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Rengdêr ===
{{rengdêr|ku}}
# {{guharto|ku|heweskar}}
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026|jêgirtin=Spîkerê Radyoya Rewanê Keremê Seyad, di sala 1971an li ser hunermendiya Zadîna Şekir nivîseke gelek '''hewaskar''' weşandiye.}}
rmnnqyg2cvb9j4yu7j6z3ebfqu7phdt
6347482
6347475
2026-08-31T21:01:51Z
Wikihez
7344
/* Rengdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347482
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Rengdêr ===
{{rengdêr|ku}}
# {{guharto|ku|heweskar}}
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|urlya-arşîvê=http://web.archive.org/web/20260831205557/https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026|jêgirtin=Spîkerê Radyoya Rewanê Keremê Seyad, di sala 1971an li ser hunermendiya Zadîna Şekir nivîseke gelek '''hewaskar''' weşandiye.}}
flfav4yv0iiqwessqcbclvczymdwqjy
6347483
6347482
2026-08-31T21:02:21Z
Wikihez
7344
/* Rengdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347483
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Rengdêr ===
{{rengdêr|ku}}
# {{guharto|ku|heweskar}}
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|urlya-arşîvê=https://web.archive.org/web/20260831205557/https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026|jêgirtin=Spîkerê Radyoya Rewanê Keremê Seyad, di sala 1971an li ser hunermendiya Zadîna Şekir nivîseke gelek '''hewaskar''' weşandiye.}}
gxjgz11yj71bt3lyirrqhx2n6ewkpfv
qilêçî
0
459270
6347419
5758207
2026-08-31T18:12:17Z
Wikihez
7344
6347419
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Navdêr ===
{{navdêr|ku|c=mn}}
# [[sefar]]
==== Etîmolojî ====
{{bêetîmolojî}}
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W-|de|Verzinner}} {{n}}
* {{Z|tr}}: {{W+|tr|bakırcı}}, {{W+|tr|kalaycı}}
{{werger-bin}}
7p1isiwkcaccj9gzy34nw6dauoh20z0
tehqîq
0
460088
6347551
6341524
2026-09-01T09:51:20Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347551
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku|z=m}}
# [[taqî]], [[ezmûn]], [[îmtîhan]], [[test]], [[ceribandin]], [[saxtî]], [[saxtî]], [[teftîş]], [[ezmayîş]], [[axulme]], [[kontrol]], [[çavdêrî]], [[seh]]kirin, [[pişkinîn]], [[temaşe]]kirin, [[venerîn]], [[azmayîş]], [[vekolîn]], [[miayene]], [[lê kolîn]], [[ezmûn kirin]], [[fehs]]
#* {{J:Albert Camus:Biyanî|jêgirtin=Piştî girtina min di cîh de çend caran '''tehqîq''' bi min re hatin çêkirin.}}
#* {{jêder-websîte|ku|jêgirtin=Bi gotinin din, ji ber ku cih mercê serekî ye, ji hebûna '''taqîkirin''' û tecribekirinê re ye, her wisa dem jî mercekî pêdivî ye. Bê wan û dervî wan tu nasîn nikare peyda bibe û hiş nikare sawêra heyînekê dervî cih bike.|nivîskar=Derwêş Derwêş|sernav=Serdem li ber Roniya Cezîrî|websîte=Pen-kurd.org|sal=jêwergirtin 11/2006}}
==== Formên alternatîv ====
{{kol3|ku
|taqî
|tahqîq<qq:di bin tesîra tirkî de>
}}
==== Jê ====
{{kol3|ku
|taqî
|tehqîqat
|tehqîq kirin<crz:lêker>
|tehqîqkirin<crz:navdêr>
|tehqîqkirî<crz:rengdêr>
}}
==== Etîmolojî ====
Ji {{ji|ar|ku|تحقیق|tr=teh'qîq}}. {{anlz|ku|te-|heqîqî}}.. Binêrin: ''[[taqî]], [[heq]], [[heqîqî]], [[hiqûq]]''.
==== Werger ====
{{werger-ser}}
* {{Z|fa}}: {{W+|fa|امتحان}}
* {{Z|fi}}: {{W+|fi|tarkastus}}
* {{Z|en}}: [[verification]] {{W+|en|examination}}, {{W+|en|inspection}}, {{W+|en|scrutiny}}, {{W+|en|check}}, {{W+|en|test}}, {{W+|en|experiment}}, {{W+|en|investigation|guman=erê}}
* {{Z|tr}}: {{W+|tr|tahkik}}, {{W+|tr|deneme}}, {{W+|tr|imtihan}}, {{W+|tr|sınama}}, {{W+|tr|sınav}}
{{werger-bin}}
o8mr7l15pp3jn6dn1we71dlwvx4j0yg
karevîn
0
480579
6347576
6327359
2026-09-01T10:23:45Z
Balyozbot
7867
sererastkirin [[Wîkîpediya:AutoWikiBrowser|AWB]]
6347576
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Freileitung mit Transformatorhaus.jpg|thumb|250px|xetên elektrîkê]]
{{navdêr|ku|z=m}}
# [[enerjî|Enerjiya]] ji [[proton]] û [[elektron]]an [[peyda]] dibe û bi taybetî bo [[peyda]]kirina [[ronahî|ronahiyê]] tê [[bikaranîn]].
==== Hevmane ====
{{kol3|ku
|kareba
|ceyran
|kehreb
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|af}}: {{W+|af|elektrisiteit}}
* {{Z|de}}: {{W|de|Elektrizität|f}}
* {{Z|bg}}: {{W+|bg|електричество}}
* {{Z|cs}}: {{W+|cs|elektřina}}
* {{Z|zh}}: [[电]]、[[電]] (diàn), [[电能]]、[[電能]] (diànnéng)
* {{Z|da}}: {{W+|da|elektricitet}}
* {{Z|eo}}: {{W+|eo|elektro}}
* {{Z|fo}}: {{W+|fo|ravmagn}}
* {{Z|fi}}: {{W+|fi|sähkö}}
* {{Z|fr}}: {{W+|fr|électricité}}
* {{Z|fy}}: {{W+|fy|elektrisiteit}}
* {{Z|nl}}: {{W+|nl|elektriciteit}}
* {{Z|he}}: [[חשמל]] (xeşmel)]]
* {{Z|io}}: {{W+|io|elektro}}
* {{Z|en}}: {{W+|en|electricity}}, {{W+|en|juice}}, {{W+|en|trad}}
* {{Z|it}}: {{W+|it|elettricità}}
* {{Z|ja}}: [[電気]] ([[でんき]], [[denki]])
* {{Z|ca}}: {{W+|ca|electricitat}}
* {{Z|la}}: {{W+|la|ēlectricitās}}
* {{Z|lv}}: {{W|lv|elektrība|f}}
* {{Z|ms}}: {{W+|ms|listrik}}
* {{Z|pap}}: {{W+|pap|elektrisidat}}
* {{Z|pt}}: {{W+|pt|eletricidade}}
* {{Z|ru}}: {{W|ru|электричество|n}}
* {{Z|sh}}: {{W+|sh|struja}}
* {{Z|sh}}:
*: Kirîlî: [[струја]] {{mê}}
*: Latînî: {{W+|la|struja}}
* {{Z|sk}}: {{W|sk|elektrina|f}}
* {{Z|es}}: {{W+|es|electricidad}}
* {{Z|sv}}: {{W+|sv|elektricitet}}, {{W+|sv|el}}
* {{Z|te}}: {{W-|te|విద్యుత్తు|tr=vidyuttu}}
* {{Z|tr}}: {{W+|tr|elektrik}}, {{W+|tr|cereyan}}
* {{Z|el}}: {{W+|el|ηλεκτρισμός}}
{{werger-bin}}
=== Rengdêr ===
{{rengdêr|ku}}
# Tişta/ê bi elektrîkê [[xebitîn|dixebite]]
==== Hevmane ====
{{kol3|ku
|karebayî
|ceyranî
|elektrîkî
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
{{werger-bin}}
o45nlx7mj9lbtarrs2qu043876fy5y7
bir sürü lafın belini bükmek
0
630475
6347371
4639074
2026-08-31T13:18:36Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes)
6347371
wikitext
text/x-wiki
== {{ziman|tr}} ==
=== Biwêj ===
{{biwêj|tr}}
# [[pir|pir]] [[axaftin|axaftin]], [[gelek|gelekî]] [[xeber dan]]
7f7p238eiu0oeb55ls5ard1xtucmlk0
6347372
6347371
2026-08-31T13:19:03Z
Wikihez
7344
/* Biwêj */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347372
wikitext
text/x-wiki
== {{ziman|tr}} ==
=== Lêker ===
{{lêker|tr}} {{e|ku|biwêjî}}
# [[pir|pir]] [[axaftin|axaftin]], [[gelek|gelekî]] [[xeber dan]]
im1uwi90cd5nnbsx3fn28jgo198wcy1
6347385
6347372
2026-08-31T15:12:13Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347385
wikitext
text/x-wiki
== {{ziman|tr}} ==
=== Lêker ===
{{lêker|tr}} {{e|ku|biwêjî}}
# [[pir]] [[axaftin]], [[gelek]]î [[xeber dan]]
5p39neyfeku36sekjueeso5pvlnhbyl
keçi yavrusu
0
633547
6347586
5804348
2026-09-01T10:41:39Z
Wikihez
7344
Cureyê rêzimanî hate diyarkirin: Navdêr (DefSideBoxes)
6347586
wikitext
text/x-wiki
== {{ziman|tr}} ==
=== Navdêr ===
{{navdêr|tr}}
# [[gîsk]]
9sxnj640qnquek7anhjh0jw1eezg59c
rüzgar gülü
0
635133
6347540
4078872
2026-09-01T09:43:17Z
~2026-43174-20
15227
6347540
wikitext
text/x-wiki
== {{ziman|tr}} ==
=== Navdêr ===
{{navdêr|tr}}
# [[perwanek]], lewheya ku alîyê ku ba jê tê tespît dike
# [[firfirk]], lîstokek zarokan e. Kaxetek rengîn milên wê bi darekî ve tê derzîkirin; li ber ba dizîvire!
imm8kjgmtnkllaggmqxlihaed9qeahq
6347541
6347540
2026-09-01T09:44:44Z
~2026-43174-20
15227
6347541
wikitext
text/x-wiki
== {{ziman|tr}} ==
=== Navdêr ===
{{navdêr|tr}}
# [[perwanek]], lewheya ku alîyê ku ba jê tê tespît dike
# [[firfirk, firfirok]], lîstokek zarokan e. Kaxetek rengîn milên wê bi darekî ve tê derzîkirin; li ber ba dizîvire!
cei14j6ctjn58vntp1kthimo2ur8wfb
6347558
6347541
2026-09-01T10:02:34Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes); guhartina pêşketî (DefSideBoxes)
6347558
wikitext
text/x-wiki
== {{ziman|tr}} ==
=== Navdêr ===
{{navdêr|tr}}
# [[perwanek]] {{îzah|[[lewhe|lewheya]] ku [[alî|alîyê]] ku ba jê tê [[tespît kirin|tespît dike]}}
# [[firfirk]], [[firfirok]] {{îzah|[[lîstok|lîstoka]] [[zarok|zarokan]]; [[kaxet|kaxetek]] [[rengîn|rengîn]] [[mil|milên]] wê bi [[dar|darekî]] ve tê [[derzî kirin|derzîkirin]]; [[li ber]] ba [[zivirîn|dizîvire]].}}
ohcwljgd9dfriol63gp85s5jebke31t
6347559
6347558
2026-09-01T10:02:56Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347559
wikitext
text/x-wiki
== {{ziman|tr}} ==
=== Navdêr ===
{{navdêr|tr}}
# [[perwanek]] {{îzah|[[lewhe|lewheya]] ku [[alî|alîyê]] ku ba jê tê [[tespît kirin|tespît dike]]}}
# [[firfirk]], [[firfirok]] {{îzah|[[lîstok|lîstoka]] [[zarok|zarokan]]; [[kaxet|kaxetek]] [[rengîn|rengîn]] [[mil|milên]] wê bi [[dar|darekî]] ve tê [[derzî kirin|derzîkirin]]; [[li ber]] ba [[zivirîn|dizîvire]].}}
j1k8no1b0h86658s6qkfsgcqan5z0pq
6347600
6347559
2026-09-01T11:12:08Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347600
wikitext
text/x-wiki
== {{ziman|tr}} ==
=== Navdêr ===
{{navdêr|tr}}
# [[perwanek]] {{îzah|[[lewhe]]ya ku [[alî]]yê ku ba jê tê [[tespît kirin|tespît dike]]}}
# [[firfirk]], [[firfirok]] {{îzah|[[lîstok]]a [[zarok]]an; [[kaxet]]ek [[rengîn]] [[mil]]ên wê bi [[dar]]ekî ve tê [[derzî kirin|derzîkirin]]; [[li ber]] ba [[zivirîn|dizîvire]].}}
b2ru62rf796y13xns9uronc31zr2dq8
myrmec-
0
639338
6347611
5854110
2026-09-01T11:25:36Z
Wikihez
7344
Cureyê rêzimanî hate diyarkirin: Pêşgir (DefSideBoxes)
6347611
wikitext
text/x-wiki
== {{ziman|en}} ==
=== Pêşgir ===
{{pêşgir|en}}
#pêşgir e ku mêrî ye
bmo4u6awbi7p4nu9fyk8q5u176qcban
solemn oath
0
640385
6347395
5856815
2026-08-31T15:36:29Z
Wikihez
7344
Cureyê rêzimanî hate diyarkirin: Navdêr (DefSideBoxes)
6347395
wikitext
text/x-wiki
== {{ziman|en}} ==
=== Navdêr ===
{{navdêr|en}}
{{bêcure|en}}
#sonda giran
t4aac30ohaqukekxxavnqg4ce6vd3z7
6347396
6347395
2026-08-31T15:36:50Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347396
wikitext
text/x-wiki
== {{ziman|en}} ==
=== Navdêr ===
{{navdêr|en}}
# [[sond]]a [[giran]]
f3u9njchzn5n4r7wo2u3g5ixb0yaawl
basme
0
647495
6347486
6277856
2026-08-31T21:07:57Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347486
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku}}
# tewirek caw e. rûyê wî cawî bi nexş û nigarên tewiratewir tê raçandin. ji basme, bi pirani cilên jinan tên dirûtin.
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|urlya-arşîvê=https://web.archive.org/web/20260831205557/https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026
|jêgirtin=Ji ber zêde biha nîn bû, gundiyan gelek caran çît û '''basme''' distendin bona jin ji xwe re pê dêran bidirûn.
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|en}}:{{W+|en|calico|guman=erê}}
{{werger-bin}}
r15n6wg9m8p5rx1syy5w50q6oc8o8qo
6347487
6347486
2026-08-31T21:09:56Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes); guhartina pêşketî (DefSideBoxes)
6347487
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku}}
# {{K|ku|cilûberg}} [[tewir|Tewirek]] [[caw|caw]] ê ku [[rû|rûyê]] wî [[cawî|cawî]] [[bi nexş]] û [[nigar|nigarên]] [[tewiratewir|tewiratewir]] tê [[raçandin|raçandin]]. Jê bi [[pirani|pirani]] [[cil|cilên]] [[jin|jinan]] [[tên|tên]] [[dirûtin|dirûtin]].
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|urlya-arşîvê=https://web.archive.org/web/20260831205557/https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026
|jêgirtin=Ji ber zêde biha nîn bû, gundiyan gelek caran çît û '''basme''' distendin bona jin ji xwe re pê dêran bidirûn.
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|en}}:{{W+|en|calico|guman=erê}}
{{werger-bin}}
f53zv249of9mtmggcinadydsi0wvuh2
6347488
6347487
2026-08-31T21:10:23Z
Wikihez
7344
/* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347488
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku}}
# {{K|ku|cilûberg}} [[tewir|Tewirek]] [[caw|caw]] ê ku [[rû|rûyê]] wî [[cawî|cawî]] [[bi nexş]] û [[nigar|nigarên]] [[tewiratewir|tewiratewir]] tê [[raçandin|raçandin]]. Jê bi [[piranî]] [[cil|cilên]] [[jin|jinan]] [[tên|tên]] [[dirûtin|dirûtin]].
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|urlya-arşîvê=https://web.archive.org/web/20260831205557/https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026
|jêgirtin=Ji ber zêde biha nîn bû, gundiyan gelek caran çît û '''basme''' distendin bona jin ji xwe re pê dêran bidirûn.
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|en}}:{{W+|en|calico|guman=erê}}
{{werger-bin}}
tw2ch15bs5g9yrdxyj2jukjj6ehqbcc
6347502
6347488
2026-08-31T22:12:08Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir, --Valahiyên nehewce.)
6347502
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-kîte}}
=== Navdêr ===
{{navdêr|ku}}
# {{K|ku|cilûberg}} [[tewir|Tewirek]] [[caw]] ê ku [[rû]]yê wî [[cawî]] [[bi nexş]] û [[nigar]]ên [[tewiratewir]] tê [[raçandin]]. Jê bi [[piranî]] [[cil]]ên [[jin]]an [[tên]] [[dirûtin]].
#* {{jêder-websîte|ku|nivîskar=w:Rohat Alakom|websîte=Kovara Bîr|sernav=Dêre Sorê Piçûkê|urlya-arşîvê=https://web.archive.org/web/20260831205557/https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|url=https://kovarabir.com/1375/dere-sore-picuke-rohat-alakom/kmr/|tarîx=20.07.2026
|jêgirtin=Ji ber zêde biha nîn bû, gundiyan gelek caran çît û '''basme''' distendin bona jin ji xwe re pê dêran bidirûn.
}}
==== Etîmolojî ====
{{bêetîmolojî|ku}}
==== Werger ====
{{werger-ser}}
* {{Z|en}}:{{W+|en|calico|guman=erê}}
{{werger-bin}}
ne6rwntkcu0o1h12n6d3cz5lq2umsgu
paradiso
0
672110
6347414
6029160
2026-08-31T17:17:57Z
Wikihez
7344
Cureyê rêzimanî hate diyarkirin: Navdêr (DefSideBoxes)
6347414
wikitext
text/x-wiki
== {{ziman|it}} ==
=== Bilêvkirin ===
* {{deng|it|LL-Q652 (ita)-Crunchy Cloaky Crackdown-paradiso.wav|Deng|dever=}}
=== Navdêr ===
{{navdêr|it}}
# [[beheşt]]
qgbjdds4kmafaydxcns472oppec1e1j
Şablon:J:Hesenê Metê:Epîlog
10
672401
6347388
6334588
2026-08-31T15:19:17Z
Wikihez
7344
6347388
wikitext
text/x-wiki
{{{{#if:{{{jêgirtin|{{{jg|}}}}}}|jêder-}}kitêb|ku<!--
-->|jêgirtin={{{jêgirtin|{{{jg|}}}}}}<!--
-->|rûpel={{{rûpel|{{{r|}}}}}}<!--
-->|nivîskar=[[w:Hesenê Metê|Hesenê Metê]]|sernav=[[w:Epîlog|Epîlog]]|weşanxane=Weşanxaneya [[w:Avesta|Avesta]]|sal=2000}}<!--
-->{{kategorî|Jêgirtinên ji Hesenê Metê}}<noinclude>
{{belgekirin}}
[[Kategorî:Jêgirtin li gorî nivîskaran ({{navê zimanî|ku}})|Hesenê Metê]]
{{jgcat|ku}}
</noinclude>
d5ue2rong0e3bo8hevk7rwo4it1ig9p
dodoyê dunikil
0
689904
6347608
6305487
2026-09-01T11:17:34Z
Wikihez
7344
/* Werger */ xelet (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347608
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Navdêr ===
[[Wêne:Upupa epops 1 Luc Viatour.jpg|thumb|dawidê dunikil]]
{{navdêr|ku|z=n}}
# [[dîksilêman]], [[hudhud]], [[silêmanê dunikil]], [[dîkilê silêmanî]], [[dîkê silêman]], [[hophopk]]
==== Tewandin ====
{{ku-tewîn-nav/nû|nêr}}
==== Navê zanistî ====
* ''Upupa epops''
==== Etîmolojî ====
Ji {{heve|ku|dodoyê|dunikil}}.
==== Werger ====
{{werger-ser}}
* {{Z|de}}: {{W|de|Wiedehopf|m}}
* {{Z|cs}}: {{W|cs|dudek}}
* {{Z|ar}}: {{W|ar|هدهد|R=hudhud}}
* {{Z|hy}}: {{W|hy|հոպոպ|R=hopop}}
* {{Z|eo}}: {{W|eo|upupo}}
* {{Z|fa}}: {{W|fa|پوپک|R=pupak}} ; {{W|fa|هدهد|R=hod hod}}
* {{Z|ka}}: {{W|ka|ოფოფი|R=opʻopʻi}}
* {{Z|nl}}: {{W|nl|hop}}
* {{Z|en}}: {{W|en|hoopoe}}
* {{Z|it}}: {{W|it|upupa}}
* {{Z|ca}}: {{W|ca|puput}} ; {{W|ca|palput}}
* {{Z|la}}: {{W|la|upupa}}
* {{Z|oc}}: {{W|oc|upa}}
* {{Z|pl}}: {{W|pl|dudek}}
* {{Z|pt}}: {{W|pt|poupa}}
* {{Z|ro}}: {{W|ro|pupăză}}
* {{Z|ru}}: {{W|ru|удод|R=udód}}
* {{Z|ses}}: {{W|ses|zunbu}}
* {{Z|es}}: {{W|es|abulilla}}
* {{Z|tr}}: {{W|tr|ibibik}} ; {{W|tr|hüthüt}}
* {{Z|el}}: {{W|el|τσαλαπετεινός|R=tsalapetinós}}
{{werger-bin}}
{{mijar|ku|balinde}}
7kd3xq7gja5wdmh7pk8bo9mvtnt9g35
Kategorî:Serhedî
14
842310
6347506
5884161
2026-08-31T23:12:12Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347506
wikitext
text/x-wiki
:'''''[[w:Serhedî|Serhedî]]''' an jî '''serhedkî''' devoka [[kurmanc]]ên li herêma Serhedê û rewanê ye.''
{{agahiyên gelemperî
| nav = [[serhedî]]
| kod = -
| malbat1 = [[hind-û-ewropî|Hind û ewropî]]
| malbat2 = Zimanên hind û îranî
| malbat3 = Zimanên îranî
| malbat4 = Zimanên îranî yên rojava
| malbat5 = Zimanên îranî yên bakur-rojava
| malbat6 = Kurdî
| malbat7 = Kurmancî
| malbat8 =
| nivîs = Latînî
| nexşe =
| binnexşe =
}}
[[Kategorî:Devokên kurmancî]]
dvoncqjrxf018wqumjth3ijsyrjve6k
Wîkîferheng:Daxwazên peyitandinê
4
843283
6347407
6346932
2026-08-31T16:41:34Z
Wikihez
7344
[[Bikarhêner:Wikihez/skrîpt/js/şablon-lêke.js|T]]: Daxwaza peyitandinê: +[[biehliyet]]
6347407
wikitext
text/x-wiki
{{/destpêk}}
= Hezîran 2020 =
== [[romî#Navdêr|romî]] ==
Li Şingalê maneya polîs? --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:00, 15 hezîran 2020 (UTC)
= Tîrmeh 2020 =
== [[kêlb#p-mane|kêlb]] ==
--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:24, 22 tîrmeh 2020 (UTC)
== [[ejî#p-mane|ejî]] ==
--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:24, 22 tîrmeh 2020 (UTC)
== [[tutirk#peyitandin|tutirk]] ==
--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:02, 22 tîrmeh 2020 (UTC)
:{{r|Guherto}} Niha çawa ye? Bi ya min çavkaniyên ku min dane têrê me dike. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:43, 22 tîrmeh 2020 (UTC)
::{{r|Balyozxane}} Nizanim.. li hin deveran wek tutirk hatîye nivîsandin û li hin jî wek tûtirk. Li hin deveran bi wateya tûşêmî (Rubus) ye, hin deveran jî bi wateya tûerd (Fragaria × ananassa) e û carna jî bi wateya tû (ê spî û reş go li ser daran çê dibin) ye. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 08:16, 23 tîrmeh 2020 (UTC)
== [[erbane#p-mane|erbane]] ==
Ji bo ''Amûreke tenê tekerekî wê heye ji bo veguhestina tiştan wek: axê, kevir, hwd'' ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]''--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:42, 31 tîrmeh 2020 (UTC)
= Tebax 2020 =
== [[cifta berazan]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:57, 9 tebax 2020 (UTC)
== [[tê gerîn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:26, 10 tebax 2020 (UTC)
== [[tapor]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:30, 22 tebax 2020 (UTC)
:{{r|Mihemed Qers}} -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 22:16, 22 tebax 2020 (UTC)
== [[şimzare]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:01, 26 tebax 2020 (UTC)
== [[bîrkok]] ==
Tenê Mehmed Uzun bi kar tîne. Ji bilî kitêbên wî çavkaniyeke din tune. —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:38, 28 tebax 2020 (UTC)
== [[hunera axaftinê]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:46, 30 tebax 2020 (UTC)
== [[derrijîn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 07:38, 31 tebax 2020 (UTC)
== [[yekal]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 09:19, 31 tebax 2020 (UTC)
== [[av û agir]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:50, 31 tebax 2020 (UTC)
: Di çavkaniyeke de wek av û agir kirin derbas dibe û ji wergerandinên inglîzî cuda ye lê nêzîk e.<br> {{jêder-pirtûk|ku|jêgirtin=weke gelek hunermendên ko dû re agir bera berhêm xwe didin Xwedê jî ji bilî maltaba Nûh tevayiyê vê berhema xwe '''av û agir dike''', van melekên xwe yên doxînsist dikişîne asîmanan, li wir wan tawanbar dike, mîna ko bibêje: de biçin û weke xwe bikin, bi derew û tevgerên xwe yên qirêj dijminiya min bikin, Xwedê wan ji asimanan de serjêr davêje xwarê.|nivîskar=Hesenê Metê|sernav=Labîrenta cinan|weşanxane=Nefel|sal=2002|rûpel=132}} --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:37, 31 tebax 2020 (UTC)
== [[elm#p-mane-notice|elm]] ==
Wateya: ''[[ewlebûn]], sihê pê zanîn, baş pê zanîn''. ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:31, 31 tebax 2020 (UTC)
:{{r|Hakîmo}} Ku çavkanî tunebûn em ê jê bibin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:47, 19 îlon 2020 (UTC)
::{{r|Balyozxane}} Mala te neketê... Hingê bixwe here lê bigere. Jixwe ez reşwî me. Ma eve ne çavkanî ye? -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 14:48, 19 îlon 2020 (UTC)
:::{{r|Hakîmo}} Hinek bixwîne [[Wîkîferheng:Pîvekên tevlîkirinê]]. Jixwe dema ti kesan din çavkanî lê zêde nakin, ez lê digerim û zêde dikim. Na tu ne ti çavkanî yî. Çavkaniyên nivîskî hewce ne. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:51, 19 îlon 2020 (UTC)
::::{{r|Balyozxane}} Erê, lê ku tine bin em çawa bikinî? Em hema jê bibinî? -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 14:52, 19 îlon 2020 (UTC)
:::::{{r|Hakîmo}} Erê em jê dibin. Lê peyvên jê hatine birin em li rûpela [[Pêvek:Bêçavkanî]] zêde dikin. bnr. [[:Kategorî:Pêvek bêçavkanî]]. Dîsa jî ez jî ji vê rewşa me aciz im û bi ya min peyvên devokî divê nayên jêbirin. Lê ji ber ku [[Wîkîferheng:Rêbazname]] dibêje divê werin jêbirin, ez jê dibim. Hevalên {{r|Jiju|Guherto|Ghybu}} [https://ku.wiktionary.org/wiki/Got%C3%BBb%C3%AAj:kejm%C3%BBn], [https://ku.wiktionary.org/wiki/Got%C3%BBb%C3%AAja_p%C3%AAvek%C3%AA:B%C3%AA%C3%A7avkan%C3%AE] jî ji vê rewşê aciz in. Lê ti kes gotûbêj nadin destpêkirin. Ku tu li vir [[Gotûbêja Wîkîferhengê:Pîvekên tevlîkirinê]] gotûbêjek bidî destpêkirin, ez ê piştgirî bidime te. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:58, 19 îlon 2020 (UTC)
::::::Ji kerema xwe min şaş fêm mekin feqet hemû bikarhêner ku tên vira dilpak nînin. Em çito ew peyvan kotrol bikinê? Mixabin, ji bo konrolkirina peyvan di destên me de tenê xwastina çavkaniyan hene amûrek din tine ye... PS: Herwiha me li ser wîkîferhengê Namespace'yên Nimînok ([[Nimînok:Kurdî/serhedî]]?, [[Nimînok:Kurdî/badînî]]?, ..) û Portal ([[Portal:Kurdî]], [[Portal:Frensî]] (mk. [[:fr:Portail:Français]]), ...) jî çêkiriye...--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 19 îlon 2020 (UTC)
:::::::Nizanim we nivîsa vira xwand, [[Wîkîferheng:Dîwan#Skotî]]. Piraniya peyvên wîkiya skotî çêkirî ne...--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 19 îlon 2020 (UTC)
::::::::@Ghybu erê min ew xwendibû. Ku em peyvan nepeyitînin, rewşa me jî wek mg.wikt û wikiya skotiyan be. Temam em peyvên devokî jê nebin lê em wan jî nexin werger û rûpelên din heta ku werin peyitandin. Herwiha tu dibêjî amûrek tune ye lê tenê ji bo peyvên devokî û navên heywan/riwekan wisa ye. Gelek caran peyitandin pir hêsan e. Mînak @Hakîmo yan jî hevalên din dikarin blogan binivîsin daku em karibin peyvên wan yên devokî (nepeyitandî) têxin rûpela [[Wîkîferheng:Tomarkirina peyvên ji wêjeya kurdî|Jêgirtinekê tomar bike]] û kengî ew peyv ji hêla nivîskar û blogvanên kurd yên din ve hatine bikaranîn hingê em dikarin li wîkîferhengê jî zêde bikin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:05, 19 îlon 2020 (UTC)
{{outdent|::::::::}}{{r|Hakîmo|Ghybu}} Xêra dê û bavên we '''[[Gotûbêja_Wîkîferhengê:Pîvekên_tevlîkirinê#Li_ser_peyvên_devokî|li vir]]''' fikrên xwe binivîsin daku kesên din bizanin kesên din jî hene vê fikrê min dipejirînin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 06:48, 3 çiriya pêşîn 2020 (UTC)
== [[nîşanbar]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:51, 31 tebax 2020 (UTC)
= Îlon 2020 =
== [[besme]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:26, 1 îlon 2020 (UTC)
== [[ferengi]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:12, 1 îlon 2020 (UTC)
== [[çelape]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:22, 1 îlon 2020 (UTC)
== [[cesasandin]] ==
Çavkaniyek klasîk heye, yên din heye gelo? —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 09:02, 2 îlon 2020 (UTC)
== [[depan]] ==
Depan guhertoyeke textan an textîn e. Lê li vir çi mane heye min fêm nekir. —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:33, 2 îlon 2020 (UTC)
== [[li rûyê dinê xweş mayîn]] ==
Çavkaniyeke klasîk heye —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:38, 2 îlon 2020 (UTC)
== [[bêsewî]] ==
klasîk —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 06:34, 4 îlon 2020 (UTC)
== [[merkemoş]] ==
Klasîk —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 06:34, 4 îlon 2020 (UTC)
== [[firfiroka bayî]] ==
{{r|Mamoste Dilovan}} ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:57, 6 îlon 2020 (UTC)
== [[guhê fîlî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:56, 7 îlon 2020 (UTC)
: {{r|Bikarhêner}} Min guh li evê peyvê bû ji kesekî ku xudan xwaringehek û baxçeyekî mezin e.
: Gelek tişt di berbelav in û xelk dizanin, lê di pertûkan de naye dîtin. {{bêîmze|IbrahimKocher Duhok}}
== [[gurovî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:41, 14 îlon 2020 (UTC)
:{{r|Bikarhêner}} Çavkanîyên peyvên ku min nivîsandin mixabin ne nivîskî ne. Ev peyv min ji hin mezinên malbatê bihîstine û min jî gelek caran dîtîne ku hatine bikaranîn. Ji bo ku ev peyv wûnda nebin min hem li ba xwe û hem jî li wîkîferhengê nivîsand. Ji bo peyvên ku çavkanîyên nivîskî tunin, mixabin gotinên devkî tene weke çavkanî dimînin. Pêşnîyara te ji bo pevên bi vî awayî çi ye gelo? Spas{{bêîmze|Xwende}}
::{{r|Xwende}} Pêşî li ser malpera [https://tirsik.net/xerhati.php] dûre jî li ser arsiv.org qeyd bike ku nikarî çavkanî peyda bikî. Herwiha bnr [[Alîkarî:Îmze]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:00, 15 îlon 2020 (UTC)
== [[şîloyî]] ==
{{r|Xwende}} ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:44, 14 îlon 2020 (UTC)
== [[dever]] ==
Ji bo wateya ''derence, sêlim û merdîwen'' [[Wîkîferheng:Pîvekên tevlîkirinê|çavkanî hewce ye]]. —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:53, 14 îlon 2020 (UTC)
== [[kerrnizî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:56, 15 îlon 2020 (UTC)
== [[li dora (yekê) gerîn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:46, 15 îlon 2020 (UTC)
== [[glas]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]. --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 12:45, 16 îlon 2020 (UTC)
== [[kejmûn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:42, 17 îlon 2020 (UTC)
== [[lirêgerîn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:20, 18 îlon 2020 (UTC)
== [[çavpeqî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:23, 23 îlon 2020 (UTC)
:http://www.geocities.ws/mehname2004a/63/pexsan5.html -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 16:58, 23 îlon 2020 (UTC)
== [[çavpeqiyayî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:14, 23 îlon 2020 (UTC)
:{{r|Balyozxane}} Çavpeqî û -iyayî eynî peyv in, heke bo nimûne 2 çavkanî ji bo çavpeqî û 1 ji bo -iyayî werin dîtin ew weke 3 ji bo yek peyv tên jimartin? -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:16, 23 îlon 2020 (UTC)
::{{r|Guherto}}. Na, divê yek ji wan peyitandî be daku em karibin yek ji wan wek guherto nîşan bidin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:45, 23 îlon 2020 (UTC)
:::Temam naxwe. {{=(}} -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:48, 23 îlon 2020 (UTC)
::::Ecêb e peyva çavpeqîn jî tune ye. Divê çavpeqî/çavpeqiyayî jê hatibe lê qet tune. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:56, 23 îlon 2020 (UTC)
:::::Em çavpeqî ne weke kesekî ku çavê wan peqî ye dibêjin. Siqêfek e. ''Wilo neke, çavpeqî!'' -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 18:10, 23 îlon 2020 (UTC)
== [[olfatûn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:58, 24 îlon 2020 (UTC)
:Du çavkanî hatiye dîtin li hêviya ya sisêyan e. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:46, 23 sibat 2025 (UTC)
== [[hekûke]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:00, 28 îlon 2020 (UTC)
:Tenê çavkaniyek ji Kovara Kurmancî heye ew jî ji kitêba Gundê Mêrxasan a Eliyê Evdilrehman hatiye girtin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:49, 23 sibat 2025 (UTC)
== [[dê bêjî kaya di serî de]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:58, 29 îlon 2020 (UTC)
== [[heçî ne li malekê, nizanit halekê]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:58, 29 îlon 2020 (UTC)
== [[heta nîva destî reş nebit, tama devî xoş nabit]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:58, 29 îlon 2020 (UTC)
== [[kirtop]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herwiha [[kirtope]]—[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:59, 29 îlon 2020 (UTC)
:
== [[pişkûmişk]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:25, 29 îlon 2020 (UTC)
= Çiriya pêşîn 2020 =
== [[ma te şulê pê ye?]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:19, 1 çiriya pêşîn 2020 (UTC)
== [[zelam yêt heyn û zelamoşk jî yêt heyn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:28, 1 çiriya pêşîn 2020 (UTC)
== [[ezîz î; ji pêrve ne mîzî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:15, 1 çiriya pêşîn 2020 (UTC)
== [[qelpez]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:19, 6 çiriya pêşîn 2020 (UTC)
== [[firêzer]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:27, 6 çiriya pêşîn 2020 (UTC)
== [[kirmişk]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 09:03, 7 çiriya pêşîn 2020 (UTC)
== [[orijîn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:03, 7 çiriya pêşîn 2020 (UTC)
== [[şequdeq]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:50, 9 çiriya pêşîn 2020 (UTC)
== [[helizandin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:23, 9 çiriya pêşîn 2020 (UTC)
== [[rewastin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:48, 9 çiriya pêşîn 2020 (UTC)
== [[xunaftin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:31, 9 çiriya pêşîn 2020 (UTC)
== [[itîmad li ser kirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 16:32, 15 çiriya pêşîn 2020 (UTC)
== [[sengesor]] ==
{{r|Saberabdollahizad}} ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:00, 16 çiriya pêşîn 2020 (UTC)
:Navçeya Mirgewerê, Ûrmîye. {{bêîmze|Saberabdollahizad}}
== [[zenek]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:03, 16 çiriya pêşîn 2020 (UTC)
:{{r|Saberabdollahizad}} [[zenek]] jî li Ûrmiyê tê bikaranîn? --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:53, 18 çiriya pêşîn 2020 (UTC)
== [[pind#p-mane|pind]] ==
Min tenê çavkaniyek dît ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:48, 17 çiriya pêşîn 2020 (UTC)
:Navçeya Mirgewerê, Ûrmîye. {{bêîmze|Saberabdollahizad}}
== [[maqezer]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:53, 18 çiriya pêşîn 2020 (UTC)
:Navçeya Mirgewerê, Ûrmîye. {{bêîmze|Saberabdollahizad}}
== [[pezpezok]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:55, 18 çiriya pêşîn 2020 (UTC)
:Navçeya Mirgewerê, Ûrmîye. {{bêîmze|Saberabdollahizad}}
== [[parapet#p-mane|parapet]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:53, 31 çiriya pêşîn 2020 (UTC)
= Çiriya paşîn 2020 =
== [[quloç#p-mane|quloç]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:43, 19 çiriya paşîn 2020 (UTC)
== [[di ber (yekî) de avêtin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:57, 20 çiriya paşîn 2020 (UTC)
:https://tirsik.net/index.php?mijarid=18749&iro=on&rupel=1 —[[Bikarhêner:Mamoste Dilovan|Mamoste Dilovan]] ([[Gotûbêja bikarhêner:Mamoste Dilovan|gotûbêj]]) 17:37, 20 çiriya paşîn 2020 (UTC)
:: {{r|Mamoste Dilovan}} [[di ber re avêtin]] heye. lê te wek di ber '''de''' lê zêde kir. Em biguherînin? Gelek çavkanî ji bo di ber re avêtin heye. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:41, 20 çiriya paşîn 2020 (UTC)
== [[hêvastin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:49, 21 çiriya paşîn 2020 (UTC)
== [[lamçîn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:28, 22 çiriya paşîn 2020 (UTC)
== [[poz#p-mane|poz]] ==
Ji bo maneya "[[quz]], [[vajîna]]" ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:28, 22 çiriya paşîn 2020 (UTC)
== [[sihetbexş]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:35, 24 çiriya paşîn 2020 (UTC)
== [[hevjêhatin ji jêhatîbûnê çêtir e]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:14, 25 çiriya paşîn 2020 (UTC)
== [[gerriyan#p-mane|gerriyan]] ==
''Ji bo wateya cereyan (tevger)''. Qasî ku dibînim tenê Cewerî bi kar aniye —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:24, 25 çiriya paşîn 2020 (UTC)
== [[derbend]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:08, 30 çiriya paşîn 2020 (UTC)
= Kanûna paşîn 2021 =
== [[desthelgirtin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:48, 6 kanûna paşîn 2021 (UTC)
== [[êşewî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:52, 7 kanûna paşîn 2021 (UTC)
== [[sexorr]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:22, 7 kanûna paşîn 2021 (UTC)
== [[sapût]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:06, 12 kanûna paşîn 2021 (UTC)
= Çiriya pêşîn 2022 =
== [[paşbingeh]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:40, 12 çiriya pêşîn 2022 (UTC)
= Kanûna paşîn 2023 =
== [[berê beringa]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:35, 1 kanûna paşîn 2023 (UTC)
== [[mûlûleya xwînê]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:36, 6 kanûna paşîn 2023 (UTC)
== [[mirovdostî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 05:38, 12 kanûna paşîn 2023 (UTC)
== [[derîner]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:02, 15 kanûna paşîn 2023 (UTC)
== [[neteba]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:01, 16 kanûna paşîn 2023 (UTC)
:Maneya "uyruksuz" ji ferhenga Farqînî hatiye kopîkirin wekî din bi giştî bi maneya "nakokî" tê bikaranîn. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:33, 26 hezîran 2026 (UTC)
== [[narkotîkfiroş]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:59, 16 kanûna paşîn 2023 (UTC)
== [[pirik#p-mane|pirik]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:15, 16 kanûna paşîn 2023 (UTC)
== [[ramyarî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ez dibêjim ev peyv tenê bi maneya "fikrî", wek rengdêr heye. Lê belê di soranî de bi şaşemilandineke wekî "siyasî" bi kar anîne, kurmancên me jî rasterast maneya soranî tevlî çend ferhengên hev-kopîkirî kirine û bi vî awayî belkî hin çavkanî hebin. Lê ez dibêjim divê ew çavkanî jî neyên hesibandin. Hin kes zen dikin ku her tiştê di soranî de ripîrast e. Mesele heqeten eletewş e.
Agahiyeke li ser peyvê: "[https://www.welateme.info/kurdi/modules.php?name=News&file=print&sid=686 Welateme.info]"
Li vir peyv bi maneya "fikrî" hatiye bikaranîn: "[https://xwebun1.org/ziman-sirhelal-e/ Xwebûn]". Qewet be. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:36, 19 kanûna paşîn 2023 (UTC)
== [[dolîwgeh]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:08, 22 kanûna paşîn 2023 (UTC)
= Sibat 2023 =
== [[herebaş]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:13, 11 sibat 2023 (UTC)
== [[balindeyê korare]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].''
Tenê çavkaniyekê tê xuyan, ew jî kitêba "Balindeyên Kurdistanê" yê Îsmaîl Taha Şahîn e (Îsmaîl Taha Şahîn (2006). Balindeyên Kurdistanê, 1-4. Spîrêz, Duhok). Ev kitêb ji ser înternetê wek word jî peyda dibe. Xuya ye ku ji Weşanên Spîrez fîzîken jî çap bûye. Lê wekî çavkanî tenê ev tê xuyan.
—[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:10, 14 sibat 2023 (UTC)
== [[dîbeyt]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:13, 18 sibat 2023 (UTC)
== [[çend pat]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:35, 24 sibat 2023 (UTC)
== [[rabînîn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji bo kurmancî bêçavkanî ye. Ger ji bo soranî çavkanî hebin jî divê ji bo soranî bi herfên aramî were nivîsîn.
An ger halê latînîkirî ya peyveke soranî be, dîsa divê ev hal were eşkerekirin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:36, 26 sibat 2023 (UTC)
= Adar 2023 =
== [[qirar#p-mane|qirar]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:23, 2 adar 2023 (UTC)
== [[pîşpêkirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê di nivîseke online ya Cemal Nebez de derbas dibe. Dibe ku peyveke başûriyan be. Û di wê nivîsa Cemal Nebezê bi forma "pîş bi ... bikin" jî derbas dibe. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:29, 3 adar 2023 (UTC)
== [[kûcag]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:27, 27 adar 2023 (UTC)
== [[destbizavî kirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].''
Xuya ye ku ev peyv tenê di kitêba “''Nameyek Şernexê''” yê Evdirehman Gundikî de derbas bûye. Û ji wir jî Mistefa Aydoganî maneya peyvê di hejmara 61em ya Kovara ''Kurmancî'' de belav kiriye (rûpela 2yem). Lê belê tenê yek çavkaniyekê ne bes e ji bo ku em vê peyvê di vê ferhengê de wekî peyveke çavkanî-temam belav bikin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:40, 28 adar 2023 (UTC)
== [[germav baş]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:23, 31 adar 2023 (UTC)
== [[germavxweş]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:27, 31 adar 2023 (UTC)
= Gulan 2023 =
== [[kirbend]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:34, 5 gulan 2023 (UTC)
: Çêkerê rûpelê wek not nivîsiye ku peyv ji herêma Çewlikê ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:24, 6 gulan 2023 (UTC)
== [[We are off now]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:13, 22 gulan 2023 (UTC)
== [[baran ji erd û esmana lê diket]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:46, 26 gulan 2023 (UTC)
== [[sîba]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:44, 30 gulan 2023 (UTC)
== [[bîrîner]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:20, 30 gulan 2023 (UTC)
= Hezîran 2023 =
== [[bidestmiz]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:49, 10 hezîran 2023 (UTC)
= Tîrmeh 2023 =
== [[parzeng]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:01, 15 tîrmeh 2023 (UTC)
== [[zerpedest]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:05, 15 tîrmeh 2023 (UTC)
== [[heta destên mirov nebine gû, devê mirov nabite tû]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:27, 19 tîrmeh 2023 (UTC)
== [[çemê mezin tê dibore diçe]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:38, 19 tîrmeh 2023 (UTC)
== [[kevanê nebî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:45, 19 tîrmeh 2023 (UTC)
== [[teybûr]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê li malpera yuksekovahaber.com-ê derbas dibe, li wir jî bi maneya "çare, çareserî"yê hatiye emilandin, ne bi vê maneyê. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:00, 19 tîrmeh 2023 (UTC)
== [[nikêtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:22, 19 tîrmeh 2023 (UTC)
= Tebax 2023 =
== [[prêze]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:19, 15 tebax 2023 (UTC)
== [[qelye]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:59, 25 tebax 2023 (UTC)
= Îlon 2023 =
== [[hetwan]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:21, 14 îlon 2023 (UTC)
== [[milyonmasî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:06, 21 îlon 2023 (UTC)
== [[tofana mêjî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:20, 21 îlon 2023 (UTC)
== [[îshaf]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:57, 23 îlon 2023 (UTC)
== [[odeya karkirinê]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:57, 26 îlon 2023 (UTC)
== [[odeya şixulînê]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:42, 26 îlon 2023 (UTC)
== [[hîter]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:08, 26 îlon 2023 (UTC)
= Çiriya pêşîn 2023 =
== [[vîtamîn waw]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:20, 1 çiriya pêşîn 2023 (UTC)
== [[berhan]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:21, 3 çiriya pêşîn 2023 (UTC)
== [[sêlikdêr]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:16, 10 çiriya pêşîn 2023 (UTC)
== [[qewandêr]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:20, 10 çiriya pêşîn 2023 (UTC)
== [[darav]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:04, 11 çiriya pêşîn 2023 (UTC)
= Çiriya paşîn 2023 =
== [[kansernasî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:54, 14 çiriya paşîn 2023 (UTC)
== [[golgir]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:06, 15 çiriya paşîn 2023 (UTC)
== [[ahardar]] ==
Tenê Zana Farqînî —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:34, 26 çiriya paşîn 2023 (UTC)
= Kanûna pêşîn 2023 =
== [[Kî mal ezîz bike, can rezîl dike; kî mal rezîl bike, can ezîz dike.]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:55, 2 kanûna pêşîn 2023 (UTC)
== [[porsing]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:22, 2 kanûna pêşîn 2023 (UTC)
== [[newelatî kirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:57, 2 kanûna pêşîn 2023 (UTC)
== [[newelatîkirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:58, 2 kanûna pêşîn 2023 (UTC)
== [[alîkar kirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 18:42, 3 kanûna pêşîn 2023 (UTC)
== [[aramoş kirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' -- [[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 18:48, 3 kanûna pêşîn 2023 (UTC)
== [[bêvil kirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 18:56, 4 kanûna pêşîn 2023 (UTC)
== [[dijberiya naverokî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 22:43, 8 kanûna pêşîn 2023 (UTC)
== [[bersivîn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'', û her wiha ne li gorî qayideyên kurdî (kurmancî) ye. —[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 22:08, 11 kanûna pêşîn 2023 (UTC)
== [[hevalzewac]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:25, 18 kanûna pêşîn 2023 (UTC)
= Kanûna paşîn 2024 =
== [[raperk]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:40, 15 kanûna paşîn 2024 (UTC)
:Bi wê manê nîne. Bi maneke dî heye. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:26, 6 tebax 2024 (UTC)
= Sibat 2024 =
== [[bi navê lîstin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:02, 3 sibat 2024 (UTC)
: Li ser agahdarkirina çêkerê rûpelê me şablona "dever"ê tevlî kir. Peyv ji herêma Qoser, Mêrdînê ye. Me li qismê "Bikaranîn"ê jî vê yekê dîyar kir. Ji xeynî vê me wê peyvê ji rûpelên din jî bir. Bi vî awayî ev made kare were girtin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:28, 10 nîsan 2024 (UTC)
== [[preskirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:43, 11 sibat 2024 (UTC)
== [[pres kirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:43, 11 sibat 2024 (UTC)
== [[Xwedê te têr bike]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:41, 13 sibat 2024 (UTC)
== [[isad]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:09, 22 sibat 2024 (UTC)
== [[razemendîtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:44, 27 sibat 2024 (UTC)
= Adar 2024 =
== [[zilhêzî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:19, 5 adar 2024 (UTC)
== [[hingihîn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:32, 13 adar 2024 (UTC)
== [[xore]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:30, 15 adar 2024 (UTC)
== [[melef]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:55, 19 adar 2024 (UTC)
== [[uğursuz ayak]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:11, 23 adar 2024 (UTC)
== [[şepûk]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:22, 23 adar 2024 (UTC)
== [[agirberdêrî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:04, 26 adar 2024 (UTC)
== [[kîrquz]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:00, 26 adar 2024 (UTC)
== [[kîrquzdê]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:01, 26 adar 2024 (UTC)
== [[quzgêj]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:03, 26 adar 2024 (UTC)
= Nîsan 2024 =
== [[hîkarîkerî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:53, 1 nîsan 2024 (UTC)
== [[hîkarîker]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:54, 1 nîsan 2024 (UTC)
== [[hîkarîdarî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:55, 1 nîsan 2024 (UTC)
== [[hîkarîdar]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:56, 1 nîsan 2024 (UTC)
== [[bihîkarîtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:57, 1 nîsan 2024 (UTC)
== [[bihîkarî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:58, 1 nîsan 2024 (UTC)
== [[bêhîkarîtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:58, 1 nîsan 2024 (UTC)
== [[bêhîkarî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:59, 1 nîsan 2024 (UTC)
== [[bêhîkarî bûn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:00, 1 nîsan 2024 (UTC)
== [[bêhîkarî kirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:00, 1 nîsan 2024 (UTC)
== [[bêhîkarîbûn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:01, 1 nîsan 2024 (UTC)
== [[bêhîkarîkirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:01, 1 nîsan 2024 (UTC)
== [[hîkarîkirî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:02, 1 nîsan 2024 (UTC)
== [[hîkarîkirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:03, 1 nîsan 2024 (UTC)
== [[hîkarî kirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:07, 1 nîsan 2024 (UTC)
== [[rayda]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:40, 1 nîsan 2024 (UTC)
== [[bêrayda]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:42, 1 nîsan 2024 (UTC)
== [[bêraydayî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:43, 1 nîsan 2024 (UTC)
== [[bêraydatî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:43, 1 nîsan 2024 (UTC)
== [[bêrayda bûn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:43, 1 nîsan 2024 (UTC)
== [[bêrayda kirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:43, 1 nîsan 2024 (UTC)
== [[bêraydabûn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:44, 1 nîsan 2024 (UTC)
== [[bêraydakirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:44, 1 nîsan 2024 (UTC)
== [[birayda]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:44, 1 nîsan 2024 (UTC)
== [[biwerêç]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:46, 1 nîsan 2024 (UTC)
== [[biwerêçî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:46, 1 nîsan 2024 (UTC)
== [[biwerêçîtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:47, 1 nîsan 2024 (UTC)
== [[biwerêçtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:47, 1 nîsan 2024 (UTC)
== [[werêç]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:49, 1 nîsan 2024 (UTC)
== [[werêç kirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:50, 1 nîsan 2024 (UTC)
== [[werêçkirî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:50, 1 nîsan 2024 (UTC)
== [[werêçkirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:51, 1 nîsan 2024 (UTC)
== [[wişto]] ==
@[[Bikarhêner:Zerwanda]] Çavkanî ji bo kurmancî tine ye. Zazakî ye? —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:19, 1 nîsan 2024 (UTC)
:ji devera mûşê, aliyê diya min "wişto/wiştik" digotin. [[Bikarhêner:Zerwanda|Zerwanda]] ([[Gotûbêja bikarhêner:Zerwanda|gotûbêj]]) 20:44, 1 nîsan 2024 (UTC)
== [[xewgerî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:19, 2 nîsan 2024 (UTC)
== [[xewgerokî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:28, 2 nîsan 2024 (UTC)
== [[nimêh]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:51, 2 nîsan 2024 (UTC)
== [[فعال]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' [[Bikarhêner:Ghybu|Gyhbu]] di 2021an de li ser rûpela wî tevlî kirîye. Lê ji ber nebûna vê sîstema me tevlî vir nebûye. Lewma min anî ser vir jî. Wê gavê tenê ji bo maneya "kar" ev şablon hatîye tevlîkirin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:27, 3 nîsan 2024 (UTC)
== [[pêjor]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:46, 6 nîsan 2024 (UTC)
== [[hafil]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:48, 6 nîsan 2024 (UTC)
== [[micemi]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Muhtemelem şiklê rast wek "micemî" ye, lê ew jî bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:52, 9 nîsan 2024 (UTC)
== [[hesaba xwe]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji xeynî van ev forma wê jî bêçavkanî ne: "[[hisaba xwe]] / [[hesaba xo]] / [[hisaba xo]]". — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:25, 9 nîsan 2024 (UTC)
== [[leşkerma]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:53, 24 nîsan 2024 (UTC)
= Gulan 2024 =
== [[serîi]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Wek "serî" belkî li kar be, lê wekî "serîi" çavkanî peyda nabe. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:20, 2 gulan 2024 (UTC)
== [[virgu]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Bêçavkanî tê xuyan. Peyv bi tirkî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:49, 2 gulan 2024 (UTC)
== [[xwerre]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:57, 20 gulan 2024 (UTC)
= Hezîran 2024 =
== [[di nav deryaya peyvan de avjenî dikir]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:34, 4 hezîran 2024 (UTC)
== [[berbixwe]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:03, 10 hezîran 2024 (UTC)
== [[şipyakî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:08, 10 hezîran 2024 (UTC)
:"şipêkî" heye [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:20, 27 tîrmeh 2024 (UTC)
== [[wetalane]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:18, 10 hezîran 2024 (UTC)
== [[wetalî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:19, 10 hezîran 2024 (UTC)
== [[wetalîtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:20, 10 hezîran 2024 (UTC)
== [[wetaltî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:20, 10 hezîran 2024 (UTC)
== [[se direye karwan dibuhire]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:49, 16 hezîran 2024 (UTC)
== [[se direwît, karwan bi rêka xo diçît]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:53, 16 hezîran 2024 (UTC)
== [[se direwît, karwan diburît]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:54, 16 hezîran 2024 (UTC)
== [[se direyê karwan dibûrê]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:55, 16 hezîran 2024 (UTC)
== [[se direye karvan li riya xwe diçe]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:56, 16 hezîran 2024 (UTC)
== [[se direye û kerwan dibihure]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:00, 16 hezîran 2024 (UTC)
== [[hingê dinya]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:07, 18 hezîran 2024 (UTC)
== [[berdanberdan]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:22, 24 hezîran 2024 (UTC)
== [[nîska mala Barzan]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:05, 25 hezîran 2024 (UTC)
= Tîrmeh 2024 =
== [[avmêwe]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:41, 16 tîrmeh 2024 (UTC)
== [[nihalok]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:53, 24 tîrmeh 2024 (UTC)
== [[nihalk]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:54, 24 tîrmeh 2024 (UTC)
== [[niwalok]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:54, 24 tîrmeh 2024 (UTC)
== [[niwalk]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:55, 24 tîrmeh 2024 (UTC)
== [[niwalik]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:55, 24 tîrmeh 2024 (UTC)
== [[nehalok]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:56, 24 tîrmeh 2024 (UTC)
== [[nehalk]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:56, 24 tîrmeh 2024 (UTC)
== [[nehalik]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:57, 24 tîrmeh 2024 (UTC)
== [[alîkarxwazî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:16, 24 tîrmeh 2024 (UTC)
== [[nihalik]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:19, 24 tîrmeh 2024 (UTC)
== [[zêrîb]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Bi dîtina min, ev form bêçavkanî ye. Dibe ku ji bo forma "zerîb" çavkanî hebe, lê ew form li ser Wîkîferhengê wek made nehatîye çêkirin. Pir kêm be jî ev peyv wek "zerîp" jî li cihekî derbas bûye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:31, 24 tîrmeh 2024 (UTC)
== [[qanat]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev peyv bi maneya "kanal"ê nîne, xelet e. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:59, 25 tîrmeh 2024 (UTC)
== [[qenat]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev peyv bi maneya "kanal"ê nîne, xelet e. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:59, 25 tîrmeh 2024 (UTC)
:Min 1 çavkanî dît, "Ev kes rojê 6-7 qenatên TV ya diğere û diaxive" https://darkamazi.info/archives/1019704 (bi lêgerana "qenatên", ji ber ko lêgeranên dî tijî tiştên dî derdixin)
:Lê mimkun e xelet nivîsîbe. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:31, 27 tîrmeh 2024 (UTC)
== [[şkaftmend]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:08, 25 tîrmeh 2024 (UTC)
:3 çavkanî hene. Lê xuya dike jêdera wan hemû ferhenga tirsik.netê e.
:* Çavkanî 1: https://tirsik.net/ferheng?query=şkaftmend (berî 2014, lê tarîx nîne)
:* Çavkanî 2: https://ku.wikipedia.org/wiki/Deranderî (2011)
:* Çavkanî 3: https://x.com/zerdeceno/status/1155331427510247425 (2019)
:[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:28, 27 tîrmeh 2024 (UTC)
== [[dan hev#p-mane|dan hev]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev mane li ser çavkanîyan peyda nabe. Tenê çêkerê rûpelê vê maneyê nivîsîye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:08, 25 tîrmeh 2024 (UTC)
== [[baristdar]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:47, 25 tîrmeh 2024 (UTC)
== [[baristdarî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:48, 25 tîrmeh 2024 (UTC)
== [[baristdarîtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:49, 25 tîrmeh 2024 (UTC)
== [[baristdartî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:50, 25 tîrmeh 2024 (UTC)
== [[bibaristî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:51, 25 tîrmeh 2024 (UTC)
== [[bibarist]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:52, 25 tîrmeh 2024 (UTC)
== [[bibaristîtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:53, 25 tîrmeh 2024 (UTC)
== [[bêbaristî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:54, 25 tîrmeh 2024 (UTC)
== [[bêbarist]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:55, 25 tîrmeh 2024 (UTC)
== [[peydabûnîtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:52, 27 tîrmeh 2024 (UTC)
== [[nexşvan]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:05, 27 tîrmeh 2024 (UTC)
== [[nexşvanî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:05, 27 tîrmeh 2024 (UTC)
== [[lêvikî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:47, 27 tîrmeh 2024 (UTC)
== [[lêvik]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Min zêde nemeyzand. —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:48, 27 tîrmeh 2024 (UTC)
== [[şerenîx kirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:51, 27 tîrmeh 2024 (UTC)
== [[sala çîn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:09, 29 tîrmeh 2024 (UTC)
== [[berê pêşîn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:57, 30 tîrmeh 2024 (UTC)
== [[berê ewilî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:57, 30 tîrmeh 2024 (UTC)
= Tebax 2024 =
== [[xwîndijmin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:02, 4 tebax 2024 (UTC)
== [[reîsîtî]]/[[reysîtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 18:17, 6 tebax 2024 (UTC)
== [[soranîaxivî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 18:43, 6 tebax 2024 (UTC)
== [[helîna bildo]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji 2020a ve şablon li wir e min tenê li vir zêde kir. —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:56, 6 tebax 2024 (UTC)
== [[hilbijêrînerî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' "Hilbij" rihê peyvê ye, "-er" jî maneya "kesê dike" dide, qertafa "-îner / -înerî" ya li dawîyê bi eşkereyî xelet e. Û ev peyv bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:45, 7 tebax 2024 (UTC)
== [[îqlîmtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:43, 10 tebax 2024 (UTC)
== [[jîrbêjî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev peyv ger di soranî de ji bo wê çavkanîyên têr hebe, tenê wek "Nivîsîna bi herfên latînî ya peyva ..." kare were qeydkirin. Lê nabe ku wek kurmancî be, were qeydkirin. Ji bo kurmancî tenê di meqaleyekê de derbas dibe, ew jî ji alî başûrîyekî ve hatîye nivîsîn. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:55, 10 tebax 2024 (UTC)
== [[hîgyen]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê ev form bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:40, 12 tebax 2024 (UTC)
== [[kolîner]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:45, 12 tebax 2024 (UTC)
== [[poşmanî kişîn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê di çavkanîyekê de peyda dibe. Ew çavkanîya dayî jî ihtîmal e ku bi tesîra zimanê tirkî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:44, 13 tebax 2024 (UTC)
== [[para hevpar a herî mezin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:09, 14 tebax 2024 (UTC)
== [[cara hevpar a herî biçûk]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:10, 14 tebax 2024 (UTC)
== [[regjimar]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:16, 14 tebax 2024 (UTC)
== [[nîvrengî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:33, 18 tebax 2024 (UTC)
== [[nîvdûrgeh]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Wek "guharto" hatiye qeydkirin, lê yek nikare wilo bêje. Ne "guharto" ye, ji ber wê çavkanî hewce ne. —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:39, 18 tebax 2024 (UTC)
== [[nîvtewlîsî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:44, 18 tebax 2024 (UTC)
== [[nîvrewa]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:44, 18 tebax 2024 (UTC)
== [[nîvşehtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:46, 18 tebax 2024 (UTC)
== [[nîvfalincî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:46, 18 tebax 2024 (UTC)
== [[nîvgilkarî]] ==
Ferhenga Sa.Sa.
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:48, 18 tebax 2024 (UTC)
== [[kesîkirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:16, 18 tebax 2024 (UTC)
== [[biryarbirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:38, 24 tebax 2024 (UTC)
= Îlon 2024 =
== [[qîblename]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:15, 1 îlon 2024 (UTC)
== [[cihetnima]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].''
Ji [https://bianet.org/yazi/ferhenga-ser-u-amrazen-ser-ji-kovara-ronahiye-2-196299 vir] hatiye —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:27, 1 îlon 2024 (UTC)
== [[qûnderîtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:36, 7 îlon 2024 (UTC)
== [[hevpîşehî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:48, 14 îlon 2024 (UTC)
== [[hevpîşeyî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Wek ''navdêr'' bêçavkanî ye. Wek ''rengdêr'' hebe jî, kêmçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:50, 14 îlon 2024 (UTC)
== [[hempay]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:04, 14 îlon 2024 (UTC)
== [[nîs]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:43, 14 îlon 2024 (UTC)
== [[êxbarçî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji bo ''îxbarçî'' çavkanîyekê peyda dibe, lê kêm e. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:06, 14 îlon 2024 (UTC)
== [[muxbîrîtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:38, 14 îlon 2024 (UTC)
== [[ixbarçî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:43, 14 îlon 2024 (UTC)
== [[westgeha pasê]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:33, 19 îlon 2024 (UTC)
== [[avikmadk]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:24, 19 îlon 2024 (UTC)
== [[ferwerîn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:18, 20 îlon 2024 (UTC)
== [[bipayderî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:12, 20 îlon 2024 (UTC)
== [[bipayderîtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:13, 20 îlon 2024 (UTC)
== [[bipaydertî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:13, 20 îlon 2024 (UTC)
== [[bipedalî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:14, 20 îlon 2024 (UTC)
== [[bipedalîtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:14, 20 îlon 2024 (UTC)
== [[bipedaltî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:14, 20 îlon 2024 (UTC)
== [[pedaldarî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:15, 20 îlon 2024 (UTC)
== [[pedaldarîtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:15, 20 îlon 2024 (UTC)
== [[pedaldartî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:16, 20 îlon 2024 (UTC)
== [[ciwên]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:11, 22 îlon 2024 (UTC)
== [[belgebirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:31, 23 îlon 2024 (UTC)
== [[avsîn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Dibe ku ev kelîme biçavkanî be, lê pir bêagahî hatîye qeydkirin. Biçavkanî be jî, ji ber qeydkirina bêagahî (li ser madeyê agahî kêm hatine pêşkêşkirin) em rûpelê jê bibin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:53, 23 îlon 2024 (UTC)
:@[[Bikarhêner:Bikarhêner|Bikarhêner]] Ma ne çêtir e li "Daxwazên zelalkirinê" be naxwe? [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 13:40, 10 çiriya paşîn 2024 (UTC)
:: {{r|Guherto}} Bi min em karin vê madeyê ji ber bêagahîbûna wî, îlaweyî "Daxwazên jêbirinê" bikin, lê "Daxwazên zelalkirinê" nabe. Wekî din ji ber ku dikeve çarçoveya her du rûpelan jî kîjan be jî dibe, lê madem me li vir da destpêkirin, bila ji vir dewam bike dengdana li ser vê kelîmeyê. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:22, 10 çiriya paşîn 2024 (UTC)
== [[kûvank]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas tenê formekê be jî, bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:14, 27 îlon 2024 (UTC)
== [[kikark]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas formekê be jî, bêçavkanî dixuye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:40, 27 îlon 2024 (UTC)
== [[kîfkarik]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas tenê formekê be jî, bêçavkanî dixuye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:45, 27 îlon 2024 (UTC)
== [[kuvank]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas formekê be jî, bêçavkanî dixuye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:53, 27 îlon 2024 (UTC)
== [[kûvarik]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas tenê formekê be jî, bêçavkanî dixuye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:01, 27 îlon 2024 (UTC)
= Çiriya pêşîn 2024 =
== [[muhil]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê qismê kurdî bêçavkanî ye, ne ya tirkî. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:00, 9 çiriya pêşîn 2024 (UTC)
== [[muhilk]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:00, 9 çiriya pêşîn 2024 (UTC)
== [[jêrmal]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:59, 15 çiriya pêşîn 2024 (UTC)
= Çiriya paşîn 2024 =
== [[bîrxistiner]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:38, 14 çiriya paşîn 2024 (UTC)
== [[wisa gotin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ne ferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:13, 15 çiriya paşîn 2024 (UTC)
== [[tenzîlatî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:12, 16 çiriya paşîn 2024 (UTC)
== [[armancparêz]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:03, 19 çiriya paşîn 2024 (UTC)
== [[şikaftmend]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:06, 19 çiriya paşîn 2024 (UTC)
== [[derander]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:08, 19 çiriya paşîn 2024 (UTC)
== [[deranderî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:09, 19 çiriya paşîn 2024 (UTC)
== [[derxwenîn]] ==
@[[User:Keyomerd]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:38, 19 çiriya paşîn 2024 (UTC)
== [[kiyû]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:53, 22 çiriya paşîn 2024 (UTC)
== [[goçavik]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:03, 23 çiriya paşîn 2024 (UTC)
== [[hûrhesibaner]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:19, 23 çiriya paşîn 2024 (UTC)
== [[heybera zindî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:01, 23 çiriya paşîn 2024 (UTC)
== [[misadereker]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:51, 24 çiriya paşîn 2024 (UTC)
== [[kêmtirkar]] ==
@[[Bikarhêner:Cyrus the virus|Cyrus the virus]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:11, 24 çiriya paşîn 2024 (UTC)
== [[cudagir]] ==
@[[Bikarhêner:Cyrus the virus|Cyrus the virus]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:15, 24 çiriya paşîn 2024 (UTC)
== [[qerwaşgir]] ==
@[[Bikarhêner:Cyrus the virus|Cyrus the virus]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:42, 24 çiriya paşîn 2024 (UTC)
== [[mişkilûr]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:45, 24 çiriya paşîn 2024 (UTC)
== [[agirbiran]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:54, 24 çiriya paşîn 2024 (UTC)
== [[alan]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:55, 24 çiriya paşîn 2024 (UTC)
== [[alêdû]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:56, 24 çiriya paşîn 2024 (UTC)
== [[henaseker]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:37, 25 çiriya paşîn 2024 (UTC)
== [[nial]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji xeynî vê, maneya 2yem ya di madeya "nihal" de (navdêr 2) jî bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:46, 27 çiriya paşîn 2024 (UTC)
== [[gilçim]] ==
@[[Bikarhêner:Roj Rewandiz|Roj Rewandiz]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:28, 29 çiriya paşîn 2024 (UTC)
:Ez ji bajarê Kobaniyê me. Min ev peyv ji ser zimanê dê û dapîra xwe girt. Ez gelekî ji vê peyvê bawer im ji ber ku devoka min e. [[Bikarhêner:Roj Rewandiz|Roj Rewandiz]] ([[Gotûbêja bikarhêner:Roj Rewandiz|gotûbêj]]) 19:14, 23 kanûna pêşîn 2024 (UTC)
::@[[Bikarhêner:Roj Rewandiz|Roj Rewandiz]] Mala te ava. Ji ber ku çavkaniyên nivîskî tine ne em ê vê kelîmeyê wek [[Wîkîferheng:Pîvekên_tevlîkirinê#Peyvên_herêmî|herêmî]] nîşan bidin. [[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:22, 25 kanûna pêşîn 2024 (UTC)
== [[reşeme kirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Li gorî çêkera sayfeyê li Kobaniyê li kar e. Loma dikare wekî herêmî nîşankirin —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:35, 29 çiriya paşîn 2024 (UTC)
:Li Kobaniyê dibêjin: ‘Tizbiyê min li xwe reş û reşeme kir’ Anko Tizbî bir û venegerand Înkar kir. [[Bikarhêner:Roj Rewandiz|Roj Rewandiz]] ([[Gotûbêja bikarhêner:Roj Rewandiz|gotûbêj]]) 23:48, 7 kanûna paşîn 2025 (UTC)
= Kanûna pêşîn 2024 =
== [[çarkunc]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:21, 27 kanûna pêşîn 2024 (UTC)
= Kanûna paşîn 2025 =
== [[pevnatî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev kelîme wek kurtkirina ji "bi hev nehatî" hatîye fikirîn, ihtimal e ku wek sunî hatîye çêkirin û bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:43, 6 kanûna paşîn 2025 (UTC)
== [[lihevnatîbûn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Wek formeke "lihevnehatîbûn"ê hatîye fikirîn, lê bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:49, 6 kanûna paşîn 2025 (UTC)
== [[Binxetê]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Em zanin ku ji ber sînora Tirkîyeyê ku Cizîrê dike du perçe û ji parçeya binî re Binxet tê gotin ku kurd lê dijîn. Feqet min herêma Binxetê seh nekirîye, û bi tedqîqeke neberfireh jî çavkanî peyda nekir ji bo vê peyvê. Lewma bi min mahîyeta vê madeyê û qeydkirina wek "Binxetê" xelet e. Ger ji bo herêma tarîfkirî çavkanî nîn be, em vê madeyê bikin "'''Binxet'''" û tarîfa wê jî bikin "''Navê Rojavayê Kurdistanê ku li binê xeta Tirkîye - Sûrîyeyê dimîne.''" — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:22, 24 kanûna paşîn 2025 (UTC)
== [[xirecir çêkirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' "''Çê''" bi maneya "''baş''" e, û "''çêkirin''" ji bo tiştên pozîtîv likar e, li nav milet jî ev wisa ye. Lewma ev xelet e. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:00, 24 kanûna paşîn 2025 (UTC)
== [[sîrkxane]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:30, 26 kanûna paşîn 2025 (UTC)
== [[anînder]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Di hin çavkanîyan de wek formeke "''der'''''anîn'''"ê hatîye qeydkirin. Lê belê çavkanîyeke eslî (ne ji kitêbên gramerê) peyda nabe ji bo vê kelîmeyê. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:24, 27 kanûna paşîn 2025 (UTC)
== [[rastî nîşandan]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:14, 30 kanûna paşîn 2025 (UTC)
= Sibat 2025 =
== [[pir hindik#p-mane|pir hindik]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:31, 3 sibat 2025 (UTC)
== [[anteroz]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:19, 15 sibat 2025 (UTC)
== [[veşidandin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:43, 15 sibat 2025 (UTC)
== [[karîwer kirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 02:01, 16 sibat 2025 (UTC)
== [[hil girtin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:06, 17 sibat 2025 (UTC)
== [[wer girtin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:07, 17 sibat 2025 (UTC)
== [[avkûre]] ==
@[[Bikarhêner:Mohajeer|Mohajeer]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:36, 18 sibat 2025 (UTC)
== [[derdek girtin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:42, 18 sibat 2025 (UTC)
== [[vekitandin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:12, 21 sibat 2025 (UTC)
== [[dînperist]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:32, 22 sibat 2025 (UTC)
== [[ayînperist]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:33, 22 sibat 2025 (UTC)
== [[ayînperistî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:33, 22 sibat 2025 (UTC)
== [[ayînperistane]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:33, 22 sibat 2025 (UTC)
== [[piştrastkirinbar]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:45, 23 sibat 2025 (UTC)
== [[diyarkirinbar]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 02:08, 23 sibat 2025 (UTC)
== [[hevhatî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 03:52, 1 adar 2025 (UTC)
== [[kerexne]] ==
@[[Bikarhêner:Rojhilat|Rojhilat]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:05, 1 adar 2025 (UTC)
== [[pawan#p-mane|pawan]] ==
Ferhenga Hejar soranî ye, ji bo maneya "cihê qedexekirî, cihê inhisarî" ji xeynî wê çavkanî heye gelo —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:17, 3 adar 2025 (UTC)
== [[taqane]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 02:11, 6 adar 2025 (UTC)
== [[gosirmetî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:07, 6 adar 2025 (UTC)
== [[matîjêker]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:08, 14 adar 2025 (UTC)
== [[hilewesan]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:14, 16 adar 2025 (UTC)
== [[peydandin#p-mane|peydandin]] ==
Ji bo maneya [[dûre]], [[paşî]], [[piştî]] wê / wî ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:26, 19 adar 2025 (UTC)
== [[peşar]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:36, 19 adar 2025 (UTC)
== [[nûzaf]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:30, 20 adar 2025 (UTC)
== [[deynname]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 20 adar 2025 (UTC)
== [[girtek]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:29, 20 adar 2025 (UTC)
== [[bêşxane]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:25, 23 adar 2025 (UTC)
== [[superleheng]] ==
@[[Bikarhêner:Avestaboy|Avestaboy]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:34, 23 adar 2025 (UTC)
== [[goranparêz]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:54, 27 adar 2025 (UTC)
== [[raber#p-mane|raber]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:09, 1 nîsan 2025 (UTC)
== [[morîvanî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:06, 1 nîsan 2025 (UTC)
== [[wevde]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:17, 3 nîsan 2025 (UTC)
== [[şandêr]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:31, 3 nîsan 2025 (UTC)
== [[giloverî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê li ser Ferhenga Zaravên Teknîkî û hejmara yekem ya kovara Bernamegehê derbas dibe. —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:10, 4 nîsan 2025 (UTC)
== [[xêvjimêr]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:00, 12 nîsan 2025 (UTC)
== [[paşekeft]] ==
@[[Bikarhêner:Jiyar Hesen|Jiyar Hesen]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:11, 13 nîsan 2025 (UTC)
== [[paşekeft kirin]] ==
@[[Bikarhêner:Jiyar Hesen|Jiyar Hesen]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:12, 13 nîsan 2025 (UTC)
== [[hawirkanî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:36, 20 nîsan 2025 (UTC)
== [[hawirkan]] ==
@[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:18, 21 nîsan 2025 (UTC)
: Di çavkanîyeke de "''hawrikan''" (ku wek forma vê kelîmeyê hatîye nîşandayîn û wek "hevrêyan" a kurmancî ye) bi maneya "''friends''"a îngilîzî hatîye emilandin. Wekî din ti çavkanî nîne ji bo vê peyvê. Ger ev "hevrik"a kurmancî be, li vir dîsa xelet e. Bi her awayî divê were jêbirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:28, 21 nîsan 2025 (UTC)
== [[hawirkanî]] ==
@[[Bikarhêner:Cyrus the virus|Cyrus the virus]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:18, 21 nîsan 2025 (UTC)
== [[hawirkanvanî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:18, 21 nîsan 2025 (UTC)
== [[riberiz]] ==
@[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:39, 21 nîsan 2025 (UTC)
:Ez bawer im ku ev hat peyitandin. Min çavkanî di beşa gotûbêjê de dan û şablona bêçavkanîtiyê rakir. [[Bikarhêner:Ferhengvan|Ferhengvan]] ([[Gotûbêja bikarhêner:Ferhengvan|gotûbêj]]) 06:11, 25 nîsan 2025 (UTC)
== [[awam]] ==
@[[User:Ferhengvan|Ferhengvan]] Min ev kelîme di ferhengên din de nedît. Gelo di kurmancî de tê bikaranîn? —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:09, 23 nîsan 2025 (UTC)
:@[[Bikarhêner:Zerwanda|Zerwanda]] tu jî forma [[vam]] ya vê kelîmeyê diemilînî, gelo çavkanî ji bo wê jî heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:11, 23 nîsan 2025 (UTC)
::Min jî li vir peyda kir û dest kar anîn kir, hemin ev li guherrên dengî ên Kurmancî dihat (*ebam > *ewam > *wam > vam; wek *ebaj- > {{q|ku|vajî}}). Min gotibû qey di zarawayê kesekî da hebûye û wî bi ser va kiriye û jixwe nepêkan nîn e ku di zimên da hebe îcar rind e, nê min jî serkanî tine ji bonê. [[Bikarhêner:Zerwanda|Zerwanda]] ([[Gotûbêja bikarhêner:Zerwanda|gotûbêj]]) 21:37, 23 nîsan 2025 (UTC)
:::https://bnk.institutkurde.org/images/pdf/4UVB2YMZG3.pdf
:::Di vê kitêbê de bi forma wam derbas dibe 1 Wam : qerz, dên. " dîsa jî gereg 3 çavkanî hebe.
:::Lê di beşa etîmolojiyê de eger em karibin zimanekî yekgirtî biemilînin, dê baştir be. Wekî din "bi vê enflasyona kelîmeyan" em nikarin ti tiştî bidin fêmkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:54, 23 nîsan 2025 (UTC)
== [[arvanê hûr]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:48, 27 nîsan 2025 (UTC)
== [[damezrak]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:47, 27 nîsan 2025 (UTC)
== [[mezrak]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:49, 27 nîsan 2025 (UTC)
== [[hevhemetî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 6 gulan 2025 (UTC)
== [[navhemetî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 6 gulan 2025 (UTC)
== [[entîte]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:08, 17 gulan 2025 (UTC)
== [[agirvekujêner]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:35, 21 gulan 2025 (UTC)
== [[progres]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 23 gulan 2025 (UTC)
== [[bûncî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:29, 28 gulan 2025 (UTC)
== [[tasît]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:36, 31 gulan 2025 (UTC)
== [[implîcît]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:37, 31 gulan 2025 (UTC)
== [[hewedar]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:14, 31 gulan 2025 (UTC)
== [[destajo]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:38, 31 gulan 2025 (UTC)
== [[binhimbank]] ==
@[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 01:23, 1 hezîran 2025 (UTC)
== [[şîmane]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:31, 2 hezîran 2025 (UTC)
== [[materya]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:12, 5 hezîran 2025 (UTC)
== [[bêtî]] ==
@[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:03, 7 hezîran 2025 (UTC)
== [[rîbat]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:21, 9 hezîran 2025 (UTC)
== [[hevtawan]] ==
@[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:26, 12 hezîran 2025 (UTC)
:Pirsek: "Hevwate" kelîmeyên ku maneyan wan hev in. "hevtawan" çawa dibe "şirîkên sûcekê"? Gereg sûcên ku tiştê wan hev bin? Ew tişt çi ye? Çima dibe şirîk? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:32, 12 hezîran 2025 (UTC)
::Merheba!
::"Hevtawan" anku "şirîkên heman tawanê, kesên ku heman tawan kiriye/dikin", wek "hevkar = şirîkên heman karî, kesên ku heman karî dikin", "hevjîn = şirîkên heman jiyanê, kesên ku bi hev re dijîn"... [[Bikarhêner:Ferhengvan|Ferhengvan]] ([[Gotûbêja bikarhêner:Ferhengvan|gotûbêj]]) 06:11, 30 hezîran 2025 (UTC)
== [[zanîş]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:07, 14 hezîran 2025 (UTC)
== [[zanîşwer]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:07, 14 hezîran 2025 (UTC)
== [[zanmend]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:09, 14 hezîran 2025 (UTC)
== [[zandar]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:08, 14 hezîran 2025 (UTC)
== [[zayîndar]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:12, 14 hezîran 2025 (UTC)
== [[zayindar]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:12, 14 hezîran 2025 (UTC)
== [[akund]] ==
@[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 01:16, 16 hezîran 2025 (UTC)
== [[destbikar]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:41, 22 hezîran 2025 (UTC)
== [[vekitandin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:DarkAngel2100|DarkAngel2100]] ([[Gotûbêja bikarhêner:DarkAngel2100|gotûbêj]]) 10:45, 2 tîrmeh 2025 (UTC)
Çavkanî: Kurdish-English Dictionary by Baran Rizgar
== [[peşarmend]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:54, 5 tîrmeh 2025 (UTC)
== [[zaîd]] ==
@[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:59, 6 tîrmeh 2025 (UTC)
== [[Xrîst]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:13, 10 tîrmeh 2025 (UTC)
== [[hesibanî kirin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:48, 13 tîrmeh 2025 (UTC)
== [[top danîn]] ==
@[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:08, 13 tîrmeh 2025 (UTC)
== [[çûkger]] ==
@[[Bikarhêner:Dûrzan|Dûrzan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:49, 18 tîrmeh 2025 (UTC)
== [[dûneçkar]] ==
@[[Bikarhêner:212.175.166.246|212.175.166.246]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:38, 10 tebax 2025 (UTC)
== [[sermirov]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:22, 13 tebax 2025 (UTC)
== [[nifira Esed]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:00, 19 tebax 2025 (UTC)
== [[dilkrîz]] ==
@[[Bikarhêner:Kurd87612|Kurd87612]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:44, 23 tebax 2025 (UTC)
== [[berxa Xwedê]] ==
@[[Bikarhêner:Kurd87612|Kurd87612]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:28, 31 tebax 2025 (UTC)
== [[destmatî]] ==
@[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:47, 21 îlon 2025 (UTC)
== [[sîbaq]] ==
@[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:33, 27 îlon 2025 (UTC)
== [[mirovê daristanê]] ==
@[[Bikarhêner:Hewarwîkîferheng|Hewarwîkîferheng]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:09, 18 çiriya pêşîn 2025 (UTC)
== [[çavbijîşk]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:30, 24 çiriya pêşîn 2025 (UTC)
== [[makeşar]] ==
@[[Bikarhêner:Avestaboy|Avestaboy]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:46, 14 kanûna pêşîn 2025 (UTC)
:Silav @[[Bikarhêner:Bikarhêner|Bikarhêner]] min bi derew peyv çê nekir. Peyva makeşar di sepana O-ferheng û her wiha di ferhenga online ferhengkurdi.org ya '''Enstîtuya Kurdî ya Stenbolê''' tê xwendin.
:https://ferhengkurdi.org/tr/kelime/make%C5%9Far-n [[Bikarhêner:Avestaboy|Avestaboy]] ([[Gotûbêja bikarhêner:Avestaboy|gotûbêj]]) 11:07, 18 kanûna pêşîn 2025 (UTC)
::Krîterên me yên tevlîkirina kelîmeyan heye. Ev made rîayeta wan krîteran nake. Lewma min vê kelîmeyê li vir bicih kir. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:28, 18 kanûna pêşîn 2025 (UTC)
== [[bihîstinzanî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:30, 23 hezîran 2026 (UTC)
== [[hevdilî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:28, 24 hezîran 2026 (UTC)
== [[kemisandin]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:45, 24 hezîran 2026 (UTC)
== [[kexme]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:53, 24 hezîran 2026 (UTC)
== [[lêpirsyarker]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:32, 24 hezîran 2026 (UTC)
== [[raypirs]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:34, 24 hezîran 2026 (UTC)
== [[helwestpirs]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:34, 24 hezîran 2026 (UTC)
== [[kopirî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' xuyaye maneyeke wekî pir jî heye dikare were zêdekirin —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:33, 25 hezîran 2026 (UTC)
== [[merxeme]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:55, 25 hezîran 2026 (UTC)
== [[mohl]] ==
@[[Bikarhêner:Far ati|Far ati]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:14, 25 hezîran 2026 (UTC)
== [[irfandarî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:30, 26 hezîran 2026 (UTC)
== [[axulme]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:20, 30 hezîran 2026 (UTC)
== [[şewane]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:26, 1 tîrmeh 2026 (UTC)
== [[poezî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:27, 1 tîrmeh 2026 (UTC)
== [[sebaxker]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:20, 1 tîrmeh 2026 (UTC)
== [[sebaxfiroş]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:21, 1 tîrmeh 2026 (UTC)
== [[siboxfiroş]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:21, 1 tîrmeh 2026 (UTC)
== [[diyardenasîtî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 1 tîrmeh 2026 (UTC)
== [[dawxane]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:41, 3 tîrmeh 2026 (UTC)
== [[pêşajotî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:15, 3 tîrmeh 2026 (UTC)
== [[kontînentaltirîn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:35, 3 tîrmeh 2026 (UTC)
== [[azmayîşker]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:16, 3 tîrmeh 2026 (UTC)
== [[ateşparêz]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 05:19, 4 tîrmeh 2026 (UTC)
== [[kurtetarîx]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:52, 4 tîrmeh 2026 (UTC)
== [[besayetî]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:57, 4 tîrmeh 2026 (UTC)
== [[tawbijêr]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:45, 4 tîrmeh 2026 (UTC)
== [[destbir]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:30, 5 tîrmeh 2026 (UTC)
== [[nekider]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:56, 5 tîrmeh 2026 (UTC)
== [[niqar]] ==
—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:39, 5 tîrmeh 2026 (UTC)
== [[parêzîn]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev form li ti derê peyda nabe. Berî çendîn salan hatîye çêkirin. Bi qenaeta min şaş e, lewma em jê bibin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:29, 6 tîrmeh 2026 (UTC)
== [[stêrfizîk]] ==
. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:33, 6 tîrmeh 2026 (UTC)
== [[pêçavik]] ==
. Eger ev kelîmeyeke mehelî be, Jkx şablona {{şx|dever|cihê ku lê tê bikaranîn}} li madeyê zêde bike. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:59, 7 tîrmeh 2026 (UTC)
== [[qerqef]] ==
. Eger ev kelîmeyeke mehelî be, Jkx şablona {{şx|dever|cihê ku lê tê bikaranîn}} li madeyê zêde bike. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:17, 7 tîrmeh 2026 (UTC)
== [[rakar]] ==
. Eger ev kelîmeyeke mehelî be, Jkx şablona {{şx|dever|cihê ku lê tê bikaranîn}} li madeyê zêde bike. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:30, 7 tîrmeh 2026 (UTC)
== [[remilîn]] ==
. Eger ev kelîmeyeke mehelî be, Jkx şablona {{şx|dever|cihê ku lê tê bikaranîn}} li madeyê zêde bike. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:36, 7 tîrmeh 2026 (UTC)
== [[segurî]] ==
. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:51, 7 tîrmeh 2026 (UTC)
== [[serdev]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:10, 7 tîrmeh 2026 (UTC)
== [[serziman]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:01, 7 tîrmeh 2026 (UTC)
== [[tenîsk]] ==
di Înternetê de gelek netîce derdikevin lê ji bo ku dûre ez kontrol bikim û çavkaniyên sehîh binivîsim li vir îlawe dikim. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:53, 7 tîrmeh 2026 (UTC)
== [[tertî]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:58, 7 tîrmeh 2026 (UTC)
== [[tirut]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:25, 7 tîrmeh 2026 (UTC)
== [[tizqa]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:28, 7 tîrmeh 2026 (UTC)
== [[têkilîdêr]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:31, 7 tîrmeh 2026 (UTC)
== [[tîtalk]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:33, 7 tîrmeh 2026 (UTC)
== [[vircoq]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 7 tîrmeh 2026 (UTC)
== [[xilêbat]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]]. Li gorî kurteya çêkirina sayfeyê li Qamişlo û Amûdê tê bikaranîn. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:14, 7 tîrmeh 2026 (UTC)
== [[xin_û_cûc]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 7 tîrmeh 2026 (UTC)
== [[çiteba]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:38, 7 tîrmeh 2026 (UTC)
== [[desttêl]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:45, 8 tîrmeh 2026 (UTC)
== [[Mîmedol]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:51, 8 tîrmeh 2026 (UTC)
== [[alaf]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:01, 8 tîrmeh 2026 (UTC)
== [[aşirme]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:13, 10 tîrmeh 2026 (UTC)
== [[geledîmentî]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:54, 13 tîrmeh 2026 (UTC)
== [[çendîmentî]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:54, 13 tîrmeh 2026 (UTC)
== [[rojeng]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:41, 18 tîrmeh 2026 (UTC)
== [[bereyîşk]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:47, 19 tîrmeh 2026 (UTC)
== [[wesekname]] ==
''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:08, 22 tîrmeh 2026 (UTC)
== [[cemaetgeh]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:17, 24 tîrmeh 2026 (UTC)
== [[iblîskanî]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:27, 30 tîrmeh 2026 (UTC)
== [[pehnik]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:51, 4 tebax 2026 (UTC)
:# Kamiran bedirxan û H. Muhammed bi maneya guwerte bi kar tînin.
:# Navê Çiyayek e li Hawarê derbas dibe
:# Farqînî tenê dibêje "yassı"
:#* [https://usercontent.one/wp/portal.arsivakurd.org/wp-content/uploads/2021/08/Azadiya-welat_67.pdf?media=1709107483 Azadiya welat hj 67] Roşan Lezgîn kevirên pehnik
:# Ferhenga destî pahnik pehnik dibêje
:# Rojen barnas li vir bi çi mana bi kar tîne?
:#* {{jêder-kitêb|ku|jêgirtin=... '''pehnika''' dirandar tê kişandin û ji nû ve bi mîxên têlkî ve tê girêdan ku firk û sistî nekevê. Piştî ku dirûtina rû bi binpiyê hundirîn ve xelas bû vêca dora binpiyê derva (binî) tê. Binpiyê binî li ser yê hun- dirîn an bitenê bi...|sal=2013|nivîskar=Rojen Barnas, Nûbihar|url=http://books.google.com.tr/books?id=pVDKEAAAQBAJ&pg=PA67&dq=%22wan+pehnikan%22+OR+%22pehnik%C3%AA%22+OR+%22pehnikin%22+OR+%22pehnikek%C3%AA%22+OR+%22pehnika%22+OR+%22w%C3%AA+pehnik%C3%AA%22+OR+%22pehnikino%22+OR+%22pehnikine%22&hl=&cd=4&source=gbs_api|sernav=Sîlvan/ Silîvan / Farqîn|weşanxane=PAK AJANS YAYINCILIK TURİZM VE DIŞ TİCARET LİMİTED ŞİRKETİ|ISBN=9786055402884|rûpel=67}}
:[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:40, 6 tebax 2026 (UTC)
== [[temirîndox]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:56, 6 tebax 2026 (UTC)
== [[kansêrolojî]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:17, 6 tebax 2026 (UTC)
== [[navçeparêzî]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:09, 6 tebax 2026 (UTC)
== [[goganîbûnî]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:23, 15 tebax 2026 (UTC)
== [[zewijandin]] ==
Bêyî çavkaniyan e. --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 18:34, 22 tebax 2026 (UTC)
== [[karbes]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 12:42, 29 tebax 2026 (UTC)
== [[biehliyet]] ==
Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:41, 31 tebax 2026 (UTC)
l73xne3qifpblfoojp2c2dag2b6oxcd
Bikarhêner:Wikihez/common.js
2
873671
6347389
6347248
2026-08-31T15:21:42Z
Wikihez
7344
6347389
javascript
text/javascript
/*---------Gadget-morebits.js-------------
[[Bikarhêner:Wikihez/skrîpt/Gadget/Gadget-morebits.js]]
[[Bikarhêner:Wikihez/skrîpt/Gadget/Gadget-morebits.css]]*/
mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/skrîpt/Gadget/Gadget-morebits.css&action=raw&ctype=text/css', 'text/css');
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/Gadget/Gadget-morebits.js&action=raw&ctype=text/javascript');
importScript( 'Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js' ); // Backlink: [[Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]]
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/load.js&action=raw&ctype=text/javascript');
/*---------Gadget-DefSideBoxes.js-------------
[[Bikarhêner:Wikihez/Gadget-DefSideBoxes.js]]
[[Bikarhêner:Wikihez/Gadget-DefSideBoxes.css]]
mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-DefSideBoxes.css&action=raw&ctype=text/css', 'text/css');
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-DefSideBoxes.js&action=raw&ctype=text/javascript');
*/
( function () {
'use strict';
if ( [ 'Recentchanges', 'Watchlist' ].indexOf( mw.config.get( 'wgCanonicalSpecialPageName' ) ) === -1 ) {
return;
}
var style = document.createElement( 'style' );
style.textContent = '.mw-rollback-link { display: none !important; }';
document.head.appendChild( style );
}() );
//[[Bikarhêner:Wikihez/skrîpt/js/templateParamRenamer.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/templateParamRenamer.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/skrîpt/js/quicklinks.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/quicklinks.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/skrîpt/js/citeKurdifier.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/citeKurdifier.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/Gadget-defaultVisibilityToggles.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-defaultVisibilityToggles.js&action=raw&ctype=text/javascript');
/*---------QQ.js-------------
[[Bikarhêner:Wikihez/Gadget-QQ.js]]
[[Bikarhêner:Wikihez/Gadget-QQ.css]]
mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-QQ.css&action=raw&ctype=text/css', 'text/css');
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-QQ.js&action=raw&ctype=text/javascript');
*/
/*---------add-examples.js-------------
[[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]]
[[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]]*/
mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-wikt.add-examples.css&action=raw&ctype=text/css', 'text/css');
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-wikt.add-examples.js&action=raw&ctype=text/javascript');
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/loader.js&action=raw&ctype=text/javascript')
importScript( 'Bikarhêner:Wikihez/skrîpt/js/copyTitle.js' ); // Backlink: [[Bikarhêner:Wikihez/skrîpt/js/copyTitle.js]]
// [[Bikarhêner:Wikihez/addAutoCat.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/addAutoCat.js&action=raw&ctype=text/javascript');
//importScript( 'Bikarhêner:Wikihez/newentrywiz.js' ); // Backlink: [[Bikarhêner:Wikihez/newentrywiz.js]]
//[[Bikarhêner:Wikihez/CreateTranslation.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/CreateTranslation.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/wergerîne.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/wergerîne.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/skrîpt/js/getinflections.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/getinflections.js&action=raw&ctype=text/javascript');
//[[:w:Bikarhêner:Wikihez/skrîpt/js/OngletPurge.js]]
mw.loader.load('//ku.wikipedia.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/OngletPurge.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/templateScript2.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/templateScript2.js&action=raw&ctype=text/javascript');
// [[Bikarhêner:Wikihez/şablon-lêke.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/şablon-lêke.js&action=raw&ctype=text/javascript');
mw.loader.load('https://en.wikipedia.org/w/index.php?title=User:BrandonXLF/TodoList.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/test.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/test.js&action=raw&ctype=text/javascript');
//================================================================================================================================
/*---------start.js-------------
[[Bikarhêner:Wikihez/Gadget-start.js]]
[[Bikarhêner:Wikihez/Gadget-start.css]]
mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-start.css&action=raw&ctype=text/css', 'text/css');
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-start.js&action=raw&ctype=text/javascript');
*/
//importScript( 'Bikarhêner:Wikihez/Gadget-linkify.js' ); // Backlink: [[Bikarhêner:Wikihez/Gadget-linkify.js]]
//[[Bikarhêner:Wikihez/skrîpt/js/Gadget-catfix.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/Gadget-catfix.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/skrîpt/js/editor.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/editor.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/skrîpt/js/UpdateLanguageNameAndCode.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/UpdateLanguageNameAndCode.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/skrîpt/js/TranslationAdder-Data.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/TranslationAdder-Data.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/LanguageUtils.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/LanguageUtils.js&action=raw&ctype=text/javascript');
/*---------aWa.js-------------
[[Bikarhêner:Wikihez/Gadget-aWa.js]]
[[Bikarhêner:Wikihez/Gadget-aWa.css]]
mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-aWa.css&action=raw&ctype=text/css', 'text/css');
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-aWa.js&action=raw&ctype=text/javascript');
*/
// This array of dependencies comes from [[MediaWiki:Gadgets-definition]].
// If the list of dependencies changes, copy the text after dependencies=
// for TranslationAdder and run console.log(JSON.stringify("paste dependencies here".split(/, ?/)))
// in your browser's JavaScript console. Put the resulting array as the first argument to mw.loader.using.
//[[User:Wikihez/skrîpt/js/TranslationAdder.js]]
//mw.loader.using(["ext.gadget.LegacyScriptsNewNode","mediawiki.cookie","mediawiki.util"],
//function() {
// importScript('User:Wikihez/skrîpt/js/TranslationAdder.js');
//});
/*
// [[:w:en:MediaWiki:Gadget-edittop.js]]
mw.loader.load('//en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-edittop.js&action=raw&ctype=text/javascript');
// [[Bikarhêner:Wikihez/addAutoCat.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/addAutoCat.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Balyozbot/Gadget-CommonWikt.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Balyozbot/Gadget-CommonWikt.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/hw-ceke.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/hw-ceke.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/sort-langheaders.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/sort-langheaders.js&action=raw&ctype=text/javascript');
//[[:en:User:Conrad.Irwin/Api.js]]
mw.loader.load('//en.wiktionary.org/w/index.php?title=User:Conrad.Irwin/Api.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/etîket-çêke.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/etîket-çêke.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/tagger.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/tagger.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/Gadget-CatMaker.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-CatMaker.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/VisibilityToggles.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/VisibilityToggles.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/Gadget-WiktAccFormCreation.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-WiktAccFormCreation.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/XMLize.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/XMLize.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/RhymesAdder.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/RhymesAdder.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/Editor.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Editor.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/FilterTranslations.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/FilterTranslations.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/custom.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/custom.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/reformat.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/reformat.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/translateWiki.js]] ji aliyê [[Bikarhêner:Guherto]], [[Taybet:PermanentLink/4854098#Translatewiki.net]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/translateWiki.js&action=raw&ctype=text/javascript');
// Various fixes for the trees generated by [[Module:family tree]].
$(function () {
// Show the top toggle.
$('.familytree-toptoggle').css('display', '');
// Initialize the text of the toggles.
$('.familytree').get().forEach(function (tree) {
var isCollapsed = tree.classList.contains('mw-collapsed');
var toggles = $(tree).find('.familytree-toggle');
if (toggles[0]) {
var customToggleClass = Array.prototype.filter.call(toggles[0].classList, function (className) {
return className.indexOf('mw-customtoggle-familytree') === 0;
})[0];
if (customToggleClass) {
var toggledElement = $('#' + customToggleClass.replace('mw-customtoggle', 'mw-customcollapsible'));
if (toggledElement) {
toggles.html(toggledElement.data(isCollapsed ? 'expandtext' : 'collapsetext'));
}
}
}
});
// Change the text in the custom toggles generated by [[Module:family tree]]
// when they are clicked.
$('.mw-collapsible').on('beforeExpand.mw-collapsible beforeCollapse.mw-collapsible',
function (event) {
if (this.id.indexOf('mw-customcollapsible-familytree') === 0) {
var toggle = $('.' + this.id.replace('mw-customcollapsible', 'mw-customtoggle'));
if (event.type === 'beforeExpand') {
toggle.html(this.dataset.collapsetext);
} else { // beforeCollapse
toggle.html(this.dataset.expandtext);
}
event.stopPropagation();
}
});
});
*/
hkfaxqnxnjh33lcrl72hwrz5g0tpve7
6347391
6347389
2026-08-31T15:24:53Z
Wikihez
7344
Restored revision 6347248 by [[Special:Contributions/Wikihez|Wikihez]] ([[User talk:Wikihez|talk]]) ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]])
6347391
javascript
text/javascript
/*---------Gadget-morebits.js-------------
[[Bikarhêner:Wikihez/skrîpt/Gadget/Gadget-morebits.js]]
[[Bikarhêner:Wikihez/skrîpt/Gadget/Gadget-morebits.css]]*/
mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/skrîpt/Gadget/Gadget-morebits.css&action=raw&ctype=text/css', 'text/css');
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/Gadget/Gadget-morebits.js&action=raw&ctype=text/javascript');
importScript( 'Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js' ); // Backlink: [[Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]]
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/load.js&action=raw&ctype=text/javascript');
/*---------Gadget-DefSideBoxes.js-------------
[[Bikarhêner:Wikihez/Gadget-DefSideBoxes.js]]
[[Bikarhêner:Wikihez/Gadget-DefSideBoxes.css]]
*/
mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-DefSideBoxes.css&action=raw&ctype=text/css', 'text/css');
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-DefSideBoxes.js&action=raw&ctype=text/javascript');
( function () {
'use strict';
if ( [ 'Recentchanges', 'Watchlist' ].indexOf( mw.config.get( 'wgCanonicalSpecialPageName' ) ) === -1 ) {
return;
}
var style = document.createElement( 'style' );
style.textContent = '.mw-rollback-link { display: none !important; }';
document.head.appendChild( style );
}() );
//[[Bikarhêner:Wikihez/skrîpt/js/templateParamRenamer.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/templateParamRenamer.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/skrîpt/js/quicklinks.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/quicklinks.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/skrîpt/js/citeKurdifier.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/citeKurdifier.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/Gadget-defaultVisibilityToggles.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-defaultVisibilityToggles.js&action=raw&ctype=text/javascript');
/*---------QQ.js-------------
[[Bikarhêner:Wikihez/Gadget-QQ.js]]
[[Bikarhêner:Wikihez/Gadget-QQ.css]]
mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-QQ.css&action=raw&ctype=text/css', 'text/css');
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-QQ.js&action=raw&ctype=text/javascript');
*/
/*---------add-examples.js-------------
[[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]]
[[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]]*/
mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-wikt.add-examples.css&action=raw&ctype=text/css', 'text/css');
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-wikt.add-examples.js&action=raw&ctype=text/javascript');
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/loader.js&action=raw&ctype=text/javascript')
importScript( 'Bikarhêner:Wikihez/skrîpt/js/copyTitle.js' ); // Backlink: [[Bikarhêner:Wikihez/skrîpt/js/copyTitle.js]]
// [[Bikarhêner:Wikihez/addAutoCat.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/addAutoCat.js&action=raw&ctype=text/javascript');
//importScript( 'Bikarhêner:Wikihez/newentrywiz.js' ); // Backlink: [[Bikarhêner:Wikihez/newentrywiz.js]]
//[[Bikarhêner:Wikihez/CreateTranslation.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/CreateTranslation.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/wergerîne.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/wergerîne.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/skrîpt/js/getinflections.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/getinflections.js&action=raw&ctype=text/javascript');
//[[:w:Bikarhêner:Wikihez/skrîpt/js/OngletPurge.js]]
mw.loader.load('//ku.wikipedia.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/OngletPurge.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/templateScript2.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/templateScript2.js&action=raw&ctype=text/javascript');
// [[Bikarhêner:Wikihez/şablon-lêke.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/şablon-lêke.js&action=raw&ctype=text/javascript');
mw.loader.load('https://en.wikipedia.org/w/index.php?title=User:BrandonXLF/TodoList.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/test.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/test.js&action=raw&ctype=text/javascript');
//================================================================================================================================
/*---------start.js-------------
[[Bikarhêner:Wikihez/Gadget-start.js]]
[[Bikarhêner:Wikihez/Gadget-start.css]]
mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-start.css&action=raw&ctype=text/css', 'text/css');
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-start.js&action=raw&ctype=text/javascript');
*/
//importScript( 'Bikarhêner:Wikihez/Gadget-linkify.js' ); // Backlink: [[Bikarhêner:Wikihez/Gadget-linkify.js]]
//[[Bikarhêner:Wikihez/skrîpt/js/Gadget-catfix.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/Gadget-catfix.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/skrîpt/js/editor.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/editor.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/skrîpt/js/UpdateLanguageNameAndCode.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/UpdateLanguageNameAndCode.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/skrîpt/js/TranslationAdder-Data.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/TranslationAdder-Data.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/LanguageUtils.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/LanguageUtils.js&action=raw&ctype=text/javascript');
/*---------aWa.js-------------
[[Bikarhêner:Wikihez/Gadget-aWa.js]]
[[Bikarhêner:Wikihez/Gadget-aWa.css]]
mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-aWa.css&action=raw&ctype=text/css', 'text/css');
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-aWa.js&action=raw&ctype=text/javascript');
*/
// This array of dependencies comes from [[MediaWiki:Gadgets-definition]].
// If the list of dependencies changes, copy the text after dependencies=
// for TranslationAdder and run console.log(JSON.stringify("paste dependencies here".split(/, ?/)))
// in your browser's JavaScript console. Put the resulting array as the first argument to mw.loader.using.
//[[User:Wikihez/skrîpt/js/TranslationAdder.js]]
//mw.loader.using(["ext.gadget.LegacyScriptsNewNode","mediawiki.cookie","mediawiki.util"],
//function() {
// importScript('User:Wikihez/skrîpt/js/TranslationAdder.js');
//});
/*
// [[:w:en:MediaWiki:Gadget-edittop.js]]
mw.loader.load('//en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-edittop.js&action=raw&ctype=text/javascript');
// [[Bikarhêner:Wikihez/addAutoCat.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/addAutoCat.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Balyozbot/Gadget-CommonWikt.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Balyozbot/Gadget-CommonWikt.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/hw-ceke.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/hw-ceke.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/sort-langheaders.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/sort-langheaders.js&action=raw&ctype=text/javascript');
//[[:en:User:Conrad.Irwin/Api.js]]
mw.loader.load('//en.wiktionary.org/w/index.php?title=User:Conrad.Irwin/Api.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/etîket-çêke.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/etîket-çêke.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/tagger.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/tagger.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/Gadget-CatMaker.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-CatMaker.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/VisibilityToggles.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/VisibilityToggles.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/Gadget-WiktAccFormCreation.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-WiktAccFormCreation.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/XMLize.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/XMLize.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/RhymesAdder.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/RhymesAdder.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/Editor.js]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Editor.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/FilterTranslations.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/FilterTranslations.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/custom.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/custom.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/reformat.js]]
//mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/reformat.js&action=raw&ctype=text/javascript');
//[[Bikarhêner:Wikihez/translateWiki.js]] ji aliyê [[Bikarhêner:Guherto]], [[Taybet:PermanentLink/4854098#Translatewiki.net]]
mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/translateWiki.js&action=raw&ctype=text/javascript');
// Various fixes for the trees generated by [[Module:family tree]].
$(function () {
// Show the top toggle.
$('.familytree-toptoggle').css('display', '');
// Initialize the text of the toggles.
$('.familytree').get().forEach(function (tree) {
var isCollapsed = tree.classList.contains('mw-collapsed');
var toggles = $(tree).find('.familytree-toggle');
if (toggles[0]) {
var customToggleClass = Array.prototype.filter.call(toggles[0].classList, function (className) {
return className.indexOf('mw-customtoggle-familytree') === 0;
})[0];
if (customToggleClass) {
var toggledElement = $('#' + customToggleClass.replace('mw-customtoggle', 'mw-customcollapsible'));
if (toggledElement) {
toggles.html(toggledElement.data(isCollapsed ? 'expandtext' : 'collapsetext'));
}
}
}
});
// Change the text in the custom toggles generated by [[Module:family tree]]
// when they are clicked.
$('.mw-collapsible').on('beforeExpand.mw-collapsible beforeCollapse.mw-collapsible',
function (event) {
if (this.id.indexOf('mw-customcollapsible-familytree') === 0) {
var toggle = $('.' + this.id.replace('mw-customcollapsible', 'mw-customtoggle'));
if (event.type === 'beforeExpand') {
toggle.html(this.dataset.collapsetext);
} else { // beforeCollapse
toggle.html(this.dataset.expandtext);
}
event.stopPropagation();
}
});
});
*/
5f6valj42q62ssmlpu23s4cria6qgqy
ဝုၼ်ႇၵျီးၶျုၵ်ႈ
0
1075458
6347421
5328220
2026-08-31T18:23:53Z
Wikihez
7344
+Etîmolojî (DefSideBoxes)
6347421
wikitext
text/x-wiki
== {{ziman|shn}} ==
=== Navdêr ===
{{navdêr|shn}}
# {{mijar|shn|siyaset}} {{g|ku|serokwezîr}}
==== Etîmolojî ====
Deyn ji {{deyn|my|shn|ဝန်ကြီးချုပ်}}.
=== Çavkanî ===
{{rûpela wergerê|shn|serokwezîr}}
3mzvo0f4et4dtpg3z08rngyyqsbenhn
6347422
6347421
2026-08-31T18:24:21Z
Wikihez
7344
Hat kontrolkirin: --shn ([[WF:KRW]])
6347422
wikitext
text/x-wiki
== {{ziman|shn}} ==
=== Navdêr ===
{{navdêr|shn}}
# {{mijar|shn|siyaset}} {{g|ku|serokwezîr}}
==== Etîmolojî ====
Deyn ji {{deyn|my|shn|ဝန်ကြီးချုပ်}}.
dxl7tm8kyxau9lu8xwdcgjhontfeil1
6347423
6347422
2026-08-31T18:25:07Z
Wikihez
7344
6347423
wikitext
text/x-wiki
== {{ziman|shn}} ==
=== Navdêr ===
{{navdêr|shn}}
# {{mijar|shn|siyaset}} {{g|ku|serokwezîr}}
==== Etîmolojî ====
Deyn ji {{deyn|my|shn|ဝန်ကြီးချုပ်}}.
283awia4220bofylp687ko4sb7aqt6b
ducare
0
1356828
6347393
6231550
2026-08-31T15:34:47Z
Wikihez
7344
/* Rengdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re)
6347393
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Bilêvkirin ===
* {{ku-IPA}}
* {{ku-kîte}}
=== Rengdêr ===
{{rengdêr|ku}}
# {{guherto|dubare}}
b2n8el80naxkv3ck6lgkrliz9moheke
Bikarhêner:Balyozbot/kontrol/jêgirtin
2
1358728
6347561
6341775
2026-09-01T10:12:12Z
Balyozbot
7867
Bot: Pirsgirêkên jêderê hat tespîtkirin
6347561
wikitext
text/x-wiki
== Bêyî |jêgirtin= ==
== [[kevirî]] ==
* <code><nowiki>{{J:Mele Mehmûdê Bayezîdî:Adat û Rusûmatnameê Ekradiye|r=135}}</nowiki></code>
=== [[wesme]] ===
* <code><nowiki>{{J:Mele Mehmûdê Bayezîdî:Adat û Rusûmatnameê Ekradiye|r=101}}</nowiki></code>
=== [[misil]] ===
* <code><nowiki>{{J:Mela Hisênê Bateyî:Mewlûda Kurdî|Zû gihiştin, çûne dora Mekkehê, <br>ket'ne bûsan '''mislê''' ava bingehê”.}}</nowiki></code>
== [[pelamar]] ==
* Pirsgirêk: jêder param 2 tune ye
* Şablon: <code><nowiki>{{jêder|ku|jêgirtin=''Pirsa êzidiya, hizir û serinca dîrokzanan ne rakêşaye û gelek bi kêmî û kurtî basî wan hatiye kirin. Basî wan( belku ji bo cara yekê) di pirtûka Şaristanî de, yê ku di sala 1153 Z de, koç kirî, hatiye kirin û careka din jî, di pirtûka Siyahetnama Olya Çelebî de, ku ew jî, di sala 1680 Z de, miriye, hatiye kirin. Jiber hindê jî, dema şêx Adî dest daye ser ola Êzidiya, êdî wan nekarî roleka giring bilîzin û cihên tiliyên xwe di dîrokê de çêkin. Lê ew li Kurdistanê jiyan û xwe ji hêriş û '''pelamarên''' musilmanan parastin. Çinku bi hizra musilmanan, ew kafir û gawir bûn û Şeytan diperistin. Bo cara dawiyê jî, di destpêka çerxê 19 ê Z de, ew ketine ber hêrişa Mehemed Paşayê Rewandizî, ku bi Mîrê Kore nav dikirin. Jiber hindê jî, roj li pey rojê, ew kêm dibûn û her hind mabû bêne qirrkirin.|Pîr Memo Osman: ''Felsefa ola êzidiyan û koka wî'', wergerrandin: Xelîl Duhokî, Newroz.com, jêwergirtin: 1/2006}}</nowiki></code>
ciw65c7e8tlwdujpwil0uqtyapy02gj
6347604
6347561
2026-09-01T11:12:20Z
Balyozbot
7867
Bot: Pirsgirêkên jêderê hat tespîtkirin
6347604
wikitext
text/x-wiki
== Bêyî |jêgirtin= ==
== [[kevirî]] ==
* <code><nowiki>{{J:Mele Mehmûdê Bayezîdî:Adat û Rusûmatnameê Ekradiye|r=135}}</nowiki></code>
=== [[wesme]] ===
* <code><nowiki>{{J:Mele Mehmûdê Bayezîdî:Adat û Rusûmatnameê Ekradiye|r=101}}</nowiki></code>
=== [[misil]] ===
* <code><nowiki>{{J:Mela Hisênê Bateyî:Mewlûda Kurdî|Zû gihiştin, çûne dora Mekkehê, <br>ket'ne bûsan '''mislê''' ava bingehê”.}}</nowiki></code>
== [[pelamar]] ==
* Pirsgirêk: jêder param 2 tune ye
* Şablon: <code><nowiki>{{jêder|ku|jêgirtin=''Pirsa êzidiya, hizir û serinca dîrokzanan ne rakêşaye û gelek bi kêmî û kurtî basî wan hatiye kirin. Basî wan( belku ji bo cara yekê) di pirtûka Şaristanî de, yê ku di sala 1153 Z de, koç kirî, hatiye kirin û careka din jî, di pirtûka Siyahetnama Olya Çelebî de, ku ew jî, di sala 1680 Z de, miriye, hatiye kirin. Jiber hindê jî, dema şêx Adî dest daye ser ola Êzidiya, êdî wan nekarî roleka giring bilîzin û cihên tiliyên xwe di dîrokê de çêkin. Lê ew li Kurdistanê jiyan û xwe ji hêriş û '''pelamarên''' musilmanan parastin. Çinku bi hizra musilmanan, ew kafir û gawir bûn û Şeytan diperistin. Bo cara dawiyê jî, di destpêka çerxê 19 ê Z de, ew ketine ber hêrişa Mehemed Paşayê Rewandizî, ku bi Mîrê Kore nav dikirin. Jiber hindê jî, roj li pey rojê, ew kêm dibûn û her hind mabû bêne qirrkirin.|Pîr Memo Osman: ''Felsefa ola êzidiyan û koka wî'', wergerrandin: Xelîl Duhokî, Newroz.com, jêwergirtin: 1/2006}}</nowiki></code>
== [[pelamar]] ==
* Pirsgirêk: jêder param 2 tune ye
* Şablon: <code><nowiki>{{jêder|ku|jêgirtin=''Pirsa êzidiya, hizir û serinca dîrokzanan ne rakêşaye û gelek bi kêmî û kurtî basî wan hatiye kirin. Basî wan( belku ji bo cara yekê) di pirtûka Şaristanî de, yê ku di sala 1153 Z de, koç kirî, hatiye kirin û careka din jî, di pirtûka Siyahetnama Olya Çelebî de, ku ew jî, di sala 1680 Z de, miriye, hatiye kirin. Jiber hindê jî, dema şêx Adî dest daye ser ola Êzidiya, êdî wan nekarî roleka giring bilîzin û cihên tiliyên xwe di dîrokê de çêkin. Lê ew li Kurdistanê jiyan û xwe ji hêriş û '''pelamarên''' musilmanan parastin. Çinku bi hizra musilmanan, ew kafir û gawir bûn û Şeytan diperistin. Bo cara dawiyê jî, di destpêka çerxê 19 ê Z de, ew ketine ber hêrişa Mehemed Paşayê Rewandizî, ku bi Mîrê Kore nav dikirin. Jiber hindê jî, roj li pey rojê, ew kêm dibûn û her hind mabû bêne qirrkirin.|Pîr Memo Osman: ''Felsefa ola êzidiyan û koka wî'', wergerrandin: Xelîl Duhokî, Newroz.com, jêwergirtin: 1/2006}}</nowiki></code>
d6twzv2b6jmz59pob39b10iz8658bnw
Bikarhêner:Wikihez/Gadget-DefSideBoxes.js
2
1358875
6347365
6347337
2026-08-31T13:03:11Z
Wikihez
7344
6347365
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary.
// Full rewrite of en.wiktionary's Gadget-DefSideBoxes.js: that file depends on Editor/AdderWrapper/LangMetadata/
// util.validateNoWikisyntax and is hard-wired to en.wiktionary's senseid/sense/trans-top system and vector-only
// hover positioning -- none of that fits ku.wiktionary. This version instead reuses the section/language-matching
// helpers already proven (and twice bugfixed) in Gadget-wikt.add-examples.js, and writes ku.wiktionary's own
// wikitext conventions (start.js's "#: {{hevmane|lang|...}}" per-sense lines and "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile) -- no hover-only UI, no absolute positioning.
// Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling (not a declared ResourceLoader dependency): the "Nimûne/jêgirtin" menu item looks for the
// button Gadget-wikt.add-examples.js already inserts on each definition, by its exact link text -- that gadget
// must run first and must keep using the same text ("Nimûneyeke bikaranînê lê zêde bike").
// <nowiki>
(function () {
"use strict";
// Same namespace guard as Wiki/start.js and Gadget-wikt.add-examples.js: main namespace, namespace 108
// (used for reconstructed-entry pages -- see start.js's own "{{jinûvesazkirî|...}}" handling), or a
// user's own /ceribandin or /test sandbox subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js's own copy.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Order matters only for where a brand-new group line lands relative to other existing group lines.
// "primary: true" groups get their own always-visible quick link on the definition (mirrors
// en.wiktionary's own DefSideBoxes, which keeps "+Add example sentence"/"+Add quotation" always visible
// and tucks everything else behind "More"); the rest live inside this gadget's own "More" menu instead.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane", primary: true },
{ key: "dijmane", label: "Dijmane", primary: true },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Dûnde is left out here -- its wikitext is a multi-language table, not yet ported.
// Order here IS the canonical ku.wiktionary entry-layout order for "====" subsections (the user's own
// full list runs Bilêvkirin, Ji wêjeya klasîk, Ji wêjeyê, Tewandin, Notên bikaranînê, Bi alfabeyên din,
// Formên alternatîv, Kurtkirin, Sembol, Navê zanistî, Hevmane, Nêzîk, Dijmane, Jornav, Jêrnav, Jê,
// Têkildar, Etîmolojî, Dûnde, Bide ber, Herwiha binêre, Bêhtir bixwîne, Bi zaravayên din, Werger, Qafiye,
// Anagram, Çavkanî) -- only the steps with a confirmed wikitext format are implemented here. Left out for
// now: Bilêvkirin (a "===" section per language in start.js, not a "====" subsection inside a POS block --
// doesn't fit this array's model at all); Dûnde/Bi zaravayên din/Werger (start.js implements these, but as
// genuinely complex multi-language table sections, same reason they were deferred in earlier rounds); Ji
// wêjeya klasîk, Ji wêjeyê, Kurtkirin, Sembol, Navê zanistî, Nêzîk, Bide ber, Qafiye, Anagram (no
// confirmed wikitext format anywhere in start.js -- adding these would mean inventing templates for a
// tool that edits live pages). insertPageSubsection() uses this array's own order as the insertion rank
// -- see subsectionRankForHeader().
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// ---- word-modifier system, ported from start.js's own makeModifierLi()/WORD_MODIFIERS (the exact widget
// start.js uses for Hevmane/Dijmane/Formên alternatîv/Termên koordîne/Jornav/Jêrnav, both as a page-level
// {{kol3|...}} list and as a per-sense "#: {{tpl|lang|...}}" line) -- every word in one of these lists can
// carry small "<key:value>" annotations (translation, gender, label, ...), which the {{hevmane}}/{{kol3}}/etc.
// templates parse back out of the raw positional param. A word with no annotations is just its plain text.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers back into the raw "word<key:value>…" form the {{hevmane}}/
* {{kol3}}/etc. templates read. No re-hydration path is needed here (unlike start.js's own form, this
* panel is never pre-filled from existing page content) so there is no matching parseWordValue(). */
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers, ported from Gadget-wikt.add-examples.js (same document-order technique, so
// mobile's per-section DOM wrapping and MediaWiki's page-wide heading-id collisions can't break it) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s+\d+$/, "");
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || $(this).text().trim();
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback -- one fetch covers both the
// edit-conflict check and the content, matching the hardened pattern in Gadget-wikt.add-examples.js
// (an earlier separate-fetch version could silently overwrite someone else's edit landed in between).
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// ---- this gadget's own save queue + floating widget ----
// Round 12/13 queued into the real "Gadget-Editor - kuwikt.js" singleton (window.editor) instead of saving
// directly, so several DefSideBoxes edits could land in one save. That gadget turned out to be the wrong
// vehicle for this: it's built around a different feature (queuing translation additions) and its own
// floating widget shows a tip about that ("Tu dikarî hin wergerên din jî lê zêde bikî…") which makes no
// sense next to a queued Hevmane/Dijmane/subsection change. This file now keeps its own small queue and its
// own floating widget instead -- same "collect several edits, one real save" idea, but with UI that's
// actually about what this gadget does.
//
// Each queued entry keeps its OWN transformFn rather than a pre-computed wikitext snapshot, so the real
// save (saveQueueNow) can re-run every queued transform against freshly-fetched content in one
// api.edit() transform -- same one-fetch, no-stale-overwrite pattern editPage() already uses everywhere
// else in this file, just threaded through N transforms instead of one.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// The real save: re-runs every queued transformFn, in order, against ONE freshly-fetched revision (inside
// editPage()'s own hardened transform) and posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var combinedSummary = dsbQueue.entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
dsbQueue.entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function () {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text("✓ hemû guhertin hatin qeydkirin — rûpel nûve bike da ku bibînî.");
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()) -- nothing here touches the page yet, so a transform that would throw
// SubmitAbort (e.g. "this subsection already exists") is only actually discovered when "Guhertinan qeyd
// bike" runs it for real, same as queuing into a real editor would work. Also runs previewFn(), which a
// caller uses to drop a small "not saved yet" preview into the live DOM at the change's own correct spot on
// the page (see buildSubsectionPreviewDom() and the inline gloss/word-group preview in buildAdvancedPanel).
// Shared by every panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel,
// buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget (start.js's own linkifyText()/$.kuLinkify -- the real,
// already-deployed word-linking logic; see its own Wiki/linkify.js for what it actually does) and calls
// back with the linkified result. Passes the text through unchanged if the gadget can't be loaded, same
// fallback start.js's own linkifyText() uses -- never blocks a save on it.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location, ported/adapted from Gadget-wikt.add-examples.js's own submit() ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal -- never by a DOM id number, which
// MediaWiki's page-wide anchor uniquification can attach to a heading for reasons unrelated to its actual
// position (see Gadget-wikt.add-examples.js's own bugfix history for why that broke on a real page).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the WHOLE rest of the page from this language's heading onward, since the caller
// reuses it to rebuild the entire saved text -- only the section-heading search itself is bounded
// (via sectionSearchEndLine), so a same-named heading in a later language can never match by mistake.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel -- an array whose
// element 0 is unused here (it's the "type|ordinal" string locateSection already resolved) and whose
// remaining elements are 0-based indices, one per nesting level (see eachLeafDefinition's own construction).
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's own wordLine()
// format). If a line for this same tplKey already exists under the definition, missing words are appended
// to it instead of adding a duplicate line; otherwise a new line lands after the last existing group line
// (or right after the definition itself), always before any "#*"/citation lines, matching start.js's order.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's own gloss
// text -- start.js itself only ever builds "{{K|lang|...}} {{e|lang|...}} <gloss>" (kategori before
// etîket; Dever/Şîve, which would sit between them, is out of scope here); maneid is placed first,
// matching the user's own live example ("{{maneid|ku|id}} {{f|ku|id}} <gloss>").
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker
// (maneid/K/e in whatever order they're already in, plus any other template already there, e.g. a form-of
// call) -- stops at the first thing that isn't one, normally the gloss text itself. Shared by
// insertLeadingSenseTpl() (which searches "calls" for an existing tplKey to extend or insert next to) and
// updateSenseGloss()/fetchCurrentGloss() (which only care about "rest", the gloss text after every call).
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts (or, unless opts.noExtend, extends) one of the small templates that prefix a definition
// line's own gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} (kategori) or {{e|lang|etîket1|...}}
// (etîket). Extending merges new values into an existing call the same way insertSenseWords() does for
// "#:" sub-lines; opts.noExtend instead aborts if the template is already there (used for maneid, which
// identifies the sense and so must never silently get a second, different id).
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the WHOLE leading-call run (not just tplKey's own regex against position 0) means an
// existing tplKey call is found and merged wherever it already sits, not just when it happens to be
// first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.noExtend) {
throw new SubmitAbort("Ev hevok jixwe xwedan " + (opts.noExtendLabel || tplKey) + " e.");
}
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call, e.g. a form-of template, always outranks everything),
// or at the end of the run if every existing call comes before tplKey.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading "{{maneid|...}}"/"{{K|...}}"/
// "{{e|...}}"/other template calls exactly as they were -- the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
var calls = splitLeadingCalls(afterMarker).calls;
// "{{mane?|lang}}" is start.js's own "no definition entered yet" placeholder (see steps.dfn's own
// getOutput()) -- once the user provides a real gloss through this form, that placeholder is fully
// replaced, never kept alongside the new text the way maneid/K/e/etc. (real metadata) are.
calls = calls.filter(function (c) { return c.key !== "mane?"; });
var leadingText = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (leadingText ? leadingText + " " : "") + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text (splitLeadingCalls().rest)
// to prefill the "Maneyê biguhêre" form. A plain read, not part of the hardened save path -- the actual
// save still runs updateSenseGloss() inside editPage()'s own transform against freshly-fetched content, so
// someone else's edit landing between this read and that save can never be silently overwritten; only the
// prefilled text itself could be a little stale, same as any edit form built from a page you loaded earlier.
function fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
var loc = locateSection(content, language, sectionType, sectionOrdinal);
var defLine = findDefinitionLine(loc.lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(loc.lines[defLine])[0];
var afterMarker = loc.lines[defLine].slice(marker.length).replace(/^\s+/, "");
return splitLeadingCalls(afterMarker).rest;
});
}
// Finds a POS block's own body range (its "===" line's own index up to, but not including, the next
// heading of level <= 3), and the header text + line index of any "====" subsections it already contains
// (the line index lets insertPageSubsection() splice a new subsection in right before an existing one,
// not just always at the very end).
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// PAGE_SUBSECTIONS' own array order IS the canonical ku.wiktionary subsection order (see its own comment) --
// this just looks up a header's rank in it. -1 for a header that isn't one of ours (hand-authored, or a
// convention step this gadget doesn't support yet); such a header is never used as an insertion anchor.
function subsectionRankForHeader(header) {
for (var i = 0; i < PAGE_SUBSECTIONS.length; i++) {
if (PAGE_SUBSECTIONS[i].header === header) {
return i;
}
}
return -1;
}
// Inserts a new "==== Header ====" subsection into its canonical position within a POS block (right before
// the first EXISTING recognized subsection that outranks it -- same "leading run" idea as
// LEADING_TPL_ORDER/insertLeadingSenseTpl, just for whole ==== blocks instead of {{...}} calls on one
// line), falling back to the end of the block when nothing there outranks it. Either a {{kol3|...}} word
// list (start.js's makeWordListStep format) or a plain paragraph, matching start.js's other custom steps
// (Etîmolojî, Notên bikaranînê, ...).
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var block;
if (subsection.kind === "wordlist") {
var params = "cure=" + subsection.header + "\n" + content.map(function (w) {
return "|" + w;
}).join("\n");
block = "\n==== " + subsection.header + " ====\n{{kol3|" + language + "|" + params + "\n}}\n";
} else {
block = "\n==== " + subsection.header + " ====\n" + content + "\n";
}
var myRank = subsectionRankForHeader(subsection.header);
var insertAt = bounds.end;
for (var i = 0; i < bounds.existingHeaders.length; i++) {
var otherRank = subsectionRankForHeader(bounds.existingHeaders[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = bounds.existingHeaders[i].lineIndex;
break;
}
}
lines.splice(insertAt, 0, block);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc. if more than one collides)
// instead of a real part-of-speech name, tagged right below with {{cure?|<lang>}} -- ku.wiktionary's own
// "cureyê rêzimanî nediyar e" (part of speech not yet determined) maintenance flag. Neither is in
// sectionNames, so sectionTypeOf() and locateSection() never match it; these two functions are a small
// parallel path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text (plus
// an optional page author's own disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading and drops the {{cure?|...}} line right
// after it, if present -- that template flags "part of speech not yet determined", which no longer holds
// once a real one is chosen. Any other content under the heading (the "#" senses, subsections, ...) is
// left untouched.
function convertManeToPos(pageContent, language, maneOrdinal, newSectionType) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
var loc = locateManeSection(pageContent, language, maneOrdinal);
var lines = loc.lines;
var m = /^(===[ ]*Mane)(\s+\d+)?([ ]*===)/.exec(lines[loc.maneLineIndex]);
lines[loc.maneLineIndex] = "=== " + newSectionType + (m[2] ? m[2] : "") + " ===";
var nextLineIndex = loc.maneLineIndex + 1;
if (nextLineIndex < lines.length && /^\{\{\s*cure\?\s*\|[^{}]*\}\}\s*$/.test(lines[nextLineIndex])) {
lines.splice(nextLineIndex, 1);
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form already used
// (updateSenseGloss/insertLeadingSenseTpl/insertSenseWords/insertPageSubsection), applying only the
// pieces the caller actually filled in (see buildAdvancedPanel()'s own collectChanges()). A piece that
// conflicts with something already on the page (maneid already set, a subsection that's already there)
// is skipped with a warning rather than failing the whole save -- everything else the user changed still
// goes through in the same edit. Throws SubmitAbort if literally nothing was filled in, so this can never
// turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
function tryApply(fn) {
try {
content = fn();
appliedAnything = true;
} catch (e) {
if (e instanceof SubmitAbort) {
warnings.push(e.message);
} else {
throw e;
}
}
}
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
if (changes.maneid) {
tryApply(function () {
return insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", [changes.maneid], {
noExtend: true,
noExtendLabel: "nasnavek (maneid)"
});
});
}
if (changes.etiket && changes.etiket.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket);
appliedAnything = true;
}
if (changes.kategori && changes.kategori.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, words);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list, ported from start.js's own makeModifierLi() + onSubInput(): every word is its own
// always-visible row (word box + a "+" to attach one of the 10 WORD_MODIFIERS as a small pill above the
// box + a "x" to drop the row); a fresh empty row appears automatically once the current last row gets
// text, so the field never needs an explicit "add another word" button. Unlike the old chip-input this
// replaces, duplicate words are allowed (start.js's own field allows them too) and there is no separate
// commit step -- every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into what is currently the last row appends a fresh empty one after it
// (ported from start.js's onSubInput) -- so there is always exactly one empty trailing row to type
// into, and the field never needs its own explicit "add word" button.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, start.js's own buildChipField() pattern (its .wiktku-dfn-chipfield-chip) --
// used for Etîket and Kategorî, which (unlike Hevmane/Dijmane/etc.) are simple value lists with no
// per-word modifiers. Enter or "," commits the current text as a tag; Backspace on an empty input
// removes the last tag; values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss (+ Oto-lînk bike) and the two
// most-used word lists (Hevmane/Dijmane) sit directly in the picker row; the remaining SENSE_GROUPS word
// lists, maneid, etîket, kategorî, and this POS block's own "+ beşek" subsection picker -- plus Nimûne/
// jêgirtin -- live behind a single "Zêdetir" dropdown -- plus one shared "Lê zêde bike" that queues
// everything the user actually filled in as a single edit, via applyAdvancedChanges() and the shared
// queueChange() helper (see this file's own floating queue box, built by ensureQueueBox()). Nimûne/
// jêgirtin is still an immediate proxy-click (see findExampleButton()), not a field this combined save
// applies -- it opens a DIFFERENT gadget's own form with its own independent save -- it just sits in the
// dropdown rather than as its own separate top-level link.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-OPEN box (key -> () => value); collectChanges() below only
// ever reads from a box the user actually clicked to add -- there is no "always all 11 fields present"
// state any more (that was tried and reverted -- see this file's own history notes).
var getters = {};
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's own wording; everything else here
// only ever ADDS to the definition line) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel).then(
function (gloss) {
originalGloss = gloss;
$textarea.val(gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: gloss + the two most-used word groups (Hevmane/Dijmane, same SENSE_GROUPS.primary
// flag start.js itself uses to feature them) sit directly in the row; everything else (the remaining
// word groups, maneid, etîket, kategorî) lives behind a single "Zêdetir" dropdown -- back to the
// pre-round-12 layout the user actually wanted, on top of round 12's click-to-open-a-box mechanic:
// clicking any link (primary or from the dropdown) builds and appends its box to $openBoxes and hides
// that link; the box's own "×" removes it, clears its getter, and un-hides the link -- several boxes can
// be open at once, unlike the old "only one form open at a time" behavior (round 3-10's $below). No
// "Beşek (====)" entry here -- buildSubsectionPanel()'s own "+ Beşek lê zêde bike" trigger already
// covers page-level subsections; having it twice was redundant (round 19). ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: !!group.primary };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
// Nimûne/jêgirtin sits first in the dropdown, ahead of every field-pick link.
$moreMenu.append($nimune);
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
});
// slideToggle()/slideUp() (jQuery's own animated show/hide, same mechanism the original en.wiktionary
// gadget's own "More ►" list used) instead of an instant show/hide -- a smooth expand/collapse rather
// than the dropdown just popping open.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle);
// Closes the dropdown on an outside click, same as round 3-10's own "More" menu -- scoped to this
// panel's own $moreToggle/$moreMenu, so it never touches another sense's panel.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via the shared queueChange()
// helper (see its own comment) -- the actual save happens later, when the user clicks "Guhertinan qeyd
// bike" on this gadget's own floating queue box. ----
// Small "not saved yet" preview of everything this one queued change will do, appended right after
// $quickRow (i.e. in the same spot the panel itself sits, right under the sense's gloss) -- plain text,
// not a real render of {{hevmane}}/etc., but placed where the real content will actually end up once
// the page is reloaded after a real save.
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
});
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: getters.maneid ? getters.maneid() : "",
etiket: getters.etiket ? getters.etiket() : [],
kategori: getters.kategori ? getters.kategori() : [],
words: words
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Same zero-links-gets-auto-linkified rule as every earlier round's gloss save -- only when the
// gloss is actually part of this save, and only ever applied automatically when the user hasn't
// already added a manual link themselves.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $moreMenu, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above: gloss/Hevmane/Dijmane sit as direct picker
// links, everything else (the remaining SENSE_GROUPS word lists, maneid, etîket, kategorî, this POS
// block's own subsections) behind a "Zêdetir" dropdown -- clicking any of them opens its own box, several
// can be open at once, then one shared "Lê zêde bike" queues everything currently open together into this
// gadget's own floating queue box (see queueChange()) -- the real save only happens when the user clicks
// that box's own "Guhertinan qeyd bike".
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
var $toggle = $("<a href='#' class='dsb-toggle' title='Guhartina pêşketî'>✎</a>");
// Revealed by $toggle -- an indented panel under the sense (like en.wiktionary's own
// "+Add example sentence +Add quotation More" row under a definition), not always visible. Built
// lazily on first open (see buildAdvancedPanel()'s own fetchCurrentGloss() call) rather than eagerly
// for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.prepend($toolbar);
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a NEW "====" subsection preview belongs in the live DOM, using the same canonical order
// subsectionRankForHeader()/PAGE_SUBSECTIONS already give insertPageSubsection() for the real wikitext --
// so the preview shows up exactly where the real content will land after a save + reload, not just tacked
// onto the end of the POS block. Returns either {insertBefore: $el} (an existing subsection that outranks
// this one) or {insertAfter: $el} (nothing does -- goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its own canonical position (domSubsectionInsertAnchor()) so it reads as
// "this is what will actually be here" rather than a form-panel status line. Plain text, not a real render
// of {{kol3|...}}/etc. Returns the inserted element so the caller can remove it again (queue cancel, or
// after a real save, when the page needs a reload to show the real thing anyway).
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4> -- existingSubsectionHeadersInDom() (".mw-heading4, h4") must never
// mistake this live-only preview for an actual subsection already on the page, or a second "+ Beşek lê
// zêde bike" would wrongly treat it as already there and hide it from the picker.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field, saved via insertPageSubsection().
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return existing.indexOf(s.header) === -1;
});
if (!available.length) {
$panel.text("Hemû beş jixwe li vê hene.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.header));
});
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
function currentSubsection() {
var id = $select.val();
return available.filter(function (s) {
return s.id === id;
})[0];
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
$fieldWrap.append(
$("<textarea class='dsb-input dsb-subsection-text' rows='3'></textarea>")
.attr("placeholder", s.header + "…")
);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
var content;
if (s.kind === "wordlist") {
content = wordField.values();
if (!content.length) {
return;
}
} else {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
}
$save.prop("disabled", true);
queueChange(
"+" + s.header + " (DefSideBoxes)",
function (pageContent) {
return { content: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, s, content), warnings: [] };
},
$save,
$status,
function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that replaces an unclassified "=== Mane ===" placeholder
// heading, saved via convertManeToPos(). Lists every name from sectionNames -- same canonical POS list
// locateSection() itself accepts.
function buildConvertPosPanel($panel, $h3, language, maneOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
$select.append($("<option></option>").val(name).text(name));
});
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertManeToPos(pageContent, language, maneOrdinal, chosen), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note right under the heading itself (its own correct spot on the
// page), rather than rewriting the real heading text -- an in-place rewrite would need to be
// reverted on failure/cancel but KEPT on a real success, and a real save failing partway
// through would otherwise leave a real heading showing a name that was never actually saved.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
}
);
});
$panel.empty().append($select, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger right under an unclassified "=== Mane ===" placeholder
// heading (see convertManeToPos()'s own comment for what that heading means).
function attachManeConvertTrigger($h3) {
if ($h3.data("dsbManeAttached")) {
return;
}
$h3.data("dsbManeAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var maneOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, maneOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (/^Mane(\s+\d+)?$/.test($h3.text().trim())) {
attachManeConvertTrigger($h3);
}
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
});
}
$(init);
// </nowiki>
})();
6okj5cz97wlx26fv40vw8pzrahe2fyv
6347378
6347365
2026-08-31T13:25:17Z
Wikihez
7344
6347378
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary.
// Full rewrite of en.wiktionary's Gadget-DefSideBoxes.js: that file depends on Editor/AdderWrapper/LangMetadata/
// util.validateNoWikisyntax and is hard-wired to en.wiktionary's senseid/sense/trans-top system and vector-only
// hover positioning -- none of that fits ku.wiktionary. This version instead reuses the section/language-matching
// helpers already proven (and twice bugfixed) in Gadget-wikt.add-examples.js, and writes ku.wiktionary's own
// wikitext conventions (start.js's "#: {{hevmane|lang|...}}" per-sense lines and "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile) -- no hover-only UI, no absolute positioning.
// Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling (not a declared ResourceLoader dependency): the "Nimûne/jêgirtin" menu item looks for the
// button Gadget-wikt.add-examples.js already inserts on each definition, by its exact link text -- that gadget
// must run first and must keep using the same text ("Nimûneyeke bikaranînê lê zêde bike").
// <nowiki>
(function () {
"use strict";
// Same namespace guard as Wiki/start.js and Gadget-wikt.add-examples.js: main namespace, namespace 108
// (used for reconstructed-entry pages -- see start.js's own "{{jinûvesazkirî|...}}" handling), or a
// user's own /ceribandin or /test sandbox subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js's own copy.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Order matters only for where a brand-new group line lands relative to other existing group lines.
// "primary: true" groups get their own always-visible quick link on the definition (mirrors
// en.wiktionary's own DefSideBoxes, which keeps "+Add example sentence"/"+Add quotation" always visible
// and tucks everything else behind "More"); the rest live inside this gadget's own "More" menu instead.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane", primary: true },
{ key: "dijmane", label: "Dijmane", primary: true },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Dûnde is left out here -- its wikitext is a multi-language table, not yet ported.
// Order here IS the canonical ku.wiktionary entry-layout order for "====" subsections (the user's own
// full list runs Bilêvkirin, Ji wêjeya klasîk, Ji wêjeyê, Tewandin, Notên bikaranînê, Bi alfabeyên din,
// Formên alternatîv, Kurtkirin, Sembol, Navê zanistî, Hevmane, Nêzîk, Dijmane, Jornav, Jêrnav, Jê,
// Têkildar, Etîmolojî, Dûnde, Bide ber, Herwiha binêre, Bêhtir bixwîne, Bi zaravayên din, Werger, Qafiye,
// Anagram, Çavkanî) -- only the steps with a confirmed wikitext format are implemented here. Left out for
// now: Bilêvkirin (a "===" section per language in start.js, not a "====" subsection inside a POS block --
// doesn't fit this array's model at all); Dûnde/Bi zaravayên din/Werger (start.js implements these, but as
// genuinely complex multi-language table sections, same reason they were deferred in earlier rounds); Ji
// wêjeya klasîk, Ji wêjeyê, Kurtkirin, Sembol, Navê zanistî, Nêzîk, Bide ber, Qafiye, Anagram (no
// confirmed wikitext format anywhere in start.js -- adding these would mean inventing templates for a
// tool that edits live pages). insertPageSubsection() uses this array's own order as the insertion rank
// -- see subsectionRankForHeader().
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// ---- word-modifier system, ported from start.js's own makeModifierLi()/WORD_MODIFIERS (the exact widget
// start.js uses for Hevmane/Dijmane/Formên alternatîv/Termên koordîne/Jornav/Jêrnav, both as a page-level
// {{kol3|...}} list and as a per-sense "#: {{tpl|lang|...}}" line) -- every word in one of these lists can
// carry small "<key:value>" annotations (translation, gender, label, ...), which the {{hevmane}}/{{kol3}}/etc.
// templates parse back out of the raw positional param. A word with no annotations is just its plain text.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers back into the raw "word<key:value>…" form the {{hevmane}}/
* {{kol3}}/etc. templates read. No re-hydration path is needed here (unlike start.js's own form, this
* panel is never pre-filled from existing page content) so there is no matching parseWordValue(). */
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers, ported from Gadget-wikt.add-examples.js (same document-order technique, so
// mobile's per-section DOM wrapping and MediaWiki's page-wide heading-id collisions can't break it) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s+\d+$/, "");
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || $(this).text().trim();
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback -- one fetch covers both the
// edit-conflict check and the content, matching the hardened pattern in Gadget-wikt.add-examples.js
// (an earlier separate-fetch version could silently overwrite someone else's edit landed in between).
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// ---- this gadget's own save queue + floating widget ----
// Round 12/13 queued into the real "Gadget-Editor - kuwikt.js" singleton (window.editor) instead of saving
// directly, so several DefSideBoxes edits could land in one save. That gadget turned out to be the wrong
// vehicle for this: it's built around a different feature (queuing translation additions) and its own
// floating widget shows a tip about that ("Tu dikarî hin wergerên din jî lê zêde bikî…") which makes no
// sense next to a queued Hevmane/Dijmane/subsection change. This file now keeps its own small queue and its
// own floating widget instead -- same "collect several edits, one real save" idea, but with UI that's
// actually about what this gadget does.
//
// Each queued entry keeps its OWN transformFn rather than a pre-computed wikitext snapshot, so the real
// save (saveQueueNow) can re-run every queued transform against freshly-fetched content in one
// api.edit() transform -- same one-fetch, no-stale-overwrite pattern editPage() already uses everywhere
// else in this file, just threaded through N transforms instead of one.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// The real save: re-runs every queued transformFn, in order, against ONE freshly-fetched revision (inside
// editPage()'s own hardened transform) and posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var combinedSummary = dsbQueue.entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
dsbQueue.entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function () {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text("✓ hemû guhertin hatin qeydkirin — rûpel nûve bike da ku bibînî.");
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()) -- nothing here touches the page yet, so a transform that would throw
// SubmitAbort (e.g. "this subsection already exists") is only actually discovered when "Guhertinan qeyd
// bike" runs it for real, same as queuing into a real editor would work. Also runs previewFn(), which a
// caller uses to drop a small "not saved yet" preview into the live DOM at the change's own correct spot on
// the page (see buildSubsectionPreviewDom() and the inline gloss/word-group preview in buildAdvancedPanel).
// Shared by every panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel,
// buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget (start.js's own linkifyText()/$.kuLinkify -- the real,
// already-deployed word-linking logic; see its own Wiki/linkify.js for what it actually does) and calls
// back with the linkified result. Passes the text through unchanged if the gadget can't be loaded, same
// fallback start.js's own linkifyText() uses -- never blocks a save on it.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location, ported/adapted from Gadget-wikt.add-examples.js's own submit() ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal -- never by a DOM id number, which
// MediaWiki's page-wide anchor uniquification can attach to a heading for reasons unrelated to its actual
// position (see Gadget-wikt.add-examples.js's own bugfix history for why that broke on a real page).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the WHOLE rest of the page from this language's heading onward, since the caller
// reuses it to rebuild the entire saved text -- only the section-heading search itself is bounded
// (via sectionSearchEndLine), so a same-named heading in a later language can never match by mistake.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel -- an array whose
// element 0 is unused here (it's the "type|ordinal" string locateSection already resolved) and whose
// remaining elements are 0-based indices, one per nesting level (see eachLeafDefinition's own construction).
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's own wordLine()
// format). If a line for this same tplKey already exists under the definition, missing words are appended
// to it instead of adding a duplicate line; otherwise a new line lands after the last existing group line
// (or right after the definition itself), always before any "#*"/citation lines, matching start.js's order.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's own gloss
// text -- start.js itself only ever builds "{{K|lang|...}} {{e|lang|...}} <gloss>" (kategori before
// etîket; Dever/Şîve, which would sit between them, is out of scope here); maneid is placed first,
// matching the user's own live example ("{{maneid|ku|id}} {{f|ku|id}} <gloss>").
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker
// (maneid/K/e in whatever order they're already in, plus any other template already there, e.g. a form-of
// call) -- stops at the first thing that isn't one, normally the gloss text itself. Shared by
// insertLeadingSenseTpl() (which searches "calls" for an existing tplKey to extend or insert next to) and
// updateSenseGloss()/fetchCurrentGloss() (which only care about "rest", the gloss text after every call).
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts (or, unless opts.noExtend, extends) one of the small templates that prefix a definition
// line's own gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} (kategori) or {{e|lang|etîket1|...}}
// (etîket). Extending merges new values into an existing call the same way insertSenseWords() does for
// "#:" sub-lines; opts.noExtend instead aborts if the template is already there (used for maneid, which
// identifies the sense and so must never silently get a second, different id).
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the WHOLE leading-call run (not just tplKey's own regex against position 0) means an
// existing tplKey call is found and merged wherever it already sits, not just when it happens to be
// first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.noExtend) {
throw new SubmitAbort("Ev hevok jixwe xwedan " + (opts.noExtendLabel || tplKey) + " e.");
}
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call, e.g. a form-of template, always outranks everything),
// or at the end of the run if every existing call comes before tplKey.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading "{{maneid|...}}"/"{{K|...}}"/
// "{{e|...}}"/other template calls exactly as they were -- the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
var calls = splitLeadingCalls(afterMarker).calls;
// "{{mane?|lang}}" is start.js's own "no definition entered yet" placeholder (see steps.dfn's own
// getOutput()) -- once the user provides a real gloss through this form, that placeholder is fully
// replaced, never kept alongside the new text the way maneid/K/e/etc. (real metadata) are.
calls = calls.filter(function (c) { return c.key !== "mane?"; });
var leadingText = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (leadingText ? leadingText + " " : "") + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text (splitLeadingCalls().rest)
// to prefill the "Maneyê biguhêre" form. A plain read, not part of the hardened save path -- the actual
// save still runs updateSenseGloss() inside editPage()'s own transform against freshly-fetched content, so
// someone else's edit landing between this read and that save can never be silently overwritten; only the
// prefilled text itself could be a little stale, same as any edit form built from a page you loaded earlier.
function fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
var loc = locateSection(content, language, sectionType, sectionOrdinal);
var defLine = findDefinitionLine(loc.lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(loc.lines[defLine])[0];
var afterMarker = loc.lines[defLine].slice(marker.length).replace(/^\s+/, "");
return splitLeadingCalls(afterMarker).rest;
});
}
// Finds a POS block's own body range (its "===" line's own index up to, but not including, the next
// heading of level <= 3), and the header text + line index of any "====" subsections it already contains
// (the line index lets insertPageSubsection() splice a new subsection in right before an existing one,
// not just always at the very end).
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// PAGE_SUBSECTIONS' own array order IS the canonical ku.wiktionary subsection order (see its own comment) --
// this just looks up a header's rank in it. -1 for a header that isn't one of ours (hand-authored, or a
// convention step this gadget doesn't support yet); such a header is never used as an insertion anchor.
function subsectionRankForHeader(header) {
for (var i = 0; i < PAGE_SUBSECTIONS.length; i++) {
if (PAGE_SUBSECTIONS[i].header === header) {
return i;
}
}
return -1;
}
// Inserts a new "==== Header ====" subsection into its canonical position within a POS block (right before
// the first EXISTING recognized subsection that outranks it -- same "leading run" idea as
// LEADING_TPL_ORDER/insertLeadingSenseTpl, just for whole ==== blocks instead of {{...}} calls on one
// line), falling back to the end of the block when nothing there outranks it. Either a {{kol3|...}} word
// list (start.js's makeWordListStep format) or a plain paragraph, matching start.js's other custom steps
// (Etîmolojî, Notên bikaranînê, ...).
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var block;
if (subsection.kind === "wordlist") {
var params = "cure=" + subsection.header + "\n" + content.map(function (w) {
return "|" + w;
}).join("\n");
block = "\n==== " + subsection.header + " ====\n{{kol3|" + language + "|" + params + "\n}}\n";
} else {
block = "\n==== " + subsection.header + " ====\n" + content + "\n";
}
var myRank = subsectionRankForHeader(subsection.header);
var insertAt = bounds.end;
for (var i = 0; i < bounds.existingHeaders.length; i++) {
var otherRank = subsectionRankForHeader(bounds.existingHeaders[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = bounds.existingHeaders[i].lineIndex;
break;
}
}
lines.splice(insertAt, 0, block);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc. if more than one collides)
// instead of a real part-of-speech name, tagged right below with {{cure?|<lang>}} -- ku.wiktionary's own
// "cureyê rêzimanî nediyar e" (part of speech not yet determined) maintenance flag. Neither is in
// sectionNames, so sectionTypeOf() and locateSection() never match it; these two functions are a small
// parallel path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text (plus
// an optional page author's own disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading and drops the {{cure?|...}} line right
// after it, if present -- that template flags "part of speech not yet determined", which no longer holds
// once a real one is chosen. Any other content under the heading (the "#" senses, subsections, ...) is
// left untouched.
function convertManeToPos(pageContent, language, maneOrdinal, newSectionType) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
var loc = locateManeSection(pageContent, language, maneOrdinal);
var lines = loc.lines;
var m = /^(===[ ]*Mane)(\s+\d+)?([ ]*===)/.exec(lines[loc.maneLineIndex]);
lines[loc.maneLineIndex] = "=== " + newSectionType + (m[2] ? m[2] : "") + " ===";
var nextLineIndex = loc.maneLineIndex + 1;
if (nextLineIndex < lines.length && /^\{\{\s*cure\?\s*\|[^{}]*\}\}\s*$/.test(lines[nextLineIndex])) {
lines.splice(nextLineIndex, 1);
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form already used
// (updateSenseGloss/insertLeadingSenseTpl/insertSenseWords/insertPageSubsection), applying only the
// pieces the caller actually filled in (see buildAdvancedPanel()'s own collectChanges()). A piece that
// conflicts with something already on the page (maneid already set, a subsection that's already there)
// is skipped with a warning rather than failing the whole save -- everything else the user changed still
// goes through in the same edit. Throws SubmitAbort if literally nothing was filled in, so this can never
// turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
function tryApply(fn) {
try {
content = fn();
appliedAnything = true;
} catch (e) {
if (e instanceof SubmitAbort) {
warnings.push(e.message);
} else {
throw e;
}
}
}
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
if (changes.maneid) {
tryApply(function () {
return insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", [changes.maneid], {
noExtend: true,
noExtendLabel: "nasnavek (maneid)"
});
});
}
if (changes.etiket && changes.etiket.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket);
appliedAnything = true;
}
if (changes.kategori && changes.kategori.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, words);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list, ported from start.js's own makeModifierLi() + onSubInput(): every word is its own
// always-visible row (word box + a "+" to attach one of the 10 WORD_MODIFIERS as a small pill above the
// box + a "x" to drop the row); a fresh empty row appears automatically once the current last row gets
// text, so the field never needs an explicit "add another word" button. Unlike the old chip-input this
// replaces, duplicate words are allowed (start.js's own field allows them too) and there is no separate
// commit step -- every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into what is currently the last row appends a fresh empty one after it
// (ported from start.js's onSubInput) -- so there is always exactly one empty trailing row to type
// into, and the field never needs its own explicit "add word" button.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, start.js's own buildChipField() pattern (its .wiktku-dfn-chipfield-chip) --
// used for Etîket and Kategorî, which (unlike Hevmane/Dijmane/etc.) are simple value lists with no
// per-word modifiers. Enter or "," commits the current text as a tag; Backspace on an empty input
// removes the last tag; values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss (+ Oto-lînk bike) and the two
// most-used word lists (Hevmane/Dijmane) sit directly in the picker row; the remaining SENSE_GROUPS word
// lists, maneid, etîket, kategorî, and this POS block's own "+ beşek" subsection picker -- plus Nimûne/
// jêgirtin -- live behind a single "Zêdetir" dropdown -- plus one shared "Lê zêde bike" that queues
// everything the user actually filled in as a single edit, via applyAdvancedChanges() and the shared
// queueChange() helper (see this file's own floating queue box, built by ensureQueueBox()). Nimûne/
// jêgirtin is still an immediate proxy-click (see findExampleButton()), not a field this combined save
// applies -- it opens a DIFFERENT gadget's own form with its own independent save -- it just sits in the
// dropdown rather than as its own separate top-level link.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-OPEN box (key -> () => value); collectChanges() below only
// ever reads from a box the user actually clicked to add -- there is no "always all 11 fields present"
// state any more (that was tried and reverted -- see this file's own history notes).
var getters = {};
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's own wording; everything else here
// only ever ADDS to the definition line) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel).then(
function (gloss) {
originalGloss = gloss;
$textarea.val(gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: gloss + the two most-used word groups (Hevmane/Dijmane, same SENSE_GROUPS.primary
// flag start.js itself uses to feature them) sit directly in the row; everything else (the remaining
// word groups, maneid, etîket, kategorî) lives behind a single "Zêdetir" dropdown -- back to the
// pre-round-12 layout the user actually wanted, on top of round 12's click-to-open-a-box mechanic:
// clicking any link (primary or from the dropdown) builds and appends its box to $openBoxes and hides
// that link; the box's own "×" removes it, clears its getter, and un-hides the link -- several boxes can
// be open at once, unlike the old "only one form open at a time" behavior (round 3-10's $below). No
// "Beşek (====)" entry here -- buildSubsectionPanel()'s own "+ Beşek lê zêde bike" trigger already
// covers page-level subsections; having it twice was redundant (round 19). ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: !!group.primary };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
// Nimûne/jêgirtin sits first in the dropdown, ahead of every field-pick link.
$moreMenu.append($nimune);
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
});
// slideToggle()/slideUp() (jQuery's own animated show/hide, same mechanism the original en.wiktionary
// gadget's own "More ►" list used) instead of an instant show/hide -- a smooth expand/collapse rather
// than the dropdown just popping open.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle);
// Closes the dropdown on an outside click, same as round 3-10's own "More" menu -- scoped to this
// panel's own $moreToggle/$moreMenu, so it never touches another sense's panel.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via the shared queueChange()
// helper (see its own comment) -- the actual save happens later, when the user clicks "Guhertinan qeyd
// bike" on this gadget's own floating queue box. ----
// Small "not saved yet" preview of everything this one queued change will do, appended right after
// $quickRow (i.e. in the same spot the panel itself sits, right under the sense's gloss) -- plain text,
// not a real render of {{hevmane}}/etc., but placed where the real content will actually end up once
// the page is reloaded after a real save.
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
});
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: getters.maneid ? getters.maneid() : "",
etiket: getters.etiket ? getters.etiket() : [],
kategori: getters.kategori ? getters.kategori() : [],
words: words
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Same zero-links-gets-auto-linkified rule as every earlier round's gloss save -- only when the
// gloss is actually part of this save, and only ever applied automatically when the user hasn't
// already added a manual link themselves.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $moreMenu, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above: gloss/Hevmane/Dijmane sit as direct picker
// links, everything else (the remaining SENSE_GROUPS word lists, maneid, etîket, kategorî, this POS
// block's own subsections) behind a "Zêdetir" dropdown -- clicking any of them opens its own box, several
// can be open at once, then one shared "Lê zêde bike" queues everything currently open together into this
// gadget's own floating queue box (see queueChange()) -- the real save only happens when the user clicks
// that box's own "Guhertinan qeyd bike".
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
// A plain pencil glyph (bare stroke, no background/border box) rather than a Unicode character --
// the nib points to the lower-left, matching the classic MediaWiki edit-pencil look (round 20).
var $toggle = $(
"<a href='#' class='dsb-toggle' title='Guhartina pêşketî'>" +
"<svg viewBox='0 0 24 24' aria-hidden='true'><path d='M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z'></path></svg>" +
"</a>"
);
// Revealed by $toggle -- an indented panel under the sense (like en.wiktionary's own
// "+Add example sentence +Add quotation More" row under a definition), not always visible. Built
// lazily on first open (see buildAdvancedPanel()'s own fetchCurrentGloss() call) rather than eagerly
// for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.prepend($toolbar);
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a NEW "====" subsection preview belongs in the live DOM, using the same canonical order
// subsectionRankForHeader()/PAGE_SUBSECTIONS already give insertPageSubsection() for the real wikitext --
// so the preview shows up exactly where the real content will land after a save + reload, not just tacked
// onto the end of the POS block. Returns either {insertBefore: $el} (an existing subsection that outranks
// this one) or {insertAfter: $el} (nothing does -- goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its own canonical position (domSubsectionInsertAnchor()) so it reads as
// "this is what will actually be here" rather than a form-panel status line. Plain text, not a real render
// of {{kol3|...}}/etc. Returns the inserted element so the caller can remove it again (queue cancel, or
// after a real save, when the page needs a reload to show the real thing anyway).
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4> -- existingSubsectionHeadersInDom() (".mw-heading4, h4") must never
// mistake this live-only preview for an actual subsection already on the page, or a second "+ Beşek lê
// zêde bike" would wrongly treat it as already there and hide it from the picker.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field, saved via insertPageSubsection().
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return existing.indexOf(s.header) === -1;
});
if (!available.length) {
$panel.text("Hemû beş jixwe li vê hene.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.header));
});
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
function currentSubsection() {
var id = $select.val();
return available.filter(function (s) {
return s.id === id;
})[0];
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
$fieldWrap.append(
$("<textarea class='dsb-input dsb-subsection-text' rows='3'></textarea>")
.attr("placeholder", s.header + "…")
);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
var content;
if (s.kind === "wordlist") {
content = wordField.values();
if (!content.length) {
return;
}
} else {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
}
$save.prop("disabled", true);
queueChange(
"+" + s.header + " (DefSideBoxes)",
function (pageContent) {
return { content: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, s, content), warnings: [] };
},
$save,
$status,
function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that replaces an unclassified "=== Mane ===" placeholder
// heading, saved via convertManeToPos(). Lists every name from sectionNames -- same canonical POS list
// locateSection() itself accepts.
function buildConvertPosPanel($panel, $h3, language, maneOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
$select.append($("<option></option>").val(name).text(name));
});
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertManeToPos(pageContent, language, maneOrdinal, chosen), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note right under the heading itself (its own correct spot on the
// page), rather than rewriting the real heading text -- an in-place rewrite would need to be
// reverted on failure/cancel but KEPT on a real success, and a real save failing partway
// through would otherwise leave a real heading showing a name that was never actually saved.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
}
);
});
$panel.empty().append($select, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger right under an unclassified "=== Mane ===" placeholder
// heading (see convertManeToPos()'s own comment for what that heading means).
function attachManeConvertTrigger($h3) {
if ($h3.data("dsbManeAttached")) {
return;
}
$h3.data("dsbManeAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var maneOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, maneOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (/^Mane(\s+\d+)?$/.test($h3.text().trim())) {
attachManeConvertTrigger($h3);
}
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
});
}
$(init);
// </nowiki>
})();
hze4ups06uz98801q0h278yi7z8r8ml
6347387
6347378
2026-08-31T15:15:03Z
Wikihez
7344
6347387
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary.
// Full rewrite of en.wiktionary's Gadget-DefSideBoxes.js: that file depends on Editor/AdderWrapper/LangMetadata/
// util.validateNoWikisyntax and is hard-wired to en.wiktionary's senseid/sense/trans-top system and vector-only
// hover positioning -- none of that fits ku.wiktionary. This version instead reuses the section/language-matching
// helpers already proven (and twice bugfixed) in Gadget-wikt.add-examples.js, and writes ku.wiktionary's own
// wikitext conventions (start.js's "#: {{hevmane|lang|...}}" per-sense lines and "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile) -- no hover-only UI, no absolute positioning.
// Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling (not a declared ResourceLoader dependency): the "Nimûne/jêgirtin" menu item looks for the
// button Gadget-wikt.add-examples.js already inserts on each definition, by its exact link text -- that gadget
// must run first and must keep using the same text ("Nimûneyeke bikaranînê lê zêde bike").
// <nowiki>
(function () {
"use strict";
// Same namespace guard as Wiki/start.js and Gadget-wikt.add-examples.js: main namespace, namespace 108
// (used for reconstructed-entry pages -- see start.js's own "{{jinûvesazkirî|...}}" handling), or a
// user's own /ceribandin or /test sandbox subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js's own copy.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// The template call convertManeToPos() (round 21) drops right under a newly-chosen POS heading, e.g.
// "Hoker" -> "{{hoker|ku}}". Matches start.js's own pos step exactly (MediaWiki:Gadget-start.js/data.json's
// posChoices list, and its own "{{" + pos + "|" + lang + "}}" fallback): a "Formeke X" (form-of) heading
// still uses the UNCHANGED base pos template, per start.js's own comment on that. "Biwêj" has no entry in
// posChoices either -- start.js's own pos step offers no template for it, so none is added here.
var POS_TEMPLATE = {
"Navdêr": "navdêr",
"Formeke navdêrê": "navdêr",
"Lêker": "lêker",
"Formeke lêkerê": "lêker",
"Rengdêr": "rengdêr",
"Formeke rengdêrê": "rengdêr",
"Hoker": "hoker",
"Formeke hokerê": "hoker",
"Serenav": "serenav",
"Formeke serenavê": "serenav",
"Artîkel": "artîkel",
"Baneşan": "baneşan",
"Bazinedaçek": "bazinedaçek",
"Cînav": "cînav",
"Daçek": "daçek",
"Girêdek": "girêdek",
"Gotineke pêşiyan": "gotineke pêşiyan",
"Hejmar": "hejmar",
"Hevok": "hevok",
"Îfade": "îfade",
"Kurtenav": "kurtenav",
"Navgir": "navgir",
"Paşdaçek": "paşdaçek",
"Paşgir": "paşgir",
"Pêşdaçek": "pêşdaçek",
"Pêşgir": "pêşgir",
"Pirtik": "pirtik",
"Reh": "reh",
"Sembol": "sembol",
"Tîp": "tîp"
};
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Order matters only for where a brand-new group line lands relative to other existing group lines.
// "primary: true" groups get their own always-visible quick link on the definition (mirrors
// en.wiktionary's own DefSideBoxes, which keeps "+Add example sentence"/"+Add quotation" always visible
// and tucks everything else behind "More"); the rest live inside this gadget's own "More" menu instead.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane", primary: true },
{ key: "dijmane", label: "Dijmane", primary: true },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Dûnde is left out here -- its wikitext is a multi-language table, not yet ported.
// Order here IS the canonical ku.wiktionary entry-layout order for "====" subsections (the user's own
// full list runs Bilêvkirin, Ji wêjeya klasîk, Ji wêjeyê, Tewandin, Notên bikaranînê, Bi alfabeyên din,
// Formên alternatîv, Kurtkirin, Sembol, Navê zanistî, Hevmane, Nêzîk, Dijmane, Jornav, Jêrnav, Jê,
// Têkildar, Etîmolojî, Dûnde, Bide ber, Herwiha binêre, Bêhtir bixwîne, Bi zaravayên din, Werger, Qafiye,
// Anagram, Çavkanî) -- only the steps with a confirmed wikitext format are implemented here. Left out for
// now: Bilêvkirin (a "===" section per language in start.js, not a "====" subsection inside a POS block --
// doesn't fit this array's model at all); Dûnde/Bi zaravayên din/Werger (start.js implements these, but as
// genuinely complex multi-language table sections, same reason they were deferred in earlier rounds); Ji
// wêjeya klasîk, Ji wêjeyê, Kurtkirin, Sembol, Navê zanistî, Nêzîk, Bide ber, Qafiye, Anagram (no
// confirmed wikitext format anywhere in start.js -- adding these would mean inventing templates for a
// tool that edits live pages). insertPageSubsection() uses this array's own order as the insertion rank
// -- see subsectionRankForHeader().
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// ---- word-modifier system, ported from start.js's own makeModifierLi()/WORD_MODIFIERS (the exact widget
// start.js uses for Hevmane/Dijmane/Formên alternatîv/Termên koordîne/Jornav/Jêrnav, both as a page-level
// {{kol3|...}} list and as a per-sense "#: {{tpl|lang|...}}" line) -- every word in one of these lists can
// carry small "<key:value>" annotations (translation, gender, label, ...), which the {{hevmane}}/{{kol3}}/etc.
// templates parse back out of the raw positional param. A word with no annotations is just its plain text.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers back into the raw "word<key:value>…" form the {{hevmane}}/
* {{kol3}}/etc. templates read. No re-hydration path is needed here (unlike start.js's own form, this
* panel is never pre-filled from existing page content) so there is no matching parseWordValue(). */
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers, ported from Gadget-wikt.add-examples.js (same document-order technique, so
// mobile's per-section DOM wrapping and MediaWiki's page-wide heading-id collisions can't break it) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s+\d+$/, "");
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || $(this).text().trim();
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback -- one fetch covers both the
// edit-conflict check and the content, matching the hardened pattern in Gadget-wikt.add-examples.js
// (an earlier separate-fetch version could silently overwrite someone else's edit landed in between).
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// ---- this gadget's own save queue + floating widget ----
// Round 12/13 queued into the real "Gadget-Editor - kuwikt.js" singleton (window.editor) instead of saving
// directly, so several DefSideBoxes edits could land in one save. That gadget turned out to be the wrong
// vehicle for this: it's built around a different feature (queuing translation additions) and its own
// floating widget shows a tip about that ("Tu dikarî hin wergerên din jî lê zêde bikî…") which makes no
// sense next to a queued Hevmane/Dijmane/subsection change. This file now keeps its own small queue and its
// own floating widget instead -- same "collect several edits, one real save" idea, but with UI that's
// actually about what this gadget does.
//
// Each queued entry keeps its OWN transformFn rather than a pre-computed wikitext snapshot, so the real
// save (saveQueueNow) can re-run every queued transform against freshly-fetched content in one
// api.edit() transform -- same one-fetch, no-stale-overwrite pattern editPage() already uses everywhere
// else in this file, just threaded through N transforms instead of one.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// The real save: re-runs every queued transformFn, in order, against ONE freshly-fetched revision (inside
// editPage()'s own hardened transform) and posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var combinedSummary = dsbQueue.entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
dsbQueue.entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function () {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text("✓ hemû guhertin hatin qeydkirin — rûpel nûve bike da ku bibînî.");
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()) -- nothing here touches the page yet, so a transform that would throw
// SubmitAbort (e.g. "this subsection already exists") is only actually discovered when "Guhertinan qeyd
// bike" runs it for real, same as queuing into a real editor would work. Also runs previewFn(), which a
// caller uses to drop a small "not saved yet" preview into the live DOM at the change's own correct spot on
// the page (see buildSubsectionPreviewDom() and the inline gloss/word-group preview in buildAdvancedPanel).
// Shared by every panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel,
// buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget (start.js's own linkifyText()/$.kuLinkify -- the real,
// already-deployed word-linking logic; see its own Wiki/linkify.js for what it actually does) and calls
// back with the linkified result. Passes the text through unchanged if the gadget can't be loaded, same
// fallback start.js's own linkifyText() uses -- never blocks a save on it.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location, ported/adapted from Gadget-wikt.add-examples.js's own submit() ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal -- never by a DOM id number, which
// MediaWiki's page-wide anchor uniquification can attach to a heading for reasons unrelated to its actual
// position (see Gadget-wikt.add-examples.js's own bugfix history for why that broke on a real page).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the WHOLE rest of the page from this language's heading onward, since the caller
// reuses it to rebuild the entire saved text -- only the section-heading search itself is bounded
// (via sectionSearchEndLine), so a same-named heading in a later language can never match by mistake.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel -- an array whose
// element 0 is unused here (it's the "type|ordinal" string locateSection already resolved) and whose
// remaining elements are 0-based indices, one per nesting level (see eachLeafDefinition's own construction).
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's own wordLine()
// format). If a line for this same tplKey already exists under the definition, missing words are appended
// to it instead of adding a duplicate line; otherwise a new line lands after the last existing group line
// (or right after the definition itself), always before any "#*"/citation lines, matching start.js's order.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's own gloss
// text -- start.js itself only ever builds "{{K|lang|...}} {{e|lang|...}} <gloss>" (kategori before
// etîket; Dever/Şîve, which would sit between them, is out of scope here); maneid is placed first,
// matching the user's own live example ("{{maneid|ku|id}} {{f|ku|id}} <gloss>").
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker
// (maneid/K/e in whatever order they're already in, plus any other template already there, e.g. a form-of
// call) -- stops at the first thing that isn't one, normally the gloss text itself. Shared by
// insertLeadingSenseTpl() (which searches "calls" for an existing tplKey to extend or insert next to) and
// updateSenseGloss()/fetchCurrentGloss() (which only care about "rest", the gloss text after every call).
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts (or, unless opts.noExtend, extends) one of the small templates that prefix a definition
// line's own gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} (kategori) or {{e|lang|etîket1|...}}
// (etîket). Extending merges new values into an existing call the same way insertSenseWords() does for
// "#:" sub-lines; opts.noExtend instead aborts if the template is already there (used for maneid, which
// identifies the sense and so must never silently get a second, different id).
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the WHOLE leading-call run (not just tplKey's own regex against position 0) means an
// existing tplKey call is found and merged wherever it already sits, not just when it happens to be
// first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.noExtend) {
throw new SubmitAbort("Ev hevok jixwe xwedan " + (opts.noExtendLabel || tplKey) + " e.");
}
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call, e.g. a form-of template, always outranks everything),
// or at the end of the run if every existing call comes before tplKey.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading "{{maneid|...}}"/"{{K|...}}"/
// "{{e|...}}"/other template calls exactly as they were -- the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
var calls = splitLeadingCalls(afterMarker).calls;
// "{{mane?|lang}}" is start.js's own "no definition entered yet" placeholder (see steps.dfn's own
// getOutput()) -- once the user provides a real gloss through this form, that placeholder is fully
// replaced, never kept alongside the new text the way maneid/K/e/etc. (real metadata) are.
calls = calls.filter(function (c) { return c.key !== "mane?"; });
var leadingText = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (leadingText ? leadingText + " " : "") + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text (splitLeadingCalls().rest)
// to prefill the "Maneyê biguhêre" form. A plain read, not part of the hardened save path -- the actual
// save still runs updateSenseGloss() inside editPage()'s own transform against freshly-fetched content, so
// someone else's edit landing between this read and that save can never be silently overwritten; only the
// prefilled text itself could be a little stale, same as any edit form built from a page you loaded earlier.
function fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
var loc = locateSection(content, language, sectionType, sectionOrdinal);
var defLine = findDefinitionLine(loc.lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(loc.lines[defLine])[0];
var afterMarker = loc.lines[defLine].slice(marker.length).replace(/^\s+/, "");
return splitLeadingCalls(afterMarker).rest;
});
}
// Finds a POS block's own body range (its "===" line's own index up to, but not including, the next
// heading of level <= 3), and the header text + line index of any "====" subsections it already contains
// (the line index lets insertPageSubsection() splice a new subsection in right before an existing one,
// not just always at the very end).
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// PAGE_SUBSECTIONS' own array order IS the canonical ku.wiktionary subsection order (see its own comment) --
// this just looks up a header's rank in it. -1 for a header that isn't one of ours (hand-authored, or a
// convention step this gadget doesn't support yet); such a header is never used as an insertion anchor.
function subsectionRankForHeader(header) {
for (var i = 0; i < PAGE_SUBSECTIONS.length; i++) {
if (PAGE_SUBSECTIONS[i].header === header) {
return i;
}
}
return -1;
}
// Inserts a new "==== Header ====" subsection into its canonical position within a POS block (right before
// the first EXISTING recognized subsection that outranks it -- same "leading run" idea as
// LEADING_TPL_ORDER/insertLeadingSenseTpl, just for whole ==== blocks instead of {{...}} calls on one
// line), falling back to the end of the block when nothing there outranks it. Either a {{kol3|...}} word
// list (start.js's makeWordListStep format) or a plain paragraph, matching start.js's other custom steps
// (Etîmolojî, Notên bikaranînê, ...).
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var block;
if (subsection.kind === "wordlist") {
var params = "cure=" + subsection.header + "\n" + content.map(function (w) {
return "|" + w;
}).join("\n");
block = "\n==== " + subsection.header + " ====\n{{kol3|" + language + "|" + params + "\n}}\n";
} else {
block = "\n==== " + subsection.header + " ====\n" + content + "\n";
}
var myRank = subsectionRankForHeader(subsection.header);
var insertAt = bounds.end;
for (var i = 0; i < bounds.existingHeaders.length; i++) {
var otherRank = subsectionRankForHeader(bounds.existingHeaders[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = bounds.existingHeaders[i].lineIndex;
break;
}
}
lines.splice(insertAt, 0, block);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc. if more than one collides)
// instead of a real part-of-speech name, tagged right below with {{cure?|<lang>}} -- ku.wiktionary's own
// "cureyê rêzimanî nediyar e" (part of speech not yet determined) maintenance flag. Neither is in
// sectionNames, so sectionTypeOf() and locateSection() never match it; these two functions are a small
// parallel path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text (plus
// an optional page author's own disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading, drops the {{cure?|...}} line right
// after it if present (that template flags "part of speech not yet determined", which no longer holds
// once a real one is chosen), and -- round 21 -- inserts the matching "{{<pos>|<lang>}}" template call in
// its place, e.g. "=== Hoker ===\n{{hoker|ku}}\n". POS_TEMPLATE has no entry for a couple of section types
// (see its own comment), in which case no template line is added, same as before round 21. Any other
// content under the heading (the "#" senses, subsections, ...) is left untouched.
function convertManeToPos(pageContent, language, maneOrdinal, newSectionType) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
var loc = locateManeSection(pageContent, language, maneOrdinal);
var lines = loc.lines;
var m = /^(===[ ]*Mane)(\s+\d+)?([ ]*===)/.exec(lines[loc.maneLineIndex]);
lines[loc.maneLineIndex] = "=== " + newSectionType + (m[2] ? m[2] : "") + " ===";
var nextLineIndex = loc.maneLineIndex + 1;
if (nextLineIndex < lines.length && /^\{\{\s*cure\?\s*\|[^{}]*\}\}\s*$/.test(lines[nextLineIndex])) {
lines.splice(nextLineIndex, 1);
}
var posTemplate = POS_TEMPLATE[newSectionType];
if (posTemplate) {
lines.splice(nextLineIndex, 0, "{{" + posTemplate + "|" + language + "}}");
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form already used
// (updateSenseGloss/insertLeadingSenseTpl/insertSenseWords/insertPageSubsection), applying only the
// pieces the caller actually filled in (see buildAdvancedPanel()'s own collectChanges()). A piece that
// conflicts with something already on the page (maneid already set, a subsection that's already there)
// is skipped with a warning rather than failing the whole save -- everything else the user changed still
// goes through in the same edit. Throws SubmitAbort if literally nothing was filled in, so this can never
// turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
function tryApply(fn) {
try {
content = fn();
appliedAnything = true;
} catch (e) {
if (e instanceof SubmitAbort) {
warnings.push(e.message);
} else {
throw e;
}
}
}
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
if (changes.maneid) {
tryApply(function () {
return insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", [changes.maneid], {
noExtend: true,
noExtendLabel: "nasnavek (maneid)"
});
});
}
if (changes.etiket && changes.etiket.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket);
appliedAnything = true;
}
if (changes.kategori && changes.kategori.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, words);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list, ported from start.js's own makeModifierLi() + onSubInput(): every word is its own
// always-visible row (word box + a "+" to attach one of the 10 WORD_MODIFIERS as a small pill above the
// box + a "x" to drop the row); a fresh empty row appears automatically once the current last row gets
// text, so the field never needs an explicit "add another word" button. Unlike the old chip-input this
// replaces, duplicate words are allowed (start.js's own field allows them too) and there is no separate
// commit step -- every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into what is currently the last row appends a fresh empty one after it
// (ported from start.js's onSubInput) -- so there is always exactly one empty trailing row to type
// into, and the field never needs its own explicit "add word" button.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, start.js's own buildChipField() pattern (its .wiktku-dfn-chipfield-chip) --
// used for Etîket and Kategorî, which (unlike Hevmane/Dijmane/etc.) are simple value lists with no
// per-word modifiers. Enter or "," commits the current text as a tag; Backspace on an empty input
// removes the last tag; values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss (+ Oto-lînk bike) and the two
// most-used word lists (Hevmane/Dijmane) sit directly in the picker row; the remaining SENSE_GROUPS word
// lists, maneid, etîket, kategorî, and this POS block's own "+ beşek" subsection picker -- plus Nimûne/
// jêgirtin -- live behind a single "Zêdetir" dropdown -- plus one shared "Lê zêde bike" that queues
// everything the user actually filled in as a single edit, via applyAdvancedChanges() and the shared
// queueChange() helper (see this file's own floating queue box, built by ensureQueueBox()). Nimûne/
// jêgirtin is still an immediate proxy-click (see findExampleButton()), not a field this combined save
// applies -- it opens a DIFFERENT gadget's own form with its own independent save -- it just sits in the
// dropdown rather than as its own separate top-level link.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-OPEN box (key -> () => value); collectChanges() below only
// ever reads from a box the user actually clicked to add -- there is no "always all 11 fields present"
// state any more (that was tried and reverted -- see this file's own history notes).
var getters = {};
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's own wording; everything else here
// only ever ADDS to the definition line) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel).then(
function (gloss) {
originalGloss = gloss;
$textarea.val(gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: gloss + the two most-used word groups (Hevmane/Dijmane, same SENSE_GROUPS.primary
// flag start.js itself uses to feature them) sit directly in the row; everything else (the remaining
// word groups, maneid, etîket, kategorî) lives behind a single "Zêdetir" dropdown -- back to the
// pre-round-12 layout the user actually wanted, on top of round 12's click-to-open-a-box mechanic:
// clicking any link (primary or from the dropdown) builds and appends its box to $openBoxes and hides
// that link; the box's own "×" removes it, clears its getter, and un-hides the link -- several boxes can
// be open at once, unlike the old "only one form open at a time" behavior (round 3-10's $below). No
// "Beşek (====)" entry here -- buildSubsectionPanel()'s own "+ Beşek lê zêde bike" trigger already
// covers page-level subsections; having it twice was redundant (round 19). ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: !!group.primary };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
// Nimûne/jêgirtin sits first in the dropdown, ahead of every field-pick link.
$moreMenu.append($nimune);
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
});
// slideToggle()/slideUp() (jQuery's own animated show/hide, same mechanism the original en.wiktionary
// gadget's own "More ►" list used) instead of an instant show/hide -- a smooth expand/collapse rather
// than the dropdown just popping open.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle);
// Closes the dropdown on an outside click, same as round 3-10's own "More" menu -- scoped to this
// panel's own $moreToggle/$moreMenu, so it never touches another sense's panel.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via the shared queueChange()
// helper (see its own comment) -- the actual save happens later, when the user clicks "Guhertinan qeyd
// bike" on this gadget's own floating queue box. ----
// Small "not saved yet" preview of everything this one queued change will do, appended right after
// $quickRow (i.e. in the same spot the panel itself sits, right under the sense's gloss) -- plain text,
// not a real render of {{hevmane}}/etc., but placed where the real content will actually end up once
// the page is reloaded after a real save.
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
});
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: getters.maneid ? getters.maneid() : "",
etiket: getters.etiket ? getters.etiket() : [],
kategori: getters.kategori ? getters.kategori() : [],
words: words
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Same zero-links-gets-auto-linkified rule as every earlier round's gloss save -- only when the
// gloss is actually part of this save, and only ever applied automatically when the user hasn't
// already added a manual link themselves.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $moreMenu, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above: gloss/Hevmane/Dijmane sit as direct picker
// links, everything else (the remaining SENSE_GROUPS word lists, maneid, etîket, kategorî, this POS
// block's own subsections) behind a "Zêdetir" dropdown -- clicking any of them opens its own box, several
// can be open at once, then one shared "Lê zêde bike" queues everything currently open together into this
// gadget's own floating queue box (see queueChange()) -- the real save only happens when the user clicks
// that box's own "Guhertinan qeyd bike".
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
// A plain pencil glyph (bare stroke, no background/border box) rather than a Unicode character --
// the nib points to the lower-left, matching the classic MediaWiki edit-pencil look (round 20).
var $toggle = $(
"<a href='#' class='dsb-toggle' title='Guhartina pêşketî'>" +
"<svg viewBox='0 0 24 24' aria-hidden='true'><path d='M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z'></path></svg>" +
"</a>"
);
// Revealed by $toggle -- an indented panel under the sense (like en.wiktionary's own
// "+Add example sentence +Add quotation More" row under a definition), not always visible. Built
// lazily on first open (see buildAdvancedPanel()'s own fetchCurrentGloss() call) rather than eagerly
// for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.prepend($toolbar);
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a NEW "====" subsection preview belongs in the live DOM, using the same canonical order
// subsectionRankForHeader()/PAGE_SUBSECTIONS already give insertPageSubsection() for the real wikitext --
// so the preview shows up exactly where the real content will land after a save + reload, not just tacked
// onto the end of the POS block. Returns either {insertBefore: $el} (an existing subsection that outranks
// this one) or {insertAfter: $el} (nothing does -- goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its own canonical position (domSubsectionInsertAnchor()) so it reads as
// "this is what will actually be here" rather than a form-panel status line. Plain text, not a real render
// of {{kol3|...}}/etc. Returns the inserted element so the caller can remove it again (queue cancel, or
// after a real save, when the page needs a reload to show the real thing anyway).
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4> -- existingSubsectionHeadersInDom() (".mw-heading4, h4") must never
// mistake this live-only preview for an actual subsection already on the page, or a second "+ Beşek lê
// zêde bike" would wrongly treat it as already there and hide it from the picker.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field, saved via insertPageSubsection().
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return existing.indexOf(s.header) === -1;
});
if (!available.length) {
$panel.text("Hemû beş jixwe li vê hene.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.header));
});
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
function currentSubsection() {
var id = $select.val();
return available.filter(function (s) {
return s.id === id;
})[0];
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
$fieldWrap.append(
$("<textarea class='dsb-input dsb-subsection-text' rows='3'></textarea>")
.attr("placeholder", s.header + "…")
);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
var content;
if (s.kind === "wordlist") {
content = wordField.values();
if (!content.length) {
return;
}
} else {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
}
$save.prop("disabled", true);
queueChange(
"+" + s.header + " (DefSideBoxes)",
function (pageContent) {
return { content: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, s, content), warnings: [] };
},
$save,
$status,
function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that replaces an unclassified "=== Mane ===" placeholder
// heading, saved via convertManeToPos(). Lists every name from sectionNames -- same canonical POS list
// locateSection() itself accepts.
function buildConvertPosPanel($panel, $h3, language, maneOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
$select.append($("<option></option>").val(name).text(name));
});
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertManeToPos(pageContent, language, maneOrdinal, chosen), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note right under the heading itself (its own correct spot on the
// page), rather than rewriting the real heading text -- an in-place rewrite would need to be
// reverted on failure/cancel but KEPT on a real success, and a real save failing partway
// through would otherwise leave a real heading showing a name that was never actually saved.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
}
);
});
$panel.empty().append($select, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger right under an unclassified "=== Mane ===" placeholder
// heading (see convertManeToPos()'s own comment for what that heading means).
function attachManeConvertTrigger($h3) {
if ($h3.data("dsbManeAttached")) {
return;
}
$h3.data("dsbManeAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var maneOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, maneOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (/^Mane(\s+\d+)?$/.test($h3.text().trim())) {
attachManeConvertTrigger($h3);
}
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
});
}
$(init);
// </nowiki>
})();
crrbosq3vutxvr3v11fvsrmw7kpmxpc
6347392
6347387
2026-08-31T15:26:49Z
Wikihez
7344
6347392
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary.
// Full rewrite of en.wiktionary's Gadget-DefSideBoxes.js: that file depends on Editor/AdderWrapper/LangMetadata/
// util.validateNoWikisyntax and is hard-wired to en.wiktionary's senseid/sense/trans-top system and vector-only
// hover positioning -- none of that fits ku.wiktionary. This version instead reuses the section/language-matching
// helpers already proven (and twice bugfixed) in Gadget-wikt.add-examples.js, and writes ku.wiktionary's own
// wikitext conventions (start.js's "#: {{hevmane|lang|...}}" per-sense lines and "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile) -- no hover-only UI, no absolute positioning.
// Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling (not a declared ResourceLoader dependency): the "Nimûne/jêgirtin" menu item looks for the
// button Gadget-wikt.add-examples.js already inserts on each definition, by its exact link text -- that gadget
// must run first and must keep using the same text ("Nimûneyeke bikaranînê lê zêde bike").
// <nowiki>
(function () {
"use strict";
// Same namespace guard as Wiki/start.js and Gadget-wikt.add-examples.js: main namespace, namespace 108
// (used for reconstructed-entry pages -- see start.js's own "{{jinûvesazkirî|...}}" handling), or a
// user's own /ceribandin or /test sandbox subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js's own copy.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// The template call convertManeToPos() (round 21) drops right under a newly-chosen POS heading, e.g.
// "Hoker" -> "{{hoker|ku}}". Matches start.js's own pos step exactly (MediaWiki:Gadget-start.js/data.json's
// posChoices list, and its own "{{" + pos + "|" + lang + "}}" fallback): a "Formeke X" (form-of) heading
// still uses the UNCHANGED base pos template, per start.js's own comment on that. "Biwêj" has no entry in
// posChoices either -- start.js's own pos step offers no template for it, so none is added here.
var POS_TEMPLATE = {
"Navdêr": "navdêr",
"Formeke navdêrê": "navdêr",
"Lêker": "lêker",
"Formeke lêkerê": "lêker",
"Rengdêr": "rengdêr",
"Formeke rengdêrê": "rengdêr",
"Hoker": "hoker",
"Formeke hokerê": "hoker",
"Serenav": "serenav",
"Formeke serenavê": "serenav",
"Artîkel": "artîkel",
"Baneşan": "baneşan",
"Bazinedaçek": "bazinedaçek",
"Cînav": "cînav",
"Daçek": "daçek",
"Girêdek": "girêdek",
"Gotineke pêşiyan": "gotineke pêşiyan",
"Hejmar": "hejmar",
"Hevok": "hevok",
"Îfade": "îfade",
"Kurtenav": "kurtenav",
"Navgir": "navgir",
"Paşdaçek": "paşdaçek",
"Paşgir": "paşgir",
"Pêşdaçek": "pêşdaçek",
"Pêşgir": "pêşgir",
"Pirtik": "pirtik",
"Reh": "reh",
"Sembol": "sembol",
"Tîp": "tîp"
};
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Order matters only for where a brand-new group line lands relative to other existing group lines.
// "primary: true" groups get their own always-visible quick link on the definition (mirrors
// en.wiktionary's own DefSideBoxes, which keeps "+Add example sentence"/"+Add quotation" always visible
// and tucks everything else behind "More"); the rest live inside this gadget's own "More" menu instead.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane", primary: true },
{ key: "dijmane", label: "Dijmane", primary: true },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Dûnde is left out here -- its wikitext is a multi-language table, not yet ported.
// Order here IS the canonical ku.wiktionary entry-layout order for "====" subsections (the user's own
// full list runs Bilêvkirin, Ji wêjeya klasîk, Ji wêjeyê, Tewandin, Notên bikaranînê, Bi alfabeyên din,
// Formên alternatîv, Kurtkirin, Sembol, Navê zanistî, Hevmane, Nêzîk, Dijmane, Jornav, Jêrnav, Jê,
// Têkildar, Etîmolojî, Dûnde, Bide ber, Herwiha binêre, Bêhtir bixwîne, Bi zaravayên din, Werger, Qafiye,
// Anagram, Çavkanî) -- only the steps with a confirmed wikitext format are implemented here. Left out for
// now: Bilêvkirin (a "===" section per language in start.js, not a "====" subsection inside a POS block --
// doesn't fit this array's model at all); Dûnde/Bi zaravayên din/Werger (start.js implements these, but as
// genuinely complex multi-language table sections, same reason they were deferred in earlier rounds); Ji
// wêjeya klasîk, Ji wêjeyê, Kurtkirin, Sembol, Navê zanistî, Nêzîk, Bide ber, Qafiye, Anagram (no
// confirmed wikitext format anywhere in start.js -- adding these would mean inventing templates for a
// tool that edits live pages). insertPageSubsection() uses this array's own order as the insertion rank
// -- see subsectionRankForHeader().
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// ---- word-modifier system, ported from start.js's own makeModifierLi()/WORD_MODIFIERS (the exact widget
// start.js uses for Hevmane/Dijmane/Formên alternatîv/Termên koordîne/Jornav/Jêrnav, both as a page-level
// {{kol3|...}} list and as a per-sense "#: {{tpl|lang|...}}" line) -- every word in one of these lists can
// carry small "<key:value>" annotations (translation, gender, label, ...), which the {{hevmane}}/{{kol3}}/etc.
// templates parse back out of the raw positional param. A word with no annotations is just its plain text.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers back into the raw "word<key:value>…" form the {{hevmane}}/
* {{kol3}}/etc. templates read. No re-hydration path is needed here (unlike start.js's own form, this
* panel is never pre-filled from existing page content) so there is no matching parseWordValue(). */
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers, ported from Gadget-wikt.add-examples.js (same document-order technique, so
// mobile's per-section DOM wrapping and MediaWiki's page-wide heading-id collisions can't break it) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s+\d+$/, "");
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || $(this).text().trim();
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback -- one fetch covers both the
// edit-conflict check and the content, matching the hardened pattern in Gadget-wikt.add-examples.js
// (an earlier separate-fetch version could silently overwrite someone else's edit landed in between).
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// ---- this gadget's own save queue + floating widget ----
// Round 12/13 queued into the real "Gadget-Editor - kuwikt.js" singleton (window.editor) instead of saving
// directly, so several DefSideBoxes edits could land in one save. That gadget turned out to be the wrong
// vehicle for this: it's built around a different feature (queuing translation additions) and its own
// floating widget shows a tip about that ("Tu dikarî hin wergerên din jî lê zêde bikî…") which makes no
// sense next to a queued Hevmane/Dijmane/subsection change. This file now keeps its own small queue and its
// own floating widget instead -- same "collect several edits, one real save" idea, but with UI that's
// actually about what this gadget does.
//
// Each queued entry keeps its OWN transformFn rather than a pre-computed wikitext snapshot, so the real
// save (saveQueueNow) can re-run every queued transform against freshly-fetched content in one
// api.edit() transform -- same one-fetch, no-stale-overwrite pattern editPage() already uses everywhere
// else in this file, just threaded through N transforms instead of one.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// The real save: re-runs every queued transformFn, in order, against ONE freshly-fetched revision (inside
// editPage()'s own hardened transform) and posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var combinedSummary = dsbQueue.entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
dsbQueue.entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function () {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text("✓ hemû guhertin hatin qeydkirin — rûpel nûve bike da ku bibînî.");
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()) -- nothing here touches the page yet, so a transform that would throw
// SubmitAbort (e.g. "this subsection already exists") is only actually discovered when "Guhertinan qeyd
// bike" runs it for real, same as queuing into a real editor would work. Also runs previewFn(), which a
// caller uses to drop a small "not saved yet" preview into the live DOM at the change's own correct spot on
// the page (see buildSubsectionPreviewDom() and the inline gloss/word-group preview in buildAdvancedPanel).
// Shared by every panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel,
// buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget (start.js's own linkifyText()/$.kuLinkify -- the real,
// already-deployed word-linking logic; see its own Wiki/linkify.js for what it actually does) and calls
// back with the linkified result. Passes the text through unchanged if the gadget can't be loaded, same
// fallback start.js's own linkifyText() uses -- never blocks a save on it.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location, ported/adapted from Gadget-wikt.add-examples.js's own submit() ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal -- never by a DOM id number, which
// MediaWiki's page-wide anchor uniquification can attach to a heading for reasons unrelated to its actual
// position (see Gadget-wikt.add-examples.js's own bugfix history for why that broke on a real page).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the WHOLE rest of the page from this language's heading onward, since the caller
// reuses it to rebuild the entire saved text -- only the section-heading search itself is bounded
// (via sectionSearchEndLine), so a same-named heading in a later language can never match by mistake.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel -- an array whose
// element 0 is unused here (it's the "type|ordinal" string locateSection already resolved) and whose
// remaining elements are 0-based indices, one per nesting level (see eachLeafDefinition's own construction).
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's own wordLine()
// format). If a line for this same tplKey already exists under the definition, missing words are appended
// to it instead of adding a duplicate line; otherwise a new line lands after the last existing group line
// (or right after the definition itself), always before any "#*"/citation lines, matching start.js's order.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's own gloss
// text -- start.js itself only ever builds "{{K|lang|...}} {{e|lang|...}} <gloss>" (kategori before
// etîket; Dever/Şîve, which would sit between them, is out of scope here); maneid is placed first,
// matching the user's own live example ("{{maneid|ku|id}} {{f|ku|id}} <gloss>").
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker
// (maneid/K/e in whatever order they're already in, plus any other template already there, e.g. a form-of
// call) -- stops at the first thing that isn't one, normally the gloss text itself. Shared by
// insertLeadingSenseTpl() (which searches "calls" for an existing tplKey to extend or insert next to) and
// updateSenseGloss()/fetchCurrentGloss() (which only care about "rest", the gloss text after every call).
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts (or, unless opts.noExtend, extends) one of the small templates that prefix a definition
// line's own gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} (kategori) or {{e|lang|etîket1|...}}
// (etîket). Extending merges new values into an existing call the same way insertSenseWords() does for
// "#:" sub-lines; opts.noExtend instead aborts if the template is already there (used for maneid, which
// identifies the sense and so must never silently get a second, different id).
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the WHOLE leading-call run (not just tplKey's own regex against position 0) means an
// existing tplKey call is found and merged wherever it already sits, not just when it happens to be
// first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.noExtend) {
throw new SubmitAbort("Ev hevok jixwe xwedan " + (opts.noExtendLabel || tplKey) + " e.");
}
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call, e.g. a form-of template, always outranks everything),
// or at the end of the run if every existing call comes before tplKey.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading "{{maneid|...}}"/"{{K|...}}"/
// "{{e|...}}"/other template calls exactly as they were -- the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
var calls = splitLeadingCalls(afterMarker).calls;
// "{{mane?|lang}}" is start.js's own "no definition entered yet" placeholder (see steps.dfn's own
// getOutput()) -- once the user provides a real gloss through this form, that placeholder is fully
// replaced, never kept alongside the new text the way maneid/K/e/etc. (real metadata) are.
calls = calls.filter(function (c) { return c.key !== "mane?"; });
var leadingText = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (leadingText ? leadingText + " " : "") + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text (splitLeadingCalls().rest)
// to prefill the "Maneyê biguhêre" form. A plain read, not part of the hardened save path -- the actual
// save still runs updateSenseGloss() inside editPage()'s own transform against freshly-fetched content, so
// someone else's edit landing between this read and that save can never be silently overwritten; only the
// prefilled text itself could be a little stale, same as any edit form built from a page you loaded earlier.
function fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
var loc = locateSection(content, language, sectionType, sectionOrdinal);
var defLine = findDefinitionLine(loc.lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(loc.lines[defLine])[0];
var afterMarker = loc.lines[defLine].slice(marker.length).replace(/^\s+/, "");
return splitLeadingCalls(afterMarker).rest;
});
}
// Finds a POS block's own body range (its "===" line's own index up to, but not including, the next
// heading of level <= 3), and the header text + line index of any "====" subsections it already contains
// (the line index lets insertPageSubsection() splice a new subsection in right before an existing one,
// not just always at the very end).
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// PAGE_SUBSECTIONS' own array order IS the canonical ku.wiktionary subsection order (see its own comment) --
// this just looks up a header's rank in it. -1 for a header that isn't one of ours (hand-authored, or a
// convention step this gadget doesn't support yet); such a header is never used as an insertion anchor.
function subsectionRankForHeader(header) {
for (var i = 0; i < PAGE_SUBSECTIONS.length; i++) {
if (PAGE_SUBSECTIONS[i].header === header) {
return i;
}
}
return -1;
}
// Inserts a new "==== Header ====" subsection into its canonical position within a POS block (right before
// the first EXISTING recognized subsection that outranks it -- same "leading run" idea as
// LEADING_TPL_ORDER/insertLeadingSenseTpl, just for whole ==== blocks instead of {{...}} calls on one
// line), falling back to the end of the block when nothing there outranks it. Either a {{kol3|...}} word
// list (start.js's makeWordListStep format) or a plain paragraph, matching start.js's other custom steps
// (Etîmolojî, Notên bikaranînê, ...).
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var block;
if (subsection.kind === "wordlist") {
var params = "cure=" + subsection.header + "\n" + content.map(function (w) {
return "|" + w;
}).join("\n");
block = "\n==== " + subsection.header + " ====\n{{kol3|" + language + "|" + params + "\n}}\n";
} else {
block = "\n==== " + subsection.header + " ====\n" + content + "\n";
}
var myRank = subsectionRankForHeader(subsection.header);
var insertAt = bounds.end;
for (var i = 0; i < bounds.existingHeaders.length; i++) {
var otherRank = subsectionRankForHeader(bounds.existingHeaders[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = bounds.existingHeaders[i].lineIndex;
break;
}
}
lines.splice(insertAt, 0, block);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc. if more than one collides)
// instead of a real part-of-speech name, tagged right below with {{cure?|<lang>}} -- ku.wiktionary's own
// "cureyê rêzimanî nediyar e" (part of speech not yet determined) maintenance flag. Neither is in
// sectionNames, so sectionTypeOf() and locateSection() never match it; these two functions are a small
// parallel path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text (plus
// an optional page author's own disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading, drops the {{cure?|...}} line right
// after it if present (that template flags "part of speech not yet determined", which no longer holds
// once a real one is chosen), and -- round 21 -- inserts the matching "{{<pos>|<lang>}}" template call in
// its place, e.g. "=== Hoker ===\n{{hoker|ku}}\n". POS_TEMPLATE has no entry for a couple of section types
// (see its own comment), in which case no template line is added, same as before round 21. Any other
// content under the heading (the "#" senses, subsections, ...) is left untouched.
function convertManeToPos(pageContent, language, maneOrdinal, newSectionType) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
var loc = locateManeSection(pageContent, language, maneOrdinal);
var lines = loc.lines;
var m = /^(===[ ]*Mane)(\s+\d+)?([ ]*===)/.exec(lines[loc.maneLineIndex]);
lines[loc.maneLineIndex] = "=== " + newSectionType + (m[2] ? m[2] : "") + " ===";
var nextLineIndex = loc.maneLineIndex + 1;
if (nextLineIndex < lines.length && /^\{\{\s*cure\?\s*\|[^{}]*\}\}\s*$/.test(lines[nextLineIndex])) {
lines.splice(nextLineIndex, 1);
}
var posTemplate = POS_TEMPLATE[newSectionType];
if (posTemplate) {
lines.splice(nextLineIndex, 0, "{{" + posTemplate + "|" + language + "}}");
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form already used
// (updateSenseGloss/insertLeadingSenseTpl/insertSenseWords/insertPageSubsection), applying only the
// pieces the caller actually filled in (see buildAdvancedPanel()'s own collectChanges()). A piece that
// conflicts with something already on the page (maneid already set, a subsection that's already there)
// is skipped with a warning rather than failing the whole save -- everything else the user changed still
// goes through in the same edit. Throws SubmitAbort if literally nothing was filled in, so this can never
// turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
function tryApply(fn) {
try {
content = fn();
appliedAnything = true;
} catch (e) {
if (e instanceof SubmitAbort) {
warnings.push(e.message);
} else {
throw e;
}
}
}
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
if (changes.maneid) {
tryApply(function () {
return insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", [changes.maneid], {
noExtend: true,
noExtendLabel: "nasnavek (maneid)"
});
});
}
if (changes.etiket && changes.etiket.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket);
appliedAnything = true;
}
if (changes.kategori && changes.kategori.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, words);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list, ported from start.js's own makeModifierLi() + onSubInput(): every word is its own
// always-visible row (word box + a "+" to attach one of the 10 WORD_MODIFIERS as a small pill above the
// box + a "x" to drop the row); a fresh empty row appears automatically once the current last row gets
// text, so the field never needs an explicit "add another word" button. Unlike the old chip-input this
// replaces, duplicate words are allowed (start.js's own field allows them too) and there is no separate
// commit step -- every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into what is currently the last row appends a fresh empty one after it
// (ported from start.js's onSubInput) -- so there is always exactly one empty trailing row to type
// into, and the field never needs its own explicit "add word" button.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, start.js's own buildChipField() pattern (its .wiktku-dfn-chipfield-chip) --
// used for Etîket and Kategorî, which (unlike Hevmane/Dijmane/etc.) are simple value lists with no
// per-word modifiers. Enter or "," commits the current text as a tag; Backspace on an empty input
// removes the last tag; values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss (+ Oto-lînk bike) and the two
// most-used word lists (Hevmane/Dijmane) sit directly in the picker row; the remaining SENSE_GROUPS word
// lists, maneid, etîket, kategorî, and this POS block's own "+ beşek" subsection picker -- plus Nimûne/
// jêgirtin -- live behind a single "Zêdetir" dropdown -- plus one shared "Lê zêde bike" that queues
// everything the user actually filled in as a single edit, via applyAdvancedChanges() and the shared
// queueChange() helper (see this file's own floating queue box, built by ensureQueueBox()). Nimûne/
// jêgirtin is still an immediate proxy-click (see findExampleButton()), not a field this combined save
// applies -- it opens a DIFFERENT gadget's own form with its own independent save -- it just sits in the
// dropdown rather than as its own separate top-level link.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-OPEN box (key -> () => value); collectChanges() below only
// ever reads from a box the user actually clicked to add -- there is no "always all 11 fields present"
// state any more (that was tried and reverted -- see this file's own history notes).
var getters = {};
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's own wording; everything else here
// only ever ADDS to the definition line) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel).then(
function (gloss) {
originalGloss = gloss;
$textarea.val(gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: gloss + the two most-used word groups (Hevmane/Dijmane, same SENSE_GROUPS.primary
// flag start.js itself uses to feature them) sit directly in the row; everything else (the remaining
// word groups, maneid, etîket, kategorî) lives behind a single "Zêdetir" dropdown -- back to the
// pre-round-12 layout the user actually wanted, on top of round 12's click-to-open-a-box mechanic:
// clicking any link (primary or from the dropdown) builds and appends its box to $openBoxes and hides
// that link; the box's own "×" removes it, clears its getter, and un-hides the link -- several boxes can
// be open at once, unlike the old "only one form open at a time" behavior (round 3-10's $below). No
// "Beşek (====)" entry here -- buildSubsectionPanel()'s own "+ Beşek lê zêde bike" trigger already
// covers page-level subsections; having it twice was redundant (round 19). ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: !!group.primary };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
// Nimûne/jêgirtin sits first in the dropdown, ahead of every field-pick link.
$moreMenu.append($nimune);
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
});
// slideToggle()/slideUp() (jQuery's own animated show/hide, same mechanism the original en.wiktionary
// gadget's own "More ►" list used) instead of an instant show/hide -- a smooth expand/collapse rather
// than the dropdown just popping open.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle);
// Closes the dropdown on an outside click, same as round 3-10's own "More" menu -- scoped to this
// panel's own $moreToggle/$moreMenu, so it never touches another sense's panel.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via the shared queueChange()
// helper (see its own comment) -- the actual save happens later, when the user clicks "Guhertinan qeyd
// bike" on this gadget's own floating queue box. ----
// Small "not saved yet" preview of everything this one queued change will do, appended right after
// $quickRow (i.e. in the same spot the panel itself sits, right under the sense's gloss) -- plain text,
// not a real render of {{hevmane}}/etc., but placed where the real content will actually end up once
// the page is reloaded after a real save.
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
});
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: getters.maneid ? getters.maneid() : "",
etiket: getters.etiket ? getters.etiket() : [],
kategori: getters.kategori ? getters.kategori() : [],
words: words
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Same zero-links-gets-auto-linkified rule as every earlier round's gloss save -- only when the
// gloss is actually part of this save, and only ever applied automatically when the user hasn't
// already added a manual link themselves.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $moreMenu, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above: gloss/Hevmane/Dijmane sit as direct picker
// links, everything else (the remaining SENSE_GROUPS word lists, maneid, etîket, kategorî, this POS
// block's own subsections) behind a "Zêdetir" dropdown -- clicking any of them opens its own box, several
// can be open at once, then one shared "Lê zêde bike" queues everything currently open together into this
// gadget's own floating queue box (see queueChange()) -- the real save only happens when the user clicks
// that box's own "Guhertinan qeyd bike".
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
// A plain pencil glyph (bare stroke, no background/border box) rather than a Unicode character --
// the nib points to the lower-left, matching the classic MediaWiki edit-pencil look (round 20).
var $toggle = $(
"<a href='#' class='dsb-toggle' title='Guhartina pêşketî'>" +
"<svg viewBox='0 0 24 24' aria-hidden='true'><path d='M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z'></path></svg>" +
"</a>"
);
// Revealed by $toggle -- an indented panel under the sense (like en.wiktionary's own
// "+Add example sentence +Add quotation More" row under a definition), not always visible. Built
// lazily on first open (see buildAdvancedPanel()'s own fetchCurrentGloss() call) rather than eagerly
// for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.prepend($toolbar);
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a NEW "====" subsection preview belongs in the live DOM, using the same canonical order
// subsectionRankForHeader()/PAGE_SUBSECTIONS already give insertPageSubsection() for the real wikitext --
// so the preview shows up exactly where the real content will land after a save + reload, not just tacked
// onto the end of the POS block. Returns either {insertBefore: $el} (an existing subsection that outranks
// this one) or {insertAfter: $el} (nothing does -- goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its own canonical position (domSubsectionInsertAnchor()) so it reads as
// "this is what will actually be here" rather than a form-panel status line. Plain text, not a real render
// of {{kol3|...}}/etc. Returns the inserted element so the caller can remove it again (queue cancel, or
// after a real save, when the page needs a reload to show the real thing anyway).
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4> -- existingSubsectionHeadersInDom() (".mw-heading4, h4") must never
// mistake this live-only preview for an actual subsection already on the page, or a second "+ Beşek lê
// zêde bike" would wrongly treat it as already there and hide it from the picker.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field, saved via insertPageSubsection().
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return existing.indexOf(s.header) === -1;
});
if (!available.length) {
$panel.text("Hemû beş jixwe li vê hene.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.header));
});
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
function currentSubsection() {
var id = $select.val();
return available.filter(function (s) {
return s.id === id;
})[0];
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
$fieldWrap.append(
$("<textarea class='dsb-input dsb-subsection-text' rows='3'></textarea>")
.attr("placeholder", s.header + "…")
);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
var content;
if (s.kind === "wordlist") {
content = wordField.values();
if (!content.length) {
return;
}
} else {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
}
$save.prop("disabled", true);
queueChange(
"+" + s.header + " (DefSideBoxes)",
function (pageContent) {
return { content: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, s, content), warnings: [] };
},
$save,
$status,
function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that replaces an unclassified "=== Mane ===" placeholder
// heading, saved via convertManeToPos(). Lists every name from sectionNames -- same canonical POS list
// locateSection() itself accepts.
function buildConvertPosPanel($panel, $h3, language, maneOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
$select.append($("<option></option>").val(name).text(name));
});
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertManeToPos(pageContent, language, maneOrdinal, chosen), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note right under the heading itself (its own correct spot on the
// page), rather than rewriting the real heading text -- an in-place rewrite would need to be
// reverted on failure/cancel but KEPT on a real success, and a real save failing partway
// through would otherwise leave a real heading showing a name that was never actually saved.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
}
);
});
$panel.empty().append($select, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger right under an unclassified "=== Mane ===" placeholder
// heading (see convertManeToPos()'s own comment for what that heading means).
function attachManeConvertTrigger($h3) {
if ($h3.data("dsbManeAttached")) {
return;
}
$h3.data("dsbManeAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var maneOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, maneOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (/^Mane(\s+\d+)?$/.test($h3.text().trim())) {
attachManeConvertTrigger($h3);
}
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
});
}
// bfcache safety net (round 22 bugfix): a browser's back/forward cache can freeze this gadget's own OPEN UI
// -- an open "guhartina pêşketî" panel, an open "Zêdetir" dropdown, the floating queue box, a "not yet
// saved" preview block -- into its snapshot of the page. Navigating back/forward to that snapshot then
// briefly flashes that stale, out-of-place state onto the screen before the browser replaces it with a
// fresh reload -- reported live as "a large blob of text" flashing on browser back/forward; none of this
// UI existed on the page before this gadget. Collapsing everything back to its normal closed state on
// "pagehide" (fires reliably right before a page is cached, unlike "pageshow", which would only run after
// the flash already happened) means there is nothing left open to flash.
$(window).on("pagehide", function () {
clearQueue(); // drops the floating queue box and every live "not yet saved" preview it's tracking
$(".dsb-quick-row, .dsb-more-menu, .dsb-convert-pos-panel, .dsb-subsection-panel").hide();
});
$(init);
// </nowiki>
})();
mfxwk669mk13ha7rdakhzipsuokiutu
6347397
6347392
2026-08-31T16:22:36Z
Wikihez
7344
6347397
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary, writing start.js's own wikitext
// conventions ("#: {{hevmane|lang|...}}" per-sense lines, "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile). Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling: the "Nimûne/jêgirtin" menu item looks for the button Gadget-wikt.add-examples.js
// inserts on each definition, by its exact link text, so that gadget must run first.
// <nowiki>
(function () {
"use strict";
// Main namespace, namespace 108 (reconstructed-entry pages), or a user's own /ceribandin or /test subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// Template call convertManeToPos() drops under a newly-chosen POS heading, e.g. "Hoker" -> "{{hoker|ku}}".
// A "Formeke X" (form-of) heading uses the unchanged base pos template; "Biwêj" has no template at all.
var POS_TEMPLATE = {
"Navdêr": "navdêr",
"Formeke navdêrê": "navdêr",
"Lêker": "lêker",
"Formeke lêkerê": "lêker",
"Rengdêr": "rengdêr",
"Formeke rengdêrê": "rengdêr",
"Hoker": "hoker",
"Formeke hokerê": "hoker",
"Serenav": "serenav",
"Formeke serenavê": "serenav",
"Artîkel": "artîkel",
"Baneşan": "baneşan",
"Bazinedaçek": "bazinedaçek",
"Cînav": "cînav",
"Daçek": "daçek",
"Girêdek": "girêdek",
"Gotineke pêşiyan": "gotineke pêşiyan",
"Hejmar": "hejmar",
"Hevok": "hevok",
"Îfade": "îfade",
"Kurtenav": "kurtenav",
"Navgir": "navgir",
"Paşdaçek": "paşdaçek",
"Paşgir": "paşgir",
"Pêşdaçek": "pêşdaçek",
"Pêşgir": "pêşgir",
"Pirtik": "pirtik",
"Reh": "reh",
"Sembol": "sembol",
"Tîp": "tîp"
};
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Array order controls where a new group line lands relative to existing ones. "primary" groups get their
// own always-visible quick link on the definition; the rest live in this gadget's "More" menu.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane", primary: true },
{ key: "dijmane", label: "Dijmane", primary: true },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Array order is the canonical ku.wiktionary "====" subsection order and doubles as insertPageSubsection()'s
// insertion rank (see subsectionRankForHeader()). Only steps with a confirmed wikitext format are included;
// Bilêvkirin/Dûnde/Bi zaravayên din/Werger and a few others with no settled format are left out.
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// ---- word-modifier system (same widget start.js uses for Hevmane/Dijmane/etc. word lists) ----
// Every word in one of these lists can carry small "<key:value>" annotations (translation, gender, label,
// ...), which the {{hevmane}}/{{kol3}}/etc. templates parse back out of the raw positional param.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers into the raw "word<key:value>…" form {{hevmane}}/{{kol3}}/etc. read. */
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers (document-order based, immune to mobile's per-section DOM wrapping and
// MediaWiki's page-wide heading-id collisions) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s+\d+$/, "");
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || $(this).text().trim();
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback so one fetch covers both the
// edit-conflict check and the content, preventing a stale overwrite of someone else's edit.
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// This gadget's own save queue + floating widget, separate from the shared Gadget-Editor queue.
// Each entry keeps its own transformFn so saveQueueNow() can re-run all of them against one fresh fetch.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// The real save: re-runs every queued transformFn, in order, against one freshly-fetched revision and
// posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var combinedSummary = dsbQueue.entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
dsbQueue.entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function () {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text("✓ hemû guhertin hatin qeydkirin — rûpel nûve bike da ku bibînî.");
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()); nothing here touches the page yet. Also runs previewFn(), which drops a
// small "not saved yet" preview into the live DOM at the change's own spot on the page. Shared by every
// panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel, buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget ($.kuLinkify) and calls back with the linkified result.
// Passes the text through unchanged if the gadget can't be loaded, so it never blocks a save.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal, never by a DOM id number (MediaWiki's
// page-wide anchor uniquification can attach an id to a heading unrelated to its actual position).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the whole rest of the page from this language's heading onward, since the caller reuses
// it to rebuild the entire saved text; only the section-heading search itself is bounded by sectionSearchEndLine.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel: element 0 is
// unused (it's the "type|ordinal" string locateSection already resolved), remaining elements are 0-based
// indices, one per nesting level.
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's wordLine()
// format). If a line for this tplKey already exists under the definition, missing words are appended to
// it; otherwise a new line lands after the last existing group line, always before any "#*" citation lines.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's gloss text:
// maneid, then kategori (K), then etîket (e).
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker,
// stopping at the first thing that isn't one (normally the gloss text). Shared by insertLeadingSenseTpl()
// (uses "calls") and updateSenseGloss()/fetchCurrentGloss() (uses "rest", the gloss text after every call).
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts (or, unless opts.noExtend, extends) one of the small templates that prefix a definition line's
// gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} or {{e|lang|etîket1|...}}. opts.noExtend aborts
// instead if the template is already there (used for maneid, which must never get a second, different id).
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the whole leading-call run means an existing tplKey call is found and merged wherever it
// already sits, not just when it happens to be first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.noExtend) {
throw new SubmitAbort("Ev hevok jixwe xwedan " + (opts.noExtendLabel || tplKey) + " e.");
}
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call always outranks everything), or at the end of the run.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading template calls untouched --
// the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
var calls = splitLeadingCalls(afterMarker).calls;
// "{{mane?|lang}}" is start.js's "no definition entered yet" placeholder; drop it once a real gloss is set.
calls = calls.filter(function (c) { return c.key !== "mane?"; });
var leadingText = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (leadingText ? leadingText + " " : "") + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text to prefill the "Maneyê
// biguhêre" form. A plain read, not part of the hardened save path -- the actual save still re-fetches
// fresh content, so only the prefilled text itself could be a little stale.
function fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
var loc = locateSection(content, language, sectionType, sectionOrdinal);
var defLine = findDefinitionLine(loc.lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(loc.lines[defLine])[0];
var afterMarker = loc.lines[defLine].slice(marker.length).replace(/^\s+/, "");
return splitLeadingCalls(afterMarker).rest;
});
}
// Finds a POS block's body range (up to, but not including, the next heading of level <= 3), and the
// header text + line index of any "====" subsections it already contains.
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// Looks up a header's rank in PAGE_SUBSECTIONS' order. -1 for a header that isn't one of ours; such a
// header is never used as an insertion anchor.
function subsectionRankForHeader(header) {
for (var i = 0; i < PAGE_SUBSECTIONS.length; i++) {
if (PAGE_SUBSECTIONS[i].header === header) {
return i;
}
}
return -1;
}
// Inserts a new "==== Header ====" subsection into its canonical position within a POS block, right before
// the first existing recognized subsection that outranks it, or at the end if none does. Either a
// {{kol3|...}} word list or a plain paragraph, matching start.js's own subsection formats.
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var block;
if (subsection.kind === "wordlist") {
var params = "cure=" + subsection.header + "\n" + content.map(function (w) {
return "|" + w;
}).join("\n");
block = "\n==== " + subsection.header + " ====\n{{kol3|" + language + "|" + params + "\n}}\n";
} else {
block = "\n==== " + subsection.header + " ====\n" + content + "\n";
}
var myRank = subsectionRankForHeader(subsection.header);
var insertAt = bounds.end;
for (var i = 0; i < bounds.existingHeaders.length; i++) {
var otherRank = subsectionRankForHeader(bounds.existingHeaders[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = bounds.existingHeaders[i].lineIndex;
break;
}
}
lines.splice(insertAt, 0, block);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc.) instead of a real
// part-of-speech name, tagged right below with {{cure?|<lang>}} (ku.wiktionary's "part of speech not yet
// determined" maintenance flag). Neither is in sectionNames, so these two functions are a small parallel
// path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text
// (plus an optional disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading, drops the {{cure?|...}} line right
// after it if present, and inserts the matching "{{<pos>|<lang>}}" template call in its place (skipped
// for section types with no POS_TEMPLATE entry). Other content under the heading is left untouched.
function convertManeToPos(pageContent, language, maneOrdinal, newSectionType) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
var loc = locateManeSection(pageContent, language, maneOrdinal);
var lines = loc.lines;
var m = /^(===[ ]*Mane)(\s+\d+)?([ ]*===)/.exec(lines[loc.maneLineIndex]);
lines[loc.maneLineIndex] = "=== " + newSectionType + (m[2] ? m[2] : "") + " ===";
var nextLineIndex = loc.maneLineIndex + 1;
if (nextLineIndex < lines.length && /^\{\{\s*cure\?\s*\|[^{}]*\}\}\s*$/.test(lines[nextLineIndex])) {
lines.splice(nextLineIndex, 1);
}
var posTemplate = POS_TEMPLATE[newSectionType];
if (posTemplate) {
lines.splice(nextLineIndex, 0, "{{" + posTemplate + "|" + language + "}}");
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form uses, applying only the
// pieces the caller actually filled in. A piece that conflicts with the page (maneid already set, a
// subsection that's already there) is skipped with a warning rather than failing the whole save. Throws
// SubmitAbort if nothing was filled in, so this can never turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
function tryApply(fn) {
try {
content = fn();
appliedAnything = true;
} catch (e) {
if (e instanceof SubmitAbort) {
warnings.push(e.message);
} else {
throw e;
}
}
}
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
if (changes.maneid) {
tryApply(function () {
return insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", [changes.maneid], {
noExtend: true,
noExtendLabel: "nasnavek (maneid)"
});
});
}
if (changes.etiket && changes.etiket.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket);
appliedAnything = true;
}
if (changes.kategori && changes.kategori.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, words);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list: every word is its own always-visible row (word box + a "+" to attach one of the 10
// WORD_MODIFIERS as a small pill + an "x" to drop the row); a fresh empty row appears automatically once
// the current last row gets text. Duplicate words are allowed; every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into the current last row appends a fresh empty one after it, so there
// is always exactly one empty trailing row to type into.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, used for Etîket and Kategorî (simple value lists with no per-word modifiers).
// Enter or "," commits the current text as a tag; Backspace on an empty input removes the last tag;
// values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss and the two most-used word lists
// (Hevmane/Dijmane) sit directly in the picker row; the remaining word lists, maneid, etîket, kategorî
// and Nimûne/jêgirtin live behind a "Zêdetir" dropdown; one shared "Lê zêde bike" queues everything the
// user filled in as a single edit via applyAdvancedChanges() and queueChange(). Nimûne/jêgirtin is an
// immediate proxy-click into a different gadget's own form, not part of this combined save.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-open box (key -> () => value); collectChanges() only ever
// reads from a box the user actually clicked to add.
var getters = {};
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's wording; everything else here only ADDS) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel).then(
function (gloss) {
originalGloss = gloss;
$textarea.val(gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: gloss + the two most-used word groups (SENSE_GROUPS.primary) sit directly in the
// row; everything else lives behind a "Zêdetir" dropdown. Clicking any link builds and appends its box
// to $openBoxes and hides that link; the box's own "×" removes it, clears its getter, and un-hides the
// link -- several boxes can be open at once. No "Beşek (====)" entry here: buildSubsectionPanel()'s
// own "+ Beşek lê zêde bike" trigger already covers page-level subsections. ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: !!group.primary };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
// Nimûne/jêgirtin sits first in the dropdown, ahead of every field-pick link.
$moreMenu.append($nimune);
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
});
// slideToggle()/slideUp() give a smooth expand/collapse rather than the dropdown just popping open.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle);
// Closes the dropdown on an outside click, scoped to this panel's own $moreToggle/$moreMenu.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via queueChange(); the actual
// save happens when the user clicks "Guhertinan qeyd bike" on the floating queue box. ----
// Small "not saved yet" preview of everything this queued change will do, appended right under the
// sense's gloss (plain text, not a real render of {{hevmane}}/etc.).
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
});
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: getters.maneid ? getters.maneid() : "",
etiket: getters.etiket ? getters.etiket() : [],
kategori: getters.kategori ? getters.kategori() : [],
words: words
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Auto-linkify the gloss only when it's part of this save and has no manual link already.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $moreMenu, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above.
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
// A plain pencil glyph (bare stroke, no background/border box), nib pointing lower-left, matching the
// classic MediaWiki edit-pencil look.
var $toggle = $(
"<a href='#' class='dsb-toggle' title='Guhartina pêşketî'>" +
"<svg viewBox='0 0 24 24' aria-hidden='true'><path d='M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z'></path></svg>" +
"</a>"
);
// Revealed by $toggle -- an indented panel under the sense, not always visible. Built lazily on
// first open rather than eagerly for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.prepend($toolbar);
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a new "====" subsection preview belongs in the live DOM, using the same canonical order
// subsectionRankForHeader() gives insertPageSubsection(). Returns {insertBefore: $el} (an existing
// subsection that outranks this one) or {insertAfter: $el} (goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its canonical position. Plain text, not a real render of {{kol3|...}}/etc.
// Returns the inserted element so the caller can remove it again.
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4>, so existingSubsectionHeadersInDom() never mistakes this live-only
// preview for an actual subsection already on the page.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field, saved via insertPageSubsection().
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return existing.indexOf(s.header) === -1;
});
if (!available.length) {
$panel.text("Hemû beş jixwe li vê hene.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.header));
});
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
function currentSubsection() {
var id = $select.val();
return available.filter(function (s) {
return s.id === id;
})[0];
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
$fieldWrap.append(
$("<textarea class='dsb-input dsb-subsection-text' rows='3'></textarea>")
.attr("placeholder", s.header + "…")
);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
var content;
if (s.kind === "wordlist") {
content = wordField.values();
if (!content.length) {
return;
}
} else {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
}
$save.prop("disabled", true);
queueChange(
"+" + s.header + " (DefSideBoxes)",
function (pageContent) {
return { content: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, s, content), warnings: [] };
},
$save,
$status,
function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that replaces an unclassified "=== Mane ===" placeholder
// heading, saved via convertManeToPos(). Lists every name from sectionNames.
function buildConvertPosPanel($panel, $h3, language, maneOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
$select.append($("<option></option>").val(name).text(name));
});
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertManeToPos(pageContent, language, maneOrdinal, chosen), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note under the heading, rather than rewriting the real heading
// text -- avoids leaving a heading showing a name that was never actually saved if the
// save fails partway through.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
}
);
});
$panel.empty().append($select, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger right under an unclassified "=== Mane ===" placeholder
// heading (see convertManeToPos()'s own comment for what that heading means).
function attachManeConvertTrigger($h3) {
if ($h3.data("dsbManeAttached")) {
return;
}
$h3.data("dsbManeAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var maneOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, maneOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (/^Mane(\s+\d+)?$/.test($h3.text().trim())) {
attachManeConvertTrigger($h3);
}
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
});
}
// Closes every open panel/preview this gadget can leave in the DOM, so bfcache never freezes one mid-open.
function closeAllOpenUi() {
clearQueue();
$(".dsb-quick-row, .dsb-more-menu, .dsb-convert-pos-panel, .dsb-subsection-panel, .dsb-queue-box, .dsb-preview-inline, .dsb-preview-block").hide();
}
$(window).on("pagehide", closeAllOpenUi);
// Belt-and-suspenders: also close on restore-from-bfcache, in case pagehide's own hide didn't stick.
$(window).on("pageshow", function (e) {
if (e.originalEvent && e.originalEvent.persisted) {
closeAllOpenUi();
}
});
$(init);
// </nowiki>
})();
190q1ntgjqljut24lk68kibo5frieqe
6347409
6347397
2026-08-31T16:43:02Z
Wikihez
7344
6347409
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary, writing start.js's own wikitext
// conventions ("#: {{hevmane|lang|...}}" per-sense lines, "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile). Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling: the "Nimûne/jêgirtin" menu item looks for the button Gadget-wikt.add-examples.js
// inserts on each definition, by its exact link text, so that gadget must run first.
// <nowiki>
(function () {
"use strict";
// Main namespace, namespace 108 (reconstructed-entry pages), or a user's own /ceribandin or /test subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// Template call convertManeToPos() drops under a newly-chosen POS heading, e.g. "Hoker" -> "{{hoker|ku}}".
// A "Formeke X" (form-of) heading uses the unchanged base pos template; "Biwêj" has no template at all.
var POS_TEMPLATE = {
"Navdêr": "navdêr",
"Formeke navdêrê": "navdêr",
"Lêker": "lêker",
"Formeke lêkerê": "lêker",
"Rengdêr": "rengdêr",
"Formeke rengdêrê": "rengdêr",
"Hoker": "hoker",
"Formeke hokerê": "hoker",
"Serenav": "serenav",
"Formeke serenavê": "serenav",
"Artîkel": "artîkel",
"Baneşan": "baneşan",
"Bazinedaçek": "bazinedaçek",
"Cînav": "cînav",
"Daçek": "daçek",
"Girêdek": "girêdek",
"Gotineke pêşiyan": "gotineke pêşiyan",
"Hejmar": "hejmar",
"Hevok": "hevok",
"Îfade": "îfade",
"Kurtenav": "kurtenav",
"Navgir": "navgir",
"Paşdaçek": "paşdaçek",
"Paşgir": "paşgir",
"Pêşdaçek": "pêşdaçek",
"Pêşgir": "pêşgir",
"Pirtik": "pirtik",
"Reh": "reh",
"Sembol": "sembol",
"Tîp": "tîp"
};
// The "needs a POS" maintenance tag under a placeholder "Mane" heading, and every known redirect/alias name
// it's also called under on real pages -- convertManeToPos() drops whichever one is actually present.
var MANE_TAG_REGEX = /^\{\{\s*(?:cure\?|rêziman\?|kat-rêziman|kategoriya\s+rêzimanê\?|bêcure)\s*(?:\|[^{}]*)?\}\}\s*$/i;
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Array order controls where a new group line lands relative to existing ones. "primary" groups get their
// own always-visible quick link on the definition; the rest live in this gadget's "More" menu.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane", primary: true },
{ key: "dijmane", label: "Dijmane", primary: true },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Array order is the canonical ku.wiktionary "====" subsection order and doubles as insertPageSubsection()'s
// insertion rank (see subsectionRankForHeader()). Only steps with a confirmed wikitext format are included;
// Bilêvkirin/Dûnde/Bi zaravayên din/Werger and a few others with no settled format are left out.
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// ---- word-modifier system (same widget start.js uses for Hevmane/Dijmane/etc. word lists) ----
// Every word in one of these lists can carry small "<key:value>" annotations (translation, gender, label,
// ...), which the {{hevmane}}/{{kol3}}/etc. templates parse back out of the raw positional param.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers into the raw "word<key:value>…" form {{hevmane}}/{{kol3}}/etc. read. */
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers (document-order based, immune to mobile's per-section DOM wrapping and
// MediaWiki's page-wide heading-id collisions) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s+\d+$/, "");
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || $(this).text().trim();
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback so one fetch covers both the
// edit-conflict check and the content, preventing a stale overwrite of someone else's edit.
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// This gadget's own save queue + floating widget, separate from the shared Gadget-Editor queue.
// Each entry keeps its own transformFn so saveQueueNow() can re-run all of them against one fresh fetch.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// The real save: re-runs every queued transformFn, in order, against one freshly-fetched revision and
// posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var combinedSummary = dsbQueue.entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
dsbQueue.entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function () {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text("✓ hemû guhertin hatin qeydkirin — rûpel nûve bike da ku bibînî.");
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()); nothing here touches the page yet. Also runs previewFn(), which drops a
// small "not saved yet" preview into the live DOM at the change's own spot on the page. Shared by every
// panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel, buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget ($.kuLinkify) and calls back with the linkified result.
// Passes the text through unchanged if the gadget can't be loaded, so it never blocks a save.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal, never by a DOM id number (MediaWiki's
// page-wide anchor uniquification can attach an id to a heading unrelated to its actual position).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the whole rest of the page from this language's heading onward, since the caller reuses
// it to rebuild the entire saved text; only the section-heading search itself is bounded by sectionSearchEndLine.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel: element 0 is
// unused (it's the "type|ordinal" string locateSection already resolved), remaining elements are 0-based
// indices, one per nesting level.
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's wordLine()
// format). If a line for this tplKey already exists under the definition, missing words are appended to
// it; otherwise a new line lands after the last existing group line, always before any "#*" citation lines.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's gloss text:
// maneid, then kategori (K), then etîket (e).
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker,
// stopping at the first thing that isn't one (normally the gloss text). Shared by insertLeadingSenseTpl()
// (uses "calls") and updateSenseGloss()/fetchCurrentGloss() (uses "rest", the gloss text after every call).
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts (or, unless opts.noExtend, extends) one of the small templates that prefix a definition line's
// gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} or {{e|lang|etîket1|...}}. opts.noExtend aborts
// instead if the template is already there (used for maneid, which must never get a second, different id).
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the whole leading-call run means an existing tplKey call is found and merged wherever it
// already sits, not just when it happens to be first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.noExtend) {
throw new SubmitAbort("Ev hevok jixwe xwedan " + (opts.noExtendLabel || tplKey) + " e.");
}
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call always outranks everything), or at the end of the run.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading template calls untouched --
// the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
var calls = splitLeadingCalls(afterMarker).calls;
// "{{mane?|lang}}" is start.js's "no definition entered yet" placeholder; drop it once a real gloss is set.
calls = calls.filter(function (c) { return c.key !== "mane?"; });
var leadingText = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (leadingText ? leadingText + " " : "") + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text to prefill the "Maneyê
// biguhêre" form. A plain read, not part of the hardened save path -- the actual save still re-fetches
// fresh content, so only the prefilled text itself could be a little stale.
function fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
var loc = locateSection(content, language, sectionType, sectionOrdinal);
var defLine = findDefinitionLine(loc.lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(loc.lines[defLine])[0];
var afterMarker = loc.lines[defLine].slice(marker.length).replace(/^\s+/, "");
return splitLeadingCalls(afterMarker).rest;
});
}
// Finds a POS block's body range (up to, but not including, the next heading of level <= 3), and the
// header text + line index of any "====" subsections it already contains.
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// Looks up a header's rank in PAGE_SUBSECTIONS' order. -1 for a header that isn't one of ours; such a
// header is never used as an insertion anchor.
function subsectionRankForHeader(header) {
for (var i = 0; i < PAGE_SUBSECTIONS.length; i++) {
if (PAGE_SUBSECTIONS[i].header === header) {
return i;
}
}
return -1;
}
// Inserts a new "==== Header ====" subsection into its canonical position within a POS block, right before
// the first existing recognized subsection that outranks it, or at the end if none does. Either a
// {{kol3|...}} word list or a plain paragraph, matching start.js's own subsection formats.
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var block;
if (subsection.kind === "wordlist") {
var params = "cure=" + subsection.header + "\n" + content.map(function (w) {
return "|" + w;
}).join("\n");
block = "\n==== " + subsection.header + " ====\n{{kol3|" + language + "|" + params + "\n}}\n";
} else {
block = "\n==== " + subsection.header + " ====\n" + content + "\n";
}
var myRank = subsectionRankForHeader(subsection.header);
var insertAt = bounds.end;
for (var i = 0; i < bounds.existingHeaders.length; i++) {
var otherRank = subsectionRankForHeader(bounds.existingHeaders[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = bounds.existingHeaders[i].lineIndex;
break;
}
}
lines.splice(insertAt, 0, block);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc.) instead of a real
// part-of-speech name, tagged right below with {{cure?|<lang>}} (ku.wiktionary's "part of speech not yet
// determined" maintenance flag). Neither is in sectionNames, so these two functions are a small parallel
// path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text
// (plus an optional disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading, drops the maintenance tag line right
// after it if present (MANE_TAG_REGEX -- cure? or any of its known aliases), and inserts the matching
// "{{<pos>|<lang>}}" template call in its place (skipped for section types with no POS_TEMPLATE entry).
// Other content under the heading is left untouched.
function convertManeToPos(pageContent, language, maneOrdinal, newSectionType) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
var loc = locateManeSection(pageContent, language, maneOrdinal);
var lines = loc.lines;
var m = /^(===[ ]*Mane)(\s+\d+)?([ ]*===)/.exec(lines[loc.maneLineIndex]);
lines[loc.maneLineIndex] = "=== " + newSectionType + (m[2] ? m[2] : "") + " ===";
var nextLineIndex = loc.maneLineIndex + 1;
if (nextLineIndex < lines.length && MANE_TAG_REGEX.test(lines[nextLineIndex])) {
lines.splice(nextLineIndex, 1);
}
var posTemplate = POS_TEMPLATE[newSectionType];
if (posTemplate) {
lines.splice(nextLineIndex, 0, "{{" + posTemplate + "|" + language + "}}");
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form uses, applying only the
// pieces the caller actually filled in. A piece that conflicts with the page (maneid already set, a
// subsection that's already there) is skipped with a warning rather than failing the whole save. Throws
// SubmitAbort if nothing was filled in, so this can never turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
function tryApply(fn) {
try {
content = fn();
appliedAnything = true;
} catch (e) {
if (e instanceof SubmitAbort) {
warnings.push(e.message);
} else {
throw e;
}
}
}
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
if (changes.maneid) {
tryApply(function () {
return insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", [changes.maneid], {
noExtend: true,
noExtendLabel: "nasnavek (maneid)"
});
});
}
if (changes.etiket && changes.etiket.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket);
appliedAnything = true;
}
if (changes.kategori && changes.kategori.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, words);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list: every word is its own always-visible row (word box + a "+" to attach one of the 10
// WORD_MODIFIERS as a small pill + an "x" to drop the row); a fresh empty row appears automatically once
// the current last row gets text. Duplicate words are allowed; every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into the current last row appends a fresh empty one after it, so there
// is always exactly one empty trailing row to type into.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, used for Etîket and Kategorî (simple value lists with no per-word modifiers).
// Enter or "," commits the current text as a tag; Backspace on an empty input removes the last tag;
// values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss and the two most-used word lists
// (Hevmane/Dijmane) sit directly in the picker row; the remaining word lists, maneid, etîket, kategorî
// and Nimûne/jêgirtin live behind a "Zêdetir" dropdown; one shared "Lê zêde bike" queues everything the
// user filled in as a single edit via applyAdvancedChanges() and queueChange(). Nimûne/jêgirtin is an
// immediate proxy-click into a different gadget's own form, not part of this combined save.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-open box (key -> () => value); collectChanges() only ever
// reads from a box the user actually clicked to add.
var getters = {};
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's wording; everything else here only ADDS) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel).then(
function (gloss) {
originalGloss = gloss;
$textarea.val(gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: gloss + the two most-used word groups (SENSE_GROUPS.primary) sit directly in the
// row; everything else lives behind a "Zêdetir" dropdown. Clicking any link builds and appends its box
// to $openBoxes and hides that link; the box's own "×" removes it, clears its getter, and un-hides the
// link -- several boxes can be open at once. No "Beşek (====)" entry here: buildSubsectionPanel()'s
// own "+ Beşek lê zêde bike" trigger already covers page-level subsections. ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: !!group.primary };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
// Nimûne/jêgirtin sits first in the dropdown, ahead of every field-pick link.
$moreMenu.append($nimune);
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
});
// Lives inside $picker (not appended straight to $quickRow) so .dsb-more-menu's CSS can position it as
// an overlay anchored to $picker, instead of pushing $openBoxes/the rest of the page down when it opens.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle, $moreMenu);
// Closes the dropdown on an outside click, scoped to this panel's own $moreToggle/$moreMenu.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via queueChange(); the actual
// save happens when the user clicks "Guhertinan qeyd bike" on the floating queue box. ----
// Small "not saved yet" preview of everything this queued change will do, appended right under the
// sense's gloss (plain text, not a real render of {{hevmane}}/etc.).
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
});
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: getters.maneid ? getters.maneid() : "",
etiket: getters.etiket ? getters.etiket() : [],
kategori: getters.kategori ? getters.kategori() : [],
words: words
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Auto-linkify the gloss only when it's part of this save and has no manual link already.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above.
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
// The real InterlanguageLinks pencil icon (same asset defEditButton uses); image swap is in the CSS.
var $toggle = $("<a href='#' class='dsb-toggle' title='Guhartina pêşketî'></a>");
// Revealed by $toggle -- an indented panel under the sense, not always visible. Built lazily on
// first open rather than eagerly for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.prepend($toolbar);
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a new "====" subsection preview belongs in the live DOM, using the same canonical order
// subsectionRankForHeader() gives insertPageSubsection(). Returns {insertBefore: $el} (an existing
// subsection that outranks this one) or {insertAfter: $el} (goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its canonical position. Plain text, not a real render of {{kol3|...}}/etc.
// Returns the inserted element so the caller can remove it again.
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4>, so existingSubsectionHeadersInDom() never mistakes this live-only
// preview for an actual subsection already on the page.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field, saved via insertPageSubsection().
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return existing.indexOf(s.header) === -1;
});
if (!available.length) {
$panel.text("Hemû beş jixwe li vê hene.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.header));
});
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
function currentSubsection() {
var id = $select.val();
return available.filter(function (s) {
return s.id === id;
})[0];
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
$fieldWrap.append(
$("<textarea class='dsb-input dsb-subsection-text' rows='3'></textarea>")
.attr("placeholder", s.header + "…")
);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
var content;
if (s.kind === "wordlist") {
content = wordField.values();
if (!content.length) {
return;
}
} else {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
}
$save.prop("disabled", true);
queueChange(
"+" + s.header + " (DefSideBoxes)",
function (pageContent) {
return { content: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, s, content), warnings: [] };
},
$save,
$status,
function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that replaces an unclassified "=== Mane ===" placeholder
// heading, saved via convertManeToPos(). Lists every name from sectionNames.
function buildConvertPosPanel($panel, $h3, language, maneOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
$select.append($("<option></option>").val(name).text(name));
});
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertManeToPos(pageContent, language, maneOrdinal, chosen), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note under the heading, rather than rewriting the real heading
// text -- avoids leaving a heading showing a name that was never actually saved if the
// save fails partway through.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
}
);
});
$panel.empty().append($select, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger right under an unclassified "=== Mane ===" placeholder
// heading (see convertManeToPos()'s own comment for what that heading means).
function attachManeConvertTrigger($h3) {
if ($h3.data("dsbManeAttached")) {
return;
}
$h3.data("dsbManeAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var maneOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, maneOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (/^Mane(\s+\d+)?$/.test($h3.text().trim())) {
attachManeConvertTrigger($h3);
}
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
});
}
// Closes every open panel/preview this gadget can leave in the DOM, so bfcache never freezes one mid-open.
function closeAllOpenUi() {
clearQueue();
$(".dsb-quick-row, .dsb-more-menu, .dsb-convert-pos-panel, .dsb-subsection-panel, .dsb-queue-box, .dsb-preview-inline, .dsb-preview-block").hide();
}
$(window).on("pagehide", closeAllOpenUi);
// Belt-and-suspenders: also close on restore-from-bfcache, in case pagehide's own hide didn't stick.
$(window).on("pageshow", function (e) {
if (e.originalEvent && e.originalEvent.persisted) {
closeAllOpenUi();
}
});
$(init);
// </nowiki>
})();
gcsgh8988d1jwn83c8jaq2hsba287g4
6347444
6347409
2026-08-31T19:15:23Z
Wikihez
7344
6347444
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary, writing start.js's own wikitext
// conventions ("#: {{hevmane|lang|...}}" per-sense lines, "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile). Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling: the "Nimûne/jêgirtin" menu item looks for the button Gadget-wikt.add-examples.js
// inserts on each definition, by its exact link text, so that gadget must run first.
// <nowiki>
(function () {
"use strict";
// Main namespace, namespace 108 (reconstructed-entry pages), or a user's own /ceribandin or /test subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// Template call convertManeToPos() drops under a newly-chosen POS heading, e.g. "Hoker" -> "{{hoker|ku}}".
// A "Formeke X" (form-of) heading uses the unchanged base pos template; "Biwêj" has no template at all.
var POS_TEMPLATE = {
"Navdêr": "navdêr",
"Formeke navdêrê": "navdêr",
"Lêker": "lêker",
"Formeke lêkerê": "lêker",
"Rengdêr": "rengdêr",
"Formeke rengdêrê": "rengdêr",
"Hoker": "hoker",
"Formeke hokerê": "hoker",
"Serenav": "serenav",
"Formeke serenavê": "serenav",
"Artîkel": "artîkel",
"Baneşan": "baneşan",
"Bazinedaçek": "bazinedaçek",
"Cînav": "cînav",
"Daçek": "daçek",
"Girêdek": "girêdek",
"Gotineke pêşiyan": "gotineke pêşiyan",
"Hejmar": "hejmar",
"Hevok": "hevok",
"Îfade": "îfade",
"Kurtenav": "kurtenav",
"Navgir": "navgir",
"Paşdaçek": "paşdaçek",
"Paşgir": "paşgir",
"Pêşdaçek": "pêşdaçek",
"Pêşgir": "pêşgir",
"Pirtik": "pirtik",
"Reh": "reh",
"Sembol": "sembol",
"Tîp": "tîp"
};
// The "needs a POS" maintenance tag under a placeholder "Mane" heading, and every known redirect/alias name
// it's also called under on real pages -- convertManeToPos() drops whichever one is actually present.
var MANE_TAG_REGEX = /^\{\{\s*(?:cure\?|rêziman\?|kat-rêziman|kategoriya\s+rêzimanê\?|bêcure)\s*(?:\|[^{}]*)?\}\}\s*$/i;
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Array order controls where a new group line lands relative to existing ones. "primary" groups get their
// own always-visible quick link on the definition; the rest live in this gadget's "More" menu.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane", primary: true },
{ key: "dijmane", label: "Dijmane", primary: true },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Array order is the canonical ku.wiktionary "====" subsection order and doubles as insertPageSubsection()'s
// insertion rank (see subsectionRankForHeader()). Only steps with a confirmed wikitext format are included;
// Bilêvkirin/Dûnde/Bi zaravayên din/Werger and a few others with no settled format are left out.
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// ---- word-modifier system (same widget start.js uses for Hevmane/Dijmane/etc. word lists) ----
// Every word in one of these lists can carry small "<key:value>" annotations (translation, gender, label,
// ...), which the {{hevmane}}/{{kol3}}/etc. templates parse back out of the raw positional param.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers into the raw "word<key:value>…" form {{hevmane}}/{{kol3}}/etc. read. */
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers (document-order based, immune to mobile's per-section DOM wrapping and
// MediaWiki's page-wide heading-id collisions) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s+\d+$/, "");
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || $(this).text().trim();
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback so one fetch covers both the
// edit-conflict check and the content, preventing a stale overwrite of someone else's edit.
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// This gadget's own save queue + floating widget, separate from the shared Gadget-Editor queue.
// Each entry keeps its own transformFn so saveQueueNow() can re-run all of them against one fresh fetch.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// The real save: re-runs every queued transformFn, in order, against one freshly-fetched revision and
// posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var combinedSummary = dsbQueue.entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
dsbQueue.entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function () {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text("✓ hemû guhertin hatin qeydkirin — rûpel nûve bike da ku bibînî.");
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()); nothing here touches the page yet. Also runs previewFn(), which drops a
// small "not saved yet" preview into the live DOM at the change's own spot on the page. Shared by every
// panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel, buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget ($.kuLinkify) and calls back with the linkified result.
// Passes the text through unchanged if the gadget can't be loaded, so it never blocks a save.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal, never by a DOM id number (MediaWiki's
// page-wide anchor uniquification can attach an id to a heading unrelated to its actual position).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the whole rest of the page from this language's heading onward, since the caller reuses
// it to rebuild the entire saved text; only the section-heading search itself is bounded by sectionSearchEndLine.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel: element 0 is
// unused (it's the "type|ordinal" string locateSection already resolved), remaining elements are 0-based
// indices, one per nesting level.
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's wordLine()
// format). If a line for this tplKey already exists under the definition, missing words are appended to
// it; otherwise a new line lands after the last existing group line, always before any "#*" citation lines.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's gloss text:
// maneid, then kategori (K), then etîket (e).
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker,
// stopping at the first thing that isn't one (normally the gloss text). Shared by insertLeadingSenseTpl()
// (uses "calls") and updateSenseGloss()/fetchCurrentGloss() (uses "rest", the gloss text after every call).
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts (or, unless opts.noExtend, extends) one of the small templates that prefix a definition line's
// gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} or {{e|lang|etîket1|...}}. opts.noExtend aborts
// instead if the template is already there (used for maneid, which must never get a second, different id).
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the whole leading-call run means an existing tplKey call is found and merged wherever it
// already sits, not just when it happens to be first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.noExtend) {
throw new SubmitAbort("Ev hevok jixwe xwedan " + (opts.noExtendLabel || tplKey) + " e.");
}
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call always outranks everything), or at the end of the run.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading template calls untouched --
// the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
var calls = splitLeadingCalls(afterMarker).calls;
// "{{mane?|lang}}" is start.js's "no definition entered yet" placeholder; drop it once a real gloss is set.
calls = calls.filter(function (c) { return c.key !== "mane?"; });
var leadingText = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (leadingText ? leadingText + " " : "") + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text to prefill the "Maneyê
// biguhêre" form. A plain read, not part of the hardened save path -- the actual save still re-fetches
// fresh content, so only the prefilled text itself could be a little stale.
function fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
var loc = locateSection(content, language, sectionType, sectionOrdinal);
var defLine = findDefinitionLine(loc.lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(loc.lines[defLine])[0];
var afterMarker = loc.lines[defLine].slice(marker.length).replace(/^\s+/, "");
return splitLeadingCalls(afterMarker).rest;
});
}
// Finds a POS block's body range (up to, but not including, the next heading of level <= 3), and the
// header text + line index of any "====" subsections it already contains.
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// Looks up a header's rank in PAGE_SUBSECTIONS' order. -1 for a header that isn't one of ours; such a
// header is never used as an insertion anchor.
function subsectionRankForHeader(header) {
for (var i = 0; i < PAGE_SUBSECTIONS.length; i++) {
if (PAGE_SUBSECTIONS[i].header === header) {
return i;
}
}
return -1;
}
// Inserts a new "==== Header ====" subsection into its canonical position within a POS block, right before
// the first existing recognized subsection that outranks it, or at the end if none does. Either a
// {{kol3|...}} word list or a plain paragraph, matching start.js's own subsection formats.
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var block;
if (subsection.kind === "wordlist") {
var params = "cure=" + subsection.header + "\n" + content.map(function (w) {
return "|" + w;
}).join("\n");
block = "\n==== " + subsection.header + " ====\n{{kol3|" + language + "|" + params + "\n}}\n";
} else {
block = "\n==== " + subsection.header + " ====\n" + content + "\n";
}
var myRank = subsectionRankForHeader(subsection.header);
var insertAt = bounds.end;
for (var i = 0; i < bounds.existingHeaders.length; i++) {
var otherRank = subsectionRankForHeader(bounds.existingHeaders[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = bounds.existingHeaders[i].lineIndex;
break;
}
}
lines.splice(insertAt, 0, block);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc.) instead of a real
// part-of-speech name, tagged right below with {{cure?|<lang>}} (ku.wiktionary's "part of speech not yet
// determined" maintenance flag). Neither is in sectionNames, so these two functions are a small parallel
// path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text
// (plus an optional disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading, drops the maintenance tag line right
// after it if present (MANE_TAG_REGEX -- cure? or any of its known aliases), and inserts the matching
// "{{<pos>|<lang>}}" template call in its place (skipped for section types with no POS_TEMPLATE entry).
// Other content under the heading is left untouched.
function convertManeToPos(pageContent, language, maneOrdinal, newSectionType) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
var loc = locateManeSection(pageContent, language, maneOrdinal);
var lines = loc.lines;
var m = /^(===[ ]*Mane)(\s+\d+)?([ ]*===)/.exec(lines[loc.maneLineIndex]);
lines[loc.maneLineIndex] = "=== " + newSectionType + (m[2] ? m[2] : "") + " ===";
var nextLineIndex = loc.maneLineIndex + 1;
if (nextLineIndex < lines.length && MANE_TAG_REGEX.test(lines[nextLineIndex])) {
lines.splice(nextLineIndex, 1);
}
var posTemplate = POS_TEMPLATE[newSectionType];
if (posTemplate) {
lines.splice(nextLineIndex, 0, "{{" + posTemplate + "|" + language + "}}");
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form uses, applying only the
// pieces the caller actually filled in. A piece that conflicts with the page (maneid already set, a
// subsection that's already there) is skipped with a warning rather than failing the whole save. Throws
// SubmitAbort if nothing was filled in, so this can never turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
function tryApply(fn) {
try {
content = fn();
appliedAnything = true;
} catch (e) {
if (e instanceof SubmitAbort) {
warnings.push(e.message);
} else {
throw e;
}
}
}
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
if (changes.maneid) {
tryApply(function () {
return insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", [changes.maneid], {
noExtend: true,
noExtendLabel: "nasnavek (maneid)"
});
});
}
if (changes.etiket && changes.etiket.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket);
appliedAnything = true;
}
if (changes.kategori && changes.kategori.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, words);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list: every word is its own always-visible row (word box + a "+" to attach one of the 10
// WORD_MODIFIERS as a small pill + an "x" to drop the row); a fresh empty row appears automatically once
// the current last row gets text. Duplicate words are allowed; every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into the current last row appends a fresh empty one after it, so there
// is always exactly one empty trailing row to type into.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, used for Etîket and Kategorî (simple value lists with no per-word modifiers).
// Enter or "," commits the current text as a tag; Backspace on an empty input removes the last tag;
// values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss and the two most-used word lists
// (Hevmane/Dijmane) sit directly in the picker row; the remaining word lists, maneid, etîket, kategorî
// and Nimûne/jêgirtin live behind a "Zêdetir" dropdown; one shared "Lê zêde bike" queues everything the
// user filled in as a single edit via applyAdvancedChanges() and queueChange(). Nimûne/jêgirtin is an
// immediate proxy-click into a different gadget's own form, not part of this combined save.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-open box (key -> () => value); collectChanges() only ever
// reads from a box the user actually clicked to add.
var getters = {};
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's wording; everything else here only ADDS) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel).then(
function (gloss) {
originalGloss = gloss;
$textarea.val(gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: gloss + the two most-used word groups (SENSE_GROUPS.primary) sit directly in the
// row; everything else lives behind a "Zêdetir" dropdown. Clicking any link builds and appends its box
// to $openBoxes and hides that link; the box's own "×" removes it, clears its getter, and un-hides the
// link -- several boxes can be open at once. No "Beşek (====)" entry here: buildSubsectionPanel()'s
// own "+ Beşek lê zêde bike" trigger already covers page-level subsections. ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: !!group.primary };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
// Nimûne/jêgirtin sits first in the dropdown, ahead of every field-pick link.
$moreMenu.append($nimune);
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
});
// Lives inside $picker (not appended straight to $quickRow) so .dsb-more-menu's CSS can position it as
// an overlay anchored to $picker, instead of pushing $openBoxes/the rest of the page down when it opens.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle, $moreMenu);
// Closes the dropdown on an outside click, scoped to this panel's own $moreToggle/$moreMenu.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via queueChange(); the actual
// save happens when the user clicks "Guhertinan qeyd bike" on the floating queue box. ----
// Small "not saved yet" preview of everything this queued change will do, appended right under the
// sense's gloss (plain text, not a real render of {{hevmane}}/etc.).
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
});
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: getters.maneid ? getters.maneid() : "",
etiket: getters.etiket ? getters.etiket() : [],
kategori: getters.kategori ? getters.kategori() : [],
words: words
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Auto-linkify the gloss only when it's part of this save and has no manual link already.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above.
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
// The real InterlanguageLinks pencil icon (same asset defEditButton uses); image swap is in the CSS.
var $toggle = $("<a href='#' class='dsb-toggle' title='Guhartina pêşketî'></a>");
// Revealed by $toggle -- an indented panel under the sense, not always visible. Built lazily on
// first open rather than eagerly for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.prepend($toolbar);
// Touch has no :hover -- a tap anywhere on the line reveals the pencil the same way hovering does on
// desktop (CSS gates this to touch devices; harmless if it also fires on a mouse click).
$li.on("click.dsbReveal", function () {
$toolbar.addClass("dsb-revealed");
});
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a new "====" subsection preview belongs in the live DOM, using the same canonical order
// subsectionRankForHeader() gives insertPageSubsection(). Returns {insertBefore: $el} (an existing
// subsection that outranks this one) or {insertAfter: $el} (goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its canonical position. Plain text, not a real render of {{kol3|...}}/etc.
// Returns the inserted element so the caller can remove it again.
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4>, so existingSubsectionHeadersInDom() never mistakes this live-only
// preview for an actual subsection already on the page.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field, saved via insertPageSubsection().
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return existing.indexOf(s.header) === -1;
});
if (!available.length) {
$panel.text("Hemû beş jixwe li vê hene.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.header));
});
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
function currentSubsection() {
var id = $select.val();
return available.filter(function (s) {
return s.id === id;
})[0];
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
$fieldWrap.append(
$("<textarea class='dsb-input dsb-subsection-text' rows='3'></textarea>")
.attr("placeholder", s.header + "…")
);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
var content;
if (s.kind === "wordlist") {
content = wordField.values();
if (!content.length) {
return;
}
} else {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
}
$save.prop("disabled", true);
queueChange(
"+" + s.header + " (DefSideBoxes)",
function (pageContent) {
return { content: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, s, content), warnings: [] };
},
$save,
$status,
function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that replaces an unclassified "=== Mane ===" placeholder
// heading, saved via convertManeToPos(). Lists every name from sectionNames.
function buildConvertPosPanel($panel, $h3, language, maneOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
$select.append($("<option></option>").val(name).text(name));
});
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertManeToPos(pageContent, language, maneOrdinal, chosen), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note under the heading, rather than rewriting the real heading
// text -- avoids leaving a heading showing a name that was never actually saved if the
// save fails partway through.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
}
);
});
$panel.empty().append($select, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger right under an unclassified "=== Mane ===" placeholder
// heading (see convertManeToPos()'s own comment for what that heading means).
function attachManeConvertTrigger($h3) {
if ($h3.data("dsbManeAttached")) {
return;
}
$h3.data("dsbManeAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var maneOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, maneOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (/^Mane(\s+\d+)?$/.test($h3.text().trim())) {
attachManeConvertTrigger($h3);
}
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
});
}
// Closes every open panel/preview this gadget can leave in the DOM, so bfcache never freezes one mid-open.
function closeAllOpenUi() {
clearQueue();
$(".dsb-quick-row, .dsb-more-menu, .dsb-convert-pos-panel, .dsb-subsection-panel, .dsb-queue-box, .dsb-preview-inline, .dsb-preview-block").hide();
}
$(window).on("pagehide", closeAllOpenUi);
// Belt-and-suspenders: also close on restore-from-bfcache, in case pagehide's own hide didn't stick.
$(window).on("pageshow", function (e) {
if (e.originalEvent && e.originalEvent.persisted) {
closeAllOpenUi();
}
});
$(init);
// </nowiki>
})();
3pdi5520hwuduffnio94ttx7pbj8chq
6347448
6347444
2026-08-31T19:35:03Z
Wikihez
7344
6347448
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary, writing start.js's own wikitext
// conventions ("#: {{hevmane|lang|...}}" per-sense lines, "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile). Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling: the "Nimûne/jêgirtin" menu item looks for the button Gadget-wikt.add-examples.js
// inserts on each definition, by its exact link text, so that gadget must run first.
// <nowiki>
(function () {
"use strict";
// Main namespace, namespace 108 (reconstructed-entry pages), or a user's own /ceribandin or /test subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// Template call convertManeToPos() drops under a newly-chosen POS heading, e.g. "Hoker" -> "{{hoker|ku}}".
// A "Formeke X" (form-of) heading uses the unchanged base pos template; "Biwêj" has no template at all.
var POS_TEMPLATE = {
"Navdêr": "navdêr",
"Formeke navdêrê": "navdêr",
"Lêker": "lêker",
"Formeke lêkerê": "lêker",
"Rengdêr": "rengdêr",
"Formeke rengdêrê": "rengdêr",
"Hoker": "hoker",
"Formeke hokerê": "hoker",
"Serenav": "serenav",
"Formeke serenavê": "serenav",
"Artîkel": "artîkel",
"Baneşan": "baneşan",
"Bazinedaçek": "bazinedaçek",
"Cînav": "cînav",
"Daçek": "daçek",
"Girêdek": "girêdek",
"Gotineke pêşiyan": "gotineke pêşiyan",
"Hejmar": "hejmar",
"Hevok": "hevok",
"Îfade": "îfade",
"Kurtenav": "kurtenav",
"Navgir": "navgir",
"Paşdaçek": "paşdaçek",
"Paşgir": "paşgir",
"Pêşdaçek": "pêşdaçek",
"Pêşgir": "pêşgir",
"Pirtik": "pirtik",
"Reh": "reh",
"Sembol": "sembol",
"Tîp": "tîp"
};
// The "needs a POS" maintenance tag under a placeholder "Mane" heading, and every known redirect/alias name
// it's also called under on real pages -- convertManeToPos() drops whichever one is actually present.
var MANE_TAG_REGEX = /^\{\{\s*(?:cure\?|rêziman\?|kat-rêziman|kategoriya\s+rêzimanê\?|bêcure)\s*(?:\|[^{}]*)?\}\}\s*$/i;
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Array order controls where a new group line lands relative to existing ones. "primary" groups get their
// own always-visible quick link on the definition; the rest live in this gadget's "More" menu.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane", primary: true },
{ key: "dijmane", label: "Dijmane", primary: true },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Array order is the canonical ku.wiktionary "====" subsection order and doubles as insertPageSubsection()'s
// insertion rank (see subsectionRankForHeader()). Only steps with a confirmed wikitext format are included;
// Bilêvkirin/Dûnde/Bi zaravayên din/Werger and a few others with no settled format are left out.
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// ---- word-modifier system (same widget start.js uses for Hevmane/Dijmane/etc. word lists) ----
// Every word in one of these lists can carry small "<key:value>" annotations (translation, gender, label,
// ...), which the {{hevmane}}/{{kol3}}/etc. templates parse back out of the raw positional param.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers into the raw "word<key:value>…" form {{hevmane}}/{{kol3}}/etc. read. */
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers (document-order based, immune to mobile's per-section DOM wrapping and
// MediaWiki's page-wide heading-id collisions) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s+\d+$/, "");
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || $(this).text().trim();
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback so one fetch covers both the
// edit-conflict check and the content, preventing a stale overwrite of someone else's edit.
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// This gadget's own save queue + floating widget, separate from the shared Gadget-Editor queue.
// Each entry keeps its own transformFn so saveQueueNow() can re-run all of them against one fresh fetch.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// The real save: re-runs every queued transformFn, in order, against one freshly-fetched revision and
// posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var combinedSummary = dsbQueue.entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
dsbQueue.entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function () {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text("✓ hemû guhertin hatin qeydkirin — rûpel nûve bike da ku bibînî.");
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()); nothing here touches the page yet. Also runs previewFn(), which drops a
// small "not saved yet" preview into the live DOM at the change's own spot on the page. Shared by every
// panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel, buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget ($.kuLinkify) and calls back with the linkified result.
// Passes the text through unchanged if the gadget can't be loaded, so it never blocks a save.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal, never by a DOM id number (MediaWiki's
// page-wide anchor uniquification can attach an id to a heading unrelated to its actual position).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the whole rest of the page from this language's heading onward, since the caller reuses
// it to rebuild the entire saved text; only the section-heading search itself is bounded by sectionSearchEndLine.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel: element 0 is
// unused (it's the "type|ordinal" string locateSection already resolved), remaining elements are 0-based
// indices, one per nesting level.
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's wordLine()
// format). If a line for this tplKey already exists under the definition, missing words are appended to
// it; otherwise a new line lands after the last existing group line, always before any "#*" citation lines.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's gloss text:
// maneid, then kategori (K), then etîket (e).
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker,
// stopping at the first thing that isn't one (normally the gloss text). Shared by insertLeadingSenseTpl()
// (uses "calls") and updateSenseGloss()/fetchCurrentGloss() (uses "rest", the gloss text after every call).
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts (or, unless opts.noExtend, extends) one of the small templates that prefix a definition line's
// gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} or {{e|lang|etîket1|...}}. opts.noExtend aborts
// instead if the template is already there (used for maneid, which must never get a second, different id).
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the whole leading-call run means an existing tplKey call is found and merged wherever it
// already sits, not just when it happens to be first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.noExtend) {
throw new SubmitAbort("Ev hevok jixwe xwedan " + (opts.noExtendLabel || tplKey) + " e.");
}
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call always outranks everything), or at the end of the run.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading template calls untouched --
// the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
var calls = splitLeadingCalls(afterMarker).calls;
// "{{mane?|lang}}" is start.js's "no definition entered yet" placeholder; drop it once a real gloss is set.
calls = calls.filter(function (c) { return c.key !== "mane?"; });
var leadingText = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (leadingText ? leadingText + " " : "") + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text to prefill the "Maneyê
// biguhêre" form. A plain read, not part of the hardened save path -- the actual save still re-fetches
// fresh content, so only the prefilled text itself could be a little stale.
function fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
var loc = locateSection(content, language, sectionType, sectionOrdinal);
var defLine = findDefinitionLine(loc.lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(loc.lines[defLine])[0];
var afterMarker = loc.lines[defLine].slice(marker.length).replace(/^\s+/, "");
return splitLeadingCalls(afterMarker).rest;
});
}
// Finds a POS block's body range (up to, but not including, the next heading of level <= 3), and the
// header text + line index of any "====" subsections it already contains.
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// Looks up a header's rank in PAGE_SUBSECTIONS' order. -1 for a header that isn't one of ours; such a
// header is never used as an insertion anchor.
function subsectionRankForHeader(header) {
for (var i = 0; i < PAGE_SUBSECTIONS.length; i++) {
if (PAGE_SUBSECTIONS[i].header === header) {
return i;
}
}
return -1;
}
// Inserts a new "==== Header ====" subsection into its canonical position within a POS block, right before
// the first existing recognized subsection that outranks it, or at the end if none does. Either a
// {{kol3|...}} word list or a plain paragraph, matching start.js's own subsection formats.
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var block;
if (subsection.kind === "wordlist") {
var params = "cure=" + subsection.header + "\n" + content.map(function (w) {
return "|" + w;
}).join("\n");
block = "\n==== " + subsection.header + " ====\n{{kol3|" + language + "|" + params + "\n}}\n";
} else {
block = "\n==== " + subsection.header + " ====\n" + content + "\n";
}
var myRank = subsectionRankForHeader(subsection.header);
var insertAt = bounds.end;
for (var i = 0; i < bounds.existingHeaders.length; i++) {
var otherRank = subsectionRankForHeader(bounds.existingHeaders[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = bounds.existingHeaders[i].lineIndex;
break;
}
}
lines.splice(insertAt, 0, block);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc.) instead of a real
// part-of-speech name, tagged right below with {{cure?|<lang>}} (ku.wiktionary's "part of speech not yet
// determined" maintenance flag). Neither is in sectionNames, so these two functions are a small parallel
// path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text
// (plus an optional disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading, drops the maintenance tag line right
// after it if present (MANE_TAG_REGEX -- cure? or any of its known aliases), and inserts the matching
// "{{<pos>|<lang>}}" template call in its place (skipped for section types with no POS_TEMPLATE entry).
// Other content under the heading is left untouched.
function convertManeToPos(pageContent, language, maneOrdinal, newSectionType) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
var loc = locateManeSection(pageContent, language, maneOrdinal);
var lines = loc.lines;
var m = /^(===[ ]*Mane)(\s+\d+)?([ ]*===)/.exec(lines[loc.maneLineIndex]);
lines[loc.maneLineIndex] = "=== " + newSectionType + (m[2] ? m[2] : "") + " ===";
var nextLineIndex = loc.maneLineIndex + 1;
if (nextLineIndex < lines.length && MANE_TAG_REGEX.test(lines[nextLineIndex])) {
lines.splice(nextLineIndex, 1);
}
var posTemplate = POS_TEMPLATE[newSectionType];
if (posTemplate) {
lines.splice(nextLineIndex, 0, "{{" + posTemplate + "|" + language + "}}");
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form uses, applying only the
// pieces the caller actually filled in. A piece that conflicts with the page (maneid already set, a
// subsection that's already there) is skipped with a warning rather than failing the whole save. Throws
// SubmitAbort if nothing was filled in, so this can never turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
function tryApply(fn) {
try {
content = fn();
appliedAnything = true;
} catch (e) {
if (e instanceof SubmitAbort) {
warnings.push(e.message);
} else {
throw e;
}
}
}
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
if (changes.maneid) {
tryApply(function () {
return insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", [changes.maneid], {
noExtend: true,
noExtendLabel: "nasnavek (maneid)"
});
});
}
if (changes.etiket && changes.etiket.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket);
appliedAnything = true;
}
if (changes.kategori && changes.kategori.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, words);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list: every word is its own always-visible row (word box + a "+" to attach one of the 10
// WORD_MODIFIERS as a small pill + an "x" to drop the row); a fresh empty row appears automatically once
// the current last row gets text. Duplicate words are allowed; every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into the current last row appends a fresh empty one after it, so there
// is always exactly one empty trailing row to type into.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, used for Etîket and Kategorî (simple value lists with no per-word modifiers).
// Enter or "," commits the current text as a tag; Backspace on an empty input removes the last tag;
// values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss and the two most-used word lists
// (Hevmane/Dijmane) sit directly in the picker row; the remaining word lists, maneid, etîket, kategorî
// and Nimûne/jêgirtin live behind a "Zêdetir" dropdown; one shared "Lê zêde bike" queues everything the
// user filled in as a single edit via applyAdvancedChanges() and queueChange(). Nimûne/jêgirtin is an
// immediate proxy-click into a different gadget's own form, not part of this combined save.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-open box (key -> () => value); collectChanges() only ever
// reads from a box the user actually clicked to add.
var getters = {};
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's wording; everything else here only ADDS) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel).then(
function (gloss) {
originalGloss = gloss;
$textarea.val(gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: gloss + the two most-used word groups (SENSE_GROUPS.primary) sit directly in the
// row; everything else lives behind a "Zêdetir" dropdown. Clicking any link builds and appends its box
// to $openBoxes and hides that link; the box's own "×" removes it, clears its getter, and un-hides the
// link -- several boxes can be open at once. No "Beşek (====)" entry here: buildSubsectionPanel()'s
// own "+ Beşek lê zêde bike" trigger already covers page-level subsections. ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: !!group.primary };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
// Nimûne/jêgirtin sits first in the dropdown, ahead of every field-pick link.
$moreMenu.append($nimune);
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
});
// Lives inside $picker (not appended straight to $quickRow) so .dsb-more-menu's CSS can position it as
// an overlay anchored to $picker, instead of pushing $openBoxes/the rest of the page down when it opens.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle, $moreMenu);
// Closes the dropdown on an outside click, scoped to this panel's own $moreToggle/$moreMenu.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via queueChange(); the actual
// save happens when the user clicks "Guhertinan qeyd bike" on the floating queue box. ----
// Small "not saved yet" preview of everything this queued change will do, appended right under the
// sense's gloss (plain text, not a real render of {{hevmane}}/etc.).
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
});
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: getters.maneid ? getters.maneid() : "",
etiket: getters.etiket ? getters.etiket() : [],
kategori: getters.kategori ? getters.kategori() : [],
words: words
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Auto-linkify the gloss only when it's part of this save and has no manual link already.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above.
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
// The real InterlanguageLinks pencil icon (same asset defEditButton uses); image swap is in the CSS.
var $toggle = $("<a href='#' class='dsb-toggle' title='Guhartina pêşketî'></a>");
// Revealed by $toggle -- an indented panel under the sense, not always visible. Built lazily on
// first open rather than eagerly for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.addClass("dsb-has-toolbar").prepend($toolbar);
// Touch has no :hover -- a tap anywhere on the line reveals the pencil the same way hovering does on
// desktop (CSS gates this to touch devices; harmless if it also fires on a mouse click).
$li.on("click.dsbReveal", function () {
$toolbar.addClass("dsb-revealed");
});
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a new "====" subsection preview belongs in the live DOM, using the same canonical order
// subsectionRankForHeader() gives insertPageSubsection(). Returns {insertBefore: $el} (an existing
// subsection that outranks this one) or {insertAfter: $el} (goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its canonical position. Plain text, not a real render of {{kol3|...}}/etc.
// Returns the inserted element so the caller can remove it again.
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4>, so existingSubsectionHeadersInDom() never mistakes this live-only
// preview for an actual subsection already on the page.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field, saved via insertPageSubsection().
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return existing.indexOf(s.header) === -1;
});
if (!available.length) {
$panel.text("Hemû beş jixwe li vê hene.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.header));
});
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
function currentSubsection() {
var id = $select.val();
return available.filter(function (s) {
return s.id === id;
})[0];
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
$fieldWrap.append(
$("<textarea class='dsb-input dsb-subsection-text' rows='3'></textarea>")
.attr("placeholder", s.header + "…")
);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
var content;
if (s.kind === "wordlist") {
content = wordField.values();
if (!content.length) {
return;
}
} else {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
}
$save.prop("disabled", true);
queueChange(
"+" + s.header + " (DefSideBoxes)",
function (pageContent) {
return { content: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, s, content), warnings: [] };
},
$save,
$status,
function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that replaces an unclassified "=== Mane ===" placeholder
// heading, saved via convertManeToPos(). Lists every name from sectionNames.
function buildConvertPosPanel($panel, $h3, language, maneOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
$select.append($("<option></option>").val(name).text(name));
});
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertManeToPos(pageContent, language, maneOrdinal, chosen), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note under the heading, rather than rewriting the real heading
// text -- avoids leaving a heading showing a name that was never actually saved if the
// save fails partway through.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
}
);
});
$panel.empty().append($select, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger right under an unclassified "=== Mane ===" placeholder
// heading (see convertManeToPos()'s own comment for what that heading means).
function attachManeConvertTrigger($h3) {
if ($h3.data("dsbManeAttached")) {
return;
}
$h3.data("dsbManeAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var maneOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, maneOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (/^Mane(\s+\d+)?$/.test($h3.text().trim())) {
attachManeConvertTrigger($h3);
}
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
});
}
// Closes every open panel/preview this gadget can leave in the DOM, so bfcache never freezes one mid-open.
function closeAllOpenUi() {
clearQueue();
$(".dsb-quick-row, .dsb-more-menu, .dsb-convert-pos-panel, .dsb-subsection-panel, .dsb-queue-box, .dsb-preview-inline, .dsb-preview-block").hide();
}
$(window).on("pagehide", closeAllOpenUi);
// Belt-and-suspenders: also close on restore-from-bfcache, in case pagehide's own hide didn't stick.
$(window).on("pageshow", function (e) {
if (e.originalEvent && e.originalEvent.persisted) {
closeAllOpenUi();
}
});
$(init);
// </nowiki>
})();
o2r05ajnk0xs64j4om8muh9t6lsfn26
6347450
6347448
2026-08-31T19:40:09Z
Wikihez
7344
6347450
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary, writing start.js's own wikitext
// conventions ("#: {{hevmane|lang|...}}" per-sense lines, "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile). Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling: the "Nimûne/jêgirtin" menu item looks for the button Gadget-wikt.add-examples.js
// inserts on each definition, by its exact link text, so that gadget must run first.
// <nowiki>
(function () {
"use strict";
// Main namespace, namespace 108 (reconstructed-entry pages), or a user's own /ceribandin or /test subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// Template call convertManeToPos() drops under a newly-chosen POS heading, e.g. "Hoker" -> "{{hoker|ku}}".
// A "Formeke X" (form-of) heading uses the unchanged base pos template; "Biwêj" has no template at all.
var POS_TEMPLATE = {
"Navdêr": "navdêr",
"Formeke navdêrê": "navdêr",
"Lêker": "lêker",
"Formeke lêkerê": "lêker",
"Rengdêr": "rengdêr",
"Formeke rengdêrê": "rengdêr",
"Hoker": "hoker",
"Formeke hokerê": "hoker",
"Serenav": "serenav",
"Formeke serenavê": "serenav",
"Artîkel": "artîkel",
"Baneşan": "baneşan",
"Bazinedaçek": "bazinedaçek",
"Cînav": "cînav",
"Daçek": "daçek",
"Girêdek": "girêdek",
"Gotineke pêşiyan": "gotineke pêşiyan",
"Hejmar": "hejmar",
"Hevok": "hevok",
"Îfade": "îfade",
"Kurtenav": "kurtenav",
"Navgir": "navgir",
"Paşdaçek": "paşdaçek",
"Paşgir": "paşgir",
"Pêşdaçek": "pêşdaçek",
"Pêşgir": "pêşgir",
"Pirtik": "pirtik",
"Reh": "reh",
"Sembol": "sembol",
"Tîp": "tîp"
};
// The "needs a POS" maintenance tag under a placeholder "Mane" heading, and every known redirect/alias name
// it's also called under on real pages -- convertManeToPos() drops whichever one is actually present.
var MANE_TAG_REGEX = /^\{\{\s*(?:cure\?|rêziman\?|kat-rêziman|kategoriya\s+rêzimanê\?|bêcure)\s*(?:\|[^{}]*)?\}\}\s*$/i;
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Array order controls where a new group line lands relative to existing ones. "primary" groups get their
// own always-visible quick link on the definition; the rest live in this gadget's "More" menu.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane", primary: true },
{ key: "dijmane", label: "Dijmane", primary: true },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Array order is the canonical ku.wiktionary "====" subsection order and doubles as insertPageSubsection()'s
// insertion rank (see subsectionRankForHeader()). Only steps with a confirmed wikitext format are included;
// Bilêvkirin/Dûnde/Bi zaravayên din/Werger and a few others with no settled format are left out.
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// ---- word-modifier system (same widget start.js uses for Hevmane/Dijmane/etc. word lists) ----
// Every word in one of these lists can carry small "<key:value>" annotations (translation, gender, label,
// ...), which the {{hevmane}}/{{kol3}}/etc. templates parse back out of the raw positional param.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers into the raw "word<key:value>…" form {{hevmane}}/{{kol3}}/etc. read. */
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers (document-order based, immune to mobile's per-section DOM wrapping and
// MediaWiki's page-wide heading-id collisions) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s+\d+$/, "");
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || $(this).text().trim();
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback so one fetch covers both the
// edit-conflict check and the content, preventing a stale overwrite of someone else's edit.
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// This gadget's own save queue + floating widget, separate from the shared Gadget-Editor queue.
// Each entry keeps its own transformFn so saveQueueNow() can re-run all of them against one fresh fetch.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// The real save: re-runs every queued transformFn, in order, against one freshly-fetched revision and
// posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var combinedSummary = dsbQueue.entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
dsbQueue.entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function () {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text("✓ hemû guhertin hatin qeydkirin — rûpel nûve bike da ku bibînî.");
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()); nothing here touches the page yet. Also runs previewFn(), which drops a
// small "not saved yet" preview into the live DOM at the change's own spot on the page. Shared by every
// panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel, buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget ($.kuLinkify) and calls back with the linkified result.
// Passes the text through unchanged if the gadget can't be loaded, so it never blocks a save.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal, never by a DOM id number (MediaWiki's
// page-wide anchor uniquification can attach an id to a heading unrelated to its actual position).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the whole rest of the page from this language's heading onward, since the caller reuses
// it to rebuild the entire saved text; only the section-heading search itself is bounded by sectionSearchEndLine.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel: element 0 is
// unused (it's the "type|ordinal" string locateSection already resolved), remaining elements are 0-based
// indices, one per nesting level.
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's wordLine()
// format). If a line for this tplKey already exists under the definition, missing words are appended to
// it; otherwise a new line lands after the last existing group line, always before any "#*" citation lines.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's gloss text:
// maneid, then kategori (K), then etîket (e).
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker,
// stopping at the first thing that isn't one (normally the gloss text). Shared by insertLeadingSenseTpl()
// (uses "calls") and updateSenseGloss()/fetchCurrentGloss() (uses "rest", the gloss text after every call).
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts (or, unless opts.noExtend, extends) one of the small templates that prefix a definition line's
// gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} or {{e|lang|etîket1|...}}. opts.noExtend aborts
// instead if the template is already there (used for maneid, which must never get a second, different id).
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the whole leading-call run means an existing tplKey call is found and merged wherever it
// already sits, not just when it happens to be first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.noExtend) {
throw new SubmitAbort("Ev hevok jixwe xwedan " + (opts.noExtendLabel || tplKey) + " e.");
}
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call always outranks everything), or at the end of the run.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading template calls untouched --
// the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
var calls = splitLeadingCalls(afterMarker).calls;
// "{{mane?|lang}}" is start.js's "no definition entered yet" placeholder; drop it once a real gloss is set.
calls = calls.filter(function (c) { return c.key !== "mane?"; });
var leadingText = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (leadingText ? leadingText + " " : "") + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text to prefill the "Maneyê
// biguhêre" form. A plain read, not part of the hardened save path -- the actual save still re-fetches
// fresh content, so only the prefilled text itself could be a little stale.
function fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
var loc = locateSection(content, language, sectionType, sectionOrdinal);
var defLine = findDefinitionLine(loc.lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(loc.lines[defLine])[0];
var afterMarker = loc.lines[defLine].slice(marker.length).replace(/^\s+/, "");
return splitLeadingCalls(afterMarker).rest;
});
}
// Finds a POS block's body range (up to, but not including, the next heading of level <= 3), and the
// header text + line index of any "====" subsections it already contains.
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// Looks up a header's rank in PAGE_SUBSECTIONS' order. -1 for a header that isn't one of ours; such a
// header is never used as an insertion anchor.
function subsectionRankForHeader(header) {
for (var i = 0; i < PAGE_SUBSECTIONS.length; i++) {
if (PAGE_SUBSECTIONS[i].header === header) {
return i;
}
}
return -1;
}
// Inserts a new "==== Header ====" subsection into its canonical position within a POS block, right before
// the first existing recognized subsection that outranks it, or at the end if none does. Either a
// {{kol3|...}} word list or a plain paragraph, matching start.js's own subsection formats.
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var block;
if (subsection.kind === "wordlist") {
var params = "cure=" + subsection.header + "\n" + content.map(function (w) {
return "|" + w;
}).join("\n");
block = "\n==== " + subsection.header + " ====\n{{kol3|" + language + "|" + params + "\n}}\n";
} else {
block = "\n==== " + subsection.header + " ====\n" + content + "\n";
}
var myRank = subsectionRankForHeader(subsection.header);
var insertAt = bounds.end;
for (var i = 0; i < bounds.existingHeaders.length; i++) {
var otherRank = subsectionRankForHeader(bounds.existingHeaders[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = bounds.existingHeaders[i].lineIndex;
break;
}
}
lines.splice(insertAt, 0, block);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc.) instead of a real
// part-of-speech name, tagged right below with {{cure?|<lang>}} (ku.wiktionary's "part of speech not yet
// determined" maintenance flag). Neither is in sectionNames, so these two functions are a small parallel
// path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text
// (plus an optional disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading, drops the maintenance tag line right
// after it if present (MANE_TAG_REGEX -- cure? or any of its known aliases), and inserts the matching
// "{{<pos>|<lang>}}" template call in its place (skipped for section types with no POS_TEMPLATE entry).
// Other content under the heading is left untouched.
function convertManeToPos(pageContent, language, maneOrdinal, newSectionType) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
var loc = locateManeSection(pageContent, language, maneOrdinal);
var lines = loc.lines;
var m = /^(===[ ]*Mane)(\s+\d+)?([ ]*===)/.exec(lines[loc.maneLineIndex]);
lines[loc.maneLineIndex] = "=== " + newSectionType + (m[2] ? m[2] : "") + " ===";
var nextLineIndex = loc.maneLineIndex + 1;
if (nextLineIndex < lines.length && MANE_TAG_REGEX.test(lines[nextLineIndex])) {
lines.splice(nextLineIndex, 1);
}
var posTemplate = POS_TEMPLATE[newSectionType];
if (posTemplate) {
lines.splice(nextLineIndex, 0, "{{" + posTemplate + "|" + language + "}}");
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form uses, applying only the
// pieces the caller actually filled in. A piece that conflicts with the page (maneid already set, a
// subsection that's already there) is skipped with a warning rather than failing the whole save. Throws
// SubmitAbort if nothing was filled in, so this can never turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
function tryApply(fn) {
try {
content = fn();
appliedAnything = true;
} catch (e) {
if (e instanceof SubmitAbort) {
warnings.push(e.message);
} else {
throw e;
}
}
}
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
if (changes.maneid) {
tryApply(function () {
return insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", [changes.maneid], {
noExtend: true,
noExtendLabel: "nasnavek (maneid)"
});
});
}
if (changes.etiket && changes.etiket.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket);
appliedAnything = true;
}
if (changes.kategori && changes.kategori.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, words);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list: every word is its own always-visible row (word box + a "+" to attach one of the 10
// WORD_MODIFIERS as a small pill + an "x" to drop the row); a fresh empty row appears automatically once
// the current last row gets text. Duplicate words are allowed; every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into the current last row appends a fresh empty one after it, so there
// is always exactly one empty trailing row to type into.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, used for Etîket and Kategorî (simple value lists with no per-word modifiers).
// Enter or "," commits the current text as a tag; Backspace on an empty input removes the last tag;
// values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss and the two most-used word lists
// (Hevmane/Dijmane) sit directly in the picker row; the remaining word lists, maneid, etîket, kategorî
// and Nimûne/jêgirtin live behind a "Zêdetir" dropdown; one shared "Lê zêde bike" queues everything the
// user filled in as a single edit via applyAdvancedChanges() and queueChange(). Nimûne/jêgirtin is an
// immediate proxy-click into a different gadget's own form, not part of this combined save.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-open box (key -> () => value); collectChanges() only ever
// reads from a box the user actually clicked to add.
var getters = {};
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's wording; everything else here only ADDS) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel).then(
function (gloss) {
originalGloss = gloss;
$textarea.val(gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: gloss + the two most-used word groups (SENSE_GROUPS.primary) sit directly in the
// row; everything else lives behind a "Zêdetir" dropdown. Clicking any link builds and appends its box
// to $openBoxes and hides that link; the box's own "×" removes it, clears its getter, and un-hides the
// link -- several boxes can be open at once. No "Beşek (====)" entry here: buildSubsectionPanel()'s
// own "+ Beşek lê zêde bike" trigger already covers page-level subsections. ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: !!group.primary };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
// Nimûne/jêgirtin sits first in the dropdown, ahead of every field-pick link.
$moreMenu.append($nimune);
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
});
// Lives inside $picker (not appended straight to $quickRow) so .dsb-more-menu's CSS can position it as
// an overlay anchored to $picker, instead of pushing $openBoxes/the rest of the page down when it opens.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle, $moreMenu);
// Closes the dropdown on an outside click, scoped to this panel's own $moreToggle/$moreMenu.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via queueChange(); the actual
// save happens when the user clicks "Guhertinan qeyd bike" on the floating queue box. ----
// Small "not saved yet" preview of everything this queued change will do, appended right under the
// sense's gloss (plain text, not a real render of {{hevmane}}/etc.).
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
});
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: getters.maneid ? getters.maneid() : "",
etiket: getters.etiket ? getters.etiket() : [],
kategori: getters.kategori ? getters.kategori() : [],
words: words
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Auto-linkify the gloss only when it's part of this save and has no manual link already.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above.
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
// The real InterlanguageLinks pencil icon (same asset defEditButton uses); image swap is in the CSS.
var $toggle = $("<a href='#' class='dsb-toggle' title='Guhartina pêşketî'></a>");
// Revealed by $toggle -- an indented panel under the sense, not always visible. Built lazily on
// first open rather than eagerly for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.prepend($toolbar);
// Touch has no :hover -- a tap anywhere on the line reveals the pencil the same way hovering does on
// desktop (CSS gates this to touch devices; harmless if it also fires on a mouse click).
$li.on("click.dsbReveal", function () {
$toolbar.addClass("dsb-revealed");
});
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a new "====" subsection preview belongs in the live DOM, using the same canonical order
// subsectionRankForHeader() gives insertPageSubsection(). Returns {insertBefore: $el} (an existing
// subsection that outranks this one) or {insertAfter: $el} (goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its canonical position. Plain text, not a real render of {{kol3|...}}/etc.
// Returns the inserted element so the caller can remove it again.
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4>, so existingSubsectionHeadersInDom() never mistakes this live-only
// preview for an actual subsection already on the page.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field, saved via insertPageSubsection().
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return existing.indexOf(s.header) === -1;
});
if (!available.length) {
$panel.text("Hemû beş jixwe li vê hene.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.header));
});
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
function currentSubsection() {
var id = $select.val();
return available.filter(function (s) {
return s.id === id;
})[0];
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
$fieldWrap.append(
$("<textarea class='dsb-input dsb-subsection-text' rows='3'></textarea>")
.attr("placeholder", s.header + "…")
);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
var content;
if (s.kind === "wordlist") {
content = wordField.values();
if (!content.length) {
return;
}
} else {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
}
$save.prop("disabled", true);
queueChange(
"+" + s.header + " (DefSideBoxes)",
function (pageContent) {
return { content: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, s, content), warnings: [] };
},
$save,
$status,
function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that replaces an unclassified "=== Mane ===" placeholder
// heading, saved via convertManeToPos(). Lists every name from sectionNames.
function buildConvertPosPanel($panel, $h3, language, maneOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
$select.append($("<option></option>").val(name).text(name));
});
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertManeToPos(pageContent, language, maneOrdinal, chosen), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note under the heading, rather than rewriting the real heading
// text -- avoids leaving a heading showing a name that was never actually saved if the
// save fails partway through.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
}
);
});
$panel.empty().append($select, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger right under an unclassified "=== Mane ===" placeholder
// heading (see convertManeToPos()'s own comment for what that heading means).
function attachManeConvertTrigger($h3) {
if ($h3.data("dsbManeAttached")) {
return;
}
$h3.data("dsbManeAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var maneOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, maneOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (/^Mane(\s+\d+)?$/.test($h3.text().trim())) {
attachManeConvertTrigger($h3);
}
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
});
}
// Closes every open panel/preview this gadget can leave in the DOM, so bfcache never freezes one mid-open.
function closeAllOpenUi() {
clearQueue();
$(".dsb-quick-row, .dsb-more-menu, .dsb-convert-pos-panel, .dsb-subsection-panel, .dsb-queue-box, .dsb-preview-inline, .dsb-preview-block").hide();
}
$(window).on("pagehide", closeAllOpenUi);
// Belt-and-suspenders: also close on restore-from-bfcache, in case pagehide's own hide didn't stick.
$(window).on("pageshow", function (e) {
if (e.originalEvent && e.originalEvent.persisted) {
closeAllOpenUi();
}
});
$(init);
// </nowiki>
})();
3pdi5520hwuduffnio94ttx7pbj8chq
6347535
6347450
2026-09-01T09:38:58Z
Wikihez
7344
6347535
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary, writing start.js's own wikitext
// conventions ("#: {{hevmane|lang|...}}" per-sense lines, "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile). Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling: the "Nimûne/jêgirtin" menu item looks for the button Gadget-wikt.add-examples.js
// inserts on each definition, by its exact link text, so that gadget must run first.
// <nowiki>
(function () {
"use strict";
// Main namespace, namespace 108 (reconstructed-entry pages), or a user's own /ceribandin or /test subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// Template call convertManeToPos() drops under a newly-chosen POS heading, e.g. "Hoker" -> "{{hoker|ku}}".
// A "Formeke X" (form-of) heading uses the unchanged base pos template; "Biwêj" has no template at all.
var POS_TEMPLATE = {
"Navdêr": "navdêr",
"Formeke navdêrê": "navdêr",
"Lêker": "lêker",
"Formeke lêkerê": "lêker",
"Rengdêr": "rengdêr",
"Formeke rengdêrê": "rengdêr",
"Hoker": "hoker",
"Formeke hokerê": "hoker",
"Serenav": "serenav",
"Formeke serenavê": "serenav",
"Artîkel": "artîkel",
"Baneşan": "baneşan",
"Bazinedaçek": "bazinedaçek",
"Cînav": "cînav",
"Daçek": "daçek",
"Girêdek": "girêdek",
"Gotineke pêşiyan": "gotineke pêşiyan",
"Hejmar": "hejmar",
"Hevok": "hevok",
"Îfade": "îfade",
"Kurtenav": "kurtenav",
"Navgir": "navgir",
"Paşdaçek": "paşdaçek",
"Paşgir": "paşgir",
"Pêşdaçek": "pêşdaçek",
"Pêşgir": "pêşgir",
"Pirtik": "pirtik",
"Reh": "reh",
"Sembol": "sembol",
"Tîp": "tîp"
};
// The "needs a POS" maintenance tag under a placeholder "Mane" heading, and every known redirect/alias name
// it's also called under on real pages -- convertManeToPos() drops whichever one is actually present.
var MANE_TAG_REGEX = /^\{\{\s*(?:cure\?|rêziman\?|kat-rêziman|kategoriya\s+rêzimanê\?|bêcure)\s*(?:\|[^{}]*)?\}\}\s*$/i;
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Array order controls where a new group line lands relative to existing ones. "primary" groups get their
// own always-visible quick link on the definition; the rest live in this gadget's "More" menu.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane", primary: true },
{ key: "dijmane", label: "Dijmane", primary: true },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Only steps with a confirmed wikitext format are included; insertion rank comes from SUBSECTION_ORDER below.
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// Canonical ku.wiktionary "====" subsection order, used only as insertPageSubsection()'s insertion rank
// (see subsectionRankForHeader()). Wider than PAGE_SUBSECTIONS: it also covers subsections the gadget
// cannot create but still has to order around.
var SUBSECTION_ORDER = [
"Bilêvkirin",
"Ji wêjeya klasîk",
"Ji wêjeyê",
"Tewandin",
"Notên bikaranînê",
"Bi alfabeyên din",
"Formên alternatîv",
"Kurtkirin",
"Sembol",
"Navê zanistî",
"Hevmane",
"Nêzîk",
"Dijmane",
"Jornav",
"Jêrnav",
"Jê",
"Têkildar",
"Etîmolojî",
"Dûnde",
"Bide ber",
"Herwiha binêre",
"Bêhtir xwendin",
// Both spellings are in use on-wiki; PAGE_SUBSECTIONS creates this one, so it ranks in the same slot.
"Bêhtir bixwîne",
"Bi zaravayên din",
"Werger",
"Qafiye",
"Anagram",
// Creatable but absent from the canonical order; put last so it never displaces a ranked subsection.
"Çavkanî"
];
// ---- word-modifier system (same widget start.js uses for Hevmane/Dijmane/etc. word lists) ----
// Every word in one of these lists can carry small "<key:value>" annotations (translation, gender, label,
// ...), which the {{hevmane}}/{{kol3}}/etc. templates parse back out of the raw positional param.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers into the raw "word<key:value>…" form {{hevmane}}/{{kol3}}/etc. read. */
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers (document-order based, immune to mobile's per-section DOM wrapping and
// MediaWiki's page-wide heading-id collisions) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s*\d+$/, ""); // \s* not \s+: locateSection() also accepts "Navdêr2"
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || $(this).text().trim();
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback so one fetch covers both the
// edit-conflict check and the content, preventing a stale overwrite of someone else's edit.
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// This gadget's own save queue + floating widget, separate from the shared Gadget-Editor queue.
// Each entry keeps its own transformFn so saveQueueNow() can re-run all of them against one fresh fetch.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// The real save: re-runs every queued transformFn, in order, against one freshly-fetched revision and
// posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var combinedSummary = dsbQueue.entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
dsbQueue.entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function () {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text("✓ hemû guhertin hatin qeydkirin — rûpel nûve bike da ku bibînî.");
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()); nothing here touches the page yet. Also runs previewFn(), which drops a
// small "not saved yet" preview into the live DOM at the change's own spot on the page. Shared by every
// panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel, buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget ($.kuLinkify) and calls back with the linkified result.
// Passes the text through unchanged if the gadget can't be loaded, so it never blocks a save.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal, never by a DOM id number (MediaWiki's
// page-wide anchor uniquification can attach an id to a heading unrelated to its actual position).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the whole rest of the page from this language's heading onward, since the caller reuses
// it to rebuild the entire saved text; only the section-heading search itself is bounded by sectionSearchEndLine.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
// Closing "===" anchored, like locateManeSection(): otherwise "=== Navdêra pirjimar ===" counts as a POS occurrence here while sectionTypeOf() rejects it, desyncing the ordinal.
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?[ ]*===");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel: element 0 is
// unused (it's the "type|ordinal" string locateSection already resolved), remaining elements are 0-based
// indices, one per nesting level.
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's wordLine()
// format). If a line for this tplKey already exists under the definition, missing words are appended to
// it; otherwise a new line lands after the last existing group line, always before any "#*" citation lines.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's gloss text:
// maneid, then kategori (K), then etîket (e).
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker,
// stopping at the first thing that isn't one (normally the gloss text). Shared by insertLeadingSenseTpl()
// (uses "calls") and updateSenseGloss()/fetchCurrentGloss() (uses "rest", the gloss text after every call).
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts (or, unless opts.noExtend, extends) one of the small templates that prefix a definition line's
// gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} or {{e|lang|etîket1|...}}. opts.noExtend aborts
// instead if the template is already there (used for maneid, which must never get a second, different id).
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the whole leading-call run means an existing tplKey call is found and merged wherever it
// already sits, not just when it happens to be first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.noExtend) {
throw new SubmitAbort("Ev hevok jixwe xwedan " + (opts.noExtendLabel || tplKey) + " e.");
}
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call always outranks everything), or at the end of the run.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading template calls untouched --
// the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
var calls = splitLeadingCalls(afterMarker).calls;
// "{{mane?|lang}}" is start.js's "no definition entered yet" placeholder; drop it once a real gloss is set.
calls = calls.filter(function (c) { return c.key !== "mane?"; });
var leadingText = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (leadingText ? leadingText + " " : "") + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text to prefill the "Maneyê
// biguhêre" form. A plain read, not part of the hardened save path -- the actual save still re-fetches
// fresh content, so only the prefilled text itself could be a little stale.
function fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
var loc = locateSection(content, language, sectionType, sectionOrdinal);
var defLine = findDefinitionLine(loc.lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(loc.lines[defLine])[0];
var afterMarker = loc.lines[defLine].slice(marker.length).replace(/^\s+/, "");
return splitLeadingCalls(afterMarker).rest;
});
}
// Finds a POS block's body range (up to, but not including, the next heading of level <= 3), and the
// header text + line index of any "====" subsections it already contains.
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// Looks up a header's rank in SUBSECTION_ORDER. -1 for a header that isn't one of ours; such a header is
// never used as an insertion anchor.
function subsectionRankForHeader(header) {
return SUBSECTION_ORDER.indexOf(header);
}
// Inserts a new "==== Header ====" subsection into its SUBSECTION_ORDER position within a POS block, right
// before the first ranked subsection that outranks it, or at the end if none does. Either a
// {{kol3|...}} word list or a plain paragraph, matching start.js's own subsection formats.
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var block;
if (subsection.kind === "wordlist") {
var params = "cure=" + subsection.header + "\n" + content.map(function (w) {
return "|" + w;
}).join("\n");
block = "\n==== " + subsection.header + " ====\n{{kol3|" + language + "|" + params + "\n}}\n";
} else {
block = "\n==== " + subsection.header + " ====\n" + content + "\n";
}
var myRank = subsectionRankForHeader(subsection.header);
var headers = bounds.existingHeaders;
var insertAt = bounds.end;
for (var i = 0; i < headers.length; i++) {
var otherRank = subsectionRankForHeader(headers[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = headers[i].lineIndex;
break;
}
}
lines.splice(insertAt, 0, block);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc.) instead of a real
// part-of-speech name, tagged right below with {{cure?|<lang>}} (ku.wiktionary's "part of speech not yet
// determined" maintenance flag). Neither is in sectionNames, so these two functions are a small parallel
// path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text
// (plus an optional disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading, drops the maintenance tag line right
// after it if present (MANE_TAG_REGEX -- cure? or any of its known aliases), and inserts the matching
// "{{<pos>|<lang>}}" template call in its place (skipped for section types with no POS_TEMPLATE entry).
// Other content under the heading is left untouched.
function convertManeToPos(pageContent, language, maneOrdinal, newSectionType) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
var loc = locateManeSection(pageContent, language, maneOrdinal);
var lines = loc.lines;
var m = /^(===[ ]*Mane)(\s+\d+)?([ ]*===)/.exec(lines[loc.maneLineIndex]);
lines[loc.maneLineIndex] = "=== " + newSectionType + (m[2] ? m[2] : "") + " ===";
var nextLineIndex = loc.maneLineIndex + 1;
if (nextLineIndex < lines.length && MANE_TAG_REGEX.test(lines[nextLineIndex])) {
lines.splice(nextLineIndex, 1);
}
var posTemplate = POS_TEMPLATE[newSectionType];
if (posTemplate) {
lines.splice(nextLineIndex, 0, "{{" + posTemplate + "|" + language + "}}");
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form uses, applying only the
// pieces the caller actually filled in. A piece that conflicts with the page (maneid already set, a
// subsection that's already there) is skipped with a warning rather than failing the whole save. Throws
// SubmitAbort if nothing was filled in, so this can never turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
function tryApply(fn) {
try {
content = fn();
appliedAnything = true;
} catch (e) {
if (e instanceof SubmitAbort) {
warnings.push(e.message);
} else {
throw e;
}
}
}
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
if (changes.maneid) {
tryApply(function () {
return insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", [changes.maneid], {
noExtend: true,
noExtendLabel: "nasnavek (maneid)"
});
});
}
if (changes.etiket && changes.etiket.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket);
appliedAnything = true;
}
if (changes.kategori && changes.kategori.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, words);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list: every word is its own always-visible row (word box + a "+" to attach one of the 10
// WORD_MODIFIERS as a small pill + an "x" to drop the row); a fresh empty row appears automatically once
// the current last row gets text. Duplicate words are allowed; every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into the current last row appends a fresh empty one after it, so there
// is always exactly one empty trailing row to type into.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, used for Etîket and Kategorî (simple value lists with no per-word modifiers).
// Enter or "," commits the current text as a tag; Backspace on an empty input removes the last tag;
// values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss and the two most-used word lists
// (Hevmane/Dijmane) sit directly in the picker row; the remaining word lists, maneid, etîket, kategorî
// and Nimûne/jêgirtin live behind a "Zêdetir" dropdown; one shared "Lê zêde bike" queues everything the
// user filled in as a single edit via applyAdvancedChanges() and queueChange(). Nimûne/jêgirtin is an
// immediate proxy-click into a different gadget's own form, not part of this combined save.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-open box (key -> () => value); collectChanges() only ever
// reads from a box the user actually clicked to add.
var getters = {};
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's wording; everything else here only ADDS) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel).then(
function (gloss) {
originalGloss = gloss;
$textarea.val(gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: gloss + the two most-used word groups (SENSE_GROUPS.primary) sit directly in the
// row; everything else lives behind a "Zêdetir" dropdown. Clicking any link builds and appends its box
// to $openBoxes and hides that link; the box's own "×" removes it, clears its getter, and un-hides the
// link -- several boxes can be open at once. No "Beşek (====)" entry here: buildSubsectionPanel()'s
// own "+ Beşek lê zêde bike" trigger already covers page-level subsections. ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: !!group.primary };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
// Nimûne/jêgirtin sits first in the dropdown, ahead of every field-pick link.
$moreMenu.append($nimune);
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
});
// Lives inside $picker (not appended straight to $quickRow) so .dsb-more-menu's CSS can position it as
// an overlay anchored to $picker, instead of pushing $openBoxes/the rest of the page down when it opens.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle, $moreMenu);
// Closes the dropdown on an outside click, scoped to this panel's own $moreToggle/$moreMenu.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via queueChange(); the actual
// save happens when the user clicks "Guhertinan qeyd bike" on the floating queue box. ----
// Small "not saved yet" preview of everything this queued change will do, appended right under the
// sense's gloss (plain text, not a real render of {{hevmane}}/etc.).
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
});
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: getters.maneid ? getters.maneid() : "",
etiket: getters.etiket ? getters.etiket() : [],
kategori: getters.kategori ? getters.kategori() : [],
words: words
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Auto-linkify the gloss only when it's part of this save and has no manual link already.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above.
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
// The real InterlanguageLinks pencil icon (same asset defEditButton uses); image swap is in the CSS.
var $toggle = $("<a href='#' class='dsb-toggle' title='Guhartina pêşketî'></a>");
// Revealed by $toggle -- an indented panel under the sense, not always visible. Built lazily on
// first open rather than eagerly for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.prepend($toolbar);
// Touch has no :hover -- a tap anywhere on the line reveals the pencil the same way hovering does on
// desktop (CSS gates this to touch devices; harmless if it also fires on a mouse click).
$li.on("click.dsbReveal", function () {
$toolbar.addClass("dsb-revealed");
});
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a new "====" subsection preview belongs in the live DOM, using the same SUBSECTION_ORDER rank
// insertPageSubsection() uses. Returns {insertBefore: $el} (a ranked subsection that outranks this one) or
// {insertAfter: $el} (goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its canonical position. Plain text, not a real render of {{kol3|...}}/etc.
// Returns the inserted element so the caller can remove it again.
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4>, so existingSubsectionHeadersInDom() never mistakes this live-only
// preview for an actual subsection already on the page.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field, saved via insertPageSubsection().
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return existing.indexOf(s.header) === -1;
});
if (!available.length) {
$panel.text("Hemû beş jixwe li vê hene.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.header));
});
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
function currentSubsection() {
var id = $select.val();
return available.filter(function (s) {
return s.id === id;
})[0];
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
$fieldWrap.append(
$("<textarea class='dsb-input dsb-subsection-text' rows='3'></textarea>")
.attr("placeholder", s.header + "…")
);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
var content;
if (s.kind === "wordlist") {
content = wordField.values();
if (!content.length) {
return;
}
} else {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
}
$save.prop("disabled", true);
queueChange(
"+" + s.header + " (DefSideBoxes)",
function (pageContent) {
return { content: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, s, content), warnings: [] };
},
$save,
$status,
function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that replaces an unclassified "=== Mane ===" placeholder
// heading, saved via convertManeToPos(). Lists every name from sectionNames.
function buildConvertPosPanel($panel, $h3, language, maneOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
$select.append($("<option></option>").val(name).text(name));
});
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertManeToPos(pageContent, language, maneOrdinal, chosen), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note under the heading, rather than rewriting the real heading
// text -- avoids leaving a heading showing a name that was never actually saved if the
// save fails partway through.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
}
);
});
$panel.empty().append($select, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger right under an unclassified "=== Mane ===" placeholder
// heading (see convertManeToPos()'s own comment for what that heading means).
function attachManeConvertTrigger($h3) {
if ($h3.data("dsbManeAttached")) {
return;
}
$h3.data("dsbManeAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var maneOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, maneOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (/^Mane(\s+\d+)?$/.test($h3.text().trim())) {
attachManeConvertTrigger($h3);
}
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
});
}
// Closes every open panel/preview this gadget can leave in the DOM, so bfcache never freezes one mid-open.
function closeAllOpenUi() {
clearQueue();
$(".dsb-quick-row, .dsb-more-menu, .dsb-convert-pos-panel, .dsb-subsection-panel, .dsb-queue-box, .dsb-preview-inline, .dsb-preview-block").hide();
}
$(window).on("pagehide", closeAllOpenUi);
// Belt-and-suspenders: also close on restore-from-bfcache, in case pagehide's own hide didn't stick.
$(window).on("pageshow", function (e) {
if (e.originalEvent && e.originalEvent.persisted) {
closeAllOpenUi();
}
});
$(init);
// </nowiki>
})();
3akhuzxt1h2svb8duq72k73ctcz30kk
6347556
6347535
2026-09-01T09:59:29Z
Wikihez
7344
6347556
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary, writing start.js's own wikitext
// conventions ("#: {{hevmane|lang|...}}" per-sense lines, "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile). Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling: the "Nimûne/jêgirtin" menu item looks for the button Gadget-wikt.add-examples.js
// inserts on each definition, by its exact link text, so that gadget must run first.
// <nowiki>
(function () {
"use strict";
// Main namespace, namespace 108 (reconstructed-entry pages), or a user's own /ceribandin or /test subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// Template call convertManeToPos() drops under a newly-chosen POS heading, e.g. "Hoker" -> "{{hoker|ku}}".
// A "Formeke X" (form-of) heading uses the unchanged base pos template; "Biwêj" has no template at all.
var POS_TEMPLATE = {
"Navdêr": "navdêr",
"Formeke navdêrê": "navdêr",
"Lêker": "lêker",
"Formeke lêkerê": "lêker",
"Rengdêr": "rengdêr",
"Formeke rengdêrê": "rengdêr",
"Hoker": "hoker",
"Formeke hokerê": "hoker",
"Serenav": "serenav",
"Formeke serenavê": "serenav",
"Artîkel": "artîkel",
"Baneşan": "baneşan",
"Bazinedaçek": "bazinedaçek",
"Cînav": "cînav",
"Daçek": "daçek",
"Girêdek": "girêdek",
"Gotineke pêşiyan": "gotineke pêşiyan",
"Hejmar": "hejmar",
"Hevok": "hevok",
"Îfade": "îfade",
"Kurtenav": "kurtenav",
"Navgir": "navgir",
"Paşdaçek": "paşdaçek",
"Paşgir": "paşgir",
"Pêşdaçek": "pêşdaçek",
"Pêşgir": "pêşgir",
"Pirtik": "pirtik",
"Reh": "reh",
"Sembol": "sembol",
"Tîp": "tîp"
};
// The "needs a POS" maintenance tag under a placeholder "Mane" heading, and every known redirect/alias name
// it's also called under on real pages -- convertManeToPos() drops whichever one is actually present.
var MANE_TAG_REGEX = /^\{\{\s*(?:cure\?|rêziman\?|kat-rêziman|kategoriya\s+rêzimanê\?|bêcure)\s*(?:\|[^{}]*)?\}\}\s*$/i;
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Array order controls where a new group line lands relative to existing ones. "primary" groups get their
// own always-visible quick link on the definition; the rest live in this gadget's "More" menu.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane", primary: true },
{ key: "dijmane", label: "Dijmane", primary: true },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Only steps with a confirmed wikitext format are included; insertion rank comes from SUBSECTION_ORDER below.
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// Canonical ku.wiktionary "====" subsection order, used only as insertPageSubsection()'s insertion rank
// (see subsectionRankForHeader()). Wider than PAGE_SUBSECTIONS: it also covers subsections the gadget
// cannot create but still has to order around.
var SUBSECTION_ORDER = [
"Bilêvkirin",
"Ji wêjeya klasîk",
"Ji wêjeyê",
"Tewandin",
"Notên bikaranînê",
"Bi alfabeyên din",
"Formên alternatîv",
"Kurtkirin",
"Sembol",
"Navê zanistî",
"Hevmane",
"Nêzîk",
"Dijmane",
"Jornav",
"Jêrnav",
"Jê",
"Têkildar",
"Etîmolojî",
"Dûnde",
"Bide ber",
"Herwiha binêre",
"Bêhtir xwendin",
// Both spellings are in use on-wiki; PAGE_SUBSECTIONS creates this one, so it ranks in the same slot.
"Bêhtir bixwîne",
"Bi zaravayên din",
"Werger",
"Qafiye",
"Anagram",
// Creatable but absent from the canonical order; put last so it never displaces a ranked subsection.
"Çavkanî"
];
// {{kol}}, {{kol2}}, {{kol3}} and their col* spellings are the same column word-list template. New sections
// are written as kol3; any of the six is recognized when parsing an existing one.
var WORDLIST_TEMPLATES = ["kol3", "kol2", "kol", "col3", "col2", "col"];
// ---- word-modifier system (same widget start.js uses for Hevmane/Dijmane/etc. word lists) ----
// Every word in one of these lists can carry small "<key:value>" annotations (translation, gender, label,
// ...), which the {{hevmane}}/{{kol3}}/etc. templates parse back out of the raw positional param.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers into the raw "word<key:value>…" form {{hevmane}}/{{kol3}}/etc. read. */
// Inverse of joinWordValue(): peels the trailing "<key:value>" modifiers back off a raw list entry.
function splitWordValue(raw) {
var mods = [];
var word = raw;
var tail = /<([^<>:]+):([^<>]*)>\s*$/;
var m;
while ((m = tail.exec(word)) !== null) {
mods.unshift({ key: m[1], value: m[2] });
word = word.slice(0, m.index);
}
return { word: $.trim(word), mods: mods };
}
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers (document-order based, immune to mobile's per-section DOM wrapping and
// MediaWiki's page-wide heading-id collisions) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s*\d+$/, ""); // \s* not \s+: locateSection() also accepts "Navdêr2"
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || $(this).text().trim();
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback so one fetch covers both the
// edit-conflict check and the content, preventing a stale overwrite of someone else's edit.
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// This gadget's own save queue + floating widget, separate from the shared Gadget-Editor queue.
// Each entry keeps its own transformFn so saveQueueNow() can re-run all of them against one fresh fetch.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// The real save: re-runs every queued transformFn, in order, against one freshly-fetched revision and
// posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var combinedSummary = dsbQueue.entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
dsbQueue.entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function () {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text("✓ hemû guhertin hatin qeydkirin — rûpel nûve bike da ku bibînî.");
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()); nothing here touches the page yet. Also runs previewFn(), which drops a
// small "not saved yet" preview into the live DOM at the change's own spot on the page. Shared by every
// panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel, buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget ($.kuLinkify) and calls back with the linkified result.
// Passes the text through unchanged if the gadget can't be loaded, so it never blocks a save.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal, never by a DOM id number (MediaWiki's
// page-wide anchor uniquification can attach an id to a heading unrelated to its actual position).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the whole rest of the page from this language's heading onward, since the caller reuses
// it to rebuild the entire saved text; only the section-heading search itself is bounded by sectionSearchEndLine.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
// Closing "===" anchored, like locateManeSection(): otherwise "=== Navdêra pirjimar ===" counts as a POS occurrence here while sectionTypeOf() rejects it, desyncing the ordinal.
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?[ ]*===");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel: element 0 is
// unused (it's the "type|ordinal" string locateSection already resolved), remaining elements are 0-based
// indices, one per nesting level.
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's wordLine()
// format). If a line for this tplKey already exists under the definition, missing words are appended to
// it; otherwise a new line lands after the last existing group line, always before any "#*" citation lines.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's gloss text:
// maneid, then kategori (K), then etîket (e).
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker,
// stopping at the first thing that isn't one (normally the gloss text). Shared by insertLeadingSenseTpl()
// (uses "calls") and updateSenseGloss()/fetchCurrentGloss() (uses "rest", the gloss text after every call).
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts (or, unless opts.noExtend, extends) one of the small templates that prefix a definition line's
// gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} or {{e|lang|etîket1|...}}. opts.noExtend aborts
// instead if the template is already there (used for maneid, which must never get a second, different id).
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the whole leading-call run means an existing tplKey call is found and merged wherever it
// already sits, not just when it happens to be first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.noExtend) {
throw new SubmitAbort("Ev hevok jixwe xwedan " + (opts.noExtendLabel || tplKey) + " e.");
}
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call always outranks everything), or at the end of the run.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading template calls untouched --
// the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
var calls = splitLeadingCalls(afterMarker).calls;
// "{{mane?|lang}}" is start.js's "no definition entered yet" placeholder; drop it once a real gloss is set.
calls = calls.filter(function (c) { return c.key !== "mane?"; });
var leadingText = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (leadingText ? leadingText + " " : "") + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text to prefill the "Maneyê
// biguhêre" form. A plain read, not part of the hardened save path -- the actual save still re-fetches
// fresh content, so only the prefilled text itself could be a little stale.
// Current contents of one existing subsection, for prefilling the edit form.
function fetchPageSubsection(language, sectionType, sectionOrdinal, subsection) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
return readPageSubsection(content, language, sectionType, sectionOrdinal, subsection);
});
}
function fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
var loc = locateSection(content, language, sectionType, sectionOrdinal);
var defLine = findDefinitionLine(loc.lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(loc.lines[defLine])[0];
var afterMarker = loc.lines[defLine].slice(marker.length).replace(/^\s+/, "");
return splitLeadingCalls(afterMarker).rest;
});
}
// Finds a POS block's body range (up to, but not including, the next heading of level <= 3), and the
// header text + line index of any "====" subsections it already contains.
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// Looks up a header's rank in SUBSECTION_ORDER. -1 for a header that isn't one of ours; such a header is
// never used as an insertion anchor.
function subsectionRankForHeader(header) {
return SUBSECTION_ORDER.indexOf(header);
}
// Body line range of one "====" subsection inside a POS block: everything after its heading up to the next
// "====" heading, or the end of the block. Null if the block has no such subsection.
function subsectionBodyRange(bounds, header) {
var headers = bounds.existingHeaders;
for (var i = 0; i < headers.length; i++) {
if (headers[i].header === header) {
return {
start: headers[i].lineIndex + 1,
end: i + 1 < headers.length ? headers[i + 1].lineIndex : bounds.end
};
}
}
return null;
}
// Splits a template call's inner text on its top-level "|", ignoring pipes nested in {{...}} or [[...]].
function splitTemplateParams(inner) {
var parts = [];
var buf = "";
var tpl = 0;
var link = 0;
for (var i = 0; i < inner.length; i++) {
var two = inner.substr(i, 2);
if (two === "{{" || two === "}}" || two === "[[" || two === "]]") {
if (two === "{{") { tpl++; } else if (two === "}}") { tpl--; } else if (two === "[[") { link++; } else { link--; }
buf += two;
i++;
continue;
}
if (inner.charAt(i) === "|" && tpl === 0 && link === 0) {
parts.push(buf);
buf = "";
continue;
}
buf += inner.charAt(i);
}
parts.push(buf);
return parts;
}
// Pulls a {{kol3|ku|cure=Jê|word|word}}-style call apart into the bits an edit has to preserve (template
// name, language, named params) plus the positional word list. Null if the body has no such call.
function parseWordListCall(text) {
var m = new RegExp("\{\{\s*(" + WORDLIST_TEMPLATES.join("|") + ")\s*[|}]", "i").exec(text);
if (!m) {
return null;
}
var open = m.index;
var depth = 0;
var close = -1;
for (var i = open; i < text.length - 1; i++) {
var two = text.substr(i, 2);
if (two === "{{") {
depth++;
i++;
} else if (two === "}}") {
depth--;
i++;
if (depth === 0) {
close = i + 1;
break;
}
}
}
if (close === -1) {
return null;
}
var parts = splitTemplateParams(text.slice(open + 2, close - 2));
var named = [];
var words = [];
for (var pi = 2; pi < parts.length; pi++) {
var val = $.trim(parts[pi]);
if (!val) {
continue;
}
if (/^[A-Za-z][A-Za-z0-9_-]*\s*=/.test(val)) {
named.push(val);
} else {
words.push(val);
}
}
return {
name: $.trim(parts[0]),
lang: parts.length > 1 ? $.trim(parts[1]) : "",
named: named,
words: words,
start: open,
end: close
};
}
// Canonical multi-line layout, matching how existing ku.wiktionary lists are written (one word per line).
function buildWordListCall(name, lang, named, words) {
var head = "{{" + name + "|" + lang;
named.forEach(function (n) {
head += "|" + n;
});
return words.length ? head + "\n|" + words.join("\n|") + "\n}}" : head + "\n}}";
}
// Current contents of an existing "====" subsection. A wordlist one whose template can't be parsed comes
// back as {kind: "text"} so the caller can still edit it as raw wikitext instead of refusing outright.
function readPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var bounds = posBlockBounds(loc.lines, loc.posLineIndex);
var range = subsectionBodyRange(bounds, subsection.header);
if (!range) {
return null;
}
var body = loc.lines.slice(range.start, range.end).join("\n");
if (subsection.kind === "wordlist") {
var call = parseWordListCall(body);
if (call) {
return { kind: "wordlist", words: call.words };
}
}
return { kind: "text", text: $.trim(body) };
}
// Rewrites an existing "====" subsection in place. A wordlist one keeps its own template name, language and
// named params ("cure=Jê", ...) and only has its positional words replaced; a text one is replaced whole.
function updatePageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var range = subsectionBodyRange(bounds, subsection.header);
if (!range) {
throw new SubmitAbort("Ev beş li vir tune: " + subsection.header);
}
var body = lines.slice(range.start, range.end).join("\n");
var replacement;
if (subsection.kind === "wordlist") {
var call = parseWordListCall(body);
if (!call) {
throw new SubmitAbort("Nikarî lîsteya vê beşê bixwîne: " + subsection.header);
}
// body.slice(call.end) already carries whatever trailed the call, blank separator line included.
replacement = body.slice(0, call.start) +
buildWordListCall(call.name, call.lang, call.named, content) +
body.slice(call.end);
} else {
// Replacing the body wholesale drops that separator, so put it back.
replacement = content + (/\n\s*$/.test(body) ? "\n" : "");
}
lines.splice(range.start, range.end - range.start, replacement);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Inserts a new "==== Header ====" subsection into its SUBSECTION_ORDER position within a POS block, right
// before the first ranked subsection that outranks it, or at the end if none does. Either a
// {{kol3|...}} word list or a plain paragraph, matching start.js's own subsection formats.
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var block;
if (subsection.kind === "wordlist") {
var params = "cure=" + subsection.header + "\n" + content.map(function (w) {
return "|" + w;
}).join("\n");
block = "\n==== " + subsection.header + " ====\n{{kol3|" + language + "|" + params + "\n}}\n";
} else {
block = "\n==== " + subsection.header + " ====\n" + content + "\n";
}
var myRank = subsectionRankForHeader(subsection.header);
var headers = bounds.existingHeaders;
var insertAt = bounds.end;
for (var i = 0; i < headers.length; i++) {
var otherRank = subsectionRankForHeader(headers[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = headers[i].lineIndex;
break;
}
}
lines.splice(insertAt, 0, block);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc.) instead of a real
// part-of-speech name, tagged right below with {{cure?|<lang>}} (ku.wiktionary's "part of speech not yet
// determined" maintenance flag). Neither is in sectionNames, so these two functions are a small parallel
// path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text
// (plus an optional disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading, drops the maintenance tag line right
// after it if present (MANE_TAG_REGEX -- cure? or any of its known aliases), and inserts the matching
// "{{<pos>|<lang>}}" template call in its place (skipped for section types with no POS_TEMPLATE entry).
// Other content under the heading is left untouched.
function convertManeToPos(pageContent, language, maneOrdinal, newSectionType) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
var loc = locateManeSection(pageContent, language, maneOrdinal);
var lines = loc.lines;
var m = /^(===[ ]*Mane)(\s+\d+)?([ ]*===)/.exec(lines[loc.maneLineIndex]);
lines[loc.maneLineIndex] = "=== " + newSectionType + (m[2] ? m[2] : "") + " ===";
var nextLineIndex = loc.maneLineIndex + 1;
if (nextLineIndex < lines.length && MANE_TAG_REGEX.test(lines[nextLineIndex])) {
lines.splice(nextLineIndex, 1);
}
var posTemplate = POS_TEMPLATE[newSectionType];
if (posTemplate) {
lines.splice(nextLineIndex, 0, "{{" + posTemplate + "|" + language + "}}");
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form uses, applying only the
// pieces the caller actually filled in. A piece that conflicts with the page (maneid already set, a
// subsection that's already there) is skipped with a warning rather than failing the whole save. Throws
// SubmitAbort if nothing was filled in, so this can never turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
function tryApply(fn) {
try {
content = fn();
appliedAnything = true;
} catch (e) {
if (e instanceof SubmitAbort) {
warnings.push(e.message);
} else {
throw e;
}
}
}
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
if (changes.maneid) {
tryApply(function () {
return insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", [changes.maneid], {
noExtend: true,
noExtendLabel: "nasnavek (maneid)"
});
});
}
if (changes.etiket && changes.etiket.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket);
appliedAnything = true;
}
if (changes.kategori && changes.kategori.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, words);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list: every word is its own always-visible row (word box + a "+" to attach one of the 10
// WORD_MODIFIERS as a small pill + an "x" to drop the row); a fresh empty row appears automatically once
// the current last row gets text. Duplicate words are allowed; every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into the current last row appends a fresh empty one after it, so there
// is always exactly one empty trailing row to type into.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.data("setRaw", function (raw) {
var parsed = splitWordValue(raw);
mods = parsed.mods;
$wordInput.val(parsed.word);
renderMods();
updateButtons();
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
// Replaces the whole list, keeping one empty trailing row to type into.
setValues: function (raws) {
$list.empty();
raws.forEach(function (raw) {
var $row = makeRow();
$list.append($row);
$row.data("setRaw")(raw);
});
$list.append(makeRow());
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, used for Etîket and Kategorî (simple value lists with no per-word modifiers).
// Enter or "," commits the current text as a tag; Backspace on an empty input removes the last tag;
// values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss and the two most-used word lists
// (Hevmane/Dijmane) sit directly in the picker row; the remaining word lists, maneid, etîket, kategorî
// and Nimûne/jêgirtin live behind a "Zêdetir" dropdown; one shared "Lê zêde bike" queues everything the
// user filled in as a single edit via applyAdvancedChanges() and queueChange(). Nimûne/jêgirtin is an
// immediate proxy-click into a different gadget's own form, not part of this combined save.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-open box (key -> () => value); collectChanges() only ever
// reads from a box the user actually clicked to add.
var getters = {};
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's wording; everything else here only ADDS) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel).then(
function (gloss) {
originalGloss = gloss;
$textarea.val(gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: gloss + the two most-used word groups (SENSE_GROUPS.primary) sit directly in the
// row; everything else lives behind a "Zêdetir" dropdown. Clicking any link builds and appends its box
// to $openBoxes and hides that link; the box's own "×" removes it, clears its getter, and un-hides the
// link -- several boxes can be open at once. No "Beşek (====)" entry here: buildSubsectionPanel()'s
// own "+ Beşek lê zêde bike" trigger already covers page-level subsections. ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: !!group.primary };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
// Nimûne/jêgirtin sits first in the dropdown, ahead of every field-pick link.
$moreMenu.append($nimune);
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
});
// Lives inside $picker (not appended straight to $quickRow) so .dsb-more-menu's CSS can position it as
// an overlay anchored to $picker, instead of pushing $openBoxes/the rest of the page down when it opens.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle, $moreMenu);
// Closes the dropdown on an outside click, scoped to this panel's own $moreToggle/$moreMenu.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via queueChange(); the actual
// save happens when the user clicks "Guhertinan qeyd bike" on the floating queue box. ----
// Small "not saved yet" preview of everything this queued change will do, appended right under the
// sense's gloss (plain text, not a real render of {{hevmane}}/etc.).
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
});
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: getters.maneid ? getters.maneid() : "",
etiket: getters.etiket ? getters.etiket() : [],
kategori: getters.kategori ? getters.kategori() : [],
words: words
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Auto-linkify the gloss only when it's part of this save and has no manual link already.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above.
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
// The real InterlanguageLinks pencil icon (same asset defEditButton uses); image swap is in the CSS.
var $toggle = $("<a href='#' class='dsb-toggle' title='Guhartina pêşketî'></a>");
// Revealed by $toggle -- an indented panel under the sense, not always visible. Built lazily on
// first open rather than eagerly for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.prepend($toolbar);
// Touch has no :hover -- a tap anywhere on the line reveals the pencil the same way hovering does on
// desktop (CSS gates this to touch devices; harmless if it also fires on a mouse click).
$li.on("click.dsbReveal", function () {
$toolbar.addClass("dsb-revealed");
});
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a new "====" subsection preview belongs in the live DOM, using the same SUBSECTION_ORDER rank
// insertPageSubsection() uses. Returns {insertBefore: $el} (a ranked subsection that outranks this one) or
// {insertAfter: $el} (goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its canonical position. Plain text, not a real render of {{kol3|...}}/etc.
// Returns the inserted element so the caller can remove it again.
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4>, so existingSubsectionHeadersInDom() never mistakes this live-only
// preview for an actual subsection already on the page.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field. A subsection that isn't on the page yet is saved
// via insertPageSubsection(); one that already is gets prefilled and saved via updatePageSubsection().
// onlyHeader pins the panel to a single subsection (the per-heading pencil); omit it for the full picker.
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal, onlyHeader) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return !onlyHeader || s.header === onlyHeader;
}).map(function (s) {
return $.extend({}, s, { existing: existing.indexOf(s.header) !== -1 });
});
if (!available.length) {
$panel.text("Ji bo vê beşê guhartin tune.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.existing ? s.header + " (biguhêre)" : s.header));
});
if (onlyHeader) {
$select.hide();
}
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
function currentSubsection() {
var id = $select.val();
return available.filter(function (s) {
return s.id === id;
})[0];
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
var editAsText = false; // set when an existing wordlist section turns out to be unparseable
function renderTextArea(s, rows) {
$fieldWrap.empty().append(
$("<textarea class='dsb-input dsb-subsection-text'></textarea>")
.attr("rows", rows)
.attr("placeholder", s.header + "…")
);
}
// Loads what the page already has into the form, so an edit starts from the current list rather than
// from an empty one. A wordlist section we can't parse degrades to raw wikitext editing.
function prefill(s) {
$status.removeClass("dsb-status-error dsb-status-ok").text("Tê xwendin…");
$save.prop("disabled", true);
fetchPageSubsection(language, sectionType, sectionOrdinal, s).then(function (current) {
$save.prop("disabled", false);
$status.text("");
if (!current) {
return;
}
if (current.kind === "wordlist" && wordField) {
wordField.setValues(current.words);
return;
}
if (s.kind === "wordlist") {
editAsText = true;
wordField = null;
renderTextArea(s, 6);
$status.text("Şablona vê lîsteyê nehate naskirin — wekî wikitext biguhêre.");
}
$fieldWrap.find(".dsb-subsection-text").val(current.text);
}, function () {
$save.prop("disabled", false);
$status.addClass("dsb-status-error").text("Nikarî muhtewaya heyî bixwîne.");
});
}
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
editAsText = false;
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
renderTextArea(s, 3);
}
$save.text(s.existing ? "Biguhêre" : "Lê zêde bike");
if (s.existing) {
prefill(s);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
var asText = editAsText || s.kind !== "wordlist";
var effective = asText ? $.extend({}, s, { kind: "text" }) : s;
var content;
if (asText) {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
} else {
content = wordField.values();
if (!content.length) {
return;
}
}
$save.prop("disabled", true);
queueChange(
(s.existing ? "~" : "+") + s.header + " (DefSideBoxes)",
function (pageContent) {
return {
content: s.existing
? updatePageSubsection(pageContent, language, sectionType, sectionOrdinal, effective, content)
: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, effective, content),
warnings: []
};
},
$save,
$status,
// Only a brand-new subsection gets a preview block; an edit would have to rewrite the rendered
// section in place, which this plain-text preview can't do faithfully.
s.existing ? null : function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that replaces an unclassified "=== Mane ===" placeholder
// heading, saved via convertManeToPos(). Lists every name from sectionNames.
function buildConvertPosPanel($panel, $h3, language, maneOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
$select.append($("<option></option>").val(name).text(name));
});
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertManeToPos(pageContent, language, maneOrdinal, chosen), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note under the heading, rather than rewriting the real heading
// text -- avoids leaving a heading showing a name that was never actually saved if the
// save fails partway through.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
}
);
});
$panel.empty().append($select, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
// Puts the same pencil the definitions use on every existing "====" subsection heading the gadget knows how
// to edit, opening buildSubsectionPanel() pinned to that one subsection.
function attachSubsectionEditors($h3, language, sectionType, sectionOrdinal) {
var editable = {};
PAGE_SUBSECTIONS.forEach(function (s) {
editable[s.header] = true;
});
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if (!$cursor.is(".mw-heading4, h4")) {
continue;
}
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var header = $hh.text().trim();
if (!editable[header] || $hh.data("dsbAttached")) {
continue;
}
$hh.data("dsbAttached", true);
attachSubsectionEditor($hh, $cursor, $h3, header, language, sectionType, sectionOrdinal);
}
}
function attachSubsectionEditor($hh, $heading, $h3, header, language, sectionType, sectionOrdinal) {
var $toolbar = $("<span class='dsb-toolbar dsb-toolbar-heading'></span>");
var $toggle = $("<a href='#' class='dsb-toggle'></a>").attr("title", header + " biguhêre");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$toolbar.append($toggle);
$hh.prepend($toolbar);
$heading.after($panel);
$toggle.on("click", function (e) {
e.preventDefault();
$toolbar.addClass("dsb-revealed");
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal, header);
$panel.data("built", true);
}
});
}
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger right under an unclassified "=== Mane ===" placeholder
// heading (see convertManeToPos()'s own comment for what that heading means).
function attachManeConvertTrigger($h3) {
if ($h3.data("dsbManeAttached")) {
return;
}
$h3.data("dsbManeAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var maneOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, maneOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (/^Mane(\s+\d+)?$/.test($h3.text().trim())) {
attachManeConvertTrigger($h3);
}
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
attachSubsectionEditors($h3, language, sectionType, sectionOrdinal);
});
}
// Closes every open panel/preview this gadget can leave in the DOM, so bfcache never freezes one mid-open.
function closeAllOpenUi() {
clearQueue();
$(".dsb-quick-row, .dsb-more-menu, .dsb-convert-pos-panel, .dsb-subsection-panel, .dsb-queue-box, .dsb-preview-inline, .dsb-preview-block").hide();
}
$(window).on("pagehide", closeAllOpenUi);
// Belt-and-suspenders: also close on restore-from-bfcache, in case pagehide's own hide didn't stick.
$(window).on("pageshow", function (e) {
if (e.originalEvent && e.originalEvent.persisted) {
closeAllOpenUi();
}
});
$(init);
// </nowiki>
})();
g2iy3pdmd1iajysuxatqhp1bq52zszx
6347565
6347556
2026-09-01T10:14:05Z
Wikihez
7344
6347565
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary, writing start.js's own wikitext
// conventions ("#: {{hevmane|lang|...}}" per-sense lines, "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile). Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling: the "Nimûne/jêgirtin" menu item looks for the button Gadget-wikt.add-examples.js
// inserts on each definition, by its exact link text, so that gadget must run first.
// <nowiki>
(function () {
"use strict";
// Main namespace, namespace 108 (reconstructed-entry pages), or a user's own /ceribandin or /test subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// Template call convertManeToPos() drops under a newly-chosen POS heading, e.g. "Hoker" -> "{{hoker|ku}}".
// A "Formeke X" (form-of) heading uses the unchanged base pos template; "Biwêj" has no template at all.
var POS_TEMPLATE = {
"Navdêr": "navdêr",
"Formeke navdêrê": "navdêr",
"Lêker": "lêker",
"Formeke lêkerê": "lêker",
"Rengdêr": "rengdêr",
"Formeke rengdêrê": "rengdêr",
"Hoker": "hoker",
"Formeke hokerê": "hoker",
"Serenav": "serenav",
"Formeke serenavê": "serenav",
"Artîkel": "artîkel",
"Baneşan": "baneşan",
"Bazinedaçek": "bazinedaçek",
"Cînav": "cînav",
"Daçek": "daçek",
"Girêdek": "girêdek",
"Gotineke pêşiyan": "gotineke pêşiyan",
"Hejmar": "hejmar",
"Hevok": "hevok",
"Îfade": "îfade",
"Kurtenav": "kurtenav",
"Navgir": "navgir",
"Paşdaçek": "paşdaçek",
"Paşgir": "paşgir",
"Pêşdaçek": "pêşdaçek",
"Pêşgir": "pêşgir",
"Pirtik": "pirtik",
"Reh": "reh",
"Sembol": "sembol",
"Tîp": "tîp"
};
// The "needs a POS" maintenance tag under a placeholder "Mane" heading, and every known redirect/alias name
// it's also called under on real pages -- convertManeToPos() drops whichever one is actually present.
var MANE_TAG_REGEX = /^\{\{\s*(?:cure\?|rêziman\?|kat-rêziman|kategoriya\s+rêzimanê\?|bêcure)\s*(?:\|[^{}]*)?\}\}\s*$/i;
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Array order controls where a new group line lands relative to existing ones. "primary" groups get their
// own always-visible quick link on the definition; the rest live in this gadget's "More" menu.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane", primary: true },
{ key: "dijmane", label: "Dijmane", primary: true },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Only steps with a confirmed wikitext format are included; insertion rank comes from SUBSECTION_ORDER below.
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// Canonical ku.wiktionary "====" subsection order, used only as insertPageSubsection()'s insertion rank
// (see subsectionRankForHeader()). Wider than PAGE_SUBSECTIONS: it also covers subsections the gadget
// cannot create but still has to order around.
var SUBSECTION_ORDER = [
"Bilêvkirin",
"Ji wêjeya klasîk",
"Ji wêjeyê",
"Tewandin",
"Notên bikaranînê",
"Bi alfabeyên din",
"Formên alternatîv",
"Kurtkirin",
"Sembol",
"Navê zanistî",
"Hevmane",
"Nêzîk",
"Dijmane",
"Jornav",
"Jêrnav",
"Jê",
"Têkildar",
"Etîmolojî",
"Dûnde",
"Bide ber",
"Herwiha binêre",
"Bêhtir xwendin",
// Both spellings are in use on-wiki; PAGE_SUBSECTIONS creates this one, so it ranks in the same slot.
"Bêhtir bixwîne",
"Bi zaravayên din",
"Werger",
"Qafiye",
"Anagram",
// Creatable but absent from the canonical order; put last so it never displaces a ranked subsection.
"Çavkanî"
];
// {{kol}}, {{kol2}}, {{kol3}} and their col* spellings are the same column word-list template. New sections
// are written as kol3; any of the six is recognized when parsing an existing one.
var WORDLIST_TEMPLATES = ["kol3", "kol2", "kol", "col3", "col2", "col"];
// ---- word-modifier system (same widget start.js uses for Hevmane/Dijmane/etc. word lists) ----
// Every word in one of these lists can carry small "<key:value>" annotations (translation, gender, label,
// ...), which the {{hevmane}}/{{kol3}}/etc. templates parse back out of the raw positional param.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers into the raw "word<key:value>…" form {{hevmane}}/{{kol3}}/etc. read. */
// Inverse of joinWordValue(): peels the trailing "<key:value>" modifiers back off a raw list entry.
function splitWordValue(raw) {
var mods = [];
var word = raw;
var tail = /<([^<>:]+):([^<>]*)>\s*$/;
var m;
while ((m = tail.exec(word)) !== null) {
mods.unshift({ key: m[1], value: m[2] });
word = word.slice(0, m.index);
}
return { word: $.trim(word), mods: mods };
}
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers (document-order based, immune to mobile's per-section DOM wrapping and
// MediaWiki's page-wide heading-id collisions) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s*\d+$/, ""); // \s* not \s+: locateSection() also accepts "Navdêr2"
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || $(this).text().trim();
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback so one fetch covers both the
// edit-conflict check and the content, preventing a stale overwrite of someone else's edit.
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// This gadget's own save queue + floating widget, separate from the shared Gadget-Editor queue.
// Each entry keeps its own transformFn so saveQueueNow() can re-run all of them against one fresh fetch.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// The real save: re-runs every queued transformFn, in order, against one freshly-fetched revision and
// posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var combinedSummary = dsbQueue.entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
dsbQueue.entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function () {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text("✓ hemû guhertin hatin qeydkirin — rûpel nûve bike da ku bibînî.");
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()); nothing here touches the page yet. Also runs previewFn(), which drops a
// small "not saved yet" preview into the live DOM at the change's own spot on the page. Shared by every
// panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel, buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget ($.kuLinkify) and calls back with the linkified result.
// Passes the text through unchanged if the gadget can't be loaded, so it never blocks a save.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal, never by a DOM id number (MediaWiki's
// page-wide anchor uniquification can attach an id to a heading unrelated to its actual position).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the whole rest of the page from this language's heading onward, since the caller reuses
// it to rebuild the entire saved text; only the section-heading search itself is bounded by sectionSearchEndLine.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
// Closing "===" anchored, like locateManeSection(): otherwise "=== Navdêra pirjimar ===" counts as a POS occurrence here while sectionTypeOf() rejects it, desyncing the ordinal.
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?[ ]*===");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel: element 0 is
// unused (it's the "type|ordinal" string locateSection already resolved), remaining elements are 0-based
// indices, one per nesting level.
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's wordLine()
// format). If a line for this tplKey already exists under the definition, missing words are appended to
// it; otherwise a new line lands after the last existing group line, always before any "#*" citation lines.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's gloss text:
// maneid, then kategori (K), then etîket (e).
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker,
// stopping at the first thing that isn't one (normally the gloss text). Shared by insertLeadingSenseTpl()
// (uses "calls") and updateSenseGloss()/fetchCurrentGloss() (uses "rest", the gloss text after every call).
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts (or, unless opts.noExtend, extends) one of the small templates that prefix a definition line's
// gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} or {{e|lang|etîket1|...}}. opts.noExtend aborts
// instead if the template is already there (used for maneid, which must never get a second, different id).
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the whole leading-call run means an existing tplKey call is found and merged wherever it
// already sits, not just when it happens to be first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.noExtend) {
throw new SubmitAbort("Ev hevok jixwe xwedan " + (opts.noExtendLabel || tplKey) + " e.");
}
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call always outranks everything), or at the end of the run.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading template calls untouched --
// the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
var calls = splitLeadingCalls(afterMarker).calls;
// "{{mane?|lang}}" is start.js's "no definition entered yet" placeholder; drop it once a real gloss is set.
calls = calls.filter(function (c) { return c.key !== "mane?"; });
var leadingText = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (leadingText ? leadingText + " " : "") + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text to prefill the "Maneyê
// biguhêre" form. A plain read, not part of the hardened save path -- the actual save still re-fetches
// fresh content, so only the prefilled text itself could be a little stale.
// Current contents of one existing subsection, for prefilling the edit form.
function fetchPageSubsection(language, sectionType, sectionOrdinal, subsection) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
return readPageSubsection(content, language, sectionType, sectionOrdinal, subsection);
});
}
function fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
var loc = locateSection(content, language, sectionType, sectionOrdinal);
var defLine = findDefinitionLine(loc.lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(loc.lines[defLine])[0];
var afterMarker = loc.lines[defLine].slice(marker.length).replace(/^\s+/, "");
return splitLeadingCalls(afterMarker).rest;
});
}
// Finds a POS block's body range (up to, but not including, the next heading of level <= 3), and the
// header text + line index of any "====" subsections it already contains.
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// Looks up a header's rank in SUBSECTION_ORDER. -1 for a header that isn't one of ours; such a header is
// never used as an insertion anchor.
function subsectionRankForHeader(header) {
return SUBSECTION_ORDER.indexOf(header);
}
// Body line range of one "====" subsection inside a POS block: everything after its heading up to the next
// "====" heading, or the end of the block. Null if the block has no such subsection.
function subsectionBodyRange(bounds, header) {
var headers = bounds.existingHeaders;
for (var i = 0; i < headers.length; i++) {
if (headers[i].header === header) {
return {
start: headers[i].lineIndex + 1,
end: i + 1 < headers.length ? headers[i + 1].lineIndex : bounds.end
};
}
}
return null;
}
// Splits a template call's inner text on its top-level "|", ignoring pipes nested in {{...}} or [[...]].
function splitTemplateParams(inner) {
var parts = [];
var buf = "";
var tpl = 0;
var link = 0;
for (var i = 0; i < inner.length; i++) {
var two = inner.substr(i, 2);
if (two === "{{" || two === "}}" || two === "[[" || two === "]]") {
if (two === "{{") { tpl++; } else if (two === "}}") { tpl--; } else if (two === "[[") { link++; } else { link--; }
buf += two;
i++;
continue;
}
if (inner.charAt(i) === "|" && tpl === 0 && link === 0) {
parts.push(buf);
buf = "";
continue;
}
buf += inner.charAt(i);
}
parts.push(buf);
return parts;
}
// Pulls a {{kol3|ku|cure=Jê|word|word}}-style call apart into the bits an edit has to preserve (template
// name, language, named params) plus the positional word list. Null if the body has no such call.
function parseWordListCall(text) {
var m = new RegExp("\{\{\s*(" + WORDLIST_TEMPLATES.join("|") + ")\s*[|}]", "i").exec(text);
if (!m) {
return null;
}
var open = m.index;
var depth = 0;
var close = -1;
for (var i = open; i < text.length - 1; i++) {
var two = text.substr(i, 2);
if (two === "{{") {
depth++;
i++;
} else if (two === "}}") {
depth--;
i++;
if (depth === 0) {
close = i + 1;
break;
}
}
}
if (close === -1) {
return null;
}
var parts = splitTemplateParams(text.slice(open + 2, close - 2));
var named = [];
var words = [];
for (var pi = 2; pi < parts.length; pi++) {
var val = $.trim(parts[pi]);
if (!val) {
continue;
}
if (/^[A-Za-z][A-Za-z0-9_-]*\s*=/.test(val)) {
named.push(val);
} else {
words.push(val);
}
}
return {
name: $.trim(parts[0]),
lang: parts.length > 1 ? $.trim(parts[1]) : "",
named: named,
words: words,
start: open,
end: close
};
}
// Canonical multi-line layout, matching how existing ku.wiktionary lists are written (one word per line).
function buildWordListCall(name, lang, named, words) {
var head = "{{" + name + "|" + lang;
named.forEach(function (n) {
head += "|" + n;
});
return words.length ? head + "\n|" + words.join("\n|") + "\n}}" : head + "\n}}";
}
// Current contents of an existing "====" subsection. A wordlist one whose template can't be parsed comes
// back as {kind: "text"} so the caller can still edit it as raw wikitext instead of refusing outright.
function readPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var bounds = posBlockBounds(loc.lines, loc.posLineIndex);
var range = subsectionBodyRange(bounds, subsection.header);
if (!range) {
return null;
}
var body = loc.lines.slice(range.start, range.end).join("\n");
if (subsection.kind === "wordlist") {
var call = parseWordListCall(body);
if (call) {
return { kind: "wordlist", words: call.words };
}
}
return { kind: "text", text: $.trim(body) };
}
// Rewrites an existing "====" subsection in place. A wordlist one keeps its own template name, language and
// named params ("cure=Jê", ...) and only has its positional words replaced; a text one is replaced whole.
function updatePageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var range = subsectionBodyRange(bounds, subsection.header);
if (!range) {
throw new SubmitAbort("Ev beş li vir tune: " + subsection.header);
}
var body = lines.slice(range.start, range.end).join("\n");
var replacement;
if (subsection.kind === "wordlist") {
var call = parseWordListCall(body);
if (!call) {
throw new SubmitAbort("Nikarî lîsteya vê beşê bixwîne: " + subsection.header);
}
// body.slice(call.end) already carries whatever trailed the call, blank separator line included.
replacement = body.slice(0, call.start) +
buildWordListCall(call.name, call.lang, call.named, content) +
body.slice(call.end);
} else {
// Replacing the body wholesale drops that separator, so put it back.
replacement = content + (/\n\s*$/.test(body) ? "\n" : "");
}
lines.splice(range.start, range.end - range.start, replacement);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Inserts a new "==== Header ====" subsection into its SUBSECTION_ORDER position within a POS block, right
// before the first ranked subsection that outranks it, or at the end if none does. Either a
// {{kol3|...}} word list or a plain paragraph, matching start.js's own subsection formats.
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var block;
if (subsection.kind === "wordlist") {
var params = "cure=" + subsection.header + "\n" + content.map(function (w) {
return "|" + w;
}).join("\n");
block = "\n==== " + subsection.header + " ====\n{{kol3|" + language + "|" + params + "\n}}\n";
} else {
block = "\n==== " + subsection.header + " ====\n" + content + "\n";
}
var myRank = subsectionRankForHeader(subsection.header);
var headers = bounds.existingHeaders;
var insertAt = bounds.end;
for (var i = 0; i < headers.length; i++) {
var otherRank = subsectionRankForHeader(headers[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = headers[i].lineIndex;
break;
}
}
lines.splice(insertAt, 0, block);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc.) instead of a real
// part-of-speech name, tagged right below with {{cure?|<lang>}} (ku.wiktionary's "part of speech not yet
// determined" maintenance flag). Neither is in sectionNames, so these two functions are a small parallel
// path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text
// (plus an optional disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading, drops the maintenance tag line right
// after it if present (MANE_TAG_REGEX -- cure? or any of its known aliases), and inserts the matching
// "{{<pos>|<lang>}}" template call in its place (skipped for section types with no POS_TEMPLATE entry).
// Other content under the heading is left untouched.
function convertManeToPos(pageContent, language, maneOrdinal, newSectionType) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
var loc = locateManeSection(pageContent, language, maneOrdinal);
var lines = loc.lines;
var m = /^(===[ ]*Mane)(\s+\d+)?([ ]*===)/.exec(lines[loc.maneLineIndex]);
lines[loc.maneLineIndex] = "=== " + newSectionType + (m[2] ? m[2] : "") + " ===";
var nextLineIndex = loc.maneLineIndex + 1;
if (nextLineIndex < lines.length && MANE_TAG_REGEX.test(lines[nextLineIndex])) {
lines.splice(nextLineIndex, 1);
}
var posTemplate = POS_TEMPLATE[newSectionType];
if (posTemplate) {
lines.splice(nextLineIndex, 0, "{{" + posTemplate + "|" + language + "}}");
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form uses, applying only the
// pieces the caller actually filled in. A piece that conflicts with the page (maneid already set, a
// subsection that's already there) is skipped with a warning rather than failing the whole save. Throws
// SubmitAbort if nothing was filled in, so this can never turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
function tryApply(fn) {
try {
content = fn();
appliedAnything = true;
} catch (e) {
if (e instanceof SubmitAbort) {
warnings.push(e.message);
} else {
throw e;
}
}
}
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
if (changes.maneid) {
tryApply(function () {
return insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", [changes.maneid], {
noExtend: true,
noExtendLabel: "nasnavek (maneid)"
});
});
}
if (changes.etiket && changes.etiket.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket);
appliedAnything = true;
}
if (changes.kategori && changes.kategori.length) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, words);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list: every word is its own always-visible row (word box + a "+" to attach one of the 10
// WORD_MODIFIERS as a small pill + an "x" to drop the row); a fresh empty row appears automatically once
// the current last row gets text. Duplicate words are allowed; every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into the current last row appends a fresh empty one after it, so there
// is always exactly one empty trailing row to type into.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.data("setRaw", function (raw) {
var parsed = splitWordValue(raw);
mods = parsed.mods;
$wordInput.val(parsed.word);
renderMods();
updateButtons();
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
// Replaces the whole list, keeping one empty trailing row to type into.
setValues: function (raws) {
$list.empty();
raws.forEach(function (raw) {
var $row = makeRow();
$list.append($row);
$row.data("setRaw")(raw);
});
$list.append(makeRow());
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, used for Etîket and Kategorî (simple value lists with no per-word modifiers).
// Enter or "," commits the current text as a tag; Backspace on an empty input removes the last tag;
// values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss and the two most-used word lists
// (Hevmane/Dijmane) sit directly in the picker row; the remaining word lists, maneid, etîket, kategorî
// and Nimûne/jêgirtin live behind a "Zêdetir" dropdown; one shared "Lê zêde bike" queues everything the
// user filled in as a single edit via applyAdvancedChanges() and queueChange(). Nimûne/jêgirtin is an
// immediate proxy-click into a different gadget's own form, not part of this combined save.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-open box (key -> () => value); collectChanges() only ever
// reads from a box the user actually clicked to add.
var getters = {};
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's wording; everything else here only ADDS) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
fetchCurrentGloss(language, sectionType, sectionOrdinal, definitionLevel).then(
function (gloss) {
originalGloss = gloss;
$textarea.val(gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: gloss + the two most-used word groups (SENSE_GROUPS.primary) sit directly in the
// row; everything else lives behind a "Zêdetir" dropdown. Clicking any link builds and appends its box
// to $openBoxes and hides that link; the box's own "×" removes it, clears its getter, and un-hides the
// link -- several boxes can be open at once. No "Beşek (====)" entry here: buildSubsectionPanel()'s
// own "+ Beşek lê zêde bike" trigger already covers page-level subsections. ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: !!group.primary };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
// Nimûne/jêgirtin sits first in the dropdown, ahead of every field-pick link.
$moreMenu.append($nimune);
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
});
// Lives inside $picker (not appended straight to $quickRow) so .dsb-more-menu's CSS can position it as
// an overlay anchored to $picker, instead of pushing $openBoxes/the rest of the page down when it opens.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle, $moreMenu);
// Closes the dropdown on an outside click, scoped to this panel's own $moreToggle/$moreMenu.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via queueChange(); the actual
// save happens when the user clicks "Guhertinan qeyd bike" on the floating queue box. ----
// Small "not saved yet" preview of everything this queued change will do, appended right under the
// sense's gloss (plain text, not a real render of {{hevmane}}/etc.).
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
});
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: getters.maneid ? getters.maneid() : "",
etiket: getters.etiket ? getters.etiket() : [],
kategori: getters.kategori ? getters.kategori() : [],
words: words
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Auto-linkify the gloss only when it's part of this save and has no manual link already.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above.
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
// The real InterlanguageLinks pencil icon (same asset defEditButton uses); image swap is in the CSS.
var $toggle = $("<a href='#' class='dsb-toggle' title='Guhartina pêşketî'></a>");
// Revealed by $toggle -- an indented panel under the sense, not always visible. Built lazily on
// first open rather than eagerly for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.prepend($toolbar);
// Touch has no :hover -- a tap anywhere on the line reveals the pencil the same way hovering does on
// desktop (CSS gates this to touch devices; harmless if it also fires on a mouse click).
$li.on("click.dsbReveal", function () {
$toolbar.addClass("dsb-revealed");
});
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a new "====" subsection preview belongs in the live DOM, using the same SUBSECTION_ORDER rank
// insertPageSubsection() uses. Returns {insertBefore: $el} (a ranked subsection that outranks this one) or
// {insertAfter: $el} (goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its canonical position. Plain text, not a real render of {{kol3|...}}/etc.
// Returns the inserted element so the caller can remove it again.
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4>, so existingSubsectionHeadersInDom() never mistakes this live-only
// preview for an actual subsection already on the page.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field. A subsection that isn't on the page yet is saved
// via insertPageSubsection(); one that already is gets prefilled and saved via updatePageSubsection().
// onlyHeader pins the panel to a single subsection (the per-heading pencil); omit it for the full picker.
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal, onlyHeader) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return !onlyHeader || s.header === onlyHeader;
}).map(function (s) {
return $.extend({}, s, { existing: existing.indexOf(s.header) !== -1 });
});
if (!available.length) {
$panel.text("Ji bo vê beşê guhartin tune.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.existing ? s.header + " (biguhêre)" : s.header));
});
if (onlyHeader) {
$select.hide();
}
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status);
$cancel.on("click", function () {
$panel.hide();
});
function currentSubsection() {
var id = $select.val();
return available.filter(function (s) {
return s.id === id;
})[0];
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
var editAsText = false; // set when an existing wordlist section turns out to be unparseable
function renderTextArea(s, rows) {
$fieldWrap.empty().append(
$("<textarea class='dsb-input dsb-subsection-text'></textarea>")
.attr("rows", rows)
.attr("placeholder", s.header + "…")
);
}
// Loads what the page already has into the form, so an edit starts from the current list rather than
// from an empty one. A wordlist section we can't parse degrades to raw wikitext editing.
function prefill(s) {
$status.removeClass("dsb-status-error dsb-status-ok").text("Tê xwendin…");
$save.prop("disabled", true);
fetchPageSubsection(language, sectionType, sectionOrdinal, s).then(function (current) {
$save.prop("disabled", false);
$status.text("");
if (!current) {
return;
}
if (current.kind === "wordlist" && wordField) {
wordField.setValues(current.words);
return;
}
if (s.kind === "wordlist") {
editAsText = true;
wordField = null;
renderTextArea(s, 6);
$status.text("Şablona vê lîsteyê nehate naskirin — wekî wikitext biguhêre.");
}
$fieldWrap.find(".dsb-subsection-text").val(current.text);
}, function () {
$save.prop("disabled", false);
$status.addClass("dsb-status-error").text("Nikarî muhtewaya heyî bixwîne.");
});
}
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
editAsText = false;
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
renderTextArea(s, 3);
}
$save.text(s.existing ? "Biguhêre" : "Lê zêde bike");
if (s.existing) {
prefill(s);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
var asText = editAsText || s.kind !== "wordlist";
var effective = asText ? $.extend({}, s, { kind: "text" }) : s;
var content;
if (asText) {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
} else {
content = wordField.values();
if (!content.length) {
return;
}
}
$save.prop("disabled", true);
queueChange(
(s.existing ? "~" : "+") + s.header + " (DefSideBoxes)",
function (pageContent) {
return {
content: s.existing
? updatePageSubsection(pageContent, language, sectionType, sectionOrdinal, effective, content)
: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, effective, content),
warnings: []
};
},
$save,
$status,
// Only a brand-new subsection gets a preview block; an edit would have to rewrite the rendered
// section in place, which this plain-text preview can't do faithfully.
s.existing ? null : function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that replaces an unclassified "=== Mane ===" placeholder
// heading, saved via convertManeToPos(). Lists every name from sectionNames.
function buildConvertPosPanel($panel, $h3, language, maneOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
$select.append($("<option></option>").val(name).text(name));
});
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertManeToPos(pageContent, language, maneOrdinal, chosen), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note under the heading, rather than rewriting the real heading
// text -- avoids leaving a heading showing a name that was never actually saved if the
// save fails partway through.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
}
);
});
$panel.empty().append($select, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
// Puts the same pencil the definitions use on every existing "====" subsection heading the gadget knows how
// to edit, opening buildSubsectionPanel() pinned to that one subsection.
function attachSubsectionEditors($h3, language, sectionType, sectionOrdinal) {
var editable = {};
PAGE_SUBSECTIONS.forEach(function (s) {
editable[s.header] = true;
});
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if (!$cursor.is(".mw-heading4, h4")) {
continue;
}
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var header = $hh.text().trim();
if (!editable[header] || $hh.data("dsbAttached")) {
continue;
}
$hh.data("dsbAttached", true);
attachSubsectionEditor($hh, $cursor, $h3, header, language, sectionType, sectionOrdinal);
}
}
function attachSubsectionEditor($hh, $heading, $h3, header, language, sectionType, sectionOrdinal) {
var $toolbar = $("<span class='dsb-toolbar dsb-toolbar-heading'></span>");
var $toggle = $("<a href='#' class='dsb-toggle'></a>").attr("title", header + " biguhêre");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$toolbar.append($toggle);
$hh.append($toolbar);
$heading.after($panel);
$toggle.on("click", function (e) {
e.preventDefault();
$toolbar.addClass("dsb-revealed");
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal, header);
$panel.data("built", true);
}
});
}
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger right under an unclassified "=== Mane ===" placeholder
// heading (see convertManeToPos()'s own comment for what that heading means).
function attachManeConvertTrigger($h3) {
if ($h3.data("dsbManeAttached")) {
return;
}
$h3.data("dsbManeAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var maneOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, maneOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (/^Mane(\s+\d+)?$/.test($h3.text().trim())) {
attachManeConvertTrigger($h3);
}
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
attachSubsectionEditors($h3, language, sectionType, sectionOrdinal);
});
}
// Closes every open panel/preview this gadget can leave in the DOM, so bfcache never freezes one mid-open.
function closeAllOpenUi() {
clearQueue();
$(".dsb-quick-row, .dsb-more-menu, .dsb-convert-pos-panel, .dsb-subsection-panel, .dsb-queue-box, .dsb-preview-inline, .dsb-preview-block").hide();
}
$(window).on("pagehide", closeAllOpenUi);
// Belt-and-suspenders: also close on restore-from-bfcache, in case pagehide's own hide didn't stick.
$(window).on("pageshow", function (e) {
if (e.originalEvent && e.originalEvent.persisted) {
closeAllOpenUi();
}
});
$(init);
// </nowiki>
})();
dp08q3ayodwo3kkl0kkmc6d5272ptxy
6347579
6347565
2026-09-01T10:30:29Z
Wikihez
7344
6347579
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary, writing start.js's own wikitext
// conventions ("#: {{hevmane|lang|...}}" per-sense lines, "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile). Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling: the "Nimûne/jêgirtin" menu item looks for the button Gadget-wikt.add-examples.js
// inserts on each definition, by its exact link text, so that gadget must run first.
// <nowiki>
(function () {
"use strict";
// Main namespace, namespace 108 (reconstructed-entry pages), or a user's own /ceribandin or /test subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// Template call convertManeToPos() drops under a newly-chosen POS heading, e.g. "Hoker" -> "{{hoker|ku}}".
// A "Formeke X" (form-of) heading uses the unchanged base pos template; "Biwêj" has no template at all.
var POS_TEMPLATE = {
"Navdêr": "navdêr",
"Formeke navdêrê": "navdêr",
"Lêker": "lêker",
"Formeke lêkerê": "lêker",
"Rengdêr": "rengdêr",
"Formeke rengdêrê": "rengdêr",
"Hoker": "hoker",
"Formeke hokerê": "hoker",
"Serenav": "serenav",
"Formeke serenavê": "serenav",
"Artîkel": "artîkel",
"Baneşan": "baneşan",
"Bazinedaçek": "bazinedaçek",
"Cînav": "cînav",
"Daçek": "daçek",
"Girêdek": "girêdek",
"Gotineke pêşiyan": "gotineke pêşiyan",
"Hejmar": "hejmar",
"Hevok": "hevok",
"Îfade": "îfade",
"Kurtenav": "kurtenav",
"Navgir": "navgir",
"Paşdaçek": "paşdaçek",
"Paşgir": "paşgir",
"Pêşdaçek": "pêşdaçek",
"Pêşgir": "pêşgir",
"Pirtik": "pirtik",
"Reh": "reh",
"Sembol": "sembol",
"Tîp": "tîp"
};
// The "needs a POS" maintenance tag under a placeholder "Mane" heading, and every known redirect/alias name
// it's also called under on real pages -- convertManeToPos() drops whichever one is actually present.
var MANE_TAG_REGEX = /^\{\{\s*(?:cure\?|rêziman\?|kat-rêziman|kategoriya\s+rêzimanê\?|bêcure)\s*(?:\|[^{}]*)?\}\}\s*$/i;
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Array order controls where a new group line lands relative to existing ones. "primary" groups get their
// own always-visible quick link on the definition; the rest live in this gadget's "More" menu.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane", primary: true },
{ key: "dijmane", label: "Dijmane", primary: true },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Only steps with a confirmed wikitext format are included; insertion rank comes from SUBSECTION_ORDER below.
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// Canonical ku.wiktionary "====" subsection order, used only as insertPageSubsection()'s insertion rank
// (see subsectionRankForHeader()). Wider than PAGE_SUBSECTIONS: it also covers subsections the gadget
// cannot create but still has to order around.
var SUBSECTION_ORDER = [
"Bilêvkirin",
"Ji wêjeya klasîk",
"Ji wêjeyê",
"Tewandin",
"Notên bikaranînê",
"Bi alfabeyên din",
"Formên alternatîv",
"Kurtkirin",
"Sembol",
"Navê zanistî",
"Hevmane",
"Nêzîk",
"Dijmane",
"Jornav",
"Jêrnav",
"Jê",
"Têkildar",
"Etîmolojî",
"Dûnde",
"Bide ber",
"Herwiha binêre",
"Bêhtir xwendin",
// Both spellings are in use on-wiki; PAGE_SUBSECTIONS creates this one, so it ranks in the same slot.
"Bêhtir bixwîne",
"Bi zaravayên din",
"Werger",
"Qafiye",
"Anagram",
// Creatable but absent from the canonical order; put last so it never displaces a ranked subsection.
"Çavkanî"
];
// {{kol}}, {{kol2}}, {{kol3}} and their col* spellings are the same column word-list template. New sections
// are written as kol3; any of the six is recognized when parsing an existing one.
var WORDLIST_TEMPLATES = ["kol3", "kol2", "kol", "col3", "col2", "col"];
// ---- word-modifier system (same widget start.js uses for Hevmane/Dijmane/etc. word lists) ----
// Every word in one of these lists can carry small "<key:value>" annotations (translation, gender, label,
// ...), which the {{hevmane}}/{{kol3}}/etc. templates parse back out of the raw positional param.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers into the raw "word<key:value>…" form {{hevmane}}/{{kol3}}/etc. read. */
// Inverse of joinWordValue(): peels the trailing "<key:value>" modifiers back off a raw list entry.
function splitWordValue(raw) {
var mods = [];
var word = raw;
var tail = /<([^<>:]+):([^<>]*)>\s*$/;
var m;
while ((m = tail.exec(word)) !== null) {
mods.unshift({ key: m[1], value: m[2] });
word = word.slice(0, m.index);
}
return { word: $.trim(word), mods: mods };
}
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers (document-order based, immune to mobile's per-section DOM wrapping and
// MediaWiki's page-wide heading-id collisions) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s*\d+$/, ""); // \s* not \s+: locateSection() also accepts "Navdêr2"
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || $(this).text().trim();
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback so one fetch covers both the
// edit-conflict check and the content, preventing a stale overwrite of someone else's edit.
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// This gadget's own save queue + floating widget, separate from the shared Gadget-Editor queue.
// Each entry keeps its own transformFn so saveQueueNow() can re-run all of them against one fresh fetch.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// "diff=prev" against the revision the save just created, i.e. exactly what this gadget changed. Built by
// hand rather than with mw.util.getUrl() so the gadget needs no extra module dependency.
function diffUrl(newrevid) {
return mw.config.get("wgScript") +
"?title=" + encodeURIComponent(mw.config.get("wgPageName")) +
"&diff=prev&oldid=" + encodeURIComponent(newrevid);
}
// The real save: re-runs every queued transformFn, in order, against one freshly-fetched revision and
// posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var combinedSummary = dsbQueue.entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
dsbQueue.entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function (data) {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status
.removeClass("dsb-status-error")
.addClass("dsb-status-ok")
.empty()
.append("✓ Hemû guhartin hatin qeydkirin — rûpel nû bike da ku bibînî. ");
// A null edit changes nothing, so there is no revision to diff against.
if (data && data.newrevid) {
box.$status.append(
"Ji bo dîtina guhartina xwe ",
$("<a class='dsb-diff-link'></a>")
.attr("href", diffUrl(data.newrevid))
.attr("target", "_blank")
.attr("rel", "noopener")
.text("binêre"),
"."
);
}
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()); nothing here touches the page yet. Also runs previewFn(), which drops a
// small "not saved yet" preview into the live DOM at the change's own spot on the page. Shared by every
// panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel, buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget ($.kuLinkify) and calls back with the linkified result.
// Passes the text through unchanged if the gadget can't be loaded, so it never blocks a save.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal, never by a DOM id number (MediaWiki's
// page-wide anchor uniquification can attach an id to a heading unrelated to its actual position).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the whole rest of the page from this language's heading onward, since the caller reuses
// it to rebuild the entire saved text; only the section-heading search itself is bounded by sectionSearchEndLine.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
// Closing "===" anchored, like locateManeSection(): otherwise "=== Navdêra pirjimar ===" counts as a POS occurrence here while sectionTypeOf() rejects it, desyncing the ordinal.
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?[ ]*===");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel: element 0 is
// unused (it's the "type|ordinal" string locateSection already resolved), remaining elements are 0-based
// indices, one per nesting level.
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's wordLine()
// format). If a line for this tplKey already exists under the definition, missing words are appended to
// it; otherwise a new line lands after the last existing group line, always before any "#*" citation lines.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
if (opts.replace) {
// Editing an existing list: an empty result means the user cleared it, so drop the line.
if (words.length) {
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}";
} else {
lines.splice(i, 1);
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's gloss text:
// maneid, then kategori (K), then etîket (e).
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker,
// stopping at the first thing that isn't one (normally the gloss text). Shared by insertLeadingSenseTpl()
// (uses "calls", as readSenseFields() also does). "rest" is the gloss text left after every leading call.
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts, extends, or (with opts.replace) overwrites one of the small templates that prefix a definition
// line's gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} or {{e|lang|etîket1|...}}. Under
// opts.replace an empty values list removes the call rather than writing an empty one.
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the whole leading-call run means an existing tplKey call is found and merged wherever it
// already sits, not just when it happens to be first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.replace) {
// Editing an existing call: an empty result means the user cleared it, so drop the call.
if (values.length) {
existing.params = [language].concat(values);
} else {
calls = calls.filter(function (c) { return c !== existing; });
}
} else {
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
}
} else if (!values.length) {
return pageContent; // nothing to add, and nothing there to clear
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call always outranks everything), or at the end of the run.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading template calls untouched --
// the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
// The box shows the raw line, templates included, so whatever the user left in it is what gets written.
lines[defLine] = marker + " " + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text to prefill the "Maneyê
// biguhêre" form. A plain read, not part of the hardened save path -- the actual save still re-fetches
// fresh content, so only the prefilled text itself could be a little stale.
// Current contents of one existing subsection, for prefilling the edit form.
function fetchPageSubsection(language, sectionType, sectionOrdinal, subsection) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
return readPageSubsection(content, language, sectionType, sectionOrdinal, subsection);
});
}
function fetchSenseFields(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
return readSenseFields(content, language, sectionType, sectionOrdinal, definitionLevel);
});
}
// Everything the advanced panel can edit about one sense, read off its definition line and the "#:" lines
// under it: the raw gloss (templates included), the leading maneid/K/e values, and each word-list group.
function readSenseFields(pageContent, language, sectionType, sectionOrdinal, definitionLevel) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var defMarker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(defMarker.length).replace(/^\s+/, "");
var leading = {};
splitLeadingCalls(afterMarker).calls.forEach(function (c) {
leading[c.key] = c.params.slice(1);
});
// Only start.js's "{{mane?|lang}}" placeholder is hidden; every other template stays visible so it can
// be edited by hand in the gloss box.
var gloss = afterMarker.replace(/^\{\{\s*mane\?\s*\|[^{}]*\}\}\s*/, "");
var marker = new Array(definitionLevel.length).join("#");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\s*\{\{\s*(" + groupKeysPattern + ")\s*\|([^}]*)\}\}\s*$");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var words = {};
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var m = groupLineRegex.exec(lines[i]);
if (m) {
words[m[1]] = m[2].split("|").slice(1);
}
}
return {
gloss: gloss,
maneid: leading.maneid ? leading.maneid[0] : "",
etiket: leading.e || [],
kategori: leading.K || [],
words: words
};
}
// Finds a POS block's body range (up to, but not including, the next heading of level <= 3), and the
// header text + line index of any "====" subsections it already contains.
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// Looks up a header's rank in SUBSECTION_ORDER. -1 for a header that isn't one of ours; such a header is
// never used as an insertion anchor.
function subsectionRankForHeader(header) {
return SUBSECTION_ORDER.indexOf(header);
}
// Body line range of one "====" subsection inside a POS block: everything after its heading up to the next
// "====" heading, or the end of the block. Null if the block has no such subsection.
function subsectionBodyRange(bounds, header) {
var headers = bounds.existingHeaders;
for (var i = 0; i < headers.length; i++) {
if (headers[i].header === header) {
return {
start: headers[i].lineIndex + 1,
end: i + 1 < headers.length ? headers[i + 1].lineIndex : bounds.end
};
}
}
return null;
}
// Splits a template call's inner text on its top-level "|", ignoring pipes nested in {{...}} or [[...]].
function splitTemplateParams(inner) {
var parts = [];
var buf = "";
var tpl = 0;
var link = 0;
for (var i = 0; i < inner.length; i++) {
var two = inner.substr(i, 2);
if (two === "{{" || two === "}}" || two === "[[" || two === "]]") {
if (two === "{{") { tpl++; } else if (two === "}}") { tpl--; } else if (two === "[[") { link++; } else { link--; }
buf += two;
i++;
continue;
}
if (inner.charAt(i) === "|" && tpl === 0 && link === 0) {
parts.push(buf);
buf = "";
continue;
}
buf += inner.charAt(i);
}
parts.push(buf);
return parts;
}
// Pulls a {{kol3|ku|cure=Jê|word|word}}-style call apart into the bits an edit has to preserve (template
// name, language, named params) plus the positional word list. Null if the body has no such call.
function parseWordListCall(text) {
var m = new RegExp("\{\{\s*(" + WORDLIST_TEMPLATES.join("|") + ")\s*[|}]", "i").exec(text);
if (!m) {
return null;
}
var open = m.index;
var depth = 0;
var close = -1;
for (var i = open; i < text.length - 1; i++) {
var two = text.substr(i, 2);
if (two === "{{") {
depth++;
i++;
} else if (two === "}}") {
depth--;
i++;
if (depth === 0) {
close = i + 1;
break;
}
}
}
if (close === -1) {
return null;
}
var parts = splitTemplateParams(text.slice(open + 2, close - 2));
var named = [];
var words = [];
for (var pi = 2; pi < parts.length; pi++) {
var val = $.trim(parts[pi]);
if (!val) {
continue;
}
if (/^[A-Za-z][A-Za-z0-9_-]*\s*=/.test(val)) {
named.push(val);
} else {
words.push(val);
}
}
return {
name: $.trim(parts[0]),
lang: parts.length > 1 ? $.trim(parts[1]) : "",
named: named,
words: words,
start: open,
end: close
};
}
// Canonical multi-line layout, matching how existing ku.wiktionary lists are written (one word per line).
function buildWordListCall(name, lang, named, words) {
var head = "{{" + name + "|" + lang;
named.forEach(function (n) {
head += "|" + n;
});
return words.length ? head + "\n|" + words.join("\n|") + "\n}}" : head + "\n}}";
}
// Current contents of an existing "====" subsection. A wordlist one whose template can't be parsed comes
// back as {kind: "text"} so the caller can still edit it as raw wikitext instead of refusing outright.
function readPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var bounds = posBlockBounds(loc.lines, loc.posLineIndex);
var range = subsectionBodyRange(bounds, subsection.header);
if (!range) {
return null;
}
var body = loc.lines.slice(range.start, range.end).join("\n");
if (subsection.kind === "wordlist") {
var call = parseWordListCall(body);
if (call) {
return { kind: "wordlist", words: call.words };
}
}
return { kind: "text", text: $.trim(body) };
}
// Rewrites an existing "====" subsection in place. A wordlist one keeps its own template name, language and
// named params ("cure=Jê", ...) and only has its positional words replaced; a text one is replaced whole.
function updatePageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var range = subsectionBodyRange(bounds, subsection.header);
if (!range) {
throw new SubmitAbort("Ev beş li vir tune: " + subsection.header);
}
var body = lines.slice(range.start, range.end).join("\n");
var replacement;
if (subsection.kind === "wordlist") {
var call = parseWordListCall(body);
if (!call) {
throw new SubmitAbort("Nikarî lîsteya vê beşê bixwîne: " + subsection.header);
}
// body.slice(call.end) already carries whatever trailed the call, blank separator line included.
replacement = body.slice(0, call.start) +
buildWordListCall(call.name, call.lang, call.named, content) +
body.slice(call.end);
} else {
// Replacing the body wholesale drops that separator, so put it back.
replacement = content + (/\n\s*$/.test(body) ? "\n" : "");
}
lines.splice(range.start, range.end - range.start, replacement);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Inserts a new "==== Header ====" subsection into its SUBSECTION_ORDER position within a POS block, right
// before the first ranked subsection that outranks it, or at the end if none does. Either a
// {{kol3|...}} word list or a plain paragraph, matching start.js's own subsection formats.
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var block;
if (subsection.kind === "wordlist") {
var params = "cure=" + subsection.header + "\n" + content.map(function (w) {
return "|" + w;
}).join("\n");
block = "\n==== " + subsection.header + " ====\n{{kol3|" + language + "|" + params + "\n}}\n";
} else {
block = "\n==== " + subsection.header + " ====\n" + content + "\n";
}
var myRank = subsectionRankForHeader(subsection.header);
var headers = bounds.existingHeaders;
var insertAt = bounds.end;
for (var i = 0; i < headers.length; i++) {
var otherRank = subsectionRankForHeader(headers[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = headers[i].lineIndex;
break;
}
}
lines.splice(insertAt, 0, block);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc.) instead of a real
// part-of-speech name, tagged right below with {{cure?|<lang>}} (ku.wiktionary's "part of speech not yet
// determined" maintenance flag). Neither is in sectionNames, so these two functions are a small parallel
// path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text
// (plus an optional disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading, drops the maintenance tag line right
// after it if present (MANE_TAG_REGEX -- cure? or any of its known aliases), and inserts the matching
// "{{<pos>|<lang>}}" template call in its place (skipped for section types with no POS_TEMPLATE entry).
// Other content under the heading is left untouched.
function convertManeToPos(pageContent, language, maneOrdinal, newSectionType) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
var loc = locateManeSection(pageContent, language, maneOrdinal);
var lines = loc.lines;
var m = /^(===[ ]*Mane)(\s+\d+)?([ ]*===)/.exec(lines[loc.maneLineIndex]);
lines[loc.maneLineIndex] = "=== " + newSectionType + (m[2] ? m[2] : "") + " ===";
var nextLineIndex = loc.maneLineIndex + 1;
if (nextLineIndex < lines.length && MANE_TAG_REGEX.test(lines[nextLineIndex])) {
lines.splice(nextLineIndex, 1);
}
var posTemplate = POS_TEMPLATE[newSectionType];
if (posTemplate) {
lines.splice(nextLineIndex, 0, "{{" + posTemplate + "|" + language + "}}");
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form uses, applying only the
// pieces the caller actually filled in. A piece that conflicts with the page (maneid already set, a
// subsection that's already there) is skipped with a warning rather than failing the whole save. Throws
// SubmitAbort if nothing was filled in, so this can never turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
// Every box below is prefilled with what the sense already has, so a save replaces that value rather
// than merging into it -- and clearing a box removes the template. changes.changed marks the boxes
// whose contents actually differ from the page, so an opened-but-untouched box writes nothing.
var replace = { replace: true };
if (changes.changed.maneid) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", changes.maneid ? [changes.maneid] : [], replace);
appliedAnything = true;
}
if (changes.changed.etiket) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket, replace);
appliedAnything = true;
}
if (changes.changed.kategori) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori, replace);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
if (changes.changed["word:" + group.key]) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, changes.words[group.key], replace);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list: every word is its own always-visible row (word box + a "+" to attach one of the 10
// WORD_MODIFIERS as a small pill + an "x" to drop the row); a fresh empty row appears automatically once
// the current last row gets text. Duplicate words are allowed; every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into the current last row appends a fresh empty one after it, so there
// is always exactly one empty trailing row to type into.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.data("setRaw", function (raw) {
var parsed = splitWordValue(raw);
mods = parsed.mods;
$wordInput.val(parsed.word);
renderMods();
updateButtons();
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
// Replaces the whole list, keeping one empty trailing row to type into.
setValues: function (raws) {
$list.empty();
raws.forEach(function (raw) {
var $row = makeRow();
$list.append($row);
$row.data("setRaw")(raw);
});
$list.append(makeRow());
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, used for Etîket and Kategorî (simple value lists with no per-word modifiers).
// Enter or "," commits the current text as a tag; Backspace on an empty input removes the last tag;
// values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
// Replaces every tag, for prefilling from what the sense already has.
setValues: function (vals) {
$element.children(".dsb-tag").remove();
vals.forEach(function (v) {
addTag(v);
});
$input.val("");
},
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss and the two most-used word lists
// (Hevmane/Dijmane) sit directly in the picker row; the remaining word lists, maneid, etîket, kategorî
// and Nimûne/jêgirtin live behind a "Zêdetir" dropdown; one shared "Lê zêde bike" queues everything the
// user filled in as a single edit via applyAdvancedChanges() and queueChange(). Nimûne/jêgirtin is an
// immediate proxy-click into a different gadget's own form, not part of this combined save.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-open box (key -> () => value); collectChanges() only ever
// reads from a box the user actually clicked to open.
var getters = {};
// What the sense currently holds, fetched once and shared by every box that prefills from it.
// collectChanges() also diffs against it, so an untouched box never queues a change.
var original = null;
var sensePromise = null;
function loadSense() {
if (!sensePromise) {
sensePromise = fetchSenseFields(language, sectionType, sectionOrdinal, definitionLevel).then(function (fields) {
original = fields;
return fields;
});
}
return sensePromise;
}
function sameList(a, b) {
return (a || []).join("\u0000") === (b || []).join("\u0000");
}
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's wording; everything else here only ADDS) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
loadSense().then(
function (fields) {
originalGloss = fields.gloss;
$textarea.val(fields.gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
loadSense().then(function (fields) {
var current = fields.words[group.key];
if (current && current.length) {
field.setValues(current);
}
});
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
loadSense().then(function (fields) {
$input.val(fields.maneid);
});
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
loadSense().then(function (fields) {
field.setValues(fields.etiket);
});
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
loadSense().then(function (fields) {
field.setValues(fields.kategori);
});
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: gloss + the two most-used word groups (SENSE_GROUPS.primary) sit directly in the
// row; everything else lives behind a "Zêdetir" dropdown. Clicking any link builds and appends its box
// to $openBoxes and hides that link; the box's own "×" removes it, clears its getter, and un-hides the
// link -- several boxes can be open at once. No "Beşek (====)" entry here: buildSubsectionPanel()'s
// own "+ Beşek lê zêde bike" trigger already covers page-level subsections. ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: !!group.primary };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
// Nimûne/jêgirtin sits first in the dropdown, ahead of every field-pick link.
$moreMenu.append($nimune);
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
});
// Lives inside $picker (not appended straight to $quickRow) so .dsb-more-menu's CSS can position it as
// an overlay anchored to $picker, instead of pushing $openBoxes/the rest of the page down when it opens.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle, $moreMenu);
// Closes the dropdown on an outside click, scoped to this panel's own $moreToggle/$moreMenu.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via queueChange(); the actual
// save happens when the user clicks "Guhertinan qeyd bike" on the floating queue box. ----
// Small "not saved yet" preview of everything this queued change will do, appended right under the
// sense's gloss (plain text, not a real render of {{hevmane}}/etc.).
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var base = original || { maneid: "", etiket: [], kategori: [], words: {} };
var changed = {};
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
if (getter && !sameList(words[group.key], base.words[group.key])) {
changed["word:" + group.key] = true;
}
});
var maneid = getters.maneid ? getters.maneid() : "";
var etiket = getters.etiket ? getters.etiket() : [];
var kategori = getters.kategori ? getters.kategori() : [];
if (getters.maneid && maneid !== (base.maneid || "")) {
changed.maneid = true;
}
if (getters.etiket && !sameList(etiket, base.etiket)) {
changed.etiket = true;
}
if (getters.kategori && !sameList(kategori, base.kategori)) {
changed.kategori = true;
}
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: maneid,
etiket: etiket,
kategori: kategori,
words: words,
changed: changed
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Auto-linkify the gloss only when it's part of this save and has no manual link already.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above.
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
// The real InterlanguageLinks pencil icon (same asset defEditButton uses); image swap is in the CSS.
var $toggle = $("<a href='#' class='dsb-toggle' title='Guhartina pêşketî'></a>");
// Revealed by $toggle -- an indented panel under the sense, not always visible. Built lazily on
// first open rather than eagerly for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.prepend($toolbar);
// Touch has no :hover -- a tap anywhere on the line reveals the pencil the same way hovering does on
// desktop (CSS gates this to touch devices; harmless if it also fires on a mouse click).
$li.on("click.dsbReveal", function () {
$toolbar.addClass("dsb-revealed");
});
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a new "====" subsection preview belongs in the live DOM, using the same SUBSECTION_ORDER rank
// insertPageSubsection() uses. Returns {insertBefore: $el} (a ranked subsection that outranks this one) or
// {insertAfter: $el} (goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its canonical position. Plain text, not a real render of {{kol3|...}}/etc.
// Returns the inserted element so the caller can remove it again.
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4>, so existingSubsectionHeadersInDom() never mistakes this live-only
// preview for an actual subsection already on the page.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field. A subsection that isn't on the page yet is saved
// via insertPageSubsection(); one that already is gets prefilled and saved via updatePageSubsection().
// onlyHeader pins the panel to a single subsection (the per-heading pencil); omit it for the full picker.
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal, onlyHeader) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return !onlyHeader || s.header === onlyHeader;
}).map(function (s) {
return $.extend({}, s, { existing: existing.indexOf(s.header) !== -1 });
});
if (!available.length) {
$panel.text("Ji bo vê beşê guhartin tune.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.existing ? s.header + " (biguhêre)" : s.header));
});
if (onlyHeader) {
$select.hide();
}
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status);
$cancel.on("click", function () {
$panel.hide();
});
function currentSubsection() {
var id = $select.val();
return available.filter(function (s) {
return s.id === id;
})[0];
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
var editAsText = false; // set when an existing wordlist section turns out to be unparseable
function renderTextArea(s, rows) {
$fieldWrap.empty().append(
$("<textarea class='dsb-input dsb-subsection-text'></textarea>")
.attr("rows", rows)
.attr("placeholder", s.header + "…")
);
}
// Loads what the page already has into the form, so an edit starts from the current list rather than
// from an empty one. A wordlist section we can't parse degrades to raw wikitext editing.
function prefill(s) {
$status.removeClass("dsb-status-error dsb-status-ok").text("Tê xwendin…");
$save.prop("disabled", true);
fetchPageSubsection(language, sectionType, sectionOrdinal, s).then(function (current) {
$save.prop("disabled", false);
$status.text("");
if (!current) {
return;
}
if (current.kind === "wordlist" && wordField) {
wordField.setValues(current.words);
return;
}
if (s.kind === "wordlist") {
editAsText = true;
wordField = null;
renderTextArea(s, 6);
$status.text("Şablona vê lîsteyê nehate naskirin — wekî wikitext biguhêre.");
}
$fieldWrap.find(".dsb-subsection-text").val(current.text);
}, function () {
$save.prop("disabled", false);
$status.addClass("dsb-status-error").text("Nikarî muhtewaya heyî bixwîne.");
});
}
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
editAsText = false;
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
renderTextArea(s, 3);
}
$save.text(s.existing ? "Biguhêre" : "Lê zêde bike");
if (s.existing) {
prefill(s);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
var asText = editAsText || s.kind !== "wordlist";
var effective = asText ? $.extend({}, s, { kind: "text" }) : s;
var content;
if (asText) {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
} else {
content = wordField.values();
if (!content.length) {
return;
}
}
$save.prop("disabled", true);
queueChange(
(s.existing ? "~" : "+") + s.header + " (DefSideBoxes)",
function (pageContent) {
return {
content: s.existing
? updatePageSubsection(pageContent, language, sectionType, sectionOrdinal, effective, content)
: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, effective, content),
warnings: []
};
},
$save,
$status,
// Only a brand-new subsection gets a preview block; an edit would have to rewrite the rendered
// section in place, which this plain-text preview can't do faithfully.
s.existing ? null : function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that replaces an unclassified "=== Mane ===" placeholder
// heading, saved via convertManeToPos(). Lists every name from sectionNames.
function buildConvertPosPanel($panel, $h3, language, maneOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
$select.append($("<option></option>").val(name).text(name));
});
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertManeToPos(pageContent, language, maneOrdinal, chosen), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note under the heading, rather than rewriting the real heading
// text -- avoids leaving a heading showing a name that was never actually saved if the
// save fails partway through.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
}
);
});
$panel.empty().append($select, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
// Puts the same pencil the definitions use on every existing "====" subsection heading the gadget knows how
// to edit, opening buildSubsectionPanel() pinned to that one subsection.
function attachSubsectionEditors($h3, language, sectionType, sectionOrdinal) {
var editable = {};
PAGE_SUBSECTIONS.forEach(function (s) {
editable[s.header] = true;
});
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if (!$cursor.is(".mw-heading4, h4")) {
continue;
}
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var header = $hh.text().trim();
if (!editable[header] || $hh.data("dsbAttached")) {
continue;
}
$hh.data("dsbAttached", true);
attachSubsectionEditor($hh, $cursor, $h3, header, language, sectionType, sectionOrdinal);
}
}
function attachSubsectionEditor($hh, $heading, $h3, header, language, sectionType, sectionOrdinal) {
var $toolbar = $("<span class='dsb-toolbar dsb-toolbar-heading'></span>");
var $toggle = $("<a href='#' class='dsb-toggle'></a>").attr("title", header + " biguhêre");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$toolbar.append($toggle);
$hh.append($toolbar);
$heading.after($panel);
$toggle.on("click", function (e) {
e.preventDefault();
$toolbar.addClass("dsb-revealed");
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal, header);
$panel.data("built", true);
}
});
}
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger right under an unclassified "=== Mane ===" placeholder
// heading (see convertManeToPos()'s own comment for what that heading means).
function attachManeConvertTrigger($h3) {
if ($h3.data("dsbManeAttached")) {
return;
}
$h3.data("dsbManeAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var maneOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, maneOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (/^Mane(\s+\d+)?$/.test($h3.text().trim())) {
attachManeConvertTrigger($h3);
}
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
attachSubsectionEditors($h3, language, sectionType, sectionOrdinal);
});
}
// Closes every open panel/preview this gadget can leave in the DOM, so bfcache never freezes one mid-open.
function closeAllOpenUi() {
clearQueue();
$(".dsb-quick-row, .dsb-more-menu, .dsb-convert-pos-panel, .dsb-subsection-panel, .dsb-queue-box, .dsb-preview-inline, .dsb-preview-block").hide();
}
$(window).on("pagehide", closeAllOpenUi);
// Belt-and-suspenders: also close on restore-from-bfcache, in case pagehide's own hide didn't stick.
$(window).on("pageshow", function (e) {
if (e.originalEvent && e.originalEvent.persisted) {
closeAllOpenUi();
}
});
$(init);
// </nowiki>
})();
5cmic2e9ij8ow0oobzgstyyn369udqz
6347582
6347579
2026-09-01T10:37:37Z
Wikihez
7344
6347582
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary, writing start.js's own wikitext
// conventions ("#: {{hevmane|lang|...}}" per-sense lines, "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile). Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling: the "Nimûne/jêgirtin" menu item looks for the button Gadget-wikt.add-examples.js
// inserts on each definition, by its exact link text, so that gadget must run first.
// <nowiki>
(function () {
"use strict";
// Main namespace, namespace 108 (reconstructed-entry pages), or a user's own /ceribandin or /test subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// Template call convertManeToPos() drops under a newly-chosen POS heading, e.g. "Hoker" -> "{{hoker|ku}}".
// A "Formeke X" (form-of) heading uses the unchanged base pos template; "Biwêj" has no template at all.
var POS_TEMPLATE = {
"Navdêr": "navdêr",
"Formeke navdêrê": "navdêr",
"Lêker": "lêker",
"Formeke lêkerê": "lêker",
"Rengdêr": "rengdêr",
"Formeke rengdêrê": "rengdêr",
"Hoker": "hoker",
"Formeke hokerê": "hoker",
"Serenav": "serenav",
"Formeke serenavê": "serenav",
"Artîkel": "artîkel",
"Baneşan": "baneşan",
"Bazinedaçek": "bazinedaçek",
"Cînav": "cînav",
"Daçek": "daçek",
"Girêdek": "girêdek",
"Gotineke pêşiyan": "gotineke pêşiyan",
"Hejmar": "hejmar",
"Hevok": "hevok",
"Îfade": "îfade",
"Kurtenav": "kurtenav",
"Navgir": "navgir",
"Paşdaçek": "paşdaçek",
"Paşgir": "paşgir",
"Pêşdaçek": "pêşdaçek",
"Pêşgir": "pêşgir",
"Pirtik": "pirtik",
"Reh": "reh",
"Sembol": "sembol",
"Tîp": "tîp"
};
// The "needs a POS" maintenance tag under a placeholder "Mane" heading, and every known redirect/alias name
// it's also called under on real pages -- convertManeToPos() drops whichever one is actually present.
var MANE_TAG_REGEX = /^\{\{\s*(?:cure\?|rêziman\?|kat-rêziman|kategoriya\s+rêzimanê\?|bêcure)\s*(?:\|[^{}]*)?\}\}\s*$/i;
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Array order controls where a new group line lands relative to existing ones. Every group lives behind the
// quick row's "Zêdetir" dropdown; only the gloss and Nimûne/jêgirtin links sit in the row itself.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane" },
{ key: "dijmane", label: "Dijmane" },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Only steps with a confirmed wikitext format are included; insertion rank comes from SUBSECTION_ORDER below.
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// Canonical ku.wiktionary "====" subsection order, used only as insertPageSubsection()'s insertion rank
// (see subsectionRankForHeader()). Wider than PAGE_SUBSECTIONS: it also covers subsections the gadget
// cannot create but still has to order around.
var SUBSECTION_ORDER = [
"Bilêvkirin",
"Ji wêjeya klasîk",
"Ji wêjeyê",
"Tewandin",
"Notên bikaranînê",
"Bi alfabeyên din",
"Formên alternatîv",
"Kurtkirin",
"Sembol",
"Navê zanistî",
"Hevmane",
"Nêzîk",
"Dijmane",
"Jornav",
"Jêrnav",
"Jê",
"Têkildar",
"Etîmolojî",
"Dûnde",
"Bide ber",
"Herwiha binêre",
"Bêhtir xwendin",
// Both spellings are in use on-wiki; PAGE_SUBSECTIONS creates this one, so it ranks in the same slot.
"Bêhtir bixwîne",
"Bi zaravayên din",
"Werger",
"Qafiye",
"Anagram",
// Creatable but absent from the canonical order; put last so it never displaces a ranked subsection.
"Çavkanî"
];
// {{kol}}, {{kol2}}, {{kol3}} and their col* spellings are the same column word-list template. New sections
// are written as kol3; any of the six is recognized when parsing an existing one.
var WORDLIST_TEMPLATES = ["kol3", "kol2", "kol", "col3", "col2", "col"];
// ---- word-modifier system (same widget start.js uses for Hevmane/Dijmane/etc. word lists) ----
// Every word in one of these lists can carry small "<key:value>" annotations (translation, gender, label,
// ...), which the {{hevmane}}/{{kol3}}/etc. templates parse back out of the raw positional param.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers into the raw "word<key:value>…" form {{hevmane}}/{{kol3}}/etc. read. */
// Inverse of joinWordValue(): peels the trailing "<key:value>" modifiers back off a raw list entry.
function splitWordValue(raw) {
var mods = [];
var word = raw;
var tail = /<([^<>:]+):([^<>]*)>\s*$/;
var m;
while ((m = tail.exec(word)) !== null) {
mods.unshift({ key: m[1], value: m[2] });
word = word.slice(0, m.index);
}
return { word: $.trim(word), mods: mods };
}
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers (document-order based, immune to mobile's per-section DOM wrapping and
// MediaWiki's page-wide heading-id collisions) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s*\d+$/, ""); // \s* not \s+: locateSection() also accepts "Navdêr2"
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || $(this).text().trim();
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback so one fetch covers both the
// edit-conflict check and the content, preventing a stale overwrite of someone else's edit.
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// This gadget's own save queue + floating widget, separate from the shared Gadget-Editor queue.
// Each entry keeps its own transformFn so saveQueueNow() can re-run all of them against one fresh fetch.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// "diff=prev" against the revision the save just created, i.e. exactly what this gadget changed. Built by
// hand rather than with mw.util.getUrl() so the gadget needs no extra module dependency.
function diffUrl(newrevid) {
return mw.config.get("wgScript") +
"?title=" + encodeURIComponent(mw.config.get("wgPageName")) +
"&diff=prev&oldid=" + encodeURIComponent(newrevid);
}
// The real save: re-runs every queued transformFn, in order, against one freshly-fetched revision and
// posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var combinedSummary = dsbQueue.entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
dsbQueue.entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function (data) {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status
.removeClass("dsb-status-error")
.addClass("dsb-status-ok")
.empty()
.append("✓ Hemû guhartin hatin qeydkirin — rûpel nû bike da ku bibînî. ");
// A null edit changes nothing, so there is no revision to diff against.
if (data && data.newrevid) {
box.$status.append(
"Ji bo dîtina guhartina xwe ",
$("<a class='dsb-diff-link'></a>")
.attr("href", diffUrl(data.newrevid))
.attr("target", "_blank")
.attr("rel", "noopener")
.text("binêre"),
"."
);
}
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()); nothing here touches the page yet. Also runs previewFn(), which drops a
// small "not saved yet" preview into the live DOM at the change's own spot on the page. Shared by every
// panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel, buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget ($.kuLinkify) and calls back with the linkified result.
// Passes the text through unchanged if the gadget can't be loaded, so it never blocks a save.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal, never by a DOM id number (MediaWiki's
// page-wide anchor uniquification can attach an id to a heading unrelated to its actual position).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the whole rest of the page from this language's heading onward, since the caller reuses
// it to rebuild the entire saved text; only the section-heading search itself is bounded by sectionSearchEndLine.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
// Closing "===" anchored, like locateManeSection(): otherwise "=== Navdêra pirjimar ===" counts as a POS occurrence here while sectionTypeOf() rejects it, desyncing the ordinal.
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?[ ]*===");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel: element 0 is
// unused (it's the "type|ordinal" string locateSection already resolved), remaining elements are 0-based
// indices, one per nesting level.
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's wordLine()
// format). If a line for this tplKey already exists under the definition, missing words are appended to
// it; otherwise a new line lands after the last existing group line, always before any "#*" citation lines.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
if (opts.replace) {
// Editing an existing list: an empty result means the user cleared it, so drop the line.
if (words.length) {
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}";
} else {
lines.splice(i, 1);
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's gloss text:
// maneid, then kategori (K), then etîket (e).
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker,
// stopping at the first thing that isn't one (normally the gloss text). Shared by insertLeadingSenseTpl()
// (uses "calls", as readSenseFields() also does). "rest" is the gloss text left after every leading call.
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts, extends, or (with opts.replace) overwrites one of the small templates that prefix a definition
// line's gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} or {{e|lang|etîket1|...}}. Under
// opts.replace an empty values list removes the call rather than writing an empty one.
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the whole leading-call run means an existing tplKey call is found and merged wherever it
// already sits, not just when it happens to be first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.replace) {
// Editing an existing call: an empty result means the user cleared it, so drop the call.
if (values.length) {
existing.params = [language].concat(values);
} else {
calls = calls.filter(function (c) { return c !== existing; });
}
} else {
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
}
} else if (!values.length) {
return pageContent; // nothing to add, and nothing there to clear
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call always outranks everything), or at the end of the run.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading template calls untouched --
// the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
// The box shows the raw line, templates included, so whatever the user left in it is what gets written.
lines[defLine] = marker + " " + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text to prefill the "Maneyê
// biguhêre" form. A plain read, not part of the hardened save path -- the actual save still re-fetches
// fresh content, so only the prefilled text itself could be a little stale.
// Current contents of one existing subsection, for prefilling the edit form.
function fetchPageSubsection(language, sectionType, sectionOrdinal, subsection) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
return readPageSubsection(content, language, sectionType, sectionOrdinal, subsection);
});
}
function fetchSenseFields(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
return readSenseFields(content, language, sectionType, sectionOrdinal, definitionLevel);
});
}
// Everything the advanced panel can edit about one sense, read off its definition line and the "#:" lines
// under it: the raw gloss (templates included), the leading maneid/K/e values, and each word-list group.
function readSenseFields(pageContent, language, sectionType, sectionOrdinal, definitionLevel) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var defMarker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(defMarker.length).replace(/^\s+/, "");
var leading = {};
splitLeadingCalls(afterMarker).calls.forEach(function (c) {
leading[c.key] = c.params.slice(1);
});
// Only start.js's "{{mane?|lang}}" placeholder is hidden; every other template stays visible so it can
// be edited by hand in the gloss box.
var gloss = afterMarker.replace(/^\{\{\s*mane\?\s*\|[^{}]*\}\}\s*/, "");
var marker = new Array(definitionLevel.length).join("#");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\s*\{\{\s*(" + groupKeysPattern + ")\s*\|([^}]*)\}\}\s*$");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var words = {};
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var m = groupLineRegex.exec(lines[i]);
if (m) {
words[m[1]] = m[2].split("|").slice(1);
}
}
return {
gloss: gloss,
maneid: leading.maneid ? leading.maneid[0] : "",
etiket: leading.e || [],
kategori: leading.K || [],
words: words
};
}
// Finds a POS block's body range (up to, but not including, the next heading of level <= 3), and the
// header text + line index of any "====" subsections it already contains.
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// Looks up a header's rank in SUBSECTION_ORDER. -1 for a header that isn't one of ours; such a header is
// never used as an insertion anchor.
function subsectionRankForHeader(header) {
return SUBSECTION_ORDER.indexOf(header);
}
// Body line range of one "====" subsection inside a POS block: everything after its heading up to the next
// "====" heading, or the end of the block. Null if the block has no such subsection.
function subsectionBodyRange(bounds, header) {
var headers = bounds.existingHeaders;
for (var i = 0; i < headers.length; i++) {
if (headers[i].header === header) {
return {
start: headers[i].lineIndex + 1,
end: i + 1 < headers.length ? headers[i + 1].lineIndex : bounds.end
};
}
}
return null;
}
// Splits a template call's inner text on its top-level "|", ignoring pipes nested in {{...}} or [[...]].
function splitTemplateParams(inner) {
var parts = [];
var buf = "";
var tpl = 0;
var link = 0;
for (var i = 0; i < inner.length; i++) {
var two = inner.substr(i, 2);
if (two === "{{" || two === "}}" || two === "[[" || two === "]]") {
if (two === "{{") { tpl++; } else if (two === "}}") { tpl--; } else if (two === "[[") { link++; } else { link--; }
buf += two;
i++;
continue;
}
if (inner.charAt(i) === "|" && tpl === 0 && link === 0) {
parts.push(buf);
buf = "";
continue;
}
buf += inner.charAt(i);
}
parts.push(buf);
return parts;
}
// Pulls a {{kol3|ku|cure=Jê|word|word}}-style call apart into the bits an edit has to preserve (template
// name, language, named params) plus the positional word list. Null if the body has no such call.
function parseWordListCall(text) {
var m = new RegExp("\{\{\s*(" + WORDLIST_TEMPLATES.join("|") + ")\s*[|}]", "i").exec(text);
if (!m) {
return null;
}
var open = m.index;
var depth = 0;
var close = -1;
for (var i = open; i < text.length - 1; i++) {
var two = text.substr(i, 2);
if (two === "{{") {
depth++;
i++;
} else if (two === "}}") {
depth--;
i++;
if (depth === 0) {
close = i + 1;
break;
}
}
}
if (close === -1) {
return null;
}
var parts = splitTemplateParams(text.slice(open + 2, close - 2));
var named = [];
var words = [];
for (var pi = 2; pi < parts.length; pi++) {
var val = $.trim(parts[pi]);
if (!val) {
continue;
}
if (/^[A-Za-z][A-Za-z0-9_-]*\s*=/.test(val)) {
named.push(val);
} else {
words.push(val);
}
}
return {
name: $.trim(parts[0]),
lang: parts.length > 1 ? $.trim(parts[1]) : "",
named: named,
words: words,
start: open,
end: close
};
}
// Canonical multi-line layout, matching how existing ku.wiktionary lists are written (one word per line).
function buildWordListCall(name, lang, named, words) {
var head = "{{" + name + "|" + lang;
named.forEach(function (n) {
head += "|" + n;
});
return words.length ? head + "\n|" + words.join("\n|") + "\n}}" : head + "\n}}";
}
// Current contents of an existing "====" subsection. A wordlist one whose template can't be parsed comes
// back as {kind: "text"} so the caller can still edit it as raw wikitext instead of refusing outright.
function readPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var bounds = posBlockBounds(loc.lines, loc.posLineIndex);
var range = subsectionBodyRange(bounds, subsection.header);
if (!range) {
return null;
}
var body = loc.lines.slice(range.start, range.end).join("\n");
if (subsection.kind === "wordlist") {
var call = parseWordListCall(body);
if (call) {
return { kind: "wordlist", words: call.words };
}
}
return { kind: "text", text: $.trim(body) };
}
// Rewrites an existing "====" subsection in place. A wordlist one keeps its own template name, language and
// named params ("cure=Jê", ...) and only has its positional words replaced; a text one is replaced whole.
function updatePageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var range = subsectionBodyRange(bounds, subsection.header);
if (!range) {
throw new SubmitAbort("Ev beş li vir tune: " + subsection.header);
}
var body = lines.slice(range.start, range.end).join("\n");
var replacement;
if (subsection.kind === "wordlist") {
var call = parseWordListCall(body);
if (!call) {
throw new SubmitAbort("Nikarî lîsteya vê beşê bixwîne: " + subsection.header);
}
// body.slice(call.end) already carries whatever trailed the call, blank separator line included.
replacement = body.slice(0, call.start) +
buildWordListCall(call.name, call.lang, call.named, content) +
body.slice(call.end);
} else {
// Replacing the body wholesale drops that separator, so put it back.
replacement = content + (/\n\s*$/.test(body) ? "\n" : "");
}
lines.splice(range.start, range.end - range.start, replacement);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Inserts a new "==== Header ====" subsection into its SUBSECTION_ORDER position within a POS block, right
// before the first ranked subsection that outranks it, or at the end if none does. Either a
// {{kol3|...}} word list or a plain paragraph, matching start.js's own subsection formats.
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var block;
if (subsection.kind === "wordlist") {
var params = "cure=" + subsection.header + "\n" + content.map(function (w) {
return "|" + w;
}).join("\n");
block = "\n==== " + subsection.header + " ====\n{{kol3|" + language + "|" + params + "\n}}\n";
} else {
block = "\n==== " + subsection.header + " ====\n" + content + "\n";
}
var myRank = subsectionRankForHeader(subsection.header);
var headers = bounds.existingHeaders;
var insertAt = bounds.end;
for (var i = 0; i < headers.length; i++) {
var otherRank = subsectionRankForHeader(headers[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = headers[i].lineIndex;
break;
}
}
lines.splice(insertAt, 0, block);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc.) instead of a real
// part-of-speech name, tagged right below with {{cure?|<lang>}} (ku.wiktionary's "part of speech not yet
// determined" maintenance flag). Neither is in sectionNames, so these two functions are a small parallel
// path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text
// (plus an optional disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading, drops the maintenance tag line right
// after it if present (MANE_TAG_REGEX -- cure? or any of its known aliases), and inserts the matching
// "{{<pos>|<lang>}}" template call in its place (skipped for section types with no POS_TEMPLATE entry).
// Other content under the heading is left untouched.
function convertManeToPos(pageContent, language, maneOrdinal, newSectionType) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
var loc = locateManeSection(pageContent, language, maneOrdinal);
var lines = loc.lines;
var m = /^(===[ ]*Mane)(\s+\d+)?([ ]*===)/.exec(lines[loc.maneLineIndex]);
lines[loc.maneLineIndex] = "=== " + newSectionType + (m[2] ? m[2] : "") + " ===";
var nextLineIndex = loc.maneLineIndex + 1;
if (nextLineIndex < lines.length && MANE_TAG_REGEX.test(lines[nextLineIndex])) {
lines.splice(nextLineIndex, 1);
}
var posTemplate = POS_TEMPLATE[newSectionType];
if (posTemplate) {
lines.splice(nextLineIndex, 0, "{{" + posTemplate + "|" + language + "}}");
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form uses, applying only the
// pieces the caller actually filled in. A piece that conflicts with the page (maneid already set, a
// subsection that's already there) is skipped with a warning rather than failing the whole save. Throws
// SubmitAbort if nothing was filled in, so this can never turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
// Every box below is prefilled with what the sense already has, so a save replaces that value rather
// than merging into it -- and clearing a box removes the template. changes.changed marks the boxes
// whose contents actually differ from the page, so an opened-but-untouched box writes nothing.
var replace = { replace: true };
if (changes.changed.maneid) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", changes.maneid ? [changes.maneid] : [], replace);
appliedAnything = true;
}
if (changes.changed.etiket) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket, replace);
appliedAnything = true;
}
if (changes.changed.kategori) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori, replace);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
if (changes.changed["word:" + group.key]) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, changes.words[group.key], replace);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list: every word is its own always-visible row (word box + a "+" to attach one of the 10
// WORD_MODIFIERS as a small pill + an "x" to drop the row); a fresh empty row appears automatically once
// the current last row gets text. Duplicate words are allowed; every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into the current last row appends a fresh empty one after it, so there
// is always exactly one empty trailing row to type into.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.data("setRaw", function (raw) {
var parsed = splitWordValue(raw);
mods = parsed.mods;
$wordInput.val(parsed.word);
renderMods();
updateButtons();
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
// Replaces the whole list, keeping one empty trailing row to type into.
setValues: function (raws) {
$list.empty();
raws.forEach(function (raw) {
var $row = makeRow();
$list.append($row);
$row.data("setRaw")(raw);
});
$list.append(makeRow());
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, used for Etîket and Kategorî (simple value lists with no per-word modifiers).
// Enter or "," commits the current text as a tag; Backspace on an empty input removes the last tag;
// values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
// Replaces every tag, for prefilling from what the sense already has.
setValues: function (vals) {
$element.children(".dsb-tag").remove();
vals.forEach(function (v) {
addTag(v);
});
$input.val("");
},
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss and the two most-used word lists
// (Hevmane/Dijmane) sit directly in the picker row; the remaining word lists, maneid, etîket, kategorî
// and Nimûne/jêgirtin live behind a "Zêdetir" dropdown; one shared "Lê zêde bike" queues everything the
// user filled in as a single edit via applyAdvancedChanges() and queueChange(). Nimûne/jêgirtin is an
// immediate proxy-click into a different gadget's own form, not part of this combined save.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
// Hidden by default (see .add-example-form-title in the CSS); the inline style beats that rule.
$btn.closest("li").show();
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-open box (key -> () => value); collectChanges() only ever
// reads from a box the user actually clicked to open.
var getters = {};
// What the sense currently holds, fetched once and shared by every box that prefills from it.
// collectChanges() also diffs against it, so an untouched box never queues a change.
var original = null;
var sensePromise = null;
function loadSense() {
if (!sensePromise) {
sensePromise = fetchSenseFields(language, sectionType, sectionOrdinal, definitionLevel).then(function (fields) {
original = fields;
return fields;
});
}
return sensePromise;
}
function sameList(a, b) {
return (a || []).join("\u0000") === (b || []).join("\u0000");
}
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's wording; everything else here only ADDS) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
loadSense().then(
function (fields) {
originalGloss = fields.gloss;
$textarea.val(fields.gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
loadSense().then(function (fields) {
var current = fields.words[group.key];
if (current && current.length) {
field.setValues(current);
}
});
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
loadSense().then(function (fields) {
$input.val(fields.maneid);
});
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
loadSense().then(function (fields) {
field.setValues(fields.etiket);
});
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
loadSense().then(function (fields) {
field.setValues(fields.kategori);
});
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: the gloss and Nimûne/jêgirtin links sit directly in the row; every word group and
// the rest live behind a "Zêdetir" dropdown. Clicking any link builds and appends its box
// to $openBoxes and hides that link; the box's own "×" removes it, clears its getter, and un-hides the
// link -- several boxes can be open at once. No "Beşek (====)" entry here: buildSubsectionPanel()'s
// own "+ Beşek lê zêde bike" trigger already covers page-level subsections. ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: false };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
if (def.key === "gloss") {
$picker.append($nimune); // directly after "Maneyê biguhêre"
}
});
// Lives inside $picker (not appended straight to $quickRow) so .dsb-more-menu's CSS can position it as
// an overlay anchored to $picker, instead of pushing $openBoxes/the rest of the page down when it opens.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle, $moreMenu);
// Closes the dropdown on an outside click, scoped to this panel's own $moreToggle/$moreMenu.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via queueChange(); the actual
// save happens when the user clicks "Guhertinan qeyd bike" on the floating queue box. ----
// Small "not saved yet" preview of everything this queued change will do, appended right under the
// sense's gloss (plain text, not a real render of {{hevmane}}/etc.).
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var base = original || { maneid: "", etiket: [], kategori: [], words: {} };
var changed = {};
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
if (getter && !sameList(words[group.key], base.words[group.key])) {
changed["word:" + group.key] = true;
}
});
var maneid = getters.maneid ? getters.maneid() : "";
var etiket = getters.etiket ? getters.etiket() : [];
var kategori = getters.kategori ? getters.kategori() : [];
if (getters.maneid && maneid !== (base.maneid || "")) {
changed.maneid = true;
}
if (getters.etiket && !sameList(etiket, base.etiket)) {
changed.etiket = true;
}
if (getters.kategori && !sameList(kategori, base.kategori)) {
changed.kategori = true;
}
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: maneid,
etiket: etiket,
kategori: kategori,
words: words,
changed: changed
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Auto-linkify the gloss only when it's part of this save and has no manual link already.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above.
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
// The real InterlanguageLinks pencil icon (same asset defEditButton uses); image swap is in the CSS.
var $toggle = $("<a href='#' class='dsb-toggle' title='Guhartina pêşketî'></a>");
// Revealed by $toggle -- an indented panel under the sense, not always visible. Built lazily on
// first open rather than eagerly for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.prepend($toolbar);
// Touch has no :hover -- a tap anywhere on the line reveals the pencil the same way hovering does on
// desktop (CSS gates this to touch devices; harmless if it also fires on a mouse click).
$li.on("click.dsbReveal", function () {
$toolbar.addClass("dsb-revealed");
});
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a new "====" subsection preview belongs in the live DOM, using the same SUBSECTION_ORDER rank
// insertPageSubsection() uses. Returns {insertBefore: $el} (a ranked subsection that outranks this one) or
// {insertAfter: $el} (goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its canonical position. Plain text, not a real render of {{kol3|...}}/etc.
// Returns the inserted element so the caller can remove it again.
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4>, so existingSubsectionHeadersInDom() never mistakes this live-only
// preview for an actual subsection already on the page.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field. A subsection that isn't on the page yet is saved
// via insertPageSubsection(); one that already is gets prefilled and saved via updatePageSubsection().
// onlyHeader pins the panel to a single subsection (the per-heading pencil); omit it for the full picker.
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal, onlyHeader) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return !onlyHeader || s.header === onlyHeader;
}).map(function (s) {
return $.extend({}, s, { existing: existing.indexOf(s.header) !== -1 });
});
if (!available.length) {
$panel.text("Ji bo vê beşê guhartin tune.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.existing ? s.header + " (biguhêre)" : s.header));
});
if (onlyHeader) {
$select.hide();
}
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status);
$cancel.on("click", function () {
$panel.hide();
});
function currentSubsection() {
var id = $select.val();
return available.filter(function (s) {
return s.id === id;
})[0];
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
var editAsText = false; // set when an existing wordlist section turns out to be unparseable
function renderTextArea(s, rows) {
$fieldWrap.empty().append(
$("<textarea class='dsb-input dsb-subsection-text'></textarea>")
.attr("rows", rows)
.attr("placeholder", s.header + "…")
);
}
// Loads what the page already has into the form, so an edit starts from the current list rather than
// from an empty one. A wordlist section we can't parse degrades to raw wikitext editing.
function prefill(s) {
$status.removeClass("dsb-status-error dsb-status-ok").text("Tê xwendin…");
$save.prop("disabled", true);
fetchPageSubsection(language, sectionType, sectionOrdinal, s).then(function (current) {
$save.prop("disabled", false);
$status.text("");
if (!current) {
return;
}
if (current.kind === "wordlist" && wordField) {
wordField.setValues(current.words);
return;
}
if (s.kind === "wordlist") {
editAsText = true;
wordField = null;
renderTextArea(s, 6);
$status.text("Şablona vê lîsteyê nehate naskirin — wekî wikitext biguhêre.");
}
$fieldWrap.find(".dsb-subsection-text").val(current.text);
}, function () {
$save.prop("disabled", false);
$status.addClass("dsb-status-error").text("Nikarî muhtewaya heyî bixwîne.");
});
}
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
editAsText = false;
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
renderTextArea(s, 3);
}
$save.text(s.existing ? "Biguhêre" : "Lê zêde bike");
if (s.existing) {
prefill(s);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
var asText = editAsText || s.kind !== "wordlist";
var effective = asText ? $.extend({}, s, { kind: "text" }) : s;
var content;
if (asText) {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
} else {
content = wordField.values();
if (!content.length) {
return;
}
}
$save.prop("disabled", true);
queueChange(
(s.existing ? "~" : "+") + s.header + " (DefSideBoxes)",
function (pageContent) {
return {
content: s.existing
? updatePageSubsection(pageContent, language, sectionType, sectionOrdinal, effective, content)
: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, effective, content),
warnings: []
};
},
$save,
$status,
// Only a brand-new subsection gets a preview block; an edit would have to rewrite the rendered
// section in place, which this plain-text preview can't do faithfully.
s.existing ? null : function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that replaces an unclassified "=== Mane ===" placeholder
// heading, saved via convertManeToPos(). Lists every name from sectionNames.
function buildConvertPosPanel($panel, $h3, language, maneOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
$select.append($("<option></option>").val(name).text(name));
});
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertManeToPos(pageContent, language, maneOrdinal, chosen), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note under the heading, rather than rewriting the real heading
// text -- avoids leaving a heading showing a name that was never actually saved if the
// save fails partway through.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
}
);
});
$panel.empty().append($select, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
// Puts the same pencil the definitions use on every existing "====" subsection heading the gadget knows how
// to edit, opening buildSubsectionPanel() pinned to that one subsection.
function attachSubsectionEditors($h3, language, sectionType, sectionOrdinal) {
var editable = {};
PAGE_SUBSECTIONS.forEach(function (s) {
editable[s.header] = true;
});
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if (!$cursor.is(".mw-heading4, h4")) {
continue;
}
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var header = $hh.text().trim();
if (!editable[header] || $hh.data("dsbAttached")) {
continue;
}
$hh.data("dsbAttached", true);
attachSubsectionEditor($hh, $cursor, $h3, header, language, sectionType, sectionOrdinal);
}
}
function attachSubsectionEditor($hh, $heading, $h3, header, language, sectionType, sectionOrdinal) {
var $toolbar = $("<span class='dsb-toolbar dsb-toolbar-heading'></span>");
var $toggle = $("<a href='#' class='dsb-toggle'></a>").attr("title", header + " biguhêre");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$toolbar.append($toggle);
$hh.append($toolbar);
$heading.after($panel);
$toggle.on("click", function (e) {
e.preventDefault();
$toolbar.addClass("dsb-revealed");
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal, header);
$panel.data("built", true);
}
});
}
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger right under an unclassified "=== Mane ===" placeholder
// heading (see convertManeToPos()'s own comment for what that heading means).
function attachManeConvertTrigger($h3) {
if ($h3.data("dsbManeAttached")) {
return;
}
$h3.data("dsbManeAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var maneOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, maneOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (/^Mane(\s+\d+)?$/.test($h3.text().trim())) {
attachManeConvertTrigger($h3);
}
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
attachSubsectionEditors($h3, language, sectionType, sectionOrdinal);
});
}
// Closes every open panel/preview this gadget can leave in the DOM, so bfcache never freezes one mid-open.
function closeAllOpenUi() {
clearQueue();
$(".dsb-quick-row, .dsb-more-menu, .dsb-convert-pos-panel, .dsb-subsection-panel, .dsb-queue-box, .dsb-preview-inline, .dsb-preview-block").hide();
}
$(window).on("pagehide", closeAllOpenUi);
// Belt-and-suspenders: also close on restore-from-bfcache, in case pagehide's own hide didn't stick.
$(window).on("pageshow", function (e) {
if (e.originalEvent && e.originalEvent.persisted) {
closeAllOpenUi();
}
});
$(init);
// </nowiki>
})();
mjqig1v9ocuzifkxrtk94x6a65omj73
6347591
6347582
2026-09-01T10:56:03Z
Wikihez
7344
6347591
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary, writing start.js's own wikitext
// conventions ("#: {{hevmane|lang|...}}" per-sense lines, "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile). Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling: the "Nimûne/jêgirtin" menu item looks for the button Gadget-wikt.add-examples.js
// inserts on each definition, by its exact link text, so that gadget must run first.
// <nowiki>
(function () {
"use strict";
// Main namespace, namespace 108 (reconstructed-entry pages), or a user's own /ceribandin or /test subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// Template call convertManeToPos() drops under a newly-chosen POS heading, e.g. "Hoker" -> "{{hoker|ku}}".
// A "Formeke X" (form-of) heading uses the unchanged base pos template; "Biwêj" has no template at all.
var POS_TEMPLATE = {
"Navdêr": "navdêr",
"Formeke navdêrê": "navdêr",
"Lêker": "lêker",
"Formeke lêkerê": "lêker",
"Rengdêr": "rengdêr",
"Formeke rengdêrê": "rengdêr",
"Hoker": "hoker",
"Formeke hokerê": "hoker",
"Serenav": "serenav",
"Formeke serenavê": "serenav",
"Artîkel": "artîkel",
"Baneşan": "baneşan",
"Bazinedaçek": "bazinedaçek",
"Cînav": "cînav",
"Daçek": "daçek",
"Girêdek": "girêdek",
"Gotineke pêşiyan": "gotineke pêşiyan",
"Hejmar": "hejmar",
"Hevok": "hevok",
"Îfade": "îfade",
"Kurtenav": "kurtenav",
"Navgir": "navgir",
"Paşdaçek": "paşdaçek",
"Paşgir": "paşgir",
"Pêşdaçek": "pêşdaçek",
"Pêşgir": "pêşgir",
"Pirtik": "pirtik",
"Reh": "reh",
"Sembol": "sembol",
"Tîp": "tîp"
};
// The "needs a POS" maintenance tag under a placeholder "Mane" heading, and every known redirect/alias name
// it's also called under on real pages -- convertManeToPos() drops whichever one is actually present.
var MANE_TAG_REGEX = /^\{\{\s*(?:cure\?|rêziman\?|kat-rêziman|kategoriya\s+rêzimanê\?|bêcure)\s*(?:\|[^{}]*)?\}\}\s*$/i;
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Array order controls where a new group line lands relative to existing ones. Every group lives behind the
// quick row's "Zêdetir" dropdown; only the gloss and Nimûne/jêgirtin links sit in the row itself.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane" },
{ key: "dijmane", label: "Dijmane" },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Only steps with a confirmed wikitext format are included; insertion rank comes from SUBSECTION_ORDER below.
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// Canonical ku.wiktionary "====" subsection order, used only as insertPageSubsection()'s insertion rank
// (see subsectionRankForHeader()). Wider than PAGE_SUBSECTIONS: it also covers subsections the gadget
// cannot create but still has to order around.
var SUBSECTION_ORDER = [
"Bilêvkirin",
"Ji wêjeya klasîk",
"Ji wêjeyê",
"Tewandin",
"Notên bikaranînê",
"Bi alfabeyên din",
"Formên alternatîv",
"Kurtkirin",
"Sembol",
"Navê zanistî",
"Hevmane",
"Nêzîk",
"Dijmane",
"Jornav",
"Jêrnav",
"Jê",
"Têkildar",
"Etîmolojî",
"Dûnde",
"Bide ber",
"Herwiha binêre",
"Bêhtir xwendin",
// Both spellings are in use on-wiki; PAGE_SUBSECTIONS creates this one, so it ranks in the same slot.
"Bêhtir bixwîne",
"Bi zaravayên din",
"Werger",
"Qafiye",
"Anagram",
// Creatable but absent from the canonical order; put last so it never displaces a ranked subsection.
"Çavkanî"
];
// {{kol}}, {{kol2}}, {{kol3}} and their col* spellings are the same column word-list template. New sections
// are written as kol3; any of the six is recognized when parsing an existing one.
var WORDLIST_TEMPLATES = ["kol3", "kol2", "kol", "col3", "col2", "col"];
// ---- word-modifier system (same widget start.js uses for Hevmane/Dijmane/etc. word lists) ----
// Every word in one of these lists can carry small "<key:value>" annotations (translation, gender, label,
// ...), which the {{hevmane}}/{{kol3}}/etc. templates parse back out of the raw positional param.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers into the raw "word<key:value>…" form {{hevmane}}/{{kol3}}/etc. read. */
// Inverse of joinWordValue(): peels the trailing "<key:value>" modifiers back off a raw list entry.
function splitWordValue(raw) {
var mods = [];
var word = raw;
var tail = /<([^<>:]+):([^<>]*)>\s*$/;
var m;
while ((m = tail.exec(word)) !== null) {
mods.unshift({ key: m[1], value: m[2] });
word = word.slice(0, m.index);
}
return { word: $.trim(word), mods: mods };
}
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers (document-order based, immune to mobile's per-section DOM wrapping and
// MediaWiki's page-wide heading-id collisions) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Pseudo section type for start.js's unclassified "=== Mane ===" / "=== Mane 2 ===" placeholder heading, so
// locateSection() (and everything built on it) can target one before a real POS has been chosen.
var MANE_SECTION = "Mane";
function isManeHeading($h) {
return /^Mane(\s+\d+)?$/.test($h.text().trim());
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s*\d+$/, ""); // \s* not \s+: locateSection() also accepts "Navdêr2"
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || (isManeHeading($(this)) ? MANE_SECTION : $(this).text().trim());
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback so one fetch covers both the
// edit-conflict check and the content, preventing a stale overwrite of someone else's edit.
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// This gadget's own save queue + floating widget, separate from the shared Gadget-Editor queue.
// Each entry keeps its own transformFn so saveQueueNow() can re-run all of them against one fresh fetch.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// "diff=prev" against the revision the save just created, i.e. exactly what this gadget changed. Built by
// hand rather than with mw.util.getUrl() so the gadget needs no extra module dependency.
function diffUrl(newrevid) {
return mw.config.get("wgScript") +
"?title=" + encodeURIComponent(mw.config.get("wgPageName")) +
"&diff=prev&oldid=" + encodeURIComponent(newrevid);
}
// Queue order, except that runLast entries move to the end: converting "=== Mane ===" into a real POS
// heading renames the very heading every other queued change locates itself by.
function orderedEntries() {
var normal = [];
var last = [];
dsbQueue.entries.forEach(function (entry) {
(entry.runLast ? last : normal).push(entry);
});
return normal.concat(last);
}
// The real save: re-runs every queued transformFn, in order, against one freshly-fetched revision and
// posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var entries = orderedEntries();
var combinedSummary = entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function (data) {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status
.removeClass("dsb-status-error")
.addClass("dsb-status-ok")
.empty()
.append("✓ Hemû guhartin hatin qeydkirin — rûpel nû bike da ku bibînî. ");
// A null edit changes nothing, so there is no revision to diff against.
if (data && data.newrevid) {
box.$status.append(
"Ji bo dîtina guhartina xwe ",
$("<a class='dsb-diff-link'></a>")
.attr("href", diffUrl(data.newrevid))
.attr("target", "_blank")
.attr("rel", "noopener")
.text("binêre"),
"."
);
}
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()); nothing here touches the page yet. Also runs previewFn(), which drops a
// small "not saved yet" preview into the live DOM at the change's own spot on the page. Shared by every
// panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel, buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn, opts) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn, runLast: !!(opts && opts.runLast) });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget ($.kuLinkify) and calls back with the linkified result.
// Passes the text through unchanged if the gadget can't be loaded, so it never blocks a save.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal, never by a DOM id number (MediaWiki's
// page-wide anchor uniquification can attach an id to a heading unrelated to its actual position).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
// The placeholder heading is matched by its own literal name, not by the POS list below.
if (sectionType === MANE_SECTION) {
var maneLoc = locateManeSection(pageContent, language, sectionOrdinal);
return {
langSectionIndex: maneLoc.langSectionIndex,
lines: maneLoc.lines,
posLineIndex: maneLoc.maneLineIndex
};
}
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the whole rest of the page from this language's heading onward, since the caller reuses
// it to rebuild the entire saved text; only the section-heading search itself is bounded by sectionSearchEndLine.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
// Closing "===" anchored, like locateManeSection(): otherwise "=== Navdêra pirjimar ===" counts as a POS occurrence here while sectionTypeOf() rejects it, desyncing the ordinal.
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?[ ]*===");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel: element 0 is
// unused (it's the "type|ordinal" string locateSection already resolved), remaining elements are 0-based
// indices, one per nesting level.
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's wordLine()
// format). If a line for this tplKey already exists under the definition, missing words are appended to
// it; otherwise a new line lands after the last existing group line, always before any "#*" citation lines.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
if (opts.replace) {
// Editing an existing list: an empty result means the user cleared it, so drop the line.
if (words.length) {
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}";
} else {
lines.splice(i, 1);
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's gloss text:
// maneid, then kategori (K), then etîket (e).
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker,
// stopping at the first thing that isn't one (normally the gloss text). Shared by insertLeadingSenseTpl()
// (uses "calls", as readSenseFields() also does). "rest" is the gloss text left after every leading call.
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts, extends, or (with opts.replace) overwrites one of the small templates that prefix a definition
// line's gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} or {{e|lang|etîket1|...}}. Under
// opts.replace an empty values list removes the call rather than writing an empty one.
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the whole leading-call run means an existing tplKey call is found and merged wherever it
// already sits, not just when it happens to be first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.replace) {
// Editing an existing call: an empty result means the user cleared it, so drop the call.
if (values.length) {
existing.params = [language].concat(values);
} else {
calls = calls.filter(function (c) { return c !== existing; });
}
} else {
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
}
} else if (!values.length) {
return pageContent; // nothing to add, and nothing there to clear
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call always outranks everything), or at the end of the run.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading template calls untouched --
// the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
// The box shows the raw line, templates included, so whatever the user left in it is what gets written.
lines[defLine] = marker + " " + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text to prefill the "Maneyê
// biguhêre" form. A plain read, not part of the hardened save path -- the actual save still re-fetches
// fresh content, so only the prefilled text itself could be a little stale.
// Current contents of one existing subsection, for prefilling the edit form.
function fetchPageSubsection(language, sectionType, sectionOrdinal, subsection) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
return readPageSubsection(content, language, sectionType, sectionOrdinal, subsection);
});
}
function fetchSenseFields(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
return readSenseFields(content, language, sectionType, sectionOrdinal, definitionLevel);
});
}
// Everything the advanced panel can edit about one sense, read off its definition line and the "#:" lines
// under it: the raw gloss (templates included), the leading maneid/K/e values, and each word-list group.
function readSenseFields(pageContent, language, sectionType, sectionOrdinal, definitionLevel) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var defMarker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(defMarker.length).replace(/^\s+/, "");
var leading = {};
splitLeadingCalls(afterMarker).calls.forEach(function (c) {
leading[c.key] = c.params.slice(1);
});
// Only start.js's "{{mane?|lang}}" placeholder is hidden; every other template stays visible so it can
// be edited by hand in the gloss box.
var gloss = afterMarker.replace(/^\{\{\s*mane\?\s*\|[^{}]*\}\}\s*/, "");
var marker = new Array(definitionLevel.length).join("#");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\s*\{\{\s*(" + groupKeysPattern + ")\s*\|([^}]*)\}\}\s*$");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var words = {};
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var m = groupLineRegex.exec(lines[i]);
if (m) {
words[m[1]] = m[2].split("|").slice(1);
}
}
return {
gloss: gloss,
maneid: leading.maneid ? leading.maneid[0] : "",
etiket: leading.e || [],
kategori: leading.K || [],
words: words
};
}
// Finds a POS block's body range (up to, but not including, the next heading of level <= 3), and the
// header text + line index of any "====" subsections it already contains.
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// Looks up a header's rank in SUBSECTION_ORDER. -1 for a header that isn't one of ours; such a header is
// never used as an insertion anchor.
function subsectionRankForHeader(header) {
return SUBSECTION_ORDER.indexOf(header);
}
// Body line range of one "====" subsection inside a POS block: everything after its heading up to the next
// "====" heading, or the end of the block. Null if the block has no such subsection.
function subsectionBodyRange(bounds, header) {
var headers = bounds.existingHeaders;
for (var i = 0; i < headers.length; i++) {
if (headers[i].header === header) {
return {
start: headers[i].lineIndex + 1,
end: i + 1 < headers.length ? headers[i + 1].lineIndex : bounds.end
};
}
}
return null;
}
// Splits a template call's inner text on its top-level "|", ignoring pipes nested in {{...}} or [[...]].
function splitTemplateParams(inner) {
var parts = [];
var buf = "";
var tpl = 0;
var link = 0;
for (var i = 0; i < inner.length; i++) {
var two = inner.substr(i, 2);
if (two === "{{" || two === "}}" || two === "[[" || two === "]]") {
if (two === "{{") { tpl++; } else if (two === "}}") { tpl--; } else if (two === "[[") { link++; } else { link--; }
buf += two;
i++;
continue;
}
if (inner.charAt(i) === "|" && tpl === 0 && link === 0) {
parts.push(buf);
buf = "";
continue;
}
buf += inner.charAt(i);
}
parts.push(buf);
return parts;
}
// Pulls a {{kol3|ku|cure=Jê|word|word}}-style call apart into the bits an edit has to preserve (template
// name, language, named params) plus the positional word list. Null if the body has no such call.
function parseWordListCall(text) {
var m = new RegExp("\{\{\s*(" + WORDLIST_TEMPLATES.join("|") + ")\s*[|}]", "i").exec(text);
if (!m) {
return null;
}
var open = m.index;
var depth = 0;
var close = -1;
for (var i = open; i < text.length - 1; i++) {
var two = text.substr(i, 2);
if (two === "{{") {
depth++;
i++;
} else if (two === "}}") {
depth--;
i++;
if (depth === 0) {
close = i + 1;
break;
}
}
}
if (close === -1) {
return null;
}
var parts = splitTemplateParams(text.slice(open + 2, close - 2));
var named = [];
var words = [];
for (var pi = 2; pi < parts.length; pi++) {
var val = $.trim(parts[pi]);
if (!val) {
continue;
}
if (/^[A-Za-z][A-Za-z0-9_-]*\s*=/.test(val)) {
named.push(val);
} else {
words.push(val);
}
}
return {
name: $.trim(parts[0]),
lang: parts.length > 1 ? $.trim(parts[1]) : "",
named: named,
words: words,
start: open,
end: close
};
}
// Canonical multi-line layout, matching how existing ku.wiktionary lists are written (one word per line).
function buildWordListCall(name, lang, named, words) {
var head = "{{" + name + "|" + lang;
named.forEach(function (n) {
head += "|" + n;
});
return words.length ? head + "\n|" + words.join("\n|") + "\n}}" : head + "\n}}";
}
// Current contents of an existing "====" subsection. A wordlist one whose template can't be parsed comes
// back as {kind: "text"} so the caller can still edit it as raw wikitext instead of refusing outright.
function readPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var bounds = posBlockBounds(loc.lines, loc.posLineIndex);
var range = subsectionBodyRange(bounds, subsection.header);
if (!range) {
return null;
}
var body = loc.lines.slice(range.start, range.end).join("\n");
if (subsection.kind === "wordlist") {
var call = parseWordListCall(body);
if (call) {
return { kind: "wordlist", words: call.words };
}
}
return { kind: "text", text: $.trim(body) };
}
// Rewrites an existing "====" subsection in place. A wordlist one keeps its own template name, language and
// named params ("cure=Jê", ...) and only has its positional words replaced; a text one is replaced whole.
function updatePageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var range = subsectionBodyRange(bounds, subsection.header);
if (!range) {
throw new SubmitAbort("Ev beş li vir tune: " + subsection.header);
}
var body = lines.slice(range.start, range.end).join("\n");
var replacement;
if (subsection.kind === "wordlist") {
var call = parseWordListCall(body);
if (!call) {
throw new SubmitAbort("Nikarî lîsteya vê beşê bixwîne: " + subsection.header);
}
// body.slice(call.end) already carries whatever trailed the call, blank separator line included.
replacement = body.slice(0, call.start) +
buildWordListCall(call.name, call.lang, call.named, content) +
body.slice(call.end);
} else {
// Replacing the body wholesale drops that separator, so put it back.
replacement = content + (/\n\s*$/.test(body) ? "\n" : "");
}
lines.splice(range.start, range.end - range.start, replacement);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Inserts a new "==== Header ====" subsection into its SUBSECTION_ORDER position within a POS block, right
// before the first ranked subsection that outranks it, or at the end if none does. Either a
// {{kol3|...}} word list or a plain paragraph, matching start.js's own subsection formats.
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var body = subsection.kind === "wordlist"
? buildWordListCall("kol3", language, ["cure=" + subsection.header], content)
: content;
var myRank = subsectionRankForHeader(subsection.header);
var headers = bounds.existingHeaders;
var insertAt = bounds.end;
for (var i = 0; i < headers.length; i++) {
var otherRank = subsectionRankForHeader(headers[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = headers[i].lineIndex;
break;
}
}
// Exactly one blank line on each side: the line before the insertion point is normally already blank
// (it separated the previous subsection from the next heading), so only add one where there isn't one.
var block = [];
if (insertAt > 0 && $.trim(lines[insertAt - 1]) !== "") {
block.push("");
}
block.push("==== " + subsection.header + " ====", body);
if (insertAt < lines.length) {
block.push("");
}
lines.splice.apply(lines, [insertAt, 0].concat(block));
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc.) instead of a real
// part-of-speech name, tagged right below with {{cure?|<lang>}} (ku.wiktionary's "part of speech not yet
// determined" maintenance flag). Neither is in sectionNames, so these two functions are a small parallel
// path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text
// (plus an optional disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading, drops the maintenance tag line right
// after it if present (MANE_TAG_REGEX -- cure? or any of its known aliases), and inserts the matching
// "{{<pos>|<lang>}}" template call in its place (skipped for section types with no POS_TEMPLATE entry).
// Other content under the heading is left untouched.
function convertManeToPos(pageContent, language, maneOrdinal, newSectionType) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
var loc = locateManeSection(pageContent, language, maneOrdinal);
var lines = loc.lines;
var m = /^(===[ ]*Mane)(\s+\d+)?([ ]*===)/.exec(lines[loc.maneLineIndex]);
lines[loc.maneLineIndex] = "=== " + newSectionType + (m[2] ? m[2] : "") + " ===";
var nextLineIndex = loc.maneLineIndex + 1;
if (nextLineIndex < lines.length && MANE_TAG_REGEX.test(lines[nextLineIndex])) {
lines.splice(nextLineIndex, 1);
}
var posTemplate = POS_TEMPLATE[newSectionType];
if (posTemplate) {
lines.splice(nextLineIndex, 0, "{{" + posTemplate + "|" + language + "}}");
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form uses, applying only the
// pieces the caller actually filled in. A piece that conflicts with the page (maneid already set, a
// subsection that's already there) is skipped with a warning rather than failing the whole save. Throws
// SubmitAbort if nothing was filled in, so this can never turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
// Every box below is prefilled with what the sense already has, so a save replaces that value rather
// than merging into it -- and clearing a box removes the template. changes.changed marks the boxes
// whose contents actually differ from the page, so an opened-but-untouched box writes nothing.
var replace = { replace: true };
if (changes.changed.maneid) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", changes.maneid ? [changes.maneid] : [], replace);
appliedAnything = true;
}
if (changes.changed.etiket) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket, replace);
appliedAnything = true;
}
if (changes.changed.kategori) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori, replace);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
if (changes.changed["word:" + group.key]) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, changes.words[group.key], replace);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list: every word is its own always-visible row (word box + a "+" to attach one of the 10
// WORD_MODIFIERS as a small pill + an "x" to drop the row); a fresh empty row appears automatically once
// the current last row gets text. Duplicate words are allowed; every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into the current last row appends a fresh empty one after it, so there
// is always exactly one empty trailing row to type into.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.data("setRaw", function (raw) {
var parsed = splitWordValue(raw);
mods = parsed.mods;
$wordInput.val(parsed.word);
renderMods();
updateButtons();
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
// Replaces the whole list, keeping one empty trailing row to type into.
setValues: function (raws) {
$list.empty();
raws.forEach(function (raw) {
var $row = makeRow();
$list.append($row);
$row.data("setRaw")(raw);
});
$list.append(makeRow());
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, used for Etîket and Kategorî (simple value lists with no per-word modifiers).
// Enter or "," commits the current text as a tag; Backspace on an empty input removes the last tag;
// values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
// Replaces every tag, for prefilling from what the sense already has.
setValues: function (vals) {
$element.children(".dsb-tag").remove();
vals.forEach(function (v) {
addTag(v);
});
$input.val("");
},
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss and the two most-used word lists
// (Hevmane/Dijmane) sit directly in the picker row; the remaining word lists, maneid, etîket, kategorî
// and Nimûne/jêgirtin live behind a "Zêdetir" dropdown; one shared "Lê zêde bike" queues everything the
// user filled in as a single edit via applyAdvancedChanges() and queueChange(). Nimûne/jêgirtin is an
// immediate proxy-click into a different gadget's own form, not part of this combined save.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
// Hidden by default (see .add-example-form-title in the CSS); the inline style beats that rule.
$btn.closest("li").show();
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-open box (key -> () => value); collectChanges() only ever
// reads from a box the user actually clicked to open.
var getters = {};
// What the sense currently holds, fetched once and shared by every box that prefills from it.
// collectChanges() also diffs against it, so an untouched box never queues a change.
var original = null;
var sensePromise = null;
function loadSense() {
if (!sensePromise) {
sensePromise = fetchSenseFields(language, sectionType, sectionOrdinal, definitionLevel).then(function (fields) {
original = fields;
return fields;
});
}
return sensePromise;
}
function sameList(a, b) {
return (a || []).join("\u0000") === (b || []).join("\u0000");
}
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's wording; everything else here only ADDS) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
loadSense().then(
function (fields) {
originalGloss = fields.gloss;
$textarea.val(fields.gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
loadSense().then(function (fields) {
var current = fields.words[group.key];
if (current && current.length) {
field.setValues(current);
}
});
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
loadSense().then(function (fields) {
$input.val(fields.maneid);
});
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
loadSense().then(function (fields) {
field.setValues(fields.etiket);
});
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
loadSense().then(function (fields) {
field.setValues(fields.kategori);
});
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: the gloss and Nimûne/jêgirtin links sit directly in the row; every word group and
// the rest live behind a "Zêdetir" dropdown. Clicking any link builds and appends its box
// to $openBoxes and hides that link; the box's own "×" removes it, clears its getter, and un-hides the
// link -- several boxes can be open at once. No "Beşek (====)" entry here: buildSubsectionPanel()'s
// own "+ Beşek lê zêde bike" trigger already covers page-level subsections. ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: false };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
if (def.key === "gloss") {
$picker.append($nimune); // directly after "Maneyê biguhêre"
}
});
// Lives inside $picker (not appended straight to $quickRow) so .dsb-more-menu's CSS can position it as
// an overlay anchored to $picker, instead of pushing $openBoxes/the rest of the page down when it opens.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle, $moreMenu);
// Closes the dropdown on an outside click, scoped to this panel's own $moreToggle/$moreMenu.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via queueChange(); the actual
// save happens when the user clicks "Guhertinan qeyd bike" on the floating queue box. ----
// Small "not saved yet" preview of everything this queued change will do, appended right under the
// sense's gloss (plain text, not a real render of {{hevmane}}/etc.).
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var base = original || { maneid: "", etiket: [], kategori: [], words: {} };
var changed = {};
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
if (getter && !sameList(words[group.key], base.words[group.key])) {
changed["word:" + group.key] = true;
}
});
var maneid = getters.maneid ? getters.maneid() : "";
var etiket = getters.etiket ? getters.etiket() : [];
var kategori = getters.kategori ? getters.kategori() : [];
if (getters.maneid && maneid !== (base.maneid || "")) {
changed.maneid = true;
}
if (getters.etiket && !sameList(etiket, base.etiket)) {
changed.etiket = true;
}
if (getters.kategori && !sameList(kategori, base.kategori)) {
changed.kategori = true;
}
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: maneid,
etiket: etiket,
kategori: kategori,
words: words,
changed: changed
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Auto-linkify the gloss only when it's part of this save and has no manual link already.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above.
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
// The real InterlanguageLinks pencil icon (same asset defEditButton uses); image swap is in the CSS.
var $toggle = $("<a href='#' class='dsb-toggle' title='Guhartina pêşketî'></a>");
// Revealed by $toggle -- an indented panel under the sense, not always visible. Built lazily on
// first open rather than eagerly for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.prepend($toolbar);
// Touch has no :hover -- a tap anywhere on the line reveals the pencil the same way hovering does on
// desktop (CSS gates this to touch devices; harmless if it also fires on a mouse click).
$li.on("click.dsbReveal", function () {
$toolbar.addClass("dsb-revealed");
});
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a new "====" subsection preview belongs in the live DOM, using the same SUBSECTION_ORDER rank
// insertPageSubsection() uses. Returns {insertBefore: $el} (a ranked subsection that outranks this one) or
// {insertAfter: $el} (goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its canonical position. Plain text, not a real render of {{kol3|...}}/etc.
// Returns the inserted element so the caller can remove it again.
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4>, so existingSubsectionHeadersInDom() never mistakes this live-only
// preview for an actual subsection already on the page.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field. A subsection that isn't on the page yet is saved
// via insertPageSubsection(); one that already is gets prefilled and saved via updatePageSubsection().
// onlyHeader pins the panel to a single subsection (the per-heading pencil); omit it for the full picker.
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal, onlyHeader) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return !onlyHeader || s.header === onlyHeader;
}).map(function (s) {
return $.extend({}, s, { existing: existing.indexOf(s.header) !== -1 });
});
if (!available.length) {
$panel.text("Ji bo vê beşê guhartin tune.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.existing ? s.header + " (biguhêre)" : s.header));
});
if (onlyHeader) {
$select.hide();
}
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status);
$cancel.on("click", function () {
$panel.hide();
});
function currentSubsection() {
var id = $select.val();
return available.filter(function (s) {
return s.id === id;
})[0];
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
var editAsText = false; // set when an existing wordlist section turns out to be unparseable
function renderTextArea(s, rows) {
$fieldWrap.empty().append(
$("<textarea class='dsb-input dsb-subsection-text'></textarea>")
.attr("rows", rows)
.attr("placeholder", s.header + "…")
);
}
// Loads what the page already has into the form, so an edit starts from the current list rather than
// from an empty one. A wordlist section we can't parse degrades to raw wikitext editing.
function prefill(s) {
$status.removeClass("dsb-status-error dsb-status-ok").text("Tê xwendin…");
$save.prop("disabled", true);
fetchPageSubsection(language, sectionType, sectionOrdinal, s).then(function (current) {
$save.prop("disabled", false);
$status.text("");
if (!current) {
return;
}
if (current.kind === "wordlist" && wordField) {
wordField.setValues(current.words);
return;
}
if (s.kind === "wordlist") {
editAsText = true;
wordField = null;
renderTextArea(s, 6);
$status.text("Şablona vê lîsteyê nehate naskirin — wekî wikitext biguhêre.");
}
$fieldWrap.find(".dsb-subsection-text").val(current.text);
}, function () {
$save.prop("disabled", false);
$status.addClass("dsb-status-error").text("Nikarî muhtewaya heyî bixwîne.");
});
}
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
editAsText = false;
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
renderTextArea(s, 3);
}
$save.text(s.existing ? "Biguhêre" : "Lê zêde bike");
if (s.existing) {
prefill(s);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
var asText = editAsText || s.kind !== "wordlist";
var effective = asText ? $.extend({}, s, { kind: "text" }) : s;
var content;
if (asText) {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
} else {
content = wordField.values();
if (!content.length) {
return;
}
}
$save.prop("disabled", true);
queueChange(
(s.existing ? "~" : "+") + s.header + " (DefSideBoxes)",
function (pageContent) {
return {
content: s.existing
? updatePageSubsection(pageContent, language, sectionType, sectionOrdinal, effective, content)
: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, effective, content),
warnings: []
};
},
$save,
$status,
// Only a brand-new subsection gets a preview block; an edit would have to rewrite the rendered
// section in place, which this plain-text preview can't do faithfully.
s.existing ? null : function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that replaces an unclassified "=== Mane ===" placeholder
// heading, saved via convertManeToPos(). Lists every name from sectionNames.
function buildConvertPosPanel($panel, $h3, language, maneOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
$select.append($("<option></option>").val(name).text(name));
});
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertManeToPos(pageContent, language, maneOrdinal, chosen), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note under the heading, rather than rewriting the real heading
// text -- avoids leaving a heading showing a name that was never actually saved if the
// save fails partway through.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
},
// Runs after every other queued change: it renames the "Mane" heading those changes locate
// themselves by, so anything edited on this section has to be applied first.
{ runLast: true }
);
});
$panel.empty().append($select, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
// Puts the same pencil the definitions use on every existing "====" subsection heading the gadget knows how
// to edit, opening buildSubsectionPanel() pinned to that one subsection.
function attachSubsectionEditors($h3, language, sectionType, sectionOrdinal) {
var editable = {};
PAGE_SUBSECTIONS.forEach(function (s) {
editable[s.header] = true;
});
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if (!$cursor.is(".mw-heading4, h4")) {
continue;
}
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var header = $hh.text().trim();
if (!editable[header] || $hh.data("dsbAttached")) {
continue;
}
$hh.data("dsbAttached", true);
attachSubsectionEditor($hh, $cursor, $h3, header, language, sectionType, sectionOrdinal);
}
}
function attachSubsectionEditor($hh, $heading, $h3, header, language, sectionType, sectionOrdinal) {
var $toolbar = $("<span class='dsb-toolbar dsb-toolbar-heading'></span>");
var $toggle = $("<a href='#' class='dsb-toggle'></a>").attr("title", header + " biguhêre");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$toolbar.append($toggle);
$hh.append($toolbar);
$heading.after($panel);
$toggle.on("click", function (e) {
e.preventDefault();
$toolbar.addClass("dsb-revealed");
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal, header);
$panel.data("built", true);
}
});
}
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger right under an unclassified "=== Mane ===" placeholder
// heading (see convertManeToPos()'s own comment for what that heading means).
function attachManeConvertTrigger($h3) {
if ($h3.data("dsbManeAttached")) {
return;
}
$h3.data("dsbManeAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var maneOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, maneOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (!isManeHeading($h3)) {
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
// An unclassified placeholder: offer the POS picker, then carry on and wire up the same
// per-sense pencils, so the POS choice and the sense edits can be queued and saved together.
attachManeConvertTrigger($h3);
sectionType = MANE_SECTION;
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
attachSubsectionEditors($h3, language, sectionType, sectionOrdinal);
});
}
// Closes every open panel/preview this gadget can leave in the DOM, so bfcache never freezes one mid-open.
function closeAllOpenUi() {
clearQueue();
$(".dsb-quick-row, .dsb-more-menu, .dsb-convert-pos-panel, .dsb-subsection-panel, .dsb-queue-box, .dsb-preview-inline, .dsb-preview-block").hide();
}
$(window).on("pagehide", closeAllOpenUi);
// Belt-and-suspenders: also close on restore-from-bfcache, in case pagehide's own hide didn't stick.
$(window).on("pageshow", function (e) {
if (e.originalEvent && e.originalEvent.persisted) {
closeAllOpenUi();
}
});
$(init);
// </nowiki>
})();
n3fna82wrvmd9bya89naeocs6mfbexy
6347592
6347591
2026-09-01T10:59:29Z
Wikihez
7344
6347592
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary, writing start.js's own wikitext
// conventions ("#: {{hevmane|lang|...}}" per-sense lines, "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile). Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling: the "Nimûne/jêgirtin" menu item looks for the button Gadget-wikt.add-examples.js
// inserts on each definition, by its exact link text, so that gadget must run first.
// <nowiki>
(function () {
"use strict";
// Main namespace, namespace 108 (reconstructed-entry pages), or a user's own /ceribandin or /test subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// Template call convertManeToPos() drops under a newly-chosen POS heading, e.g. "Hoker" -> "{{hoker|ku}}".
// A "Formeke X" (form-of) heading uses the unchanged base pos template; "Biwêj" has no template at all.
var POS_TEMPLATE = {
"Navdêr": "navdêr",
"Formeke navdêrê": "navdêr",
"Lêker": "lêker",
"Formeke lêkerê": "lêker",
"Rengdêr": "rengdêr",
"Formeke rengdêrê": "rengdêr",
"Hoker": "hoker",
"Formeke hokerê": "hoker",
"Serenav": "serenav",
"Formeke serenavê": "serenav",
"Artîkel": "artîkel",
"Baneşan": "baneşan",
"Bazinedaçek": "bazinedaçek",
"Cînav": "cînav",
"Daçek": "daçek",
"Girêdek": "girêdek",
"Gotineke pêşiyan": "gotineke pêşiyan",
"Hejmar": "hejmar",
"Hevok": "hevok",
"Îfade": "îfade",
"Kurtenav": "kurtenav",
"Navgir": "navgir",
"Paşdaçek": "paşdaçek",
"Paşgir": "paşgir",
"Pêşdaçek": "pêşdaçek",
"Pêşgir": "pêşgir",
"Pirtik": "pirtik",
"Reh": "reh",
"Sembol": "sembol",
"Tîp": "tîp"
};
// The "needs a POS" maintenance tag under a placeholder "Mane" heading, and every known redirect/alias name
// it's also called under on real pages -- convertManeToPos() drops whichever one is actually present.
var MANE_TAG_REGEX = /^\{\{\s*(?:cure\?|rêziman\?|kat-rêziman|kategoriya\s+rêzimanê\?|bêcure)\s*(?:\|[^{}]*)?\}\}\s*$/i;
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Array order controls where a new group line lands relative to existing ones. Every group lives behind the
// quick row's "Zêdetir" dropdown; only the gloss and Nimûne/jêgirtin links sit in the row itself.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane" },
{ key: "dijmane", label: "Dijmane" },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Only steps with a confirmed wikitext format are included; insertion rank comes from SUBSECTION_ORDER below.
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// Canonical ku.wiktionary "====" subsection order, used only as insertPageSubsection()'s insertion rank
// (see subsectionRankForHeader()). Wider than PAGE_SUBSECTIONS: it also covers subsections the gadget
// cannot create but still has to order around.
var SUBSECTION_ORDER = [
"Bilêvkirin",
"Ji wêjeya klasîk",
"Ji wêjeyê",
"Tewandin",
"Notên bikaranînê",
"Bi alfabeyên din",
"Formên alternatîv",
"Kurtkirin",
"Sembol",
"Navê zanistî",
"Hevmane",
"Nêzîk",
"Dijmane",
"Jornav",
"Jêrnav",
"Jê",
"Têkildar",
"Etîmolojî",
"Dûnde",
"Bide ber",
"Herwiha binêre",
"Bêhtir xwendin",
// Both spellings are in use on-wiki; PAGE_SUBSECTIONS creates this one, so it ranks in the same slot.
"Bêhtir bixwîne",
"Bi zaravayên din",
"Werger",
"Qafiye",
"Anagram",
// Creatable but absent from the canonical order; put last so it never displaces a ranked subsection.
"Çavkanî"
];
// {{kol}}, {{kol2}}, {{kol3}} and their col* spellings are the same column word-list template. New sections
// are written as kol3; any of the six is recognized when parsing an existing one.
var WORDLIST_TEMPLATES = ["kol3", "kol2", "kol", "col3", "col2", "col"];
// ---- word-modifier system (same widget start.js uses for Hevmane/Dijmane/etc. word lists) ----
// Every word in one of these lists can carry small "<key:value>" annotations (translation, gender, label,
// ...), which the {{hevmane}}/{{kol3}}/etc. templates parse back out of the raw positional param.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers into the raw "word<key:value>…" form {{hevmane}}/{{kol3}}/etc. read. */
// Inverse of joinWordValue(): peels the trailing "<key:value>" modifiers back off a raw list entry.
function splitWordValue(raw) {
var mods = [];
var word = raw;
var tail = /<([^<>:]+):([^<>]*)>\s*$/;
var m;
while ((m = tail.exec(word)) !== null) {
mods.unshift({ key: m[1], value: m[2] });
word = word.slice(0, m.index);
}
return { word: $.trim(word), mods: mods };
}
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers (document-order based, immune to mobile's per-section DOM wrapping and
// MediaWiki's page-wide heading-id collisions) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Pseudo section type for start.js's unclassified "=== Mane ===" / "=== Mane 2 ===" placeholder heading, so
// locateSection() (and everything built on it) can target one before a real POS has been chosen.
var MANE_SECTION = "Mane";
function isManeHeading($h) {
return /^Mane(\s+\d+)?$/.test($h.text().trim());
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s*\d+$/, ""); // \s* not \s+: locateSection() also accepts "Navdêr2"
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || (isManeHeading($(this)) ? MANE_SECTION : $(this).text().trim());
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback so one fetch covers both the
// edit-conflict check and the content, preventing a stale overwrite of someone else's edit.
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// This gadget's own save queue + floating widget, separate from the shared Gadget-Editor queue.
// Each entry keeps its own transformFn so saveQueueNow() can re-run all of them against one fresh fetch.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// "diff=prev" against the revision the save just created, i.e. exactly what this gadget changed. Built by
// hand rather than with mw.util.getUrl() so the gadget needs no extra module dependency.
function diffUrl(newrevid) {
return mw.config.get("wgScript") +
"?title=" + encodeURIComponent(mw.config.get("wgPageName")) +
"&diff=prev&oldid=" + encodeURIComponent(newrevid);
}
// Queue order, except that runLast entries move to the end: converting "=== Mane ===" into a real POS
// heading renames the very heading every other queued change locates itself by.
function orderedEntries() {
var normal = [];
var last = [];
dsbQueue.entries.forEach(function (entry) {
(entry.runLast ? last : normal).push(entry);
});
return normal.concat(last);
}
// The real save: re-runs every queued transformFn, in order, against one freshly-fetched revision and
// posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var entries = orderedEntries();
var combinedSummary = entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function (data) {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status
.removeClass("dsb-status-error")
.addClass("dsb-status-ok")
.empty()
.append("✓ Hemû guhartin hatin qeydkirin — rûpel nû bike da ku bibînî. ");
// A null edit changes nothing, so there is no revision to diff against.
if (data && data.newrevid) {
box.$status.append(
"Ji bo dîtina guhartina xwe ",
$("<a class='dsb-diff-link'></a>")
.attr("href", diffUrl(data.newrevid))
.attr("target", "_blank")
.attr("rel", "noopener")
.text("binêre"),
"."
);
}
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()); nothing here touches the page yet. Also runs previewFn(), which drops a
// small "not saved yet" preview into the live DOM at the change's own spot on the page. Shared by every
// panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel, buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn, opts) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn, runLast: !!(opts && opts.runLast) });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget ($.kuLinkify) and calls back with the linkified result.
// Passes the text through unchanged if the gadget can't be loaded, so it never blocks a save.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal, never by a DOM id number (MediaWiki's
// page-wide anchor uniquification can attach an id to a heading unrelated to its actual position).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
// The placeholder heading is matched by its own literal name, not by the POS list below.
if (sectionType === MANE_SECTION) {
var maneLoc = locateManeSection(pageContent, language, sectionOrdinal);
return {
langSectionIndex: maneLoc.langSectionIndex,
lines: maneLoc.lines,
posLineIndex: maneLoc.maneLineIndex
};
}
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the whole rest of the page from this language's heading onward, since the caller reuses
// it to rebuild the entire saved text; only the section-heading search itself is bounded by sectionSearchEndLine.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
// Closing "===" anchored, like locateManeSection(): otherwise "=== Navdêra pirjimar ===" counts as a POS occurrence here while sectionTypeOf() rejects it, desyncing the ordinal.
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?[ ]*===");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel: element 0 is
// unused (it's the "type|ordinal" string locateSection already resolved), remaining elements are 0-based
// indices, one per nesting level.
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's wordLine()
// format). If a line for this tplKey already exists under the definition, missing words are appended to
// it; otherwise a new line lands after the last existing group line, always before any "#*" citation lines.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
if (opts.replace) {
// Editing an existing list: an empty result means the user cleared it, so drop the line.
if (words.length) {
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}";
} else {
lines.splice(i, 1);
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's gloss text:
// maneid, then kategori (K), then etîket (e).
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker,
// stopping at the first thing that isn't one (normally the gloss text). Shared by insertLeadingSenseTpl()
// (uses "calls", as readSenseFields() also does). "rest" is the gloss text left after every leading call.
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts, extends, or (with opts.replace) overwrites one of the small templates that prefix a definition
// line's gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} or {{e|lang|etîket1|...}}. Under
// opts.replace an empty values list removes the call rather than writing an empty one.
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the whole leading-call run means an existing tplKey call is found and merged wherever it
// already sits, not just when it happens to be first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.replace) {
// Editing an existing call: an empty result means the user cleared it, so drop the call.
if (values.length) {
existing.params = [language].concat(values);
} else {
calls = calls.filter(function (c) { return c !== existing; });
}
} else {
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
}
} else if (!values.length) {
return pageContent; // nothing to add, and nothing there to clear
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call always outranks everything), or at the end of the run.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading template calls untouched --
// the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
// The box shows the raw line, templates included, so whatever the user left in it is what gets written.
lines[defLine] = marker + " " + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text to prefill the "Maneyê
// biguhêre" form. A plain read, not part of the hardened save path -- the actual save still re-fetches
// fresh content, so only the prefilled text itself could be a little stale.
// Current contents of one existing subsection, for prefilling the edit form.
function fetchPageSubsection(language, sectionType, sectionOrdinal, subsection) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
return readPageSubsection(content, language, sectionType, sectionOrdinal, subsection);
});
}
function fetchSenseFields(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
return readSenseFields(content, language, sectionType, sectionOrdinal, definitionLevel);
});
}
// Everything the advanced panel can edit about one sense, read off its definition line and the "#:" lines
// under it: the raw gloss (templates included), the leading maneid/K/e values, and each word-list group.
function readSenseFields(pageContent, language, sectionType, sectionOrdinal, definitionLevel) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var defMarker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(defMarker.length).replace(/^\s+/, "");
var leading = {};
splitLeadingCalls(afterMarker).calls.forEach(function (c) {
leading[c.key] = c.params.slice(1);
});
// Only start.js's "{{mane?|lang}}" placeholder is hidden; every other template stays visible so it can
// be edited by hand in the gloss box.
var gloss = afterMarker.replace(/^\{\{\s*mane\?\s*\|[^{}]*\}\}\s*/, "");
var marker = new Array(definitionLevel.length).join("#");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\s*\{\{\s*(" + groupKeysPattern + ")\s*\|([^}]*)\}\}\s*$");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var words = {};
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var m = groupLineRegex.exec(lines[i]);
if (m) {
words[m[1]] = m[2].split("|").slice(1);
}
}
return {
gloss: gloss,
maneid: leading.maneid ? leading.maneid[0] : "",
etiket: leading.e || [],
kategori: leading.K || [],
words: words
};
}
// Finds a POS block's body range (up to, but not including, the next heading of level <= 3), and the
// header text + line index of any "====" subsections it already contains.
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// Looks up a header's rank in SUBSECTION_ORDER. -1 for a header that isn't one of ours; such a header is
// never used as an insertion anchor.
function subsectionRankForHeader(header) {
return SUBSECTION_ORDER.indexOf(header);
}
// Body line range of one "====" subsection inside a POS block: everything after its heading up to the next
// "====" heading, or the end of the block. Null if the block has no such subsection.
function subsectionBodyRange(bounds, header) {
var headers = bounds.existingHeaders;
for (var i = 0; i < headers.length; i++) {
if (headers[i].header === header) {
return {
start: headers[i].lineIndex + 1,
end: i + 1 < headers.length ? headers[i + 1].lineIndex : bounds.end
};
}
}
return null;
}
// Splits a template call's inner text on its top-level "|", ignoring pipes nested in {{...}} or [[...]].
function splitTemplateParams(inner) {
var parts = [];
var buf = "";
var tpl = 0;
var link = 0;
for (var i = 0; i < inner.length; i++) {
var two = inner.substr(i, 2);
if (two === "{{" || two === "}}" || two === "[[" || two === "]]") {
if (two === "{{") { tpl++; } else if (two === "}}") { tpl--; } else if (two === "[[") { link++; } else { link--; }
buf += two;
i++;
continue;
}
if (inner.charAt(i) === "|" && tpl === 0 && link === 0) {
parts.push(buf);
buf = "";
continue;
}
buf += inner.charAt(i);
}
parts.push(buf);
return parts;
}
// Pulls a {{kol3|ku|cure=Jê|word|word}}-style call apart into the bits an edit has to preserve (template
// name, language, named params) plus the positional word list. Null if the body has no such call.
function parseWordListCall(text) {
var m = new RegExp("\{\{\s*(" + WORDLIST_TEMPLATES.join("|") + ")\s*[|}]", "i").exec(text);
if (!m) {
return null;
}
var open = m.index;
var depth = 0;
var close = -1;
for (var i = open; i < text.length - 1; i++) {
var two = text.substr(i, 2);
if (two === "{{") {
depth++;
i++;
} else if (two === "}}") {
depth--;
i++;
if (depth === 0) {
close = i + 1;
break;
}
}
}
if (close === -1) {
return null;
}
var parts = splitTemplateParams(text.slice(open + 2, close - 2));
var named = [];
var words = [];
for (var pi = 2; pi < parts.length; pi++) {
var val = $.trim(parts[pi]);
if (!val) {
continue;
}
if (/^[A-Za-z][A-Za-z0-9_-]*\s*=/.test(val)) {
named.push(val);
} else {
words.push(val);
}
}
return {
name: $.trim(parts[0]),
lang: parts.length > 1 ? $.trim(parts[1]) : "",
named: named,
words: words,
start: open,
end: close
};
}
// Canonical multi-line layout, matching how existing ku.wiktionary lists are written (one word per line).
function buildWordListCall(name, lang, named, words) {
var head = "{{" + name + "|" + lang;
named.forEach(function (n) {
head += "|" + n;
});
return words.length ? head + "\n|" + words.join("\n|") + "\n}}" : head + "\n}}";
}
// Current contents of an existing "====" subsection. A wordlist one whose template can't be parsed comes
// back as {kind: "text"} so the caller can still edit it as raw wikitext instead of refusing outright.
function readPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var bounds = posBlockBounds(loc.lines, loc.posLineIndex);
var range = subsectionBodyRange(bounds, subsection.header);
if (!range) {
return null;
}
var body = loc.lines.slice(range.start, range.end).join("\n");
if (subsection.kind === "wordlist") {
var call = parseWordListCall(body);
if (call) {
return { kind: "wordlist", words: call.words };
}
}
return { kind: "text", text: $.trim(body) };
}
// Rewrites an existing "====" subsection in place. A wordlist one keeps its own template name, language and
// named params ("cure=Jê", ...) and only has its positional words replaced; a text one is replaced whole.
function updatePageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var range = subsectionBodyRange(bounds, subsection.header);
if (!range) {
throw new SubmitAbort("Ev beş li vir tune: " + subsection.header);
}
var body = lines.slice(range.start, range.end).join("\n");
var replacement;
if (subsection.kind === "wordlist") {
var call = parseWordListCall(body);
if (!call) {
throw new SubmitAbort("Nikarî lîsteya vê beşê bixwîne: " + subsection.header);
}
// body.slice(call.end) already carries whatever trailed the call, blank separator line included.
replacement = body.slice(0, call.start) +
buildWordListCall(call.name, call.lang, call.named, content) +
body.slice(call.end);
} else {
// Replacing the body wholesale drops that separator, so put it back.
replacement = content + (/\n\s*$/.test(body) ? "\n" : "");
}
lines.splice(range.start, range.end - range.start, replacement);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Inserts a new "==== Header ====" subsection into its SUBSECTION_ORDER position within a POS block, right
// before the first ranked subsection that outranks it, or at the end if none does. Either a
// {{kol3|...}} word list or a plain paragraph, matching start.js's own subsection formats.
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var body = subsection.kind === "wordlist"
? buildWordListCall("kol3", language, ["cure=" + subsection.header], content)
: content;
var myRank = subsectionRankForHeader(subsection.header);
var headers = bounds.existingHeaders;
var insertAt = bounds.end;
for (var i = 0; i < headers.length; i++) {
var otherRank = subsectionRankForHeader(headers[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = headers[i].lineIndex;
break;
}
}
// Exactly one blank line on each side: the line before the insertion point is normally already blank
// (it separated the previous subsection from the next heading), so only add one where there isn't one.
var block = [];
if (insertAt > 0 && $.trim(lines[insertAt - 1]) !== "") {
block.push("");
}
block.push("==== " + subsection.header + " ====", body);
if (insertAt < lines.length) {
block.push("");
}
lines.splice.apply(lines, [insertAt, 0].concat(block));
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc.) instead of a real
// part-of-speech name, tagged right below with {{cure?|<lang>}} (ku.wiktionary's "part of speech not yet
// determined" maintenance flag). Neither is in sectionNames, so these two functions are a small parallel
// path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text
// (plus an optional disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading, drops the maintenance tag line right
// after it if present (MANE_TAG_REGEX -- cure? or any of its known aliases), and inserts the matching
// "{{<pos>|<lang>}}" template call in its place (skipped for section types with no POS_TEMPLATE entry).
// Other content under the heading is left untouched.
function convertManeToPos(pageContent, language, maneOrdinal, newSectionType) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
var loc = locateManeSection(pageContent, language, maneOrdinal);
var lines = loc.lines;
var m = /^(===[ ]*Mane)(\s+\d+)?([ ]*===)/.exec(lines[loc.maneLineIndex]);
lines[loc.maneLineIndex] = "=== " + newSectionType + (m[2] ? m[2] : "") + " ===";
var nextLineIndex = loc.maneLineIndex + 1;
if (nextLineIndex < lines.length && MANE_TAG_REGEX.test(lines[nextLineIndex])) {
lines.splice(nextLineIndex, 1);
}
var posTemplate = POS_TEMPLATE[newSectionType];
if (posTemplate) {
lines.splice(nextLineIndex, 0, "{{" + posTemplate + "|" + language + "}}");
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form uses, applying only the
// pieces the caller actually filled in. A piece that conflicts with the page (maneid already set, a
// subsection that's already there) is skipped with a warning rather than failing the whole save. Throws
// SubmitAbort if nothing was filled in, so this can never turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
// Every box below is prefilled with what the sense already has, so a save replaces that value rather
// than merging into it -- and clearing a box removes the template. changes.changed marks the boxes
// whose contents actually differ from the page, so an opened-but-untouched box writes nothing.
var replace = { replace: true };
if (changes.changed.maneid) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", changes.maneid ? [changes.maneid] : [], replace);
appliedAnything = true;
}
if (changes.changed.etiket) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket, replace);
appliedAnything = true;
}
if (changes.changed.kategori) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori, replace);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
if (changes.changed["word:" + group.key]) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, changes.words[group.key], replace);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list: every word is its own always-visible row (word box + a "+" to attach one of the 10
// WORD_MODIFIERS as a small pill + an "x" to drop the row); a fresh empty row appears automatically once
// the current last row gets text. Duplicate words are allowed; every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into the current last row appends a fresh empty one after it, so there
// is always exactly one empty trailing row to type into.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.data("setRaw", function (raw) {
var parsed = splitWordValue(raw);
mods = parsed.mods;
$wordInput.val(parsed.word);
renderMods();
updateButtons();
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
// Replaces the whole list, keeping one empty trailing row to type into.
setValues: function (raws) {
$list.empty();
raws.forEach(function (raw) {
var $row = makeRow();
$list.append($row);
$row.data("setRaw")(raw);
});
$list.append(makeRow());
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, used for Etîket and Kategorî (simple value lists with no per-word modifiers).
// Enter or "," commits the current text as a tag; Backspace on an empty input removes the last tag;
// values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
// Replaces every tag, for prefilling from what the sense already has.
setValues: function (vals) {
$element.children(".dsb-tag").remove();
vals.forEach(function (v) {
addTag(v);
});
$input.val("");
},
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss and the two most-used word lists
// (Hevmane/Dijmane) sit directly in the picker row; the remaining word lists, maneid, etîket, kategorî
// and Nimûne/jêgirtin live behind a "Zêdetir" dropdown; one shared "Lê zêde bike" queues everything the
// user filled in as a single edit via applyAdvancedChanges() and queueChange(). Nimûne/jêgirtin is an
// immediate proxy-click into a different gadget's own form, not part of this combined save.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
// Hidden by default (see .add-example-form-title in the CSS); the inline style beats that rule.
$btn.closest("li").show();
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-open box (key -> () => value); collectChanges() only ever
// reads from a box the user actually clicked to open.
var getters = {};
// What the sense currently holds, fetched once and shared by every box that prefills from it.
// collectChanges() also diffs against it, so an untouched box never queues a change.
var original = null;
var sensePromise = null;
function loadSense() {
if (!sensePromise) {
sensePromise = fetchSenseFields(language, sectionType, sectionOrdinal, definitionLevel).then(function (fields) {
original = fields;
return fields;
});
}
return sensePromise;
}
function sameList(a, b) {
return (a || []).join("\u0000") === (b || []).join("\u0000");
}
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's wording; everything else here only ADDS) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
loadSense().then(
function (fields) {
originalGloss = fields.gloss;
$textarea.val(fields.gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
loadSense().then(function (fields) {
var current = fields.words[group.key];
if (current && current.length) {
field.setValues(current);
}
});
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
loadSense().then(function (fields) {
$input.val(fields.maneid);
});
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
loadSense().then(function (fields) {
field.setValues(fields.etiket);
});
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
loadSense().then(function (fields) {
field.setValues(fields.kategori);
});
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: the gloss and Nimûne/jêgirtin links sit directly in the row; every word group and
// the rest live behind a "Zêdetir" dropdown. Clicking any link builds and appends its box
// to $openBoxes and hides that link; the box's own "×" removes it, clears its getter, and un-hides the
// link -- several boxes can be open at once. No "Beşek (====)" entry here: buildSubsectionPanel()'s
// own "+ Beşek lê zêde bike" trigger already covers page-level subsections. ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: false };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
if (def.key === "gloss") {
$picker.append($nimune); // directly after "Maneyê biguhêre"
}
});
// Lives inside $picker (not appended straight to $quickRow) so .dsb-more-menu's CSS can position it as
// an overlay anchored to $picker, instead of pushing $openBoxes/the rest of the page down when it opens.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle, $moreMenu);
// Closes the dropdown on an outside click, scoped to this panel's own $moreToggle/$moreMenu.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via queueChange(); the actual
// save happens when the user clicks "Guhertinan qeyd bike" on the floating queue box. ----
// Small "not saved yet" preview of everything this queued change will do, appended right under the
// sense's gloss (plain text, not a real render of {{hevmane}}/etc.).
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var base = original || { maneid: "", etiket: [], kategori: [], words: {} };
var changed = {};
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
if (getter && !sameList(words[group.key], base.words[group.key])) {
changed["word:" + group.key] = true;
}
});
var maneid = getters.maneid ? getters.maneid() : "";
var etiket = getters.etiket ? getters.etiket() : [];
var kategori = getters.kategori ? getters.kategori() : [];
if (getters.maneid && maneid !== (base.maneid || "")) {
changed.maneid = true;
}
if (getters.etiket && !sameList(etiket, base.etiket)) {
changed.etiket = true;
}
if (getters.kategori && !sameList(kategori, base.kategori)) {
changed.kategori = true;
}
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: maneid,
etiket: etiket,
kategori: kategori,
words: words,
changed: changed
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Auto-linkify the gloss only when it's part of this save and has no manual link already.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above.
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
// The real InterlanguageLinks pencil icon (same asset defEditButton uses); image swap is in the CSS.
var $toggle = $("<a href='#' class='dsb-toggle' title='Guhartina pêşketî'></a>");
// Revealed by $toggle -- an indented panel under the sense, not always visible. Built lazily on
// first open rather than eagerly for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.prepend($toolbar);
// Touch has no :hover -- a tap anywhere on the line reveals the pencil the same way hovering does on
// desktop (CSS gates this to touch devices; harmless if it also fires on a mouse click).
$li.on("click.dsbReveal", function () {
$toolbar.addClass("dsb-revealed");
});
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a new "====" subsection preview belongs in the live DOM, using the same SUBSECTION_ORDER rank
// insertPageSubsection() uses. Returns {insertBefore: $el} (a ranked subsection that outranks this one) or
// {insertAfter: $el} (goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its canonical position. Plain text, not a real render of {{kol3|...}}/etc.
// Returns the inserted element so the caller can remove it again.
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4>, so existingSubsectionHeadersInDom() never mistakes this live-only
// preview for an actual subsection already on the page.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field. A subsection that isn't on the page yet is saved
// via insertPageSubsection(); one that already is gets prefilled and saved via updatePageSubsection().
// onlyHeader pins the panel to a single subsection (the per-heading pencil); omit it for the full picker.
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal, onlyHeader) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return !onlyHeader || s.header === onlyHeader;
}).map(function (s) {
return $.extend({}, s, { existing: existing.indexOf(s.header) !== -1 });
});
if (!available.length) {
$panel.text("Ji bo vê beşê guhartin tune.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
if (!onlyHeader) {
$select.append($("<option value=''></option>").text("Binebeşek hilbijêre"));
}
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.existing ? s.header + " (biguhêre)" : s.header));
});
if (onlyHeader) {
$select.hide();
}
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status);
$cancel.on("click", function () {
$panel.hide();
});
// Undefined while the placeholder option is selected.
function currentSubsection() {
var id = $select.val();
return id ? available.filter(function (s) {
return s.id === id;
})[0] : undefined;
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
var editAsText = false; // set when an existing wordlist section turns out to be unparseable
function renderTextArea(s, rows) {
$fieldWrap.empty().append(
$("<textarea class='dsb-input dsb-subsection-text'></textarea>")
.attr("rows", rows)
.attr("placeholder", s.header + "…")
);
}
// Loads what the page already has into the form, so an edit starts from the current list rather than
// from an empty one. A wordlist section we can't parse degrades to raw wikitext editing.
function prefill(s) {
$status.removeClass("dsb-status-error dsb-status-ok").text("Tê xwendin…");
$save.prop("disabled", true);
fetchPageSubsection(language, sectionType, sectionOrdinal, s).then(function (current) {
$save.prop("disabled", false);
$status.text("");
if (!current) {
return;
}
if (current.kind === "wordlist" && wordField) {
wordField.setValues(current.words);
return;
}
if (s.kind === "wordlist") {
editAsText = true;
wordField = null;
renderTextArea(s, 6);
$status.text("Şablona vê lîsteyê nehate naskirin — wekî wikitext biguhêre.");
}
$fieldWrap.find(".dsb-subsection-text").val(current.text);
}, function () {
$save.prop("disabled", false);
$status.addClass("dsb-status-error").text("Nikarî muhtewaya heyî bixwîne.");
});
}
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
editAsText = false;
$status.removeClass("dsb-status-error dsb-status-ok").text("");
// Save stays disabled (but "Betal bike" usable) until something is actually chosen.
$save.prop("disabled", !s);
if (!s) {
$save.text("Lê zêde bike");
return; // still on "Binebeşek hilbijêre"
}
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
renderTextArea(s, 3);
}
$save.text(s.existing ? "Biguhêre" : "Lê zêde bike");
if (s.existing) {
prefill(s);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
if (!s) {
return;
}
var asText = editAsText || s.kind !== "wordlist";
var effective = asText ? $.extend({}, s, { kind: "text" }) : s;
var content;
if (asText) {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
} else {
content = wordField.values();
if (!content.length) {
return;
}
}
$save.prop("disabled", true);
queueChange(
(s.existing ? "~" : "+") + s.header + " (DefSideBoxes)",
function (pageContent) {
return {
content: s.existing
? updatePageSubsection(pageContent, language, sectionType, sectionOrdinal, effective, content)
: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, effective, content),
warnings: []
};
},
$save,
$status,
// Only a brand-new subsection gets a preview block; an edit would have to rewrite the rendered
// section in place, which this plain-text preview can't do faithfully.
s.existing ? null : function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that replaces an unclassified "=== Mane ===" placeholder
// heading, saved via convertManeToPos(). Lists every name from sectionNames.
function buildConvertPosPanel($panel, $h3, language, maneOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
$select.append($("<option></option>").val(name).text(name));
});
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertManeToPos(pageContent, language, maneOrdinal, chosen), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note under the heading, rather than rewriting the real heading
// text -- avoids leaving a heading showing a name that was never actually saved if the
// save fails partway through.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
},
// Runs after every other queued change: it renames the "Mane" heading those changes locate
// themselves by, so anything edited on this section has to be applied first.
{ runLast: true }
);
});
$panel.empty().append($select, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
// Puts the same pencil the definitions use on every existing "====" subsection heading the gadget knows how
// to edit, opening buildSubsectionPanel() pinned to that one subsection.
function attachSubsectionEditors($h3, language, sectionType, sectionOrdinal) {
var editable = {};
PAGE_SUBSECTIONS.forEach(function (s) {
editable[s.header] = true;
});
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if (!$cursor.is(".mw-heading4, h4")) {
continue;
}
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var header = $hh.text().trim();
if (!editable[header] || $hh.data("dsbAttached")) {
continue;
}
$hh.data("dsbAttached", true);
attachSubsectionEditor($hh, $cursor, $h3, header, language, sectionType, sectionOrdinal);
}
}
function attachSubsectionEditor($hh, $heading, $h3, header, language, sectionType, sectionOrdinal) {
var $toolbar = $("<span class='dsb-toolbar dsb-toolbar-heading'></span>");
var $toggle = $("<a href='#' class='dsb-toggle'></a>").attr("title", header + " biguhêre");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$toolbar.append($toggle);
$hh.append($toolbar);
$heading.after($panel);
$toggle.on("click", function (e) {
e.preventDefault();
$toolbar.addClass("dsb-revealed");
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal, header);
$panel.data("built", true);
}
});
}
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger right under an unclassified "=== Mane ===" placeholder
// heading (see convertManeToPos()'s own comment for what that heading means).
function attachManeConvertTrigger($h3) {
if ($h3.data("dsbManeAttached")) {
return;
}
$h3.data("dsbManeAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var maneOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, maneOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (!isManeHeading($h3)) {
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
// An unclassified placeholder: offer the POS picker, then carry on and wire up the same
// per-sense pencils, so the POS choice and the sense edits can be queued and saved together.
attachManeConvertTrigger($h3);
sectionType = MANE_SECTION;
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
attachSubsectionEditors($h3, language, sectionType, sectionOrdinal);
});
}
// Closes every open panel/preview this gadget can leave in the DOM, so bfcache never freezes one mid-open.
function closeAllOpenUi() {
clearQueue();
$(".dsb-quick-row, .dsb-more-menu, .dsb-convert-pos-panel, .dsb-subsection-panel, .dsb-queue-box, .dsb-preview-inline, .dsb-preview-block").hide();
}
$(window).on("pagehide", closeAllOpenUi);
// Belt-and-suspenders: also close on restore-from-bfcache, in case pagehide's own hide didn't stick.
$(window).on("pageshow", function (e) {
if (e.originalEvent && e.originalEvent.persisted) {
closeAllOpenUi();
}
});
$(init);
// </nowiki>
})();
ekj626tmjqrq23b1e8j9ctu88u5ogms
6347610
6347592
2026-09-01T11:24:33Z
Wikihez
7344
6347610
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary, writing start.js's own wikitext
// conventions ("#: {{hevmane|lang|...}}" per-sense lines, "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile). Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling: the "Nimûne/jêgirtin" menu item looks for the button Gadget-wikt.add-examples.js
// inserts on each definition, by its exact link text, so that gadget must run first.
// <nowiki>
(function () {
"use strict";
// Main namespace, namespace 108 (reconstructed-entry pages), or a user's own /ceribandin or /test subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// Reduced port of start.js's POS step: the two questions its posparams card asks that feed the template's
// "c=" parameter. Gender codes are metadata.ku.g from start.js's data.json, minus the number codes it
// filters out via isNumberCode(), with genderLabel()'s rendering baked in. Kurmancî only -- every other
// language has its own code set in data.json, which this gadget cannot read.
var KU_GENDER_CHOICES = [
{ code: "n", label: "nêr" },
{ code: "m", label: "mê" },
{ code: "mnmane", label: "mê yan nêr li gorî maneyê" },
{ code: "mndudil", label: "mê yan nêr bikaranîn dudil e" },
{ code: "n-p", label: "nêr (pirjimar)" },
{ code: "m-p", label: "mê (pirjimar)" }
];
// start.js asks transitivity and structural form as two questions and joins them as "<form>-<base>", so
// "gerguhêz" alone is "gh" and "xwerû" + "gerguhêz" is "x-gh".
var LEKTUR_CHOICES = [
{ code: "gh", label: "gerguhêz (îsmî mefûl digire)" },
{ code: "ngh", label: "negerguhêz (îsmî mefûl nagire)" }
];
var LEKTUR_FORM_CHOICES = [
{ code: "x", label: "xwerû" },
{ code: "p", label: "pêkhatî" },
{ code: "h", label: "hevedudanî" }
];
// Template call convertManeToPos() drops under a newly-chosen POS heading, e.g. "Hoker" -> "{{hoker|ku}}".
// A "Formeke X" (form-of) heading uses the unchanged base pos template; "Biwêj" has no template at all.
var POS_TEMPLATE = {
"Navdêr": "navdêr",
"Formeke navdêrê": "navdêr",
"Lêker": "lêker",
"Formeke lêkerê": "lêker",
"Rengdêr": "rengdêr",
"Formeke rengdêrê": "rengdêr",
"Hoker": "hoker",
"Formeke hokerê": "hoker",
"Serenav": "serenav",
"Formeke serenavê": "serenav",
"Artîkel": "artîkel",
"Baneşan": "baneşan",
"Bazinedaçek": "bazinedaçek",
"Cînav": "cînav",
"Daçek": "daçek",
"Girêdek": "girêdek",
"Gotineke pêşiyan": "gotineke pêşiyan",
"Hejmar": "hejmar",
"Hevok": "hevok",
"Îfade": "îfade",
"Kurtenav": "kurtenav",
"Navgir": "navgir",
"Paşdaçek": "paşdaçek",
"Paşgir": "paşgir",
"Pêşdaçek": "pêşdaçek",
"Pêşgir": "pêşgir",
"Pirtik": "pirtik",
"Reh": "reh",
"Sembol": "sembol",
"Tîp": "tîp"
};
// The "needs a POS" maintenance tag under a placeholder "Mane" heading, and every known redirect/alias name
// it's also called under on real pages -- convertManeToPos() drops whichever one is actually present.
var MANE_TAG_REGEX = /^\{\{\s*(?:cure\?|rêziman\?|kat-rêziman|kategoriya\s+rêzimanê\?|bêcure)\s*(?:\|[^{}]*)?\}\}\s*$/i;
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Array order controls where a new group line lands relative to existing ones. Every group lives behind the
// quick row's "Zêdetir" dropdown; only the gloss and Nimûne/jêgirtin links sit in the row itself.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane" },
{ key: "dijmane", label: "Dijmane" },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Only steps with a confirmed wikitext format are included; insertion rank comes from SUBSECTION_ORDER below.
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// Canonical ku.wiktionary "====" subsection order, used only as insertPageSubsection()'s insertion rank
// (see subsectionRankForHeader()). Wider than PAGE_SUBSECTIONS: it also covers subsections the gadget
// cannot create but still has to order around.
var SUBSECTION_ORDER = [
"Bilêvkirin",
"Ji wêjeya klasîk",
"Ji wêjeyê",
"Tewandin",
"Notên bikaranînê",
"Bi alfabeyên din",
"Formên alternatîv",
"Kurtkirin",
"Sembol",
"Navê zanistî",
"Hevmane",
"Nêzîk",
"Dijmane",
"Jornav",
"Jêrnav",
"Jê",
"Têkildar",
"Etîmolojî",
"Dûnde",
"Bide ber",
"Herwiha binêre",
"Bêhtir xwendin",
// Both spellings are in use on-wiki; PAGE_SUBSECTIONS creates this one, so it ranks in the same slot.
"Bêhtir bixwîne",
"Bi zaravayên din",
"Werger",
"Qafiye",
"Anagram",
// Creatable but absent from the canonical order; put last so it never displaces a ranked subsection.
"Çavkanî"
];
// {{kol}}, {{kol2}}, {{kol3}} and their col* spellings are the same column word-list template. New sections
// are written as kol3; any of the six is recognized when parsing an existing one.
var WORDLIST_TEMPLATES = ["kol3", "kol2", "kol", "col3", "col2", "col"];
// ---- word-modifier system (same widget start.js uses for Hevmane/Dijmane/etc. word lists) ----
// Every word in one of these lists can carry small "<key:value>" annotations (translation, gender, label,
// ...), which the {{hevmane}}/{{kol3}}/etc. templates parse back out of the raw positional param.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers into the raw "word<key:value>…" form {{hevmane}}/{{kol3}}/etc. read. */
// Inverse of joinWordValue(): peels the trailing "<key:value>" modifiers back off a raw list entry.
function splitWordValue(raw) {
var mods = [];
var word = raw;
var tail = /<([^<>:]+):([^<>]*)>\s*$/;
var m;
while ((m = tail.exec(word)) !== null) {
mods.unshift({ key: m[1], value: m[2] });
word = word.slice(0, m.index);
}
return { word: $.trim(word), mods: mods };
}
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers (document-order based, immune to mobile's per-section DOM wrapping and
// MediaWiki's page-wide heading-id collisions) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Pseudo section type for start.js's unclassified "=== Mane ===" / "=== Mane 2 ===" placeholder heading, so
// locateSection() (and everything built on it) can target one before a real POS has been chosen.
var MANE_SECTION = "Mane";
function isManeHeading($h) {
return /^Mane(\s+\d+)?$/.test($h.text().trim());
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s*\d+$/, ""); // \s* not \s+: locateSection() also accepts "Navdêr2"
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || (isManeHeading($(this)) ? MANE_SECTION : $(this).text().trim());
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback so one fetch covers both the
// edit-conflict check and the content, preventing a stale overwrite of someone else's edit.
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// This gadget's own save queue + floating widget, separate from the shared Gadget-Editor queue.
// Each entry keeps its own transformFn so saveQueueNow() can re-run all of them against one fresh fetch.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// "diff=prev" against the revision the save just created, i.e. exactly what this gadget changed. Built by
// hand rather than with mw.util.getUrl() so the gadget needs no extra module dependency.
function diffUrl(newrevid) {
return mw.config.get("wgScript") +
"?title=" + encodeURIComponent(mw.config.get("wgPageName")) +
"&diff=prev&oldid=" + encodeURIComponent(newrevid);
}
// Queue order, except that runLast entries move to the end: converting "=== Mane ===" into a real POS
// heading renames the very heading every other queued change locates itself by.
function orderedEntries() {
var normal = [];
var last = [];
dsbQueue.entries.forEach(function (entry) {
(entry.runLast ? last : normal).push(entry);
});
return normal.concat(last);
}
// The real save: re-runs every queued transformFn, in order, against one freshly-fetched revision and
// posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var entries = orderedEntries();
var combinedSummary = entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function (data) {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status
.removeClass("dsb-status-error")
.addClass("dsb-status-ok")
.empty()
.append("✓ Hemû guhartin hatin qeydkirin — rûpel nû bike da ku bibînî. ");
// A null edit changes nothing, so there is no revision to diff against.
if (data && data.newrevid) {
box.$status.append(
"Ji bo dîtina guhartina xwe ",
$("<a class='dsb-diff-link'></a>")
.attr("href", diffUrl(data.newrevid))
.attr("target", "_blank")
.attr("rel", "noopener")
.text("binêre"),
"."
);
}
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()); nothing here touches the page yet. Also runs previewFn(), which drops a
// small "not saved yet" preview into the live DOM at the change's own spot on the page. Shared by every
// panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel, buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn, opts) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn, runLast: !!(opts && opts.runLast) });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget ($.kuLinkify) and calls back with the linkified result.
// Passes the text through unchanged if the gadget can't be loaded, so it never blocks a save.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal, never by a DOM id number (MediaWiki's
// page-wide anchor uniquification can attach an id to a heading unrelated to its actual position).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
// The placeholder heading is matched by its own literal name, not by the POS list below.
if (sectionType === MANE_SECTION) {
var maneLoc = locateManeSection(pageContent, language, sectionOrdinal);
return {
langSectionIndex: maneLoc.langSectionIndex,
lines: maneLoc.lines,
posLineIndex: maneLoc.maneLineIndex
};
}
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the whole rest of the page from this language's heading onward, since the caller reuses
// it to rebuild the entire saved text; only the section-heading search itself is bounded by sectionSearchEndLine.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
// Closing "===" anchored, like locateManeSection(): otherwise "=== Navdêra pirjimar ===" counts as a POS occurrence here while sectionTypeOf() rejects it, desyncing the ordinal.
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?[ ]*===");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel: element 0 is
// unused (it's the "type|ordinal" string locateSection already resolved), remaining elements are 0-based
// indices, one per nesting level.
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's wordLine()
// format). If a line for this tplKey already exists under the definition, missing words are appended to
// it; otherwise a new line lands after the last existing group line, always before any "#*" citation lines.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
if (opts.replace) {
// Editing an existing list: an empty result means the user cleared it, so drop the line.
if (words.length) {
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}";
} else {
lines.splice(i, 1);
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's gloss text:
// maneid, then kategori (K), then etîket (e).
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker,
// stopping at the first thing that isn't one (normally the gloss text). Shared by insertLeadingSenseTpl()
// (uses "calls", as readSenseFields() also does). "rest" is the gloss text left after every leading call.
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts, extends, or (with opts.replace) overwrites one of the small templates that prefix a definition
// line's gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} or {{e|lang|etîket1|...}}. Under
// opts.replace an empty values list removes the call rather than writing an empty one.
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the whole leading-call run means an existing tplKey call is found and merged wherever it
// already sits, not just when it happens to be first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.replace) {
// Editing an existing call: an empty result means the user cleared it, so drop the call.
if (values.length) {
existing.params = [language].concat(values);
} else {
calls = calls.filter(function (c) { return c !== existing; });
}
} else {
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
}
} else if (!values.length) {
return pageContent; // nothing to add, and nothing there to clear
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call always outranks everything), or at the end of the run.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading template calls untouched --
// the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
// The box shows the raw line, templates included, so whatever the user left in it is what gets written.
lines[defLine] = marker + " " + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text to prefill the "Maneyê
// biguhêre" form. A plain read, not part of the hardened save path -- the actual save still re-fetches
// fresh content, so only the prefilled text itself could be a little stale.
// Current contents of one existing subsection, for prefilling the edit form.
function fetchPageSubsection(language, sectionType, sectionOrdinal, subsection) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
return readPageSubsection(content, language, sectionType, sectionOrdinal, subsection);
});
}
function fetchSenseFields(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
return readSenseFields(content, language, sectionType, sectionOrdinal, definitionLevel);
});
}
// Everything the advanced panel can edit about one sense, read off its definition line and the "#:" lines
// under it: the raw gloss (templates included), the leading maneid/K/e values, and each word-list group.
function readSenseFields(pageContent, language, sectionType, sectionOrdinal, definitionLevel) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var defMarker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(defMarker.length).replace(/^\s+/, "");
var leading = {};
splitLeadingCalls(afterMarker).calls.forEach(function (c) {
leading[c.key] = c.params.slice(1);
});
// Only start.js's "{{mane?|lang}}" placeholder is hidden; every other template stays visible so it can
// be edited by hand in the gloss box.
var gloss = afterMarker.replace(/^\{\{\s*mane\?\s*\|[^{}]*\}\}\s*/, "");
var marker = new Array(definitionLevel.length).join("#");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\s*\{\{\s*(" + groupKeysPattern + ")\s*\|([^}]*)\}\}\s*$");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var words = {};
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var m = groupLineRegex.exec(lines[i]);
if (m) {
words[m[1]] = m[2].split("|").slice(1);
}
}
return {
gloss: gloss,
maneid: leading.maneid ? leading.maneid[0] : "",
etiket: leading.e || [],
kategori: leading.K || [],
words: words
};
}
// Finds a POS block's body range (up to, but not including, the next heading of level <= 3), and the
// header text + line index of any "====" subsections it already contains.
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// Looks up a header's rank in SUBSECTION_ORDER. -1 for a header that isn't one of ours; such a header is
// never used as an insertion anchor.
function subsectionRankForHeader(header) {
return SUBSECTION_ORDER.indexOf(header);
}
// Body line range of one "====" subsection inside a POS block: everything after its heading up to the next
// "====" heading, or the end of the block. Null if the block has no such subsection.
function subsectionBodyRange(bounds, header) {
var headers = bounds.existingHeaders;
for (var i = 0; i < headers.length; i++) {
if (headers[i].header === header) {
return {
start: headers[i].lineIndex + 1,
end: i + 1 < headers.length ? headers[i + 1].lineIndex : bounds.end
};
}
}
return null;
}
// Splits a template call's inner text on its top-level "|", ignoring pipes nested in {{...}} or [[...]].
function splitTemplateParams(inner) {
var parts = [];
var buf = "";
var tpl = 0;
var link = 0;
for (var i = 0; i < inner.length; i++) {
var two = inner.substr(i, 2);
if (two === "{{" || two === "}}" || two === "[[" || two === "]]") {
if (two === "{{") { tpl++; } else if (two === "}}") { tpl--; } else if (two === "[[") { link++; } else { link--; }
buf += two;
i++;
continue;
}
if (inner.charAt(i) === "|" && tpl === 0 && link === 0) {
parts.push(buf);
buf = "";
continue;
}
buf += inner.charAt(i);
}
parts.push(buf);
return parts;
}
// Pulls a {{kol3|ku|cure=Jê|word|word}}-style call apart into the bits an edit has to preserve (template
// name, language, named params) plus the positional word list. Null if the body has no such call.
function parseWordListCall(text) {
var m = new RegExp("\{\{\s*(" + WORDLIST_TEMPLATES.join("|") + ")\s*[|}]", "i").exec(text);
if (!m) {
return null;
}
var open = m.index;
var depth = 0;
var close = -1;
for (var i = open; i < text.length - 1; i++) {
var two = text.substr(i, 2);
if (two === "{{") {
depth++;
i++;
} else if (two === "}}") {
depth--;
i++;
if (depth === 0) {
close = i + 1;
break;
}
}
}
if (close === -1) {
return null;
}
var parts = splitTemplateParams(text.slice(open + 2, close - 2));
var named = [];
var words = [];
for (var pi = 2; pi < parts.length; pi++) {
var val = $.trim(parts[pi]);
if (!val) {
continue;
}
if (/^[A-Za-z][A-Za-z0-9_-]*\s*=/.test(val)) {
named.push(val);
} else {
words.push(val);
}
}
return {
name: $.trim(parts[0]),
lang: parts.length > 1 ? $.trim(parts[1]) : "",
named: named,
words: words,
start: open,
end: close
};
}
// Canonical multi-line layout, matching how existing ku.wiktionary lists are written (one word per line).
function buildWordListCall(name, lang, named, words) {
var head = "{{" + name + "|" + lang;
named.forEach(function (n) {
head += "|" + n;
});
return words.length ? head + "\n|" + words.join("\n|") + "\n}}" : head + "\n}}";
}
// Current contents of an existing "====" subsection. A wordlist one whose template can't be parsed comes
// back as {kind: "text"} so the caller can still edit it as raw wikitext instead of refusing outright.
function readPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var bounds = posBlockBounds(loc.lines, loc.posLineIndex);
var range = subsectionBodyRange(bounds, subsection.header);
if (!range) {
return null;
}
var body = loc.lines.slice(range.start, range.end).join("\n");
if (subsection.kind === "wordlist") {
var call = parseWordListCall(body);
if (call) {
return { kind: "wordlist", words: call.words };
}
}
return { kind: "text", text: $.trim(body) };
}
// Rewrites an existing "====" subsection in place. A wordlist one keeps its own template name, language and
// named params ("cure=Jê", ...) and only has its positional words replaced; a text one is replaced whole.
function updatePageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var range = subsectionBodyRange(bounds, subsection.header);
if (!range) {
throw new SubmitAbort("Ev beş li vir tune: " + subsection.header);
}
var body = lines.slice(range.start, range.end).join("\n");
var replacement;
if (subsection.kind === "wordlist") {
var call = parseWordListCall(body);
if (!call) {
throw new SubmitAbort("Nikarî lîsteya vê beşê bixwîne: " + subsection.header);
}
// body.slice(call.end) already carries whatever trailed the call, blank separator line included.
replacement = body.slice(0, call.start) +
buildWordListCall(call.name, call.lang, call.named, content) +
body.slice(call.end);
} else {
// Replacing the body wholesale drops that separator, so put it back.
replacement = content + (/\n\s*$/.test(body) ? "\n" : "");
}
lines.splice(range.start, range.end - range.start, replacement);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Inserts a new "==== Header ====" subsection into its SUBSECTION_ORDER position within a POS block, right
// before the first ranked subsection that outranks it, or at the end if none does. Either a
// {{kol3|...}} word list or a plain paragraph, matching start.js's own subsection formats.
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var body = subsection.kind === "wordlist"
? buildWordListCall("kol3", language, ["cure=" + subsection.header], content)
: content;
var myRank = subsectionRankForHeader(subsection.header);
var headers = bounds.existingHeaders;
var insertAt = bounds.end;
for (var i = 0; i < headers.length; i++) {
var otherRank = subsectionRankForHeader(headers[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = headers[i].lineIndex;
break;
}
}
// Exactly one blank line on each side: the line before the insertion point is normally already blank
// (it separated the previous subsection from the next heading), so only add one where there isn't one.
var block = [];
if (insertAt > 0 && $.trim(lines[insertAt - 1]) !== "") {
block.push("");
}
block.push("==== " + subsection.header + " ====", body);
if (insertAt < lines.length) {
block.push("");
}
lines.splice.apply(lines, [insertAt, 0].concat(block));
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc.) instead of a real
// part-of-speech name, tagged right below with {{cure?|<lang>}} (ku.wiktionary's "part of speech not yet
// determined" maintenance flag). Neither is in sectionNames, so these two functions are a small parallel
// path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text
// (plus an optional disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading, drops the maintenance tag line right
// after it if present (MANE_TAG_REGEX -- cure? or any of its known aliases), and inserts the matching
// "{{<pos>|<lang>}}" template call in its place (skipped for section types with no POS_TEMPLATE entry).
// Other content under the heading is left untouched.
function convertManeToPos(pageContent, language, maneOrdinal, newSectionType, posParams) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
var loc = locateManeSection(pageContent, language, maneOrdinal);
var lines = loc.lines;
var m = /^(===[ ]*Mane)(\s+\d+)?([ ]*===)/.exec(lines[loc.maneLineIndex]);
lines[loc.maneLineIndex] = "=== " + newSectionType + (m[2] ? m[2] : "") + " ===";
var nextLineIndex = loc.maneLineIndex + 1;
if (nextLineIndex < lines.length && MANE_TAG_REGEX.test(lines[nextLineIndex])) {
lines.splice(nextLineIndex, 1);
}
var posTemplate = POS_TEMPLATE[newSectionType];
if (posTemplate) {
lines.splice(nextLineIndex, 0, "{{" + posTemplate + "|" + language + (posParams ? "|" + posParams : "") + "}}");
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form uses, applying only the
// pieces the caller actually filled in. A piece that conflicts with the page (maneid already set, a
// subsection that's already there) is skipped with a warning rather than failing the whole save. Throws
// SubmitAbort if nothing was filled in, so this can never turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
// Every box below is prefilled with what the sense already has, so a save replaces that value rather
// than merging into it -- and clearing a box removes the template. changes.changed marks the boxes
// whose contents actually differ from the page, so an opened-but-untouched box writes nothing.
var replace = { replace: true };
if (changes.changed.maneid) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", changes.maneid ? [changes.maneid] : [], replace);
appliedAnything = true;
}
if (changes.changed.etiket) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket, replace);
appliedAnything = true;
}
if (changes.changed.kategori) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori, replace);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
if (changes.changed["word:" + group.key]) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, changes.words[group.key], replace);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list: every word is its own always-visible row (word box + a "+" to attach one of the 10
// WORD_MODIFIERS as a small pill + an "x" to drop the row); a fresh empty row appears automatically once
// the current last row gets text. Duplicate words are allowed; every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into the current last row appends a fresh empty one after it, so there
// is always exactly one empty trailing row to type into.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.data("setRaw", function (raw) {
var parsed = splitWordValue(raw);
mods = parsed.mods;
$wordInput.val(parsed.word);
renderMods();
updateButtons();
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
// Replaces the whole list, keeping one empty trailing row to type into.
setValues: function (raws) {
$list.empty();
raws.forEach(function (raw) {
var $row = makeRow();
$list.append($row);
$row.data("setRaw")(raw);
});
$list.append(makeRow());
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, used for Etîket and Kategorî (simple value lists with no per-word modifiers).
// Enter or "," commits the current text as a tag; Backspace on an empty input removes the last tag;
// values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
// Replaces every tag, for prefilling from what the sense already has.
setValues: function (vals) {
$element.children(".dsb-tag").remove();
vals.forEach(function (v) {
addTag(v);
});
$input.val("");
},
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss and the two most-used word lists
// (Hevmane/Dijmane) sit directly in the picker row; the remaining word lists, maneid, etîket, kategorî
// and Nimûne/jêgirtin live behind a "Zêdetir" dropdown; one shared "Lê zêde bike" queues everything the
// user filled in as a single edit via applyAdvancedChanges() and queueChange(). Nimûne/jêgirtin is an
// immediate proxy-click into a different gadget's own form, not part of this combined save.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
// Hidden by default (see .add-example-form-title in the CSS); the inline style beats that rule.
$btn.closest("li").show();
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-open box (key -> () => value); collectChanges() only ever
// reads from a box the user actually clicked to open.
var getters = {};
// What the sense currently holds, fetched once and shared by every box that prefills from it.
// collectChanges() also diffs against it, so an untouched box never queues a change.
var original = null;
var sensePromise = null;
function loadSense() {
if (!sensePromise) {
sensePromise = fetchSenseFields(language, sectionType, sectionOrdinal, definitionLevel).then(function (fields) {
original = fields;
return fields;
});
}
return sensePromise;
}
function sameList(a, b) {
return (a || []).join("\u0000") === (b || []).join("\u0000");
}
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's wording; everything else here only ADDS) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
loadSense().then(
function (fields) {
originalGloss = fields.gloss;
$textarea.val(fields.gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
loadSense().then(function (fields) {
var current = fields.words[group.key];
if (current && current.length) {
field.setValues(current);
}
});
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
loadSense().then(function (fields) {
$input.val(fields.maneid);
});
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
loadSense().then(function (fields) {
field.setValues(fields.etiket);
});
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
loadSense().then(function (fields) {
field.setValues(fields.kategori);
});
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: the gloss and Nimûne/jêgirtin links sit directly in the row; every word group and
// the rest live behind a "Zêdetir" dropdown. Clicking any link builds and appends its box
// to $openBoxes and hides that link; the box's own "×" removes it, clears its getter, and un-hides the
// link -- several boxes can be open at once. No "Beşek (====)" entry here: buildSubsectionPanel()'s
// own "+ Beşek lê zêde bike" trigger already covers page-level subsections. ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: false };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
if (def.key === "gloss") {
$picker.append($nimune); // directly after "Maneyê biguhêre"
}
});
// Lives inside $picker (not appended straight to $quickRow) so .dsb-more-menu's CSS can position it as
// an overlay anchored to $picker, instead of pushing $openBoxes/the rest of the page down when it opens.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle, $moreMenu);
// Closes the dropdown on an outside click, scoped to this panel's own $moreToggle/$moreMenu.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via queueChange(); the actual
// save happens when the user clicks "Guhertinan qeyd bike" on the floating queue box. ----
// Small "not saved yet" preview of everything this queued change will do, appended right under the
// sense's gloss (plain text, not a real render of {{hevmane}}/etc.).
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var base = original || { maneid: "", etiket: [], kategori: [], words: {} };
var changed = {};
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
if (getter && !sameList(words[group.key], base.words[group.key])) {
changed["word:" + group.key] = true;
}
});
var maneid = getters.maneid ? getters.maneid() : "";
var etiket = getters.etiket ? getters.etiket() : [];
var kategori = getters.kategori ? getters.kategori() : [];
if (getters.maneid && maneid !== (base.maneid || "")) {
changed.maneid = true;
}
if (getters.etiket && !sameList(etiket, base.etiket)) {
changed.etiket = true;
}
if (getters.kategori && !sameList(kategori, base.kategori)) {
changed.kategori = true;
}
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: maneid,
etiket: etiket,
kategori: kategori,
words: words,
changed: changed
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Auto-linkify the gloss only when it's part of this save and has no manual link already.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above.
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
// The real InterlanguageLinks pencil icon (same asset defEditButton uses); image swap is in the CSS.
var $toggle = $("<a href='#' class='dsb-toggle' title='Guhartina pêşketî'></a>");
// Revealed by $toggle -- an indented panel under the sense, not always visible. Built lazily on
// first open rather than eagerly for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.prepend($toolbar);
// Touch has no :hover -- a tap anywhere on the line reveals the pencil the same way hovering does on
// desktop (CSS gates this to touch devices; harmless if it also fires on a mouse click).
$li.on("click.dsbReveal", function () {
$toolbar.addClass("dsb-revealed");
});
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a new "====" subsection preview belongs in the live DOM, using the same SUBSECTION_ORDER rank
// insertPageSubsection() uses. Returns {insertBefore: $el} (a ranked subsection that outranks this one) or
// {insertAfter: $el} (goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its canonical position. Plain text, not a real render of {{kol3|...}}/etc.
// Returns the inserted element so the caller can remove it again.
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4>, so existingSubsectionHeadersInDom() never mistakes this live-only
// preview for an actual subsection already on the page.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field. A subsection that isn't on the page yet is saved
// via insertPageSubsection(); one that already is gets prefilled and saved via updatePageSubsection().
// onlyHeader pins the panel to a single subsection (the per-heading pencil); omit it for the full picker.
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal, onlyHeader) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return !onlyHeader || s.header === onlyHeader;
}).map(function (s) {
return $.extend({}, s, { existing: existing.indexOf(s.header) !== -1 });
});
if (!available.length) {
$panel.text("Ji bo vê beşê guhartin tune.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
if (!onlyHeader) {
$select.append($("<option value=''></option>").text("Binebeşek hilbijêre"));
}
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.existing ? s.header + " (biguhêre)" : s.header));
});
if (onlyHeader) {
$select.hide();
}
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status);
$cancel.on("click", function () {
$panel.hide();
});
// Undefined while the placeholder option is selected.
function currentSubsection() {
var id = $select.val();
return id ? available.filter(function (s) {
return s.id === id;
})[0] : undefined;
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
var editAsText = false; // set when an existing wordlist section turns out to be unparseable
function renderTextArea(s, rows) {
$fieldWrap.empty().append(
$("<textarea class='dsb-input dsb-subsection-text'></textarea>")
.attr("rows", rows)
.attr("placeholder", s.header + "…")
);
}
// Loads what the page already has into the form, so an edit starts from the current list rather than
// from an empty one. A wordlist section we can't parse degrades to raw wikitext editing.
function prefill(s) {
$status.removeClass("dsb-status-error dsb-status-ok").text("Tê xwendin…");
$save.prop("disabled", true);
fetchPageSubsection(language, sectionType, sectionOrdinal, s).then(function (current) {
$save.prop("disabled", false);
$status.text("");
if (!current) {
return;
}
if (current.kind === "wordlist" && wordField) {
wordField.setValues(current.words);
return;
}
if (s.kind === "wordlist") {
editAsText = true;
wordField = null;
renderTextArea(s, 6);
$status.text("Şablona vê lîsteyê nehate naskirin — wekî wikitext biguhêre.");
}
$fieldWrap.find(".dsb-subsection-text").val(current.text);
}, function () {
$save.prop("disabled", false);
$status.addClass("dsb-status-error").text("Nikarî muhtewaya heyî bixwîne.");
});
}
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
editAsText = false;
$status.removeClass("dsb-status-error dsb-status-ok").text("");
// Save stays disabled (but "Betal bike" usable) until something is actually chosen.
$save.prop("disabled", !s);
if (!s) {
$save.text("Lê zêde bike");
return; // still on "Binebeşek hilbijêre"
}
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
renderTextArea(s, 3);
}
$save.text(s.existing ? "Biguhêre" : "Lê zêde bike");
if (s.existing) {
prefill(s);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
if (!s) {
return;
}
var asText = editAsText || s.kind !== "wordlist";
var effective = asText ? $.extend({}, s, { kind: "text" }) : s;
var content;
if (asText) {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
} else {
content = wordField.values();
if (!content.length) {
return;
}
}
$save.prop("disabled", true);
queueChange(
(s.existing ? "~" : "+") + s.header + " (DefSideBoxes)",
function (pageContent) {
return {
content: s.existing
? updatePageSubsection(pageContent, language, sectionType, sectionOrdinal, effective, content)
: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, effective, content),
warnings: []
};
},
$save,
$status,
// Only a brand-new subsection gets a preview block; an edit would have to rewrite the rendered
// section in place, which this plain-text preview can't do faithfully.
s.existing ? null : function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that replaces an unclassified "=== Mane ===" placeholder
// heading, saved via convertManeToPos(). Lists every name from sectionNames.
function buildConvertPosPanel($panel, $h3, language, maneOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
$select.append($("<option></option>").val(name).text(name));
});
// The two follow-up questions start.js's posparams card asks, both feeding one "c=" parameter, and both
// gated the way it gates them: gender on navdêr/serenav, transitivity on lêker.
function buildRow(labelText, choices) {
var $sel = $("<select class='dsb-convert-pos-select dsb-pos-param-select'></select>")
.append($("<option value=''></option>").text("— hilbijêre —"));
choices.forEach(function (c) {
$sel.append($("<option></option>").val(c.code).text(c.label));
});
var $row = $("<div class='dsb-pos-param-row'></div>")
.append($("<label class='dsb-adv-label'></label>").text(labelText), $sel)
.hide();
return { $row: $row, $sel: $sel };
}
var cinsiyet = buildRow("Cinsiyet", KU_GENDER_CHOICES);
var lektur = buildRow("Gerguhêziya lêkerê çawa ye?", LEKTUR_CHOICES);
var lekturForm = buildRow("Şiklê lêkerê", LEKTUR_FORM_CHOICES);
// Kurmancî only: every other language's gender codes live in start.js's data.json, which this gadget
// cannot read, and start.js asks the lêker questions for lang=ku too.
function syncRows() {
var tpl = POS_TEMPLATE[$select.val()] || "";
var isKu = language === "ku";
cinsiyet.$row.toggle(isKu && (tpl === "navdêr" || tpl === "serenav"));
lektur.$row.toggle(isKu && tpl === "lêker");
lekturForm.$row.toggle(isKu && tpl === "lêker");
}
$select.on("change", syncRows);
syncRows();
// "gh" on its own, or "<form>-<base>" once a structural form is picked -- start.js's own composition.
function posParams() {
if (cinsiyet.$row.is(":visible") && cinsiyet.$sel.val()) {
return "c=" + cinsiyet.$sel.val();
}
if (lektur.$row.is(":visible") && lektur.$sel.val()) {
var form = lekturForm.$sel.val();
return "c=" + (form ? form + "-" : "") + lektur.$sel.val();
}
return "";
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
var params = posParams();
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertManeToPos(pageContent, language, maneOrdinal, chosen, params), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note under the heading, rather than rewriting the real heading
// text -- avoids leaving a heading showing a name that was never actually saved if the
// save fails partway through.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + (params ? " (" + params + ")" : "") + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
},
// Runs after every other queued change: it renames the "Mane" heading those changes locate
// themselves by, so anything edited on this section has to be applied first.
{ runLast: true }
);
});
$panel.empty().append($select, cinsiyet.$row, lektur.$row, lekturForm.$row, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
// Puts the same pencil the definitions use on every existing "====" subsection heading the gadget knows how
// to edit, opening buildSubsectionPanel() pinned to that one subsection.
function attachSubsectionEditors($h3, language, sectionType, sectionOrdinal) {
var editable = {};
PAGE_SUBSECTIONS.forEach(function (s) {
editable[s.header] = true;
});
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if (!$cursor.is(".mw-heading4, h4")) {
continue;
}
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var header = $hh.text().trim();
if (!editable[header] || $hh.data("dsbAttached")) {
continue;
}
$hh.data("dsbAttached", true);
attachSubsectionEditor($hh, $cursor, $h3, header, language, sectionType, sectionOrdinal);
}
}
function attachSubsectionEditor($hh, $heading, $h3, header, language, sectionType, sectionOrdinal) {
var $toolbar = $("<span class='dsb-toolbar dsb-toolbar-heading'></span>");
var $toggle = $("<a href='#' class='dsb-toggle'></a>").attr("title", header + " biguhêre");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$toolbar.append($toggle);
$hh.append($toolbar);
$heading.after($panel);
$toggle.on("click", function (e) {
e.preventDefault();
$toolbar.addClass("dsb-revealed");
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal, header);
$panel.data("built", true);
}
});
}
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger right under an unclassified "=== Mane ===" placeholder
// heading (see convertManeToPos()'s own comment for what that heading means).
function attachManeConvertTrigger($h3) {
if ($h3.data("dsbManeAttached")) {
return;
}
$h3.data("dsbManeAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var maneOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, maneOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (!isManeHeading($h3)) {
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
// An unclassified placeholder: offer the POS picker, then carry on and wire up the same
// per-sense pencils, so the POS choice and the sense edits can be queued and saved together.
attachManeConvertTrigger($h3);
sectionType = MANE_SECTION;
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
attachSubsectionEditors($h3, language, sectionType, sectionOrdinal);
});
}
// Closes every open panel/preview this gadget can leave in the DOM, so bfcache never freezes one mid-open.
function closeAllOpenUi() {
clearQueue();
$(".dsb-quick-row, .dsb-more-menu, .dsb-convert-pos-panel, .dsb-subsection-panel, .dsb-queue-box, .dsb-preview-inline, .dsb-preview-block").hide();
}
$(window).on("pagehide", closeAllOpenUi);
// Belt-and-suspenders: also close on restore-from-bfcache, in case pagehide's own hide didn't stick.
$(window).on("pageshow", function (e) {
if (e.originalEvent && e.originalEvent.persisted) {
closeAllOpenUi();
}
});
$(init);
// </nowiki>
})();
87tv6kcwr6vwzdye7nlq3bvta5uhttw
6347640
6347610
2026-09-01T11:55:22Z
Wikihez
7344
6347640
javascript
text/javascript
// Gadget-DefSideBoxes.js
// Per-definition and per-section quick-add toolbar for ku.wiktionary, writing start.js's own wikitext
// conventions ("#: {{hevmane|lang|...}}" per-sense lines, "{{kol3|...}}" page subsections).
// Works on vector, vector2022 and minerva (mobile). Dependencies: mediawiki.api, mediawiki.util, jquery.
// Runtime coupling: the "Nimûne/jêgirtin" menu item looks for the button Gadget-wikt.add-examples.js
// inserts on each definition, by its exact link text, so that gadget must run first.
// <nowiki>
(function () {
"use strict";
// Main namespace, namespace 108 (reconstructed-entry pages), or a user's own /ceribandin or /test subpage.
if (mw.config.get("wgAction") !== "view") {
return;
}
var ns = mw.config.get("wgNamespaceNumber");
if (ns && ns !== 108 &&
!(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) {
return;
}
if (/&printable=yes|&diff=|&oldid=/.test(window.location.search)) {
return;
}
window.wikt = window.wikt || {};
if (window.wikt.defSideBoxesLoaded) {
return;
}
window.wikt.defSideBoxesLoaded = true;
var api = new mw.Api();
// Recognized part-of-speech section headings -- keep in sync with Gadget-wikt.add-examples.js.
var sectionNames = {
"Navdêr": ["Navdêr"],
"Formeke navdêrê": ["Formeke navdêrê"],
"Lêker": ["Lêker"],
"Formeke lêkerê": ["Formeke lêkerê"],
"Rengdêr": ["Rengdêr"],
"Formeke rengdêrê": ["Formeke rengdêrê"],
"Hoker": ["Hoker"],
"Formeke hokerê": ["Formeke hokerê"],
"Serenav": ["Serenav"],
"Formeke serenavê": ["Formeke serenavê"],
"Artîkel": ["Artîkel"],
"Baneşan": ["Baneşan"],
"Bazinedaçek": ["Bazinedaçek"],
"Biwêj": ["Biwêj"],
"Cînav": ["Cînav"],
"Daçek": ["Daçek"],
"Girêdek": ["Girêdek"],
"Gotineke pêşiyan": ["Gotineke pêşiyan"],
"Hejmar": ["Hejmar"],
"Hevok": ["Hevok"],
"Îfade": ["Îfade"],
"Kurtenav": ["Kurtenav"],
"Navgir": ["Navgir"],
"Paşdaçek": ["Paşdaçek"],
"Paşgir": ["Paşgir"],
"Pêşdaçek": ["Pêşdaçek"],
"Pêşgir": ["Pêşgir"],
"Pirtik": ["Pirtik"],
"Reh": ["Reh"],
"Sembol": ["Sembol"],
"Tîp": ["Tîp"]
};
// Reduced port of start.js's POS step: the two questions its posparams card asks that feed the template's
// "c=" parameter. Gender codes are metadata.ku.g from start.js's data.json, minus the number codes it
// filters out via isNumberCode(), with genderLabel()'s rendering baked in. Kurmancî only -- every other
// language has its own code set in data.json, which this gadget cannot read.
var KU_GENDER_CHOICES = [
{ code: "n", label: "nêr" },
{ code: "m", label: "mê" },
{ code: "mnmane", label: "mê yan nêr li gorî maneyê" },
{ code: "mndudil", label: "mê yan nêr bikaranîn dudil e" },
{ code: "n-p", label: "nêr (pirjimar)" },
{ code: "m-p", label: "mê (pirjimar)" }
];
// start.js asks transitivity and structural form as two questions and joins them as "<form>-<base>", so
// "gerguhêz" alone is "gh" and "xwerû" + "gerguhêz" is "x-gh".
var LEKTUR_CHOICES = [
{ code: "gh", label: "gerguhêz (îsmî mefûl digire)" },
{ code: "ngh", label: "negerguhêz (îsmî mefûl nagire)" }
];
var LEKTUR_FORM_CHOICES = [
{ code: "x", label: "xwerû" },
{ code: "p", label: "pêkhatî" },
{ code: "h", label: "hevedudanî" }
];
// Template call convertSectionToPos() drops under a newly-chosen POS heading, e.g. "Hoker" -> "{{hoker|ku}}".
// A "Formeke X" (form-of) heading uses the unchanged base pos template. Doubles as the list of template
// calls a conversion may find under the OLD heading and replace, rather than leave stacked beside the new one.
var POS_TEMPLATE = {
"Navdêr": "navdêr",
"Biwêj": "biwêj",
"Formeke navdêrê": "navdêr",
"Lêker": "lêker",
"Formeke lêkerê": "lêker",
"Rengdêr": "rengdêr",
"Formeke rengdêrê": "rengdêr",
"Hoker": "hoker",
"Formeke hokerê": "hoker",
"Serenav": "serenav",
"Formeke serenavê": "serenav",
"Artîkel": "artîkel",
"Baneşan": "baneşan",
"Bazinedaçek": "bazinedaçek",
"Cînav": "cînav",
"Daçek": "daçek",
"Girêdek": "girêdek",
"Gotineke pêşiyan": "gotineke pêşiyan",
"Hejmar": "hejmar",
"Hevok": "hevok",
"Îfade": "îfade",
"Kurtenav": "kurtenav",
"Navgir": "navgir",
"Paşdaçek": "paşdaçek",
"Paşgir": "paşgir",
"Pêşdaçek": "pêşdaçek",
"Pêşgir": "pêşgir",
"Pirtik": "pirtik",
"Reh": "reh",
"Sembol": "sembol",
"Tîp": "tîp"
};
// The "needs a POS" maintenance tag under a placeholder "Mane" heading, and every known redirect/alias name
// it's also called under on real pages -- convertSectionToPos() drops whichever one is actually present.
var MANE_TAG_REGEX = /^\{\{\s*(?:cure\?|rêziman\?|kat-rêziman|kategoriya\s+rêzimanê\?|bêcure)\s*(?:\|[^{}]*)?\}\}\s*$/i;
// The six per-sense groups start.js writes as "#: {{tpl|lang|word1|word2}}" sub-lines under a "#" definition.
// Array order controls where a new group line lands relative to existing ones. Every group lives behind the
// quick row's "Zêdetir" dropdown; only the gloss and Nimûne/jêgirtin links sit in the row itself.
var SENSE_GROUPS = [
{ key: "alt-r", label: "Formek alternatîv" },
{ key: "hevmane", label: "Hevmane" },
{ key: "dijmane", label: "Dijmane" },
{ key: "koordîne", label: "Termek koordîne" },
{ key: "jornav", label: "Jornav" },
{ key: "jêrnav", label: "Jêrnav" }
];
// Page-level (per part-of-speech, "====" heading) subsections start.js can also build from scratch.
// "kind: wordlist" ones use {{kol3|lang|cure=Header|word1|word2}}; "kind: text" ones are a plain paragraph.
// Only steps with a confirmed wikitext format are included; insertion rank comes from SUBSECTION_ORDER below.
var PAGE_SUBSECTIONS = [
{ id: "tewandin", header: "Tewandin", kind: "text" },
{ id: "bikaranin", header: "Notên bikaranînê", kind: "text" },
{ id: "alfabeyendin", header: "Bi alfabeyên din", kind: "text" },
{ id: "formalt", header: "Formên alternatîv", kind: "wordlist" },
{ id: "hevmane", header: "Hevmane", kind: "wordlist" },
{ id: "dijmane", header: "Dijmane", kind: "wordlist" },
{ id: "jornav", header: "Jornav", kind: "wordlist" },
{ id: "jernav", header: "Jêrnav", kind: "wordlist" },
{ id: "je", header: "Jê", kind: "wordlist" },
{ id: "tekildar", header: "Têkildar", kind: "wordlist" },
{ id: "etym", header: "Etîmolojî", kind: "text" },
{ id: "binereherwiha", header: "Herwiha binêre", kind: "wordlist" },
{ id: "xwendin", header: "Bêhtir bixwîne", kind: "text" },
{ id: "cavkani", header: "Çavkanî", kind: "text" }
];
// Canonical ku.wiktionary "====" subsection order, used only as insertPageSubsection()'s insertion rank
// (see subsectionRankForHeader()). Wider than PAGE_SUBSECTIONS: it also covers subsections the gadget
// cannot create but still has to order around.
var SUBSECTION_ORDER = [
"Bilêvkirin",
"Ji wêjeya klasîk",
"Ji wêjeyê",
"Tewandin",
"Notên bikaranînê",
"Bi alfabeyên din",
"Formên alternatîv",
"Kurtkirin",
"Sembol",
"Navê zanistî",
"Hevmane",
"Nêzîk",
"Dijmane",
"Jornav",
"Jêrnav",
"Jê",
"Têkildar",
"Etîmolojî",
"Dûnde",
"Bide ber",
"Herwiha binêre",
"Bêhtir xwendin",
// Both spellings are in use on-wiki; PAGE_SUBSECTIONS creates this one, so it ranks in the same slot.
"Bêhtir bixwîne",
"Bi zaravayên din",
"Werger",
"Qafiye",
"Anagram",
// Creatable but absent from the canonical order; put last so it never displaces a ranked subsection.
"Çavkanî"
];
// {{kol}}, {{kol2}}, {{kol3}} and their col* spellings are the same column word-list template. New sections
// are written as kol3; any of the six is recognized when parsing an existing one.
var WORDLIST_TEMPLATES = ["kol3", "kol2", "kol", "col3", "col2", "col"];
// ---- word-modifier system (same widget start.js uses for Hevmane/Dijmane/etc. word lists) ----
// Every word in one of these lists can carry small "<key:value>" annotations (translation, gender, label,
// ...), which the {{hevmane}}/{{kol3}}/etc. templates parse back out of the raw positional param.
var WORD_MODIFIERS = [
{ key: "t", label: "t: tercime / îzah", hint: "Tercimeya kelîmeyê an îzaha wê" },
{ key: "cuda", label: "cuda: alt display", hint: "Forma nîşankirinê ya alternatîv" },
{ key: "c", label: "c: cinsiyet", hint: "Cinsiyeta kelîmeyê" },
{ key: "e", label: "e: etîket (li pêşiyê)", hint: "Etîketek li pêşiya kelîmeyê" },
{ key: "ee", label: "ee: etîket (li dawiyê)", hint: "Etîketek li dawiya kelîmeyê" },
{ key: "q", label: "q: wesf (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" },
{ key: "qq", label: "qq: wesf (li dawiyê)", hint: "Wesf li dawiya kelîmeyê" },
{ key: "crz", label: "crz: cureyê rêzimanî", hint: "Cureyê rêzimanî yê kelîmeyê" },
{ key: "hrf", label: "hrf: herfiyen", hint: "Herfiyen, manaya rasterast" },
{ key: "ref", label: "ref: çavkanî", hint: "Çavkanî" }
];
// Short "key: value" prefix each modifier gets in its pill's display label -- keyed the same as WORD_MODIFIERS.
var WORD_MODIFIER_DISPLAY_PREFIX = {
t: "tercime: ",
cuda: "cuda: ",
c: "cinsiyet: ",
e: "etîket: ",
ee: "etîket: ",
q: "wesf: ",
qq: "wesf: ",
crz: "cureyê rêzimanî: ",
hrf: "herfiyen: ",
ref: "çavkanî: "
};
/** "key: value" chip label for one attached modifier. */
function modChipLabel(mo) {
var prefix = WORD_MODIFIER_DISPLAY_PREFIX[mo.key];
return (prefix === undefined ? mo.key + ": " : prefix) + mo.value;
}
/** Joins a word plus its attached modifiers into the raw "word<key:value>…" form {{hevmane}}/{{kol3}}/etc. read. */
// Inverse of joinWordValue(): peels the trailing "<key:value>" modifiers back off a raw list entry.
function splitWordValue(raw) {
var mods = [];
var word = raw;
var tail = /<([^<>:]+):([^<>]*)>\s*$/;
var m;
while ((m = tail.exec(word)) !== null) {
mods.unshift({ key: m[1], value: m[2] });
word = word.slice(0, m.index);
}
return { word: $.trim(word), mods: mods };
}
function joinWordValue(word, mods) {
if (!word) {
return "";
}
var out = word;
mods.forEach(function (mo) {
out += "<" + mo.key + ":" + mo.value + ">";
});
return out;
}
// ---- section/language helpers (document-order based, immune to mobile's per-section DOM wrapping and
// MediaWiki's page-wide heading-id collisions) ----
// MediaWiki wraps each heading in a "mw-heading2/3/.../" div in current skin output.
function headingOuter($h) {
var $wrap = $h.closest(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6");
return $wrap.length ? $wrap : $h;
}
// Section's language code: nearest preceding .besazimani[id] by document order, not sibling-walking.
function languageCodeForOl($ol) {
var $marks = $(".besazimani[id]").add($ol);
var ol = $ol.get(0);
var idx = $marks.index(ol);
for (var i = idx - 1; i >= 0; i--) {
var el = $marks.get(i);
if (el.id) {
return el.id;
}
}
return null;
}
// Pseudo section type for start.js's unclassified "=== Mane ===" / "=== Mane 2 ===" placeholder heading, so
// locateSection() (and everything built on it) can target one before a real POS has been chosen.
var MANE_SECTION = "Mane";
function isManeHeading($h) {
return /^Mane(\s+\d+)?$/.test($h.text().trim());
}
// Canonical section-type key for a heading, stripping a page author's own disambiguating trailing number.
function sectionTypeOf($h3) {
var text = $h3.text().trim();
if (sectionNames[text]) {
return text;
}
var stripped = text.replace(/\s*\d+$/, ""); // \s* not \s+: locateSection() also accepts "Navdêr2"
return sectionNames[stripped] ? stripped : null;
}
// This heading's 1-based position among same-type headings within its own language block.
function sectionOrdinalWithinLanguage($h3) {
var h3El = $h3.get(0);
var $all = $(".besazimani[id]").add($("h3"));
var counts = {};
var result = 1;
$all.each(function () {
if ($(this).is(".besazimani[id]")) {
counts = {};
return;
}
var type = sectionTypeOf($(this)) || (isManeHeading($(this)) ? MANE_SECTION : $(this).text().trim());
counts[type] = (counts[type] || 0) + 1;
if (this === h3El) {
result = counts[type];
return false;
}
});
return result;
}
// A "form of"-template-generated <li> wraps its own content; its nested <ol> isn't real "##" senses.
function isFormOfWrapper($li) {
return $li.children(".form-of-definition").length > 0;
}
// Recurse into a <li>'s nested <ol> unless it's a form-of wrapper.
function eachLeafDefinition($ol, fn) {
$ol.children("li").each(function () {
var $li = $(this);
var $childOl = $li.children("ol");
if ($childOl.length && !isFormOfWrapper($li)) {
$childOl.each(function () {
eachLeafDefinition($(this), fn);
});
} else {
fn($li);
}
});
}
// ---- small shared utilities ----
// Escapes str for safe interpolation into a RegExp.
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
// Extracts a human-readable message from an mw.Api rejection.
function apiErrorMessage(code, result) {
return (result && result.error && result.error.info) || (typeof code === "string" ? code : "Xeletiyeke nenas");
}
// Thrown from inside an edit() transform to bail out with a specific message, not a generic API failure.
function SubmitAbort(message) {
this.message = message;
}
// Runs transformFn(content) inside mw.Api().edit()'s own transform callback so one fetch covers both the
// edit-conflict check and the content, preventing a stale overwrite of someone else's edit.
function editPage(summary, transformFn, onSuccess, onError) {
api.edit(mw.config.get("wgPageName"), function (revision) {
return { text: transformFn(revision.content), summary: summary };
}).then(onSuccess, function (codeOrAbort, result) {
if (codeOrAbort instanceof SubmitAbort) {
onError(codeOrAbort.message);
} else {
onError("Nekarî rûpelê xilas bike: " + apiErrorMessage(codeOrAbort, result));
}
});
}
// This gadget's own save queue + floating widget, separate from the shared Gadget-Editor queue.
// Each entry keeps its own transformFn so saveQueueNow() can re-run all of them against one fresh fetch.
var dsbQueue = {
entries: [], // [{summary, transformFn}], transformFn: baseContent -> {content, warnings}
previews: [] // [removeFn, ...] -- undoes every live DOM preview a queued entry added; see below
};
var $queueBox = null;
function registerPreview(removeFn) {
dsbQueue.previews.push(removeFn);
}
function clearAllPreviews() {
dsbQueue.previews.forEach(function (fn) {
try {
fn();
} catch (e) { /* a preview failing to clean up should never block the queue itself */ }
});
dsbQueue.previews = [];
}
function clearQueue() {
dsbQueue.entries = [];
clearAllPreviews();
if ($queueBox) {
$queueBox.$list.empty();
$queueBox.$box.hide();
}
}
function ensureQueueBox() {
if ($queueBox) {
return $queueBox;
}
var $box = $("<div class='dsb-queue-box'></div>").hide();
var $close = $("<a href='#' class='dsb-queue-close' title='Veşêre'>×</a>");
var $title = $("<div class='dsb-queue-title'></div>").text("Guhertinên li benda qeydkirinê");
var $list = $("<ul class='dsb-queue-list'></ul>");
var $status = $("<div class='dsb-queue-status'></div>");
var $save = $("<button type='button' class='dsb-queue-save'>Guhertinan qeyd bike</button>");
var $cancel = $("<button type='button' class='dsb-queue-cancel'>Betal bike</button>");
var $actions = $("<div class='dsb-queue-actions'></div>").append($save, $cancel);
$close.on("click", function (e) {
e.preventDefault();
$box.hide();
});
$cancel.on("click", function () {
clearQueue();
});
$save.on("click", function () {
saveQueueNow();
});
$box.append($close, $title, $list, $actions, $status);
$(document.body).append($box);
$queueBox = { $box: $box, $list: $list, $status: $status, $save: $save, $cancel: $cancel };
return $queueBox;
}
function renderQueueBox() {
var box = ensureQueueBox();
box.$list.empty();
dsbQueue.entries.forEach(function (entry) {
box.$list.append($("<li></li>").text(entry.summary));
});
box.$status.removeClass("dsb-status-ok dsb-status-error").text("");
box.$save.prop("disabled", !dsbQueue.entries.length);
box.$box.show();
}
// "diff=prev" against the revision the save just created, i.e. exactly what this gadget changed. Built by
// hand rather than with mw.util.getUrl() so the gadget needs no extra module dependency.
function diffUrl(newrevid) {
return mw.config.get("wgScript") +
"?title=" + encodeURIComponent(mw.config.get("wgPageName")) +
"&diff=prev&oldid=" + encodeURIComponent(newrevid);
}
// Queue order, except that runLast entries move to the end: converting "=== Mane ===" into a real POS
// heading renames the very heading every other queued change locates itself by.
function orderedEntries() {
var normal = [];
var last = [];
dsbQueue.entries.forEach(function (entry) {
(entry.runLast ? last : normal).push(entry);
});
return normal.concat(last);
}
// The real save: re-runs every queued transformFn, in order, against one freshly-fetched revision and
// posts the result as a single edit with a combined summary.
function saveQueueNow() {
if (!dsbQueue.entries.length) {
return;
}
var box = ensureQueueBox();
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", true);
box.$status.removeClass("dsb-status-ok dsb-status-error").text("Tê qeydkirin…");
var entries = orderedEntries();
var combinedSummary = entries.map(function (entry) {
return entry.summary;
}).join("; ");
editPage(
combinedSummary,
function (pageContent) {
var content = pageContent;
entries.forEach(function (entry) {
content = entry.transformFn(content).content;
});
return content;
},
function (data) {
dsbQueue.entries = [];
clearAllPreviews();
box.$list.empty();
box.$status
.removeClass("dsb-status-error")
.addClass("dsb-status-ok")
.empty()
.append("✓ Hemû guhartin hatin qeydkirin — rûpel nû bike da ku bibînî. ");
// A null edit changes nothing, so there is no revision to diff against.
if (data && data.newrevid) {
box.$status.append(
"Ji bo dîtina guhartina xwe ",
$("<a class='dsb-diff-link'></a>")
.attr("href", diffUrl(data.newrevid))
.attr("target", "_blank")
.attr("rel", "noopener")
.text("binêre"),
"."
);
}
box.$save.prop("disabled", true);
box.$cancel.prop("disabled", false);
},
function (message) {
box.$save.prop("disabled", false);
box.$cancel.prop("disabled", false);
box.$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
}
// Queues transformFn(baseWikitext) -> {content, warnings} for the real save to run later against fresh
// content (see saveQueueNow()); nothing here touches the page yet. Also runs previewFn(), which drops a
// small "not saved yet" preview into the live DOM at the change's own spot on the page. Shared by every
// panel that queues a wikitext change: buildAdvancedPanel, buildSubsectionPanel, buildConvertPosPanel.
function queueChange(summary, transformFn, $save, $status, previewFn, opts) {
dsbQueue.entries.push({ summary: summary, transformFn: transformFn, runLast: !!(opts && opts.runLast) });
$status.removeClass("dsb-status-error").addClass("dsb-status-ok").text(
"✓ li rêza guhertinan hate zêdekirin — pêl 'Guhertinan qeyd bike' li jorê bike da ku bicîh bibe."
);
$save.prop("disabled", false);
if (previewFn) {
try {
var removePreview = previewFn();
if (typeof removePreview === "function") {
registerPreview(removePreview);
}
} catch (e) { /* a broken preview should never stop the change from being queued */ }
}
renderQueueBox();
}
// Runs text through the ext.gadget.linkify gadget ($.kuLinkify) and calls back with the linkified result.
// Passes the text through unchanged if the gadget can't be loaded, so it never blocks a save.
function linkifyText(text, cb) {
function run() {
if (typeof $.kuLinkify === "function") {
$.kuLinkify(text, cb);
} else {
cb(text);
}
}
mw.loader.using("ext.gadget.linkify", run, run);
}
// ---- wikitext location ----
// Bounds the language section as line indices into pageContent.split("\n"), and finds the matching POS
// heading's own line index within that range by sectionType+ordinal, never by a DOM id number (MediaWiki's
// page-wide anchor uniquification can attach an id to a heading unrelated to its actual position).
function locateSection(pageContent, language, sectionType, sectionOrdinal) {
// The placeholder heading is matched by its own literal name, not by the POS list below.
if (sectionType === MANE_SECTION) {
var maneLoc = locateManeSection(pageContent, language, sectionOrdinal);
return {
langSectionIndex: maneLoc.langSectionIndex,
lines: maneLoc.lines,
posLineIndex: maneLoc.maneLineIndex
};
}
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
if (!sectionNames[sectionType]) {
throw new SubmitAbort("Navê beşê xelet e.");
}
// lines covers the whole rest of the page from this language's heading onward, since the caller reuses
// it to rebuild the entire saved text; only the section-heading search itself is bounded by sectionSearchEndLine.
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var sectionNamesRegex = Object.keys(sectionNames).join("|");
// Closing "===" anchored, like locateManeSection(): otherwise "=== Navdêra pirjimar ===" counts as a POS occurrence here while sectionTypeOf() rejects it, desyncing the ordinal.
var sectionRegex = new RegExp("^===[ ]*(" + sectionNamesRegex + ")\\s*(\\d+)?[ ]*===");
var posLineIndex;
var occurrence = 0;
for (posLineIndex = 0; posLineIndex < sectionSearchEndLine; posLineIndex++) {
var m = sectionRegex.exec(lines[posLineIndex]);
if (m && sectionNames[sectionType].indexOf(m[1]) !== -1) {
occurrence++;
if (occurrence === sectionOrdinal) {
break;
}
}
}
if (posLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene.");
}
return { langSectionIndex: langSectionIndex, lines: lines, posLineIndex: posLineIndex };
}
// Walks "#"-prefixed lines from posLineIndex to find the exact line for definitionLevel: element 0 is
// unused (it's the "type|ordinal" string locateSection already resolved), remaining elements are 0-based
// indices, one per nesting level.
function findDefinitionLine(lines, posLineIndex, definitionLevel) {
var defIndex = -1;
var level = 1;
for (var i = posLineIndex; i < lines.length; i++) {
var m = /^(#+)[^*#:]/.exec(lines[i]);
if (m && m[1].length === level) {
defIndex++;
if (definitionLevel[level] === defIndex) {
if (level === definitionLevel.length - 1) {
return i;
}
level++;
defIndex = -1;
}
}
}
throw new SubmitAbort("Nikarî rêza vê maneyê di nivîsê de bibîne.");
}
// Inserts or extends a "#: {{tplKey|lang|word1|word2}}" sub-line for one sense (start.js's wordLine()
// format). If a line for this tplKey already exists under the definition, missing words are appended to
// it; otherwise a new line lands after the last existing group line, always before any "#*" citation lines.
function insertSenseWords(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, words, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = new Array(definitionLevel.length).join("#"); // definitionLevel.length - 1 "#" characters
var tplLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*" + escapeRegExp(tplKey) + "\\s*\\|([^}]*)\\}\\}\\s*$");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\\s*\\{\\{\\s*(" + groupKeysPattern + ")\\s*\\|");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var lastGroupLine = -1;
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var tplMatch = tplLineRegex.exec(lines[i]);
if (tplMatch) {
if (opts.replace) {
// Editing an existing list: an empty result means the user cleared it, so drop the line.
if (words.length) {
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}";
} else {
lines.splice(i, 1);
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
var params = tplMatch[1].split("|"); // [lang, word1, word2, ...]
var existingWords = params.slice(1);
words.forEach(function (w) {
if (existingWords.indexOf(w) === -1) {
existingWords.push(w);
}
});
lines[i] = marker + ": {{" + tplKey + "|" + language + "|" + existingWords.join("|") + "}}";
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
if (groupLineRegex.test(lines[i])) {
lastGroupLine = i;
}
}
var insertAt = lastGroupLine >= 0 ? lastGroupLine + 1 : defLine + 1;
lines.splice(insertAt, 0, marker + ": {{" + tplKey + "|" + language + "|" + words.join("|") + "}}");
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Canonical left-to-right order of the small templates that can prefix a definition line's gloss text:
// maneid, then kategori (K), then etîket (e).
var LEADING_TPL_ORDER = ["maneid", "K", "e"];
// Parses the leading run of "{{...}}" calls off the front of a definition line's text-after-marker,
// stopping at the first thing that isn't one (normally the gloss text). Shared by insertLeadingSenseTpl()
// (uses "calls", as readSenseFields() also does). "rest" is the gloss text left after every leading call.
function splitLeadingCalls(afterMarker) {
var calls = [];
var rest = afterMarker;
var leadingRegex = /^\{\{\s*([^{}|]+?)\s*\|([^{}]*)\}\}\s*/;
var m;
while ((m = leadingRegex.exec(rest)) !== null) {
calls.push({ key: m[1], params: m[2].split("|") });
rest = rest.slice(m[0].length);
}
return { calls: calls, rest: rest };
}
// Inserts, extends, or (with opts.replace) overwrites one of the small templates that prefix a definition
// line's gloss text -- {{maneid|lang|id}}, {{K|lang|kat1|...}} or {{e|lang|etîket1|...}}. Under
// opts.replace an empty values list removes the call rather than writing an empty one.
function insertLeadingSenseTpl(pageContent, language, sectionType, sectionOrdinal, definitionLevel, tplKey, values, opts) {
opts = opts || {};
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(marker.length).replace(/^\s+/, "");
// Collecting the whole leading-call run means an existing tplKey call is found and merged wherever it
// already sits, not just when it happens to be first.
var split = splitLeadingCalls(afterMarker);
var calls = split.calls;
var rest = split.rest;
var existing = null;
calls.forEach(function (c) {
if (c.key === tplKey) {
existing = c;
}
});
if (existing) {
if (opts.replace) {
// Editing an existing call: an empty result means the user cleared it, so drop the call.
if (values.length) {
existing.params = [language].concat(values);
} else {
calls = calls.filter(function (c) { return c !== existing; });
}
} else {
var existingVals = existing.params.slice(1);
values.forEach(function (v) {
if (existingVals.indexOf(v) === -1) {
existingVals.push(v);
}
});
existing.params = [language].concat(existingVals);
}
} else if (!values.length) {
return pageContent; // nothing to add, and nothing there to clear
} else {
// Not present yet -- insert right before the first existing call that outranks tplKey in
// LEADING_TPL_ORDER (an unrecognized call always outranks everything), or at the end of the run.
var myRank = LEADING_TPL_ORDER.indexOf(tplKey);
var insertAt = calls.length;
for (var i = 0; i < calls.length; i++) {
var otherRank = LEADING_TPL_ORDER.indexOf(calls[i].key);
if (otherRank === -1 || otherRank > myRank) {
insertAt = i;
break;
}
}
calls.splice(insertAt, 0, { key: tplKey, params: [language].concat(values) });
}
var rebuilt = calls.map(function (c) {
return "{{" + c.key + "|" + c.params.join("|") + "}}";
}).join(" ");
lines[defLine] = marker + " " + (rebuilt ? rebuilt + " " : "") + rest;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Replaces just the gloss text of a definition line, leaving any leading template calls untouched --
// the save half of "Maneyê biguhêre" (edit sense).
function updateSenseGloss(pageContent, language, sectionType, sectionOrdinal, definitionLevel, newGloss) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var marker = /^#+/.exec(lines[defLine])[0];
// The box shows the raw line, templates included, so whatever the user left in it is what gets written.
lines[defLine] = marker + " " + newGloss;
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Fetches the page's current wikitext and pulls out just this sense's gloss text to prefill the "Maneyê
// biguhêre" form. A plain read, not part of the hardened save path -- the actual save still re-fetches
// fresh content, so only the prefilled text itself could be a little stale.
// Current contents of one existing subsection, for prefilling the edit form.
function fetchPageSubsection(language, sectionType, sectionOrdinal, subsection) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
return readPageSubsection(content, language, sectionType, sectionOrdinal, subsection);
});
}
function fetchSenseFields(language, sectionType, sectionOrdinal, definitionLevel) {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
titles: mw.config.get("wgPageName"),
formatversion: 2
}).then(function (data) {
var page = data.query && data.query.pages && data.query.pages[0];
var content = page && !page.missing && page.revisions && page.revisions[0] && page.revisions[0].content;
if (!content) {
throw new SubmitAbort("Nikarî muhtewaya rûpelê bixwîne.");
}
return readSenseFields(content, language, sectionType, sectionOrdinal, definitionLevel);
});
}
// Everything the advanced panel can edit about one sense, read off its definition line and the "#:" lines
// under it: the raw gloss (templates included), the leading maneid/K/e values, and each word-list group.
function readSenseFields(pageContent, language, sectionType, sectionOrdinal, definitionLevel) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var defLine = findDefinitionLine(lines, loc.posLineIndex, definitionLevel);
var defMarker = /^#+/.exec(lines[defLine])[0];
var afterMarker = lines[defLine].slice(defMarker.length).replace(/^\s+/, "");
var leading = {};
splitLeadingCalls(afterMarker).calls.forEach(function (c) {
leading[c.key] = c.params.slice(1);
});
// Only start.js's "{{mane?|lang}}" placeholder is hidden; every other template stays visible so it can
// be edited by hand in the gloss box.
var gloss = afterMarker.replace(/^\{\{\s*mane\?\s*\|[^{}]*\}\}\s*/, "");
var marker = new Array(definitionLevel.length).join("#");
var groupKeysPattern = SENSE_GROUPS.map(function (g) { return escapeRegExp(g.key); }).join("|");
var groupLineRegex = new RegExp("^" + marker + ":\s*\{\{\s*(" + groupKeysPattern + ")\s*\|([^}]*)\}\}\s*$");
var anyBlockLineRegex = new RegExp("^" + marker + "[:*]");
var words = {};
for (var i = defLine + 1; i < lines.length; i++) {
if (!anyBlockLineRegex.test(lines[i])) {
break;
}
var m = groupLineRegex.exec(lines[i]);
if (m) {
words[m[1]] = m[2].split("|").slice(1);
}
}
return {
gloss: gloss,
maneid: leading.maneid ? leading.maneid[0] : "",
etiket: leading.e || [],
kategori: leading.K || [],
words: words
};
}
// Finds a POS block's body range (up to, but not including, the next heading of level <= 3), and the
// header text + line index of any "====" subsections it already contains.
function posBlockBounds(lines, posLineIndex) {
var end = lines.length;
var existingHeaders = [];
for (var i = posLineIndex + 1; i < lines.length; i++) {
if (/^===[^=]/.test(lines[i]) || /^==[^=]/.test(lines[i])) {
end = i;
break;
}
var h4 = /^====\s*([^=]+?)\s*====/.exec(lines[i]);
if (h4) {
existingHeaders.push({ header: h4[1].trim(), lineIndex: i });
}
}
return { end: end, existingHeaders: existingHeaders };
}
// Looks up a header's rank in SUBSECTION_ORDER. -1 for a header that isn't one of ours; such a header is
// never used as an insertion anchor.
function subsectionRankForHeader(header) {
return SUBSECTION_ORDER.indexOf(header);
}
// Body line range of one "====" subsection inside a POS block: everything after its heading up to the next
// "====" heading, or the end of the block. Null if the block has no such subsection.
function subsectionBodyRange(bounds, header) {
var headers = bounds.existingHeaders;
for (var i = 0; i < headers.length; i++) {
if (headers[i].header === header) {
return {
start: headers[i].lineIndex + 1,
end: i + 1 < headers.length ? headers[i + 1].lineIndex : bounds.end
};
}
}
return null;
}
// Splits a template call's inner text on its top-level "|", ignoring pipes nested in {{...}} or [[...]].
function splitTemplateParams(inner) {
var parts = [];
var buf = "";
var tpl = 0;
var link = 0;
for (var i = 0; i < inner.length; i++) {
var two = inner.substr(i, 2);
if (two === "{{" || two === "}}" || two === "[[" || two === "]]") {
if (two === "{{") { tpl++; } else if (two === "}}") { tpl--; } else if (two === "[[") { link++; } else { link--; }
buf += two;
i++;
continue;
}
if (inner.charAt(i) === "|" && tpl === 0 && link === 0) {
parts.push(buf);
buf = "";
continue;
}
buf += inner.charAt(i);
}
parts.push(buf);
return parts;
}
// Pulls a {{kol3|ku|cure=Jê|word|word}}-style call apart into the bits an edit has to preserve (template
// name, language, named params) plus the positional word list. Null if the body has no such call.
function parseWordListCall(text) {
var m = new RegExp("\{\{\s*(" + WORDLIST_TEMPLATES.join("|") + ")\s*[|}]", "i").exec(text);
if (!m) {
return null;
}
var open = m.index;
var depth = 0;
var close = -1;
for (var i = open; i < text.length - 1; i++) {
var two = text.substr(i, 2);
if (two === "{{") {
depth++;
i++;
} else if (two === "}}") {
depth--;
i++;
if (depth === 0) {
close = i + 1;
break;
}
}
}
if (close === -1) {
return null;
}
var parts = splitTemplateParams(text.slice(open + 2, close - 2));
var named = [];
var words = [];
for (var pi = 2; pi < parts.length; pi++) {
var val = $.trim(parts[pi]);
if (!val) {
continue;
}
if (/^[A-Za-z][A-Za-z0-9_-]*\s*=/.test(val)) {
named.push(val);
} else {
words.push(val);
}
}
return {
name: $.trim(parts[0]),
lang: parts.length > 1 ? $.trim(parts[1]) : "",
named: named,
words: words,
start: open,
end: close
};
}
// Canonical multi-line layout, matching how existing ku.wiktionary lists are written (one word per line).
function buildWordListCall(name, lang, named, words) {
var head = "{{" + name + "|" + lang;
named.forEach(function (n) {
head += "|" + n;
});
return words.length ? head + "\n|" + words.join("\n|") + "\n}}" : head + "\n}}";
}
// Current contents of an existing "====" subsection. A wordlist one whose template can't be parsed comes
// back as {kind: "text"} so the caller can still edit it as raw wikitext instead of refusing outright.
function readPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var bounds = posBlockBounds(loc.lines, loc.posLineIndex);
var range = subsectionBodyRange(bounds, subsection.header);
if (!range) {
return null;
}
var body = loc.lines.slice(range.start, range.end).join("\n");
if (subsection.kind === "wordlist") {
var call = parseWordListCall(body);
if (call) {
return { kind: "wordlist", words: call.words };
}
}
return { kind: "text", text: $.trim(body) };
}
// Rewrites an existing "====" subsection in place. A wordlist one keeps its own template name, language and
// named params ("cure=Jê", ...) and only has its positional words replaced; a text one is replaced whole.
function updatePageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var range = subsectionBodyRange(bounds, subsection.header);
if (!range) {
throw new SubmitAbort("Ev beş li vir tune: " + subsection.header);
}
var body = lines.slice(range.start, range.end).join("\n");
var replacement;
if (subsection.kind === "wordlist") {
var call = parseWordListCall(body);
if (!call) {
throw new SubmitAbort("Nikarî lîsteya vê beşê bixwîne: " + subsection.header);
}
// body.slice(call.end) already carries whatever trailed the call, blank separator line included.
replacement = body.slice(0, call.start) +
buildWordListCall(call.name, call.lang, call.named, content) +
body.slice(call.end);
} else {
// Replacing the body wholesale drops that separator, so put it back.
replacement = content + (/\n\s*$/.test(body) ? "\n" : "");
}
lines.splice(range.start, range.end - range.start, replacement);
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// Inserts a new "==== Header ====" subsection into its SUBSECTION_ORDER position within a POS block, right
// before the first ranked subsection that outranks it, or at the end if none does. Either a
// {{kol3|...}} word list or a plain paragraph, matching start.js's own subsection formats.
function insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, subsection, content) {
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var bounds = posBlockBounds(lines, loc.posLineIndex);
var alreadyThere = false;
bounds.existingHeaders.forEach(function (h) {
if (h.header === subsection.header) {
alreadyThere = true;
}
});
if (alreadyThere) {
throw new SubmitAbort("Ev beş jixwe heye: " + subsection.header);
}
var body = subsection.kind === "wordlist"
? buildWordListCall("kol3", language, ["cure=" + subsection.header], content)
: content;
var myRank = subsectionRankForHeader(subsection.header);
var headers = bounds.existingHeaders;
var insertAt = bounds.end;
for (var i = 0; i < headers.length; i++) {
var otherRank = subsectionRankForHeader(headers[i].header);
if (otherRank !== -1 && otherRank > myRank) {
insertAt = headers[i].lineIndex;
break;
}
}
// Exactly one blank line on each side: the line before the insertion point is normally already blank
// (it separated the previous subsection from the next heading), so only add one where there isn't one.
var block = [];
if (insertAt > 0 && $.trim(lines[insertAt - 1]) !== "") {
block.push("");
}
block.push("==== " + subsection.header + " ====", body);
if (insertAt < lines.length) {
block.push("");
}
lines.splice.apply(lines, [insertAt, 0].concat(block));
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- converting an unclassified "=== Mane ===" placeholder heading into a real POS heading ----
// Some pages carry a heading literally named "Mane" (optionally "Mane 2" etc.) instead of a real
// part-of-speech name, tagged right below with {{cure?|<lang>}} (ku.wiktionary's "part of speech not yet
// determined" maintenance flag). Neither is in sectionNames, so these two functions are a small parallel
// path just for finding/rewriting that one placeholder heading.
// Same document-position technique as locateSection(), but matches the literal "Mane" heading text
// (plus an optional disambiguating trailing number) instead of a recognized POS name.
function locateManeSection(pageContent, language, maneOrdinal) {
var langSectionRegex = new RegExp("==[ ]*\\{\\{ziman\\|" + escapeRegExp(language) + "\\}\\}[ ]*==");
var langSectionIndex = pageContent.search(langSectionRegex);
if (langSectionIndex === -1) {
throw new SubmitAbort("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + language);
}
var afterLangHeading = pageContent.indexOf("\n", langSectionIndex);
afterLangHeading = afterLangHeading === -1 ? pageContent.length : afterLangHeading + 1;
var nextLangSectionMatch = /\n==[^=\n][^\n]*==/.exec(pageContent.slice(afterLangHeading));
var langSectionEnd = nextLangSectionMatch ? afterLangHeading + nextLangSectionMatch.index : pageContent.length;
var lines = pageContent.slice(langSectionIndex).split("\n");
var sectionSearchEndLine = pageContent.slice(langSectionIndex, langSectionEnd).split("\n").length;
var maneRegex = /^===[ ]*Mane(\s+\d+)?[ ]*===/;
var maneLineIndex;
var occurrence = 0;
for (maneLineIndex = 0; maneLineIndex < sectionSearchEndLine; maneLineIndex++) {
if (maneRegex.test(lines[maneLineIndex])) {
occurrence++;
if (occurrence === maneOrdinal) {
break;
}
}
}
if (maneLineIndex === sectionSearchEndLine) {
throw new SubmitAbort("Beşa 'Mane' ya nediyarkirî li ser rûpelê nehat dîtin. Dibe ku rûpel hatibe guhertin.");
}
return { langSectionIndex: langSectionIndex, lines: lines, maneLineIndex: maneLineIndex };
}
// Renames the "=== Mane ===" placeholder to the chosen POS heading, drops the maintenance tag line right
// after it if present (MANE_TAG_REGEX -- cure? or any of its known aliases), and inserts the matching
// "{{<pos>|<lang>}}" template call in its place (skipped for section types with no POS_TEMPLATE entry).
// Other content under the heading is left untouched.
function convertSectionToPos(pageContent, language, sectionType, sectionOrdinal, newSectionType, posParams) {
if (!sectionNames[newSectionType]) {
throw new SubmitAbort("Navê cureyê rêzimanî yê hilbijartî nediyar e.");
}
// locateSection() already handles the "Mane" placeholder as a section type of its own.
var loc = locateSection(pageContent, language, sectionType, sectionOrdinal);
var lines = loc.lines;
var headingLine = loc.posLineIndex;
// Keep the author's own disambiguating number: "=== Biwêj 2 ===" becomes "=== Navdêr 2 ===".
var inner = /^===[ ]*(.*?)[ ]*===\s*$/.exec(lines[headingLine]);
var numMatch = inner ? /(\s*\d+)$/.exec(inner[1]) : null;
lines[headingLine] = "=== " + newSectionType + (numMatch ? numMatch[1] : "") + " ===";
// The line under the heading is either the old section's own template call ("{{biwêj|ku}}") or, for a
// Mane placeholder, the "needs a POS" maintenance tag. Both are replaced by the new POS's call.
var oldTemplate = POS_TEMPLATE[sectionType];
var oldTemplateRegex = oldTemplate && new RegExp("^\{\{\s*" + escapeRegExp(oldTemplate) + "\s*[|}]");
var nextLineIndex = headingLine + 1;
if (nextLineIndex < lines.length &&
(MANE_TAG_REGEX.test(lines[nextLineIndex]) ||
(oldTemplateRegex && oldTemplateRegex.test(lines[nextLineIndex])))) {
lines.splice(nextLineIndex, 1);
}
var posTemplate = POS_TEMPLATE[newSectionType];
if (posTemplate) {
lines.splice(nextLineIndex, 0, "{{" + posTemplate + "|" + language + (posParams ? "|" + posParams : "") + "}}");
}
return pageContent.slice(0, loc.langSectionIndex) + lines.join("\n");
}
// ---- "guhartina pêşketî" (advanced editing): combine several independent per-sense edits into ONE save ----
// Threads pageContent through the same pure functions every single-field form uses, applying only the
// pieces the caller actually filled in. A piece that conflicts with the page (maneid already set, a
// subsection that's already there) is skipped with a warning rather than failing the whole save. Throws
// SubmitAbort if nothing was filled in, so this can never turn into a no-op save.
function applyAdvancedChanges(pageContent, language, sectionType, sectionOrdinal, definitionLevel, changes) {
var content = pageContent;
var warnings = [];
var appliedAnything = false;
if (changes.gloss) {
content = updateSenseGloss(content, language, sectionType, sectionOrdinal, definitionLevel, changes.gloss);
appliedAnything = true;
}
// Every box below is prefilled with what the sense already has, so a save replaces that value rather
// than merging into it -- and clearing a box removes the template. changes.changed marks the boxes
// whose contents actually differ from the page, so an opened-but-untouched box writes nothing.
var replace = { replace: true };
if (changes.changed.maneid) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "maneid", changes.maneid ? [changes.maneid] : [], replace);
appliedAnything = true;
}
if (changes.changed.etiket) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "e", changes.etiket, replace);
appliedAnything = true;
}
if (changes.changed.kategori) {
content = insertLeadingSenseTpl(content, language, sectionType, sectionOrdinal, definitionLevel, "K", changes.kategori, replace);
appliedAnything = true;
}
SENSE_GROUPS.forEach(function (group) {
if (changes.changed["word:" + group.key]) {
content = insertSenseWords(content, language, sectionType, sectionOrdinal, definitionLevel, group.key, changes.words[group.key], replace);
appliedAnything = true;
}
});
if (!appliedAnything) {
throw new SubmitAbort("Tiştek nehat guhertin.");
}
return { content: content, warnings: warnings };
}
// ---- per-definition UI: a small always-visible "+" toggle (no hover, so it works on mobile/touch too) ----
// Finds the button Gadget-wikt.add-examples.js already inserted for this definition, by its exact text.
function findExampleButton($li) {
var found = null;
$li.find("a").each(function () {
if ($(this).text().trim() === "Nimûneyeke bikaranînê lê zêde bike") {
found = $(this);
return false;
}
});
return found;
}
// Growing word list: every word is its own always-visible row (word box + a "+" to attach one of the 10
// WORD_MODIFIERS as a small pill + an "x" to drop the row); a fresh empty row appears automatically once
// the current last row gets text. Duplicate words are allowed; every row's own box is always live.
function buildWordListField(placeholder) {
var $list = $("<ol class='dsb-wordlist'></ol>");
function modDef(key) {
var found = null;
WORD_MODIFIERS.forEach(function (wm) {
if (wm.key === key) {
found = wm;
}
});
return found;
}
function makeRow() {
var mods = [];
var $li = $("<li class='dsb-word-li'></li>");
var $modsRow = $("<div class='dsb-word-mods'></div>").hide();
var $wordInput = $("<input type='text' class='dsb-input dsb-word-input'>").attr("placeholder", placeholder);
var $addMod = $("<button type='button' class='dsb-mod-btn' title='Taybetiyekê lê zêde bike'>⊕</button>").hide();
var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>×</button>").hide();
var $picker = $("<div class='dsb-mod-picker'></div>").hide();
var $boxRow = $("<div class='dsb-word-box-row'></div>").append($wordInput, $addMod, $removeRow);
function usedKeys() {
var used = {};
mods.forEach(function (mo) {
used[mo.key] = true;
});
return used;
}
function renderMods() {
$modsRow.empty();
mods.forEach(function (mo, idx) {
var $chip = $("<span class='dsb-word-mod-chip' role='button' tabindex='0'></span>").text(modChipLabel(mo));
var $x = $("<button type='button' class='dsb-word-mod-chip-remove' title='Vê taybetiyê jê bibe'>×</button>");
$x.on("click", function (e) {
e.stopPropagation();
mods.splice(idx, 1);
renderMods();
});
$chip.on("click", function () {
var def = modDef(mo.key);
if (def) {
openValueEditor(def, idx);
}
});
$chip.append($x);
$modsRow.append($chip);
});
$modsRow.toggle(!!mods.length);
}
// Same value-entry UI for both "add" (existingIdx === -1) and "edit" (click on an existing pill).
function openValueEditor(mod, existingIdx) {
$picker.hide();
var $wrap = $("<span class='dsb-mod-val-wrap'></span>");
var $valInput = $("<input type='text' class='dsb-input dsb-mod-val-input'>")
.attr("placeholder", mod.hint + "…")
.val(existingIdx === -1 ? "" : mods[existingIdx].value);
var $confirm = $("<button type='button' class='dsb-mod-confirm' title='Erê'>✓</button>");
var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>✕</button>");
function apply() {
var v = $.trim($valInput.val());
if (v) {
if (existingIdx === -1) {
mods.push({ key: mod.key, value: v });
} else {
mods[existingIdx].value = v;
}
renderMods();
}
$wrap.remove();
$wordInput.trigger("focus");
}
$confirm.on("click", apply);
$cancel.on("click", function () {
$wrap.remove();
$wordInput.trigger("focus");
});
$valInput.on("keydown", function (e) {
if (e.which === 13) {
e.preventDefault();
apply();
} else if (e.which === 27) {
$wrap.remove();
$wordInput.trigger("focus");
}
});
$wrap.append($valInput, $confirm, $cancel);
$li.append($wrap);
$valInput.trigger("focus");
}
// The 10 pills are built lazily on first "+" open, not for every word row up front.
var pillsBuilt = false;
function buildPills() {
if (pillsBuilt) {
return;
}
pillsBuilt = true;
WORD_MODIFIERS.forEach(function (mod) {
var $pill = $("<button type='button' class='dsb-mod-pill'></button>").text(mod.label).attr("title", mod.hint);
$pill.data("mod-key", mod.key);
$pill.on("click", function (e) {
e.preventDefault();
if ($pill.prop("disabled")) {
return;
}
openValueEditor(mod, -1);
});
$picker.append($pill);
});
}
$addMod.on("click", function (e) {
e.preventDefault();
$list.find(".dsb-mod-picker").not($picker).hide();
buildPills();
var used = usedKeys();
$picker.find(".dsb-mod-pill").each(function () {
var isUsed = !!used[$(this).data("mod-key")];
$(this).prop("disabled", isUsed).toggleClass("dsb-mod-pill-used", isUsed);
});
$picker.toggle();
});
$removeRow.on("click", function () {
$li.remove();
});
function updateButtons() {
var hasWord = !!$.trim($wordInput.val());
$addMod.toggle(hasWord);
$removeRow.toggle(hasWord);
if (!hasWord) {
$picker.hide();
}
}
updateButtons();
// Grows the list: typing into the current last row appends a fresh empty one after it, so there
// is always exactly one empty trailing row to type into.
$wordInput.on("input", function () {
updateButtons();
var isLast = $li.is($list.children("li").last());
if (isLast && $.trim($wordInput.val()) !== "") {
$list.append(makeRow());
}
});
$wordInput.on("keydown", function (e) {
if (e.which === 13) { // Enter moves on instead of inserting a newline
e.preventDefault();
$wordInput.trigger("blur");
}
});
$li.on("focusout", function () {
setTimeout(function () {
if (!$.contains($li.get(0), document.activeElement)) {
$picker.hide();
}
}, 150);
});
$li.data("wordInput", $wordInput);
$li.data("getRaw", function () {
return joinWordValue($.trim($wordInput.val()), mods);
});
$li.data("setRaw", function (raw) {
var parsed = splitWordValue(raw);
mods = parsed.mods;
$wordInput.val(parsed.word);
renderMods();
updateButtons();
});
$li.append($modsRow, $boxRow, $picker);
return $li;
}
$list.append(makeRow());
return {
$element: $list,
values: function () {
var vals = [];
$list.children("li").each(function () {
var raw = $(this).data("getRaw")();
if (raw) {
vals.push(raw);
}
});
return vals;
},
// Replaces the whole list, keeping one empty trailing row to type into.
setValues: function (raws) {
$list.empty();
raws.forEach(function (raw) {
var $row = makeRow();
$list.append($row);
$row.data("setRaw")(raw);
});
$list.append(makeRow());
},
focus: function () {
$list.children("li").first().data("wordInput").trigger("focus");
}
};
}
// Plain removable-tag field, used for Etîket and Kategorî (simple value lists with no per-word modifiers).
// Enter or "," commits the current text as a tag; Backspace on an empty input removes the last tag;
// values() also commits whatever is still typed but not yet confirmed.
function buildTagField(placeholder) {
var $input = $("<input type='text' class='dsb-input dsb-tag-input'>").attr("placeholder", placeholder);
var $element = $("<span class='dsb-tagfield'></span>").append($input);
function currentValues() {
var vals = [];
$element.children(".dsb-tag").each(function () {
vals.push($(this).data("value"));
});
return vals;
}
function addTag(val) {
val = $.trim(val || "");
if (!val || currentValues().indexOf(val) !== -1) {
return;
}
var $tag = $("<span class='dsb-tag'></span>").text(val).data("value", val);
var $remove = $("<button type='button' class='dsb-tag-remove' title='Jê bibe'>×</button>");
$remove.on("click", function () {
$tag.remove();
$input.trigger("focus");
});
$tag.append($remove);
$tag.insertBefore($input);
}
$input.on("keydown", function (e) {
if (e.which === 13 || e.which === 188) { // Enter or comma
e.preventDefault();
addTag($input.val());
$input.val("");
} else if (e.which === 8 && !$input.val()) {
$element.children(".dsb-tag").last().remove();
}
});
$input.on("blur", function () {
addTag($input.val());
$input.val("");
});
return {
$element: $element,
// Replaces every tag, for prefilling from what the sense already has.
setValues: function (vals) {
$element.children(".dsb-tag").remove();
vals.forEach(function (v) {
addTag(v);
});
$input.val("");
},
values: function () {
addTag($input.val());
$input.val("");
return currentValues();
},
focus: function () {
$input.trigger("focus");
}
};
}
// Builds the whole "guhartina pêşketî" panel into $quickRow: gloss and the two most-used word lists
// (Hevmane/Dijmane) sit directly in the picker row; the remaining word lists, maneid, etîket, kategorî
// and Nimûne/jêgirtin live behind a "Zêdetir" dropdown; one shared "Lê zêde bike" queues everything the
// user filled in as a single edit via applyAdvancedChanges() and queueChange(). Nimûne/jêgirtin is an
// immediate proxy-click into a different gadget's own form, not part of this combined save.
function buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel) {
var $nimune = $("<a href='#' class='dsb-quick-link'></a>").text("Nimûne/jêgirtin lê zêde bike");
$nimune.on("click", function (e) {
e.preventDefault();
var $btn = findExampleButton($li);
if ($btn) {
// Hidden by default (see .add-example-form-title in the CSS); the inline style beats that rule.
$btn.closest("li").show();
$btn.trigger("click");
} else {
mw.notify("Bişkoja amûra add-examples li vê maneyê nehat dîtin.");
}
$moreMenu.slideUp();
});
// getters holds one function per currently-open box (key -> () => value); collectChanges() only ever
// reads from a box the user actually clicked to open.
var getters = {};
// What the sense currently holds, fetched once and shared by every box that prefills from it.
// collectChanges() also diffs against it, so an untouched box never queues a change.
var original = null;
var sensePromise = null;
function loadSense() {
if (!sensePromise) {
sensePromise = fetchSenseFields(language, sectionType, sectionOrdinal, definitionLevel).then(function (fields) {
original = fields;
return fields;
});
}
return sensePromise;
}
function sameList(a, b) {
return (a || []).join("\u0000") === (b || []).join("\u0000");
}
// -- gloss ("Maneyê biguhêre" -- the one box that EDITS the sense's wording; everything else here only ADDS) --
function addGlossField() {
var $textarea = $("<textarea class='dsb-input dsb-edit-gloss' rows='2'></textarea>").attr("placeholder", "tê barkirin…").prop("disabled", true);
var $autoLink = $("<button type='button' class='dsb-autolink'>Oto-lînk bike</button>").prop("disabled", true);
var $status = $("<span class='dsb-status'></span>");
var originalGloss = null;
loadSense().then(
function (fields) {
originalGloss = fields.gloss;
$textarea.val(fields.gloss).prop("disabled", false);
$autoLink.prop("disabled", false);
},
function (codeOrAbort, result) {
var message = codeOrAbort instanceof SubmitAbort ? codeOrAbort.message : "Nekarî maneya heyî bar bike: " + apiErrorMessage(codeOrAbort, result);
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text(message);
}
);
$autoLink.on("click", function () {
var current = $textarea.val();
if (!$.trim(current)) {
return;
}
$autoLink.prop("disabled", true);
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(current, function (linked) {
$textarea.val(linked);
$autoLink.prop("disabled", false);
$status.text("");
});
});
getters.gloss = function () {
var v = $.trim($textarea.val());
return (v && v !== originalGloss) ? v : null;
};
return $("<div class='dsb-adv-group'></div>").append(
$("<div class='dsb-adv-label'></div>").text("Mane"),
$textarea,
$("<div class='dsb-form-actions'></div>").append($autoLink, $status)
);
}
// -- one SENSE_GROUPS word-list box (Hevmane/Dijmane/etc.) --
function addWordField(group) {
var field = buildWordListField(group.label + "…");
loadSense().then(function (fields) {
var current = fields.words[group.key];
if (current && current.length) {
field.setValues(current);
}
});
getters["word:" + group.key] = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text(group.label), field.$element);
}
// -- maneid (single value; re-adding one that already exists is rejected -- see applyAdvancedChanges) --
function addManeidField() {
var $input = $("<input type='text' class='dsb-input' placeholder='nasnav…'>");
loadSense().then(function (fields) {
$input.val(fields.maneid);
});
getters.maneid = function () {
return $.trim($input.val());
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Nasnav (maneid)"), $input);
}
// -- etîket / kategorî --
function addEtiketField() {
var field = buildTagField("Etîket…");
loadSense().then(function (fields) {
field.setValues(fields.etiket);
});
getters.etiket = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Etîket"), field.$element);
}
function addKategoriField() {
var field = buildTagField("Kategorî…");
loadSense().then(function (fields) {
field.setValues(fields.kategori);
});
getters.kategori = function () {
return field.values();
};
return $("<div class='dsb-adv-group'></div>").append($("<div class='dsb-adv-label'></div>").text("Kategorî"), field.$element);
}
// -- the picker row: the gloss and Nimûne/jêgirtin links sit directly in the row; every word group and
// the rest live behind a "Zêdetir" dropdown. Clicking any link builds and appends its box
// to $openBoxes and hides that link; the box's own "×" removes it, clears its getter, and un-hides the
// link -- several boxes can be open at once. No "Beşek (====)" entry here: buildSubsectionPanel()'s
// own "+ Beşek lê zêde bike" trigger already covers page-level subsections. ----
var FIELD_DEFS = [{ key: "gloss", label: "Maneyê biguhêre", build: addGlossField, primary: true }]
.concat(SENSE_GROUPS.map(function (group) {
return { key: "word:" + group.key, label: group.label, build: function () { return addWordField(group); }, primary: false };
}))
.concat([
{ key: "maneid", label: "Nasnav (maneid)", build: addManeidField, primary: false },
{ key: "etiket", label: "Etîket", build: addEtiketField, primary: false },
{ key: "kategori", label: "Kategorî", build: addKategoriField, primary: false }
]);
var $picker = $("<div class='dsb-field-picker'></div>");
var $moreMenu = $("<div class='dsb-more-menu'></div>").hide();
var $openBoxes = $("<div class='dsb-open-boxes'></div>");
// $actions (built below) stays hidden until at least one field box is actually open -- otherwise
// "Lê zêde bike" sits there enabled with nothing to queue, which just produces an empty no-op change.
var openBoxCount = 0;
function updateActionsVisibility() {
$actions.toggle(openBoxCount > 0);
}
FIELD_DEFS.forEach(function (def) {
var $link = $("<a href='#' class='dsb-quick-link dsb-field-pick'></a>").text(def.key === "gloss" ? def.label : "+ " + def.label);
$link.on("click", function (e) {
e.preventDefault();
var $box = def.build();
var $remove = $("<a href='#' class='dsb-box-remove' title='Rake'>×</a>");
$remove.on("click", function (e2) {
e2.preventDefault();
delete getters[def.key];
$box.remove();
$link.show();
openBoxCount--;
updateActionsVisibility();
});
$box.prepend($remove);
$openBoxes.append($box);
$link.hide();
$moreMenu.slideUp();
openBoxCount++;
updateActionsVisibility();
});
(def.primary ? $picker : $moreMenu).append($link);
if (def.key === "gloss") {
$picker.append($nimune); // directly after "Maneyê biguhêre"
}
});
// Lives inside $picker (not appended straight to $quickRow) so .dsb-more-menu's CSS can position it as
// an overlay anchored to $picker, instead of pushing $openBoxes/the rest of the page down when it opens.
var $moreToggle = $("<a href='#' class='dsb-quick-link dsb-more-toggle'>Zêdetir</a>");
$moreToggle.on("click", function (e) {
e.preventDefault();
$moreMenu.slideToggle();
});
$picker.append($moreToggle, $moreMenu);
// Closes the dropdown on an outside click, scoped to this panel's own $moreToggle/$moreMenu.
$(document).on("click", function (e) {
if (!$(e.target).closest($moreToggle).length && !$(e.target).closest($moreMenu).length) {
$moreMenu.slideUp();
}
});
// -- combined save: whatever boxes are open right now, queued together via queueChange(); the actual
// save happens when the user clicks "Guhertinan qeyd bike" on the floating queue box. ----
// Small "not saved yet" preview of everything this queued change will do, appended right under the
// sense's gloss (plain text, not a real render of {{hevmane}}/etc.).
function buildChangesPreview(changes) {
var $prev = $("<div class='dsb-preview-inline'></div>");
$prev.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
var $list = $("<ul class='dsb-preview-list'></ul>");
function plain(w) {
return w.replace(/<[^<>]*>/g, "");
}
if (changes.gloss) {
$list.append($("<li></li>").text("Mane: " + changes.gloss));
}
SENSE_GROUPS.forEach(function (group) {
var words = changes.words && changes.words[group.key];
if (words && words.length) {
$list.append($("<li></li>").text(group.label + ": " + words.map(plain).join(", ")));
}
});
if (changes.maneid) {
$list.append($("<li></li>").text("Nasnav: " + changes.maneid));
}
if (changes.etiket && changes.etiket.length) {
$list.append($("<li></li>").text("Etîket: " + changes.etiket.join(", ")));
}
if (changes.kategori && changes.kategori.length) {
$list.append($("<li></li>").text("Kategorî: " + changes.kategori.join(", ")));
}
$prev.append($list);
return $prev;
}
function collectChanges() {
var base = original || { maneid: "", etiket: [], kategori: [], words: {} };
var changed = {};
var words = {};
SENSE_GROUPS.forEach(function (group) {
var getter = getters["word:" + group.key];
words[group.key] = getter ? getter() : [];
if (getter && !sameList(words[group.key], base.words[group.key])) {
changed["word:" + group.key] = true;
}
});
var maneid = getters.maneid ? getters.maneid() : "";
var etiket = getters.etiket ? getters.etiket() : [];
var kategori = getters.kategori ? getters.kategori() : [];
if (getters.maneid && maneid !== (base.maneid || "")) {
changed.maneid = true;
}
if (getters.etiket && !sameList(etiket, base.etiket)) {
changed.etiket = true;
}
if (getters.kategori && !sameList(kategori, base.kategori)) {
changed.kategori = true;
}
return {
gloss: getters.gloss ? getters.gloss() : null,
maneid: maneid,
etiket: etiket,
kategori: kategori,
words: words,
changed: changed
};
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status).hide();
$cancel.on("click", function () {
$quickRow.hide();
});
$save.on("click", function () {
var changes = collectChanges();
function afterLinkify() {
queueChange(
"guhartina pêşketî (DefSideBoxes)",
function (baseContent) {
return applyAdvancedChanges(baseContent, language, sectionType, sectionOrdinal, definitionLevel, changes);
},
$save,
$status,
function () {
var $prev = buildChangesPreview(changes);
$quickRow.after($prev);
return function () {
$prev.remove();
};
}
);
}
$save.prop("disabled", true);
// Auto-linkify the gloss only when it's part of this save and has no manual link already.
if (changes.gloss && !/\[\[.+?\]\]/.test(changes.gloss)) {
$status.removeClass("dsb-status-ok dsb-status-error").text("Tê lînkkirin…");
linkifyText(changes.gloss, function (linked) {
changes.gloss = $.trim(linked);
afterLinkify();
});
} else {
afterLinkify();
}
});
$quickRow.empty().append($picker, $openBoxes, $actions);
}
// Attaches the pencil toggle to one leaf definition <li> -- clicking it reveals the "guhartina pêşketî"
// (advanced editing) panel built by buildAdvancedPanel() above.
function attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3) {
if ($li.children(".dsb-toolbar").length) {
return;
}
var $toolbar = $("<span class='dsb-toolbar'></span>");
// The real InterlanguageLinks pencil icon (same asset defEditButton uses); image swap is in the CSS.
var $toggle = $("<a href='#' class='dsb-toggle' title='Guhartina pêşketî'></a>");
// Revealed by $toggle -- an indented panel under the sense, not always visible. Built lazily on
// first open rather than eagerly for every sense on the page.
var $quickRow = $("<div class='dsb-quick-row'></div>").hide();
$toggle.on("click", function (e) {
e.preventDefault();
$(".dsb-quick-row").not($quickRow).hide();
$quickRow.toggle();
if ($quickRow.is(":visible") && !$quickRow.data("built")) {
buildAdvancedPanel($quickRow, $li, $h3, language, sectionType, sectionOrdinal, definitionLevel);
$quickRow.data("built", true);
}
});
$toolbar.append($toggle);
$li.prepend($toolbar);
// Touch has no :hover -- a tap anywhere on the line reveals the pencil the same way hovering does on
// desktop (CSS gates this to touch devices; harmless if it also fires on a mouse click).
$li.on("click.dsbReveal", function () {
$toolbar.addClass("dsb-revealed");
});
// Land $quickRow right after the sense's own gloss text -- before any existing "Hevmane: ..." <dl>,
// citation <ul>, or the Nimûne/jêgirtin proxy link's own <ul>, not appended after all of that.
var $firstBlock = $li.children("dl, ul, ol").first();
if ($firstBlock.length) {
$firstBlock.before($quickRow);
} else {
$li.append($quickRow);
}
}
// ---- per-section UI: "+ Beşek lê zêde bike" after a POS block's own content ----
// Reads the header text of "====" subsections already rendered under this POS heading, straight from the DOM.
function existingSubsectionHeadersInDom($h3) {
var headers = [];
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
headers.push($hh.text().trim());
}
}
return headers;
}
// Finds where a new "====" subsection preview belongs in the live DOM, using the same SUBSECTION_ORDER rank
// insertPageSubsection() uses. Returns {insertBefore: $el} (a ranked subsection that outranks this one) or
// {insertAfter: $el} (goes at the end of the block).
function domSubsectionInsertAnchor($h3, header) {
var myRank = subsectionRankForHeader(header);
var $last = headingOuter($h3);
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if ($cursor.is(".mw-heading4, h4")) {
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var otherRank = subsectionRankForHeader($hh.text().trim());
if (otherRank !== -1 && otherRank > myRank) {
return { insertBefore: $cursor };
}
}
$last = $cursor;
}
return { insertAfter: $last };
}
// A small "not saved yet" preview of a page-level "====" subsection: a heading + its word list (or text),
// dropped into the live page at its canonical position. Plain text, not a real render of {{kol3|...}}/etc.
// Returns the inserted element so the caller can remove it again.
function buildSubsectionPreviewDom($h3, s, content) {
var $wrap = $("<div class='dsb-preview-block'></div>");
// A styled <div>, not a real <h4>, so existingSubsectionHeadersInDom() never mistakes this live-only
// preview for an actual subsection already on the page.
$wrap.append($("<div class='dsb-preview-heading' role='heading' aria-level='4'></div>").text(s.header));
$wrap.append($("<span class='dsb-preview-badge'></span>").text("nû — hîn nehatiye qeydkirin"));
if (s.kind === "wordlist") {
var $list = $("<ul class='dsb-preview-list'></ul>");
content.forEach(function (w) {
$list.append($("<li></li>").text(w.replace(/<[^<>]*>/g, "")));
});
$wrap.append($list);
} else {
$wrap.append($("<p class='dsb-preview-text'></p>").text(content));
}
var anchor = domSubsectionInsertAnchor($h3, s.header);
if (anchor.insertBefore) {
anchor.insertBefore.before($wrap);
} else {
anchor.insertAfter.after($wrap);
}
return $wrap;
}
// Builds the subsection picker + its word-list/text field. A subsection that isn't on the page yet is saved
// via insertPageSubsection(); one that already is gets prefilled and saved via updatePageSubsection().
// onlyHeader pins the panel to a single subsection (the per-heading pencil); omit it for the full picker.
function buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal, onlyHeader) {
var existing = existingSubsectionHeadersInDom($h3);
var available = PAGE_SUBSECTIONS.filter(function (s) {
return !onlyHeader || s.header === onlyHeader;
}).map(function (s) {
return $.extend({}, s, { existing: existing.indexOf(s.header) !== -1 });
});
if (!available.length) {
$panel.text("Ji bo vê beşê guhartin tune.");
return;
}
var $select = $("<select class='dsb-subsection-select'></select>");
if (!onlyHeader) {
$select.append($("<option value=''></option>").text("Binebeşek hilbijêre"));
}
available.forEach(function (s) {
$select.append($("<option></option>").val(s.id).text(s.existing ? s.header + " (biguhêre)" : s.header));
});
if (onlyHeader) {
$select.hide();
}
var $fieldWrap = $("<div class='dsb-subsection-field'></div>");
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $cancel = $("<button type='button' class='dsb-cancel'>Betal bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $cancel, $status);
$cancel.on("click", function () {
$panel.hide();
});
// Undefined while the placeholder option is selected.
function currentSubsection() {
var id = $select.val();
return id ? available.filter(function (s) {
return s.id === id;
})[0] : undefined;
}
var wordField = null; // set by renderField() whenever the current subsection is a wordlist one
var editAsText = false; // set when an existing wordlist section turns out to be unparseable
function renderTextArea(s, rows) {
$fieldWrap.empty().append(
$("<textarea class='dsb-input dsb-subsection-text'></textarea>")
.attr("rows", rows)
.attr("placeholder", s.header + "…")
);
}
// Loads what the page already has into the form, so an edit starts from the current list rather than
// from an empty one. A wordlist section we can't parse degrades to raw wikitext editing.
function prefill(s) {
$status.removeClass("dsb-status-error dsb-status-ok").text("Tê xwendin…");
$save.prop("disabled", true);
fetchPageSubsection(language, sectionType, sectionOrdinal, s).then(function (current) {
$save.prop("disabled", false);
$status.text("");
if (!current) {
return;
}
if (current.kind === "wordlist" && wordField) {
wordField.setValues(current.words);
return;
}
if (s.kind === "wordlist") {
editAsText = true;
wordField = null;
renderTextArea(s, 6);
$status.text("Şablona vê lîsteyê nehate naskirin — wekî wikitext biguhêre.");
}
$fieldWrap.find(".dsb-subsection-text").val(current.text);
}, function () {
$save.prop("disabled", false);
$status.addClass("dsb-status-error").text("Nikarî muhtewaya heyî bixwîne.");
});
}
function renderField() {
var s = currentSubsection();
$fieldWrap.empty();
wordField = null;
editAsText = false;
$status.removeClass("dsb-status-error dsb-status-ok").text("");
// Save stays disabled (but "Betal bike" usable) until something is actually chosen.
$save.prop("disabled", !s);
if (!s) {
$save.text("Lê zêde bike");
return; // still on "Binebeşek hilbijêre"
}
if (s.kind === "wordlist") {
wordField = buildWordListField(s.header + "…");
$fieldWrap.append(wordField.$element);
} else {
renderTextArea(s, 3);
}
$save.text(s.existing ? "Biguhêre" : "Lê zêde bike");
if (s.existing) {
prefill(s);
}
}
$select.on("change", renderField);
renderField();
$save.on("click", function () {
var s = currentSubsection();
if (!s) {
return;
}
var asText = editAsText || s.kind !== "wordlist";
var effective = asText ? $.extend({}, s, { kind: "text" }) : s;
var content;
if (asText) {
content = $.trim($fieldWrap.find(".dsb-subsection-text").val() || "");
if (!content) {
return;
}
} else {
content = wordField.values();
if (!content.length) {
return;
}
}
$save.prop("disabled", true);
queueChange(
(s.existing ? "~" : "+") + s.header + " (DefSideBoxes)",
function (pageContent) {
return {
content: s.existing
? updatePageSubsection(pageContent, language, sectionType, sectionOrdinal, effective, content)
: insertPageSubsection(pageContent, language, sectionType, sectionOrdinal, effective, content),
warnings: []
};
},
$save,
$status,
// Only a brand-new subsection gets a preview block; an edit would have to rewrite the rendered
// section in place, which this plain-text preview can't do faithfully.
s.existing ? null : function () {
var $preview = buildSubsectionPreviewDom($h3, s, content);
return function () {
$preview.remove();
};
}
);
});
$panel.empty().append($select, $fieldWrap, $actions);
}
// Builds the "choose a part of speech" picker that reclassifies a section -- an unclassified
// "=== Mane ===" placeholder, or a "=== Biwêj ===" that turns out to be a real part of speech. Saved via
// convertSectionToPos(); lists every name from sectionNames except the one the section already is.
function buildConvertPosPanel($panel, $h3, language, sectionType, sectionOrdinal) {
var $select = $("<select class='dsb-convert-pos-select'></select>");
$select.append($("<option value=''></option>").text("— cureyekî hilbijêre —"));
Object.keys(sectionNames).forEach(function (name) {
if (name !== sectionType) {
$select.append($("<option></option>").val(name).text(name));
}
});
// The two follow-up questions start.js's posparams card asks, both feeding one "c=" parameter, and both
// gated the way it gates them: gender on navdêr/serenav, transitivity on lêker.
function buildRow(labelText, choices) {
var $sel = $("<select class='dsb-convert-pos-select dsb-pos-param-select'></select>")
.append($("<option value=''></option>").text("— hilbijêre —"));
choices.forEach(function (c) {
$sel.append($("<option></option>").val(c.code).text(c.label));
});
var $row = $("<div class='dsb-pos-param-row'></div>")
.append($("<label class='dsb-adv-label'></label>").text(labelText), $sel)
.hide();
return { $row: $row, $sel: $sel };
}
var cinsiyet = buildRow("Cinsiyet", KU_GENDER_CHOICES);
var lektur = buildRow("Gerguhêziya lêkerê çawa ye?", LEKTUR_CHOICES);
var lekturForm = buildRow("Şiklê lêkerê", LEKTUR_FORM_CHOICES);
// Kurmancî only: every other language's gender codes live in start.js's data.json, which this gadget
// cannot read, and start.js asks the lêker questions for lang=ku too.
function syncRows() {
var tpl = POS_TEMPLATE[$select.val()] || "";
var isKu = language === "ku";
cinsiyet.$row.toggle(isKu && (tpl === "navdêr" || tpl === "serenav"));
lektur.$row.toggle(isKu && tpl === "lêker");
lekturForm.$row.toggle(isKu && tpl === "lêker");
}
$select.on("change", syncRows);
syncRows();
// "gh" on its own, or "<form>-<base>" once a structural form is picked -- start.js's own composition.
function posParams() {
if (cinsiyet.$row.is(":visible") && cinsiyet.$sel.val()) {
return "c=" + cinsiyet.$sel.val();
}
if (lektur.$row.is(":visible") && lektur.$sel.val()) {
var form = lekturForm.$sel.val();
return "c=" + (form ? form + "-" : "") + lektur.$sel.val();
}
return "";
}
var $save = $("<button type='button' class='dsb-save'>Lê zêde bike</button>");
var $status = $("<span class='dsb-status'></span>");
var $actions = $("<div class='dsb-form-actions'></div>").append($save, $status);
$save.on("click", function () {
var chosen = $select.val();
if (!chosen) {
$status.removeClass("dsb-status-ok").addClass("dsb-status-error").text("Pêşî cureyekî rêzimanî hilbijêre.");
return;
}
var params = posParams();
$save.prop("disabled", true);
$status.removeClass("dsb-status-error").text("");
queueChange(
"Cureyê rêzimanî hate diyarkirin: " + chosen + " (DefSideBoxes)",
function (pageContent) {
return { content: convertSectionToPos(pageContent, language, sectionType, sectionOrdinal, chosen, params), warnings: [] };
},
$save,
$status,
function () {
// Preview: a small pending note under the heading, rather than rewriting the real heading
// text -- avoids leaving a heading showing a name that was never actually saved if the
// save fails partway through.
var $note = $("<div class='dsb-preview-inline dsb-preview-heading-note'></div>")
.text("→ " + chosen + (params ? " (" + params + ")" : "") + " — nû, hîn nehatiye qeydkirin");
headingOuter($h3).after($note);
return function () {
$note.remove();
};
},
// Runs after every other queued change: it renames the "Mane" heading those changes locate
// themselves by, so anything edited on this section has to be applied first.
{ runLast: true }
);
});
$panel.empty().append($select, cinsiyet.$row, lektur.$row, lekturForm.$row, $actions);
}
// Attaches the "+ Beşek lê zêde bike" trigger right after a POS block's own last element.
// Puts the same pencil the definitions use on every existing "====" subsection heading the gadget knows how
// to edit, opening buildSubsectionPanel() pinned to that one subsection.
function attachSubsectionEditors($h3, language, sectionType, sectionOrdinal) {
var editable = {};
PAGE_SUBSECTIONS.forEach(function (s) {
editable[s.header] = true;
});
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, h2, h3")) {
break;
}
if (!$cursor.is(".mw-heading4, h4")) {
continue;
}
var $hh = $cursor.is("h4") ? $cursor : $cursor.find("h4").first();
var header = $hh.text().trim();
if (!editable[header] || $hh.data("dsbAttached")) {
continue;
}
$hh.data("dsbAttached", true);
attachSubsectionEditor($hh, $cursor, $h3, header, language, sectionType, sectionOrdinal);
}
}
function attachSubsectionEditor($hh, $heading, $h3, header, language, sectionType, sectionOrdinal) {
var $toolbar = $("<span class='dsb-toolbar dsb-toolbar-heading'></span>");
var $toggle = $("<a href='#' class='dsb-toggle'></a>").attr("title", header + " biguhêre");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$toolbar.append($toggle);
$hh.append($toolbar);
$heading.after($panel);
$toggle.on("click", function (e) {
e.preventDefault();
$toolbar.addClass("dsb-revealed");
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal, header);
$panel.data("built", true);
}
});
}
function attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal) {
if ($h3.data("dsbAttached")) {
return;
}
$h3.data("dsbAttached", true);
var $anchor = $ol;
for (var $cursor = $ol.next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
$anchor = $cursor;
}
var $trigger = $("<a href='#' class='dsb-add-subsection'>+ Beşek lê zêde bike</a>");
var $panel = $("<div class='dsb-subsection-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildSubsectionPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
$anchor.after($panel);
$anchor.after($trigger);
}
// Attaches the "choose a part of speech" trigger under a heading whose part of speech is unsettled: an
// unclassified "=== Mane ===" placeholder, or a "=== Biwêj ===" that is really a noun, verb, ... .
function attachConvertPosTrigger($h3, sectionType) {
if ($h3.data("dsbConvertAttached")) {
return;
}
$h3.data("dsbConvertAttached", true);
// languageCodeForOl() is really just "nearest preceding .besazimani[id] before this element in
// document order" -- nothing ol-specific about it, so it works unchanged for a heading too.
var language = languageCodeForOl($h3);
if (!language) {
return;
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $trigger = $("<a href='#' class='dsb-convert-pos-trigger'>Cureyê rêzimanî hilbijêre</a>");
var $panel = $("<div class='dsb-convert-pos-panel'></div>").hide();
$trigger.on("click", function (e) {
e.preventDefault();
$panel.toggle();
if ($panel.is(":visible") && !$panel.data("built")) {
buildConvertPosPanel($panel, $h3, language, sectionType, sectionOrdinal);
$panel.data("built", true);
}
});
headingOuter($h3).after($panel);
headingOuter($h3).after($trigger);
}
// ---- driver ----
function init() {
$("h3").each(function () {
var $h3 = $(this);
var sectionType = sectionTypeOf($h3);
if (!sectionType) {
if (!isManeHeading($h3)) {
return; // not a recognized word-sense section (Bilêvkirin, Etîmolojî, Çavkanî, ...)
}
// An unclassified placeholder: offer the POS picker, then carry on and wire up the same
// per-sense pencils, so the POS choice and the sense edits can be queued and saved together.
sectionType = MANE_SECTION;
attachConvertPosTrigger($h3, sectionType);
} else if (sectionType === "Biwêj") {
// A real section, but one that is often really a noun/verb/... -- offer the same picker.
attachConvertPosTrigger($h3, sectionType);
}
var sectionOrdinal = sectionOrdinalWithinLanguage($h3);
var $ol = null;
for (var $cursor = headingOuter($h3).next(); $cursor.length; $cursor = $cursor.next()) {
if ($cursor.is("ol")) {
$ol = $cursor;
break;
}
if ($cursor.is(".mw-heading2, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6, h2, h3, h4, h5, h6")) {
break;
}
}
if (!$ol) {
return;
}
var language = languageCodeForOl($ol);
if (!language) {
return;
}
eachLeafDefinition($ol, function ($li) {
var definitionLevel = [];
var $definitionItem = $li;
while ($definitionItem.prop("tagName") === "LI") {
definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length);
$definitionItem = $definitionItem.parent().parent();
}
definitionLevel.splice(0, 0, sectionType + "|" + sectionOrdinal);
attachToolbar($li, language, sectionType, sectionOrdinal, definitionLevel, $h3);
});
attachSubsectionTrigger($h3, $ol, language, sectionType, sectionOrdinal);
attachSubsectionEditors($h3, language, sectionType, sectionOrdinal);
});
}
// Closes every open panel/preview this gadget can leave in the DOM, so bfcache never freezes one mid-open.
function closeAllOpenUi() {
clearQueue();
$(".dsb-quick-row, .dsb-more-menu, .dsb-convert-pos-panel, .dsb-subsection-panel, .dsb-queue-box, .dsb-preview-inline, .dsb-preview-block").hide();
}
$(window).on("pagehide", closeAllOpenUi);
// Belt-and-suspenders: also close on restore-from-bfcache, in case pagehide's own hide didn't stick.
$(window).on("pageshow", function (e) {
if (e.originalEvent && e.originalEvent.persisted) {
closeAllOpenUi();
}
});
$(init);
// </nowiki>
})();
nurs5c2kng2z6pmt6s8dr907g90yyem
Bikarhêner:Wikihez/Gadget-DefSideBoxes.css
2
1358876
6347345
6347336
2026-08-31T12:14:08Z
Wikihez
7344
6347345
css
text/css
/* Gadget-DefSideBoxes.css
Skin-agnostic (vector, vector2022, minerva) -- no :hover-only reveal, no absolute
positioning against the page.
Visual layer matched to MediaWiki:Gadget-wiktku-start/styles.css ("SÊWIRANA NÛ"):
same cream surfaces, warm ink, single blue accent, 10/12px radii, pill buttons.
Those tokens are declared on #wiktku-start-form, which does not exist on an
article page -- so the same values are re-declared here under a --dsb-* prefix
(a page-scope --wikt-* block would leak the palette onto unrelated gadgets). */
:root {
--dsb-card: #fffdf8;
--dsb-card-sunken: #fbf8f1;
--dsb-rule: #ded6c8;
--dsb-rule-soft: #efe8db;
--dsb-card-edge: #e6dfd2;
--dsb-field-edge: #cfc7b8;
--dsb-field-bg: #fff;
--dsb-ink: #1c1a17;
--dsb-ink-2: #3d3830;
--dsb-ink-3: #57514a;
--dsb-muted: #8a8378;
--dsb-placeholder: #b3ab9e;
--dsb-accent: #2a5db0;
--dsb-accent-deep: #22406f;
--dsb-accent-tint: #eef2fa;
--dsb-accent-edge: #d5def0;
--dsb-ok: #3d8a55;
--dsb-danger: #9c3a28;
--dsb-r-field: 10px;
--dsb-r-card: 12px;
--dsb-r-pill: 999px;
--dsb-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--dsb-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── The "+" toggle on a definition ──────────────────────────────────
Same shape as the form's .wiktku-mod-btn: soft-cornered square, accent
tint, accent glyph. Sized to the definition line's own text, so it
never pushes the line's leading around. */
.dsb-toolbar {
display: inline-block;
margin-right: 8px;
font-family: var(--dsb-sans);
vertical-align: baseline;
}
.dsb-toggle {
display: inline-grid;
place-items: center;
width: 20px;
height: 20px;
border: 1px solid var(--dsb-accent-edge);
border-radius: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
font-size: 13px;
line-height: 1;
text-decoration: none;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease;
}
.dsb-toggle:hover,
.dsb-toggle:focus {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
background: var(--dsb-accent-tint);
text-decoration: none;
}
/* ── "Guhartina pêşketî" (advanced editing) panel ──────────────────────
Revealed by the pencil toggle above -- every action this gadget offers
for one sense (gloss, word-list groups, maneid/etîket/kategorî), plus
this POS block's own subsections, queued together with one "Lê zêde
bike", instead of each living in its own separate mini-form/separate
edit. A plain inline row, NOT a bordered/background card -- closer to
en.wiktionary's own bare "+Add example sentence +Add quotation More"
toolbar than to .dsb-subsection-panel's own sunken-card look. */
.dsb-quick-row {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
box-sizing: border-box;
max-width: 520px;
margin: 4px 0 4px 26px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
}
.dsb-quick-link {
align-self: flex-start;
margin-bottom: 10px;
color: var(--dsb-accent);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
}
.dsb-quick-link:hover,
.dsb-quick-link:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* The picker row: gloss + the two primary word groups (Hevmane/Dijmane) as direct "+ <field>" links, plus a
"Zêdetir" toggle for the rest (see .dsb-more-menu) -- clicking any link opens its box below and hides the
link itself (see .dsb-open-boxes); the box's own .dsb-box-remove un-hides it. */
.dsb-field-picker {
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-bottom: 10px;
}
.dsb-field-picker .dsb-quick-link {
margin-bottom: 0;
}
/* The "Zêdetir" dropdown: every non-primary field link (plus Nimûne/jêgirtin, which sits first) stacked as a
plain vertical list, hidden until the toggle is clicked. No cream card background (round 16's flattening),
but a thin border + a soft shadow so it still reads as a distinct menu rather than loose text falling out of
the row (round 17 -- the fully bare version looked broken). */
.dsb-more-menu {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 6px;
margin: 2px 0 10px 4px;
padding: 8px 12px;
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-field);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dsb-more-menu .dsb-quick-link {
margin-bottom: 0;
}
/* Boxes the user has actually opened, stacked in the order they were added -- several can be open at once. */
.dsb-open-boxes {
display: flex;
flex-direction: column;
}
/* One field (its label + input) within the panel -- always a currently-open, removable box. */
.dsb-adv-group {
position: relative;
margin-bottom: 14px;
padding-right: 20px;
}
.dsb-adv-label {
margin-bottom: 4px;
font-size: 12px;
font-weight: 600;
color: var(--dsb-ink-3);
}
.dsb-box-remove {
position: absolute;
top: 0;
right: 0;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-box-remove:hover,
.dsb-box-remove:focus {
color: var(--dsb-accent-deep);
}
.dsb-form-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.dsb-input {
box-sizing: border-box;
min-width: 16em;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-input::placeholder {
color: var(--dsb-placeholder);
opacity: 1;
}
.dsb-input:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
/* ── Plain tag field (Etîket, Kategorî) ────────────────────────────────
start.js's own buildChipField() pattern (its .wiktku-dfn-chipfield-chip),
simplified to plain type-and-commit tags with no suggestion panel --
unlike Hevmane/Dijmane/etc., these two values carry no modifiers. */
.dsb-tagfield {
box-sizing: border-box;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
min-width: 16em;
padding: 4px 6px;
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-tagfield:focus-within {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
}
.dsb-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
padding: 3px 6px 3px 10px;
}
.dsb-tag-remove {
border: 0;
background: transparent;
color: var(--dsb-muted);
font-size: 13px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
}
.dsb-tag-remove:hover {
color: var(--dsb-danger);
}
.dsb-tagfield .dsb-input {
flex: 1 1 8em;
min-width: 8em;
border: 0;
padding: 3px 2px;
background: transparent;
box-shadow: none;
}
.dsb-tagfield .dsb-input:focus {
box-shadow: none;
}
/* ── Word list with modifier pills ───────────────────────────────────
start.js's own makeModifierLi() pattern (Hevmane/Dijmane/Formên
alternatîv/Termên koordîne/Jornav/Jêrnav): every word is its own
always-visible row -- a word box plus a "+" that attaches one of the
10 WORD_MODIFIERS as a small pill shown above the box. A fresh empty
row is appended automatically once the current last one gets text. */
.dsb-wordlist {
margin: 0;
padding-left: 0;
list-style: none;
}
.dsb-word-li {
margin-bottom: 6px;
}
.dsb-word-li:last-child {
margin-bottom: 0;
}
.dsb-word-mods {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
}
.dsb-word-mod-chip {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 11.5px;
padding: 3px 4px 3px 10px;
cursor: pointer;
}
.dsb-word-mod-chip-remove {
border: 0;
background: transparent;
color: var(--dsb-accent-deep);
font-size: 12px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
opacity: 0.7;
}
.dsb-word-mod-chip-remove:hover {
color: var(--dsb-danger);
opacity: 1;
}
.dsb-word-box-row {
display: flex;
align-items: center;
gap: 6px;
}
.dsb-word-box-row .dsb-word-input {
flex: 1 1 auto;
min-width: 0;
}
.dsb-mod-btn,
.dsb-word-remove {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.dsb-mod-btn {
border: 1px solid var(--dsb-accent-edge);
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
}
.dsb-mod-btn:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-word-remove {
border: 1px solid var(--dsb-field-edge);
background: var(--dsb-field-bg);
color: var(--dsb-muted);
}
.dsb-word-remove:hover {
border-color: var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-mod-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
margin-top: 6px;
padding: 8px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-card);
box-shadow: none;
}
.dsb-mod-pill {
font-family: var(--dsb-sans);
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
white-space: nowrap;
padding: 5px 10px;
cursor: pointer;
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.dsb-mod-pill:hover {
border-color: var(--dsb-accent);
background: var(--dsb-accent);
color: #fff;
}
.dsb-mod-pill:disabled,
.dsb-mod-pill.dsb-mod-pill-used {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
cursor: not-allowed;
opacity: 0.7;
}
.dsb-mod-pill:disabled:hover,
.dsb-mod-pill.dsb-mod-pill-used:hover {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
}
.dsb-mod-val-wrap {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
margin-top: 6px;
}
.dsb-mod-val-input {
flex: 1 1 auto;
min-width: 0;
max-width: 16em;
}
.dsb-mod-confirm,
.dsb-mod-cancel {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
background: var(--dsb-accent-tint);
cursor: pointer;
}
.dsb-mod-confirm {
border: 1px solid var(--dsb-ok);
color: var(--dsb-ok);
}
.dsb-mod-cancel {
border: 1px solid var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-save,
.dsb-cancel,
.dsb-autolink {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
/* One filled pill per row — the same rule the form's footer follows. */
.dsb-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-cancel {
background: transparent;
border: 1px solid transparent;
color: var(--dsb-ink-3);
}
.dsb-cancel:hover {
border-color: var(--dsb-field-edge);
color: var(--dsb-ink);
}
/* An outline pill, distinct from both the filled .dsb-save and the plain-text .dsb-cancel -- a secondary
utility action, not the primary save nor a dismissal. */
.dsb-autolink {
background: transparent;
border: 1px solid var(--dsb-accent-edge);
color: var(--dsb-accent);
}
.dsb-autolink:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-autolink:disabled {
opacity: 0.55;
cursor: progress;
}
/* Status line. Color comes from .dsb-status-ok/.dsb-status-error (added by the .js on success/failure)
rather than an inline style, so these tokens (and dark mode) apply. */
.dsb-status {
font-family: var(--dsb-sans);
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-status-ok { color: var(--dsb-ok); }
.dsb-status-error { color: var(--dsb-danger); }
/* ── "+ Beşek lê zêde bike" ──────────────────────────────────────────
An accent-coloured action link, like the form's .wiktku-adv-toggle:
it opens something, so it is not muted grey. */
.dsb-add-subsection,
.dsb-convert-pos-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-family: var(--dsb-sans);
font-size: 14px;
font-weight: 500;
color: var(--dsb-accent);
text-decoration: none;
border-bottom: 0;
cursor: pointer;
}
.dsb-add-subsection:hover,
.dsb-add-subsection:focus,
.dsb-convert-pos-trigger:hover,
.dsb-convert-pos-trigger:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* ── Subsection panel ────────────────────────────────────────────────
A sunken card rather than a grey utility box; fields stack so the
picker and its input are not competing for one narrow row. */
.dsb-subsection-panel,
.dsb-convert-pos-panel {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
box-sizing: border-box;
max-width: 520px;
margin: 6px 0 14px;
padding: 14px 16px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card-sunken);
border: 1px solid var(--dsb-card-edge);
border-radius: var(--dsb-r-card);
}
.dsb-subsection-select,
.dsb-convert-pos-select {
box-sizing: border-box;
width: 100%;
max-width: 100%;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
}
.dsb-subsection-select:focus,
.dsb-convert-pos-select:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
.dsb-subsection-field {
min-width: 0;
}
.dsb-subsection-words,
.dsb-subsection-text {
box-sizing: border-box;
width: 100%;
min-width: 0;
}
.dsb-subsection-text {
line-height: 1.6;
resize: vertical;
}
/* ── Gloss field inside the advanced-editing panel ────────────────────
Same shape as .dsb-subsection-text. */
.dsb-edit-gloss {
width: 100%;
line-height: 1.6;
resize: vertical;
}
/* ── Live "not saved yet" previews ─────────────────────────────────────
Dropped into the actual rendered page, at the change's own correct
spot (see buildSubsectionPreviewDom()/buildChangesPreview() in the
.js), instead of only a status line inside the panel that queued it.
Dashed edge + a small badge mark it as pending, not real content --
it disappears again on "Betal bike" or once the real save lands. */
.dsb-preview-block,
.dsb-preview-inline {
margin: 8px 0;
padding: 8px 12px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-accent-tint);
border: 1px dashed var(--dsb-accent-edge);
border-radius: var(--dsb-r-field);
}
.dsb-preview-inline {
margin-left: 26px;
max-width: 520px;
}
.dsb-preview-heading {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-preview-badge {
display: inline-block;
margin-bottom: 6px;
padding: 1px 8px;
font-size: 11px;
font-weight: 500;
color: var(--dsb-accent-deep);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
}
.dsb-preview-badge-inline {
margin-left: 8px;
margin-bottom: 0;
vertical-align: middle;
}
.dsb-preview-list,
.dsb-preview-text {
margin: 0;
padding-left: 18px;
}
.dsb-preview-text {
padding-left: 0;
}
/* ── Floating save-queue widget ─────────────────────────────────────
This gadget's own version of the small floating box the real
Gadget-Editor - kuwikt.js singleton shows -- built and owned by this
file instead of piggybacking on that (unrelated) gadget, so its
copy only ever talks about DefSideBoxes' own queued changes. One
"Lê zêde bike" click anywhere on the page adds a line here; "Guhertinan
qeyd bike" makes the one real save; "Betal bike" drops everything
queued (and every live preview) without touching the page. */
.dsb-queue-box {
position: fixed;
top: 60px;
right: 16px;
z-index: 1000;
box-sizing: border-box;
width: 280px;
max-width: calc(100vw - 32px);
max-height: calc(100vh - 90px);
overflow-y: auto;
padding: 12px 14px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent);
border-radius: var(--dsb-r-card);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.16);
}
.dsb-queue-title {
margin-right: 20px;
font-size: 13px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-queue-close {
float: right;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-queue-close:hover,
.dsb-queue-close:focus {
color: var(--dsb-accent-deep);
}
.dsb-queue-list {
margin: 8px 0;
padding-left: 18px;
max-height: 160px;
overflow-y: auto;
}
.dsb-queue-list li {
margin-bottom: 4px;
}
.dsb-queue-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 4px;
}
.dsb-queue-save,
.dsb-queue-cancel {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.dsb-queue-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-queue-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-queue-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-queue-cancel {
background: transparent;
border: 1px solid var(--dsb-field-edge);
color: var(--dsb-ink-3);
}
.dsb-queue-cancel:hover {
border-color: var(--dsb-ink-3);
color: var(--dsb-ink);
}
.dsb-queue-status {
margin-top: 6px;
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-queue-status.dsb-status-ok { color: var(--dsb-ok); }
.dsb-queue-status.dsb-status-error { color: var(--dsb-danger); }
/* ── Minerva (mobile) ────────────────────────────────────────────────
Narrower viewport: keep the panel on screen and give every tap
target the form's 44px minimum. */
.skin-minerva .dsb-quick-row,
.skin-minerva .dsb-subsection-panel,
.skin-minerva .dsb-convert-pos-panel {
max-width: 100%;
}
@media (max-width: 720px), (pointer: coarse) {
.dsb-toggle {
width: 28px;
height: 28px;
font-size: 15px;
}
.dsb-quick-row {
font-size: 14px;
margin-left: 20px;
}
.dsb-input,
.dsb-subsection-select,
.dsb-convert-pos-select {
min-height: 40px;
/* >=16px stops iOS Safari zooming the page on focus. */
font-size: 16px;
}
.dsb-mod-btn,
.dsb-word-remove,
.dsb-mod-confirm,
.dsb-mod-cancel {
width: 36px;
height: 36px;
font-size: 15px;
}
.dsb-mod-pill {
padding: 8px 12px;
}
.dsb-mod-val-input {
max-width: none;
}
.dsb-tagfield .dsb-input {
min-height: 32px;
}
.dsb-tag-remove {
padding: 0 6px;
}
.dsb-save,
.dsb-cancel,
.dsb-autolink,
.dsb-queue-save,
.dsb-queue-cancel {
min-height: 40px;
padding: 8px 16px;
}
.dsb-queue-box {
top: auto;
bottom: 8px;
right: 8px;
left: 8px;
width: auto;
}
}
/* ── Dark mode ───────────────────────────────────────────────────────
Same warm dark palette and same explicit-signal-only rule as the
form's stylesheet: no bare prefers-color-scheme fallback, since
legacy Vector sets no theme class and would go dark on its own. */
html.skin-theme-clientpref-night,
html.skin-nightmode {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-night .dsb-save,
html.skin-nightmode .dsb-save,
html.skin-theme-clientpref-night .dsb-queue-save,
html.skin-nightmode .dsb-queue-save {
color: #14213a;
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-os .dsb-save,
html.skin-theme-clientpref-os .dsb-queue-save {
color: #14213a;
}
}
4zvkwr68q55pw9fjqx9jhsj5cfrtry6
6347377
6347345
2026-08-31T13:25:02Z
Wikihez
7344
6347377
css
text/css
/* Gadget-DefSideBoxes.css
Skin-agnostic (vector, vector2022, minerva) -- no :hover-only reveal, no absolute
positioning against the page.
Visual layer matched to MediaWiki:Gadget-wiktku-start/styles.css ("SÊWIRANA NÛ"):
same cream surfaces, warm ink, single blue accent, 10/12px radii, pill buttons.
Those tokens are declared on #wiktku-start-form, which does not exist on an
article page -- so the same values are re-declared here under a --dsb-* prefix
(a page-scope --wikt-* block would leak the palette onto unrelated gadgets). */
:root {
--dsb-card: #fffdf8;
--dsb-card-sunken: #fbf8f1;
--dsb-rule: #ded6c8;
--dsb-rule-soft: #efe8db;
--dsb-card-edge: #e6dfd2;
--dsb-field-edge: #cfc7b8;
--dsb-field-bg: #fff;
--dsb-ink: #1c1a17;
--dsb-ink-2: #3d3830;
--dsb-ink-3: #57514a;
--dsb-muted: #8a8378;
--dsb-placeholder: #b3ab9e;
--dsb-accent: #2a5db0;
--dsb-accent-deep: #22406f;
--dsb-accent-tint: #eef2fa;
--dsb-accent-edge: #d5def0;
--dsb-ok: #3d8a55;
--dsb-danger: #9c3a28;
--dsb-r-field: 10px;
--dsb-r-card: 12px;
--dsb-r-pill: 999px;
--dsb-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--dsb-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── The pencil toggle on a definition ─────────────────────────────────
A bare stroked pencil glyph, no background/border box around it (round
20 -- the earlier accent-tint square read as too heavy). Sized to sit
quietly next to the definition line's own text. */
.dsb-toolbar {
display: inline-block;
margin-right: 8px;
font-family: var(--dsb-sans);
vertical-align: baseline;
}
.dsb-toggle {
display: inline-grid;
place-items: center;
width: 13px;
height: 13px;
color: var(--dsb-accent);
text-decoration: none;
cursor: pointer;
transition: color 0.12s ease;
}
.dsb-toggle svg {
display: block;
width: 100%;
height: 100%;
fill: none;
stroke: currentColor;
stroke-width: 2.6;
stroke-linecap: round;
stroke-linejoin: round;
}
.dsb-toggle:hover,
.dsb-toggle:focus {
color: var(--dsb-accent-deep);
text-decoration: none;
}
/* ── "Guhartina pêşketî" (advanced editing) panel ──────────────────────
Revealed by the pencil toggle above -- every action this gadget offers
for one sense (gloss, word-list groups, maneid/etîket/kategorî), plus
this POS block's own subsections, queued together with one "Lê zêde
bike", instead of each living in its own separate mini-form/separate
edit. A plain inline row, NOT a bordered/background card -- closer to
en.wiktionary's own bare "+Add example sentence +Add quotation More"
toolbar than to .dsb-subsection-panel's own sunken-card look. */
.dsb-quick-row {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
box-sizing: border-box;
max-width: 520px;
margin: 4px 0 4px 26px;
font-family: var(--dsb-sans);
font-size: 12px;
color: var(--dsb-ink-2);
}
.dsb-quick-link {
align-self: flex-start;
margin-bottom: 10px;
color: var(--dsb-accent);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
}
.dsb-quick-link:hover,
.dsb-quick-link:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* The picker row: gloss + the two primary word groups (Hevmane/Dijmane) as direct "+ <field>" links, plus a
"Zêdetir" toggle for the rest (see .dsb-more-menu) -- clicking any link opens its box below and hides the
link itself (see .dsb-open-boxes); the box's own .dsb-box-remove un-hides it. */
.dsb-field-picker {
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-bottom: 10px;
}
.dsb-field-picker .dsb-quick-link {
margin-bottom: 0;
}
/* The "Zêdetir" dropdown: every non-primary field link (plus Nimûne/jêgirtin, which sits first) stacked as a
plain vertical list, hidden until the toggle is clicked. No cream card background (round 16's flattening),
but a thin border + a soft shadow so it still reads as a distinct menu rather than loose text falling out of
the row (round 18 -- the fully bare version looked broken). align-self: flex-start keeps it hugging its own
content width and the row's left edge, instead of stretching to .dsb-quick-row's own max-width (round 20 --
it was reading as one big wide card). */
.dsb-more-menu {
display: flex;
flex-direction: column;
align-items: flex-start;
align-self: flex-start;
gap: 6px;
margin: 2px 0 10px 4px;
padding: 8px 12px;
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-field);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dsb-more-menu .dsb-quick-link {
margin-bottom: 0;
}
/* Boxes the user has actually opened, stacked in the order they were added -- several can be open at once. */
.dsb-open-boxes {
display: flex;
flex-direction: column;
}
/* One field (its label + input) within the panel -- always a currently-open, removable box. */
.dsb-adv-group {
position: relative;
margin-bottom: 14px;
padding-right: 20px;
}
.dsb-adv-label {
margin-bottom: 4px;
font-size: 12px;
font-weight: 600;
color: var(--dsb-ink-3);
}
.dsb-box-remove {
position: absolute;
top: 0;
right: 0;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-box-remove:hover,
.dsb-box-remove:focus {
color: var(--dsb-accent-deep);
}
.dsb-form-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.dsb-input {
box-sizing: border-box;
min-width: 16em;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-input::placeholder {
color: var(--dsb-placeholder);
opacity: 1;
}
.dsb-input:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
/* ── Plain tag field (Etîket, Kategorî) ────────────────────────────────
start.js's own buildChipField() pattern (its .wiktku-dfn-chipfield-chip),
simplified to plain type-and-commit tags with no suggestion panel --
unlike Hevmane/Dijmane/etc., these two values carry no modifiers. */
.dsb-tagfield {
box-sizing: border-box;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
min-width: 16em;
padding: 4px 6px;
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-tagfield:focus-within {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
}
.dsb-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
padding: 3px 6px 3px 10px;
}
.dsb-tag-remove {
border: 0;
background: transparent;
color: var(--dsb-muted);
font-size: 13px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
}
.dsb-tag-remove:hover {
color: var(--dsb-danger);
}
.dsb-tagfield .dsb-input {
flex: 1 1 8em;
min-width: 8em;
border: 0;
padding: 3px 2px;
background: transparent;
box-shadow: none;
}
.dsb-tagfield .dsb-input:focus {
box-shadow: none;
}
/* ── Word list with modifier pills ───────────────────────────────────
start.js's own makeModifierLi() pattern (Hevmane/Dijmane/Formên
alternatîv/Termên koordîne/Jornav/Jêrnav): every word is its own
always-visible row -- a word box plus a "+" that attaches one of the
10 WORD_MODIFIERS as a small pill shown above the box. A fresh empty
row is appended automatically once the current last one gets text. */
.dsb-wordlist {
margin: 0;
padding-left: 0;
list-style: none;
}
.dsb-word-li {
margin-bottom: 6px;
}
.dsb-word-li:last-child {
margin-bottom: 0;
}
.dsb-word-mods {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
}
.dsb-word-mod-chip {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 11.5px;
padding: 3px 4px 3px 10px;
cursor: pointer;
}
.dsb-word-mod-chip-remove {
border: 0;
background: transparent;
color: var(--dsb-accent-deep);
font-size: 12px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
opacity: 0.7;
}
.dsb-word-mod-chip-remove:hover {
color: var(--dsb-danger);
opacity: 1;
}
.dsb-word-box-row {
display: flex;
align-items: center;
gap: 6px;
}
.dsb-word-box-row .dsb-word-input {
flex: 1 1 auto;
min-width: 0;
}
.dsb-mod-btn,
.dsb-word-remove {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.dsb-mod-btn {
border: 1px solid var(--dsb-accent-edge);
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
}
.dsb-mod-btn:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-word-remove {
border: 1px solid var(--dsb-field-edge);
background: var(--dsb-field-bg);
color: var(--dsb-muted);
}
.dsb-word-remove:hover {
border-color: var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-mod-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
margin-top: 6px;
padding: 8px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-card);
box-shadow: none;
}
.dsb-mod-pill {
font-family: var(--dsb-sans);
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
white-space: nowrap;
padding: 5px 10px;
cursor: pointer;
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.dsb-mod-pill:hover {
border-color: var(--dsb-accent);
background: var(--dsb-accent);
color: #fff;
}
.dsb-mod-pill:disabled,
.dsb-mod-pill.dsb-mod-pill-used {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
cursor: not-allowed;
opacity: 0.7;
}
.dsb-mod-pill:disabled:hover,
.dsb-mod-pill.dsb-mod-pill-used:hover {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
}
.dsb-mod-val-wrap {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
margin-top: 6px;
}
.dsb-mod-val-input {
flex: 1 1 auto;
min-width: 0;
max-width: 16em;
}
.dsb-mod-confirm,
.dsb-mod-cancel {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
background: var(--dsb-accent-tint);
cursor: pointer;
}
.dsb-mod-confirm {
border: 1px solid var(--dsb-ok);
color: var(--dsb-ok);
}
.dsb-mod-cancel {
border: 1px solid var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-save,
.dsb-cancel,
.dsb-autolink {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
/* One filled pill per row — the same rule the form's footer follows. */
.dsb-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-cancel {
background: transparent;
border: 1px solid transparent;
color: var(--dsb-ink-3);
}
.dsb-cancel:hover {
border-color: var(--dsb-field-edge);
color: var(--dsb-ink);
}
/* An outline pill, distinct from both the filled .dsb-save and the plain-text .dsb-cancel -- a secondary
utility action, not the primary save nor a dismissal. */
.dsb-autolink {
background: transparent;
border: 1px solid var(--dsb-accent-edge);
color: var(--dsb-accent);
}
.dsb-autolink:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-autolink:disabled {
opacity: 0.55;
cursor: progress;
}
/* Status line. Color comes from .dsb-status-ok/.dsb-status-error (added by the .js on success/failure)
rather than an inline style, so these tokens (and dark mode) apply. */
.dsb-status {
font-family: var(--dsb-sans);
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-status-ok { color: var(--dsb-ok); }
.dsb-status-error { color: var(--dsb-danger); }
/* ── "+ Beşek lê zêde bike" ──────────────────────────────────────────
An accent-coloured action link, like the form's .wiktku-adv-toggle:
it opens something, so it is not muted grey. */
.dsb-add-subsection,
.dsb-convert-pos-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-family: var(--dsb-sans);
font-size: 14px;
font-weight: 500;
color: var(--dsb-accent);
text-decoration: none;
border-bottom: 0;
cursor: pointer;
}
.dsb-add-subsection:hover,
.dsb-add-subsection:focus,
.dsb-convert-pos-trigger:hover,
.dsb-convert-pos-trigger:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* ── Subsection panel ────────────────────────────────────────────────
A sunken card rather than a grey utility box; fields stack so the
picker and its input are not competing for one narrow row. */
.dsb-subsection-panel,
.dsb-convert-pos-panel {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
box-sizing: border-box;
max-width: 520px;
margin: 6px 0 14px;
padding: 14px 16px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card-sunken);
border: 1px solid var(--dsb-card-edge);
border-radius: var(--dsb-r-card);
}
.dsb-subsection-select,
.dsb-convert-pos-select {
box-sizing: border-box;
width: 100%;
max-width: 100%;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
}
.dsb-subsection-select:focus,
.dsb-convert-pos-select:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
.dsb-subsection-field {
min-width: 0;
}
.dsb-subsection-words,
.dsb-subsection-text {
box-sizing: border-box;
width: 100%;
min-width: 0;
}
.dsb-subsection-text {
line-height: 1.6;
resize: vertical;
}
/* ── Gloss field inside the advanced-editing panel ────────────────────
Same shape as .dsb-subsection-text. */
.dsb-edit-gloss {
width: 100%;
line-height: 1.6;
resize: vertical;
}
/* ── Live "not saved yet" previews ─────────────────────────────────────
Dropped into the actual rendered page, at the change's own correct
spot (see buildSubsectionPreviewDom()/buildChangesPreview() in the
.js), instead of only a status line inside the panel that queued it.
Dashed edge + a small badge mark it as pending, not real content --
it disappears again on "Betal bike" or once the real save lands. */
.dsb-preview-block,
.dsb-preview-inline {
margin: 8px 0;
padding: 8px 12px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-accent-tint);
border: 1px dashed var(--dsb-accent-edge);
border-radius: var(--dsb-r-field);
}
.dsb-preview-inline {
margin-left: 26px;
max-width: 520px;
}
.dsb-preview-heading {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-preview-badge {
display: inline-block;
margin-bottom: 6px;
padding: 1px 8px;
font-size: 11px;
font-weight: 500;
color: var(--dsb-accent-deep);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
}
.dsb-preview-badge-inline {
margin-left: 8px;
margin-bottom: 0;
vertical-align: middle;
}
.dsb-preview-list,
.dsb-preview-text {
margin: 0;
padding-left: 18px;
}
.dsb-preview-text {
padding-left: 0;
}
/* ── Floating save-queue widget ─────────────────────────────────────
This gadget's own version of the small floating box the real
Gadget-Editor - kuwikt.js singleton shows -- built and owned by this
file instead of piggybacking on that (unrelated) gadget, so its
copy only ever talks about DefSideBoxes' own queued changes. One
"Lê zêde bike" click anywhere on the page adds a line here; "Guhertinan
qeyd bike" makes the one real save; "Betal bike" drops everything
queued (and every live preview) without touching the page. */
.dsb-queue-box {
position: fixed;
top: 60px;
right: 16px;
z-index: 1000;
box-sizing: border-box;
width: 280px;
max-width: calc(100vw - 32px);
max-height: calc(100vh - 90px);
overflow-y: auto;
padding: 12px 14px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent);
border-radius: var(--dsb-r-card);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.16);
}
.dsb-queue-title {
margin-right: 20px;
font-size: 13px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-queue-close {
float: right;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-queue-close:hover,
.dsb-queue-close:focus {
color: var(--dsb-accent-deep);
}
.dsb-queue-list {
margin: 8px 0;
padding-left: 18px;
max-height: 160px;
overflow-y: auto;
}
.dsb-queue-list li {
margin-bottom: 4px;
}
.dsb-queue-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 4px;
}
.dsb-queue-save,
.dsb-queue-cancel {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.dsb-queue-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-queue-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-queue-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-queue-cancel {
background: transparent;
border: 1px solid var(--dsb-field-edge);
color: var(--dsb-ink-3);
}
.dsb-queue-cancel:hover {
border-color: var(--dsb-ink-3);
color: var(--dsb-ink);
}
.dsb-queue-status {
margin-top: 6px;
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-queue-status.dsb-status-ok { color: var(--dsb-ok); }
.dsb-queue-status.dsb-status-error { color: var(--dsb-danger); }
/* ── Minerva (mobile) ────────────────────────────────────────────────
Narrower viewport: keep the panel on screen and give every tap
target the form's 44px minimum. */
.skin-minerva .dsb-quick-row,
.skin-minerva .dsb-subsection-panel,
.skin-minerva .dsb-convert-pos-panel {
max-width: 100%;
}
@media (max-width: 720px), (pointer: coarse) {
.dsb-toggle {
width: 20px;
height: 20px;
}
.dsb-quick-row {
font-size: 13px;
margin-left: 20px;
}
.dsb-input,
.dsb-subsection-select,
.dsb-convert-pos-select {
min-height: 40px;
/* >=16px stops iOS Safari zooming the page on focus. */
font-size: 16px;
}
.dsb-mod-btn,
.dsb-word-remove,
.dsb-mod-confirm,
.dsb-mod-cancel {
width: 36px;
height: 36px;
font-size: 15px;
}
.dsb-mod-pill {
padding: 8px 12px;
}
.dsb-mod-val-input {
max-width: none;
}
.dsb-tagfield .dsb-input {
min-height: 32px;
}
.dsb-tag-remove {
padding: 0 6px;
}
.dsb-save,
.dsb-cancel,
.dsb-autolink,
.dsb-queue-save,
.dsb-queue-cancel {
min-height: 40px;
padding: 8px 16px;
}
.dsb-queue-box {
top: auto;
bottom: 8px;
right: 8px;
left: 8px;
width: auto;
}
}
/* ── Dark mode ───────────────────────────────────────────────────────
Same warm dark palette and same explicit-signal-only rule as the
form's stylesheet: no bare prefers-color-scheme fallback, since
legacy Vector sets no theme class and would go dark on its own. */
html.skin-theme-clientpref-night,
html.skin-nightmode {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-night .dsb-save,
html.skin-nightmode .dsb-save,
html.skin-theme-clientpref-night .dsb-queue-save,
html.skin-nightmode .dsb-queue-save {
color: #14213a;
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-os .dsb-save,
html.skin-theme-clientpref-os .dsb-queue-save {
color: #14213a;
}
}
pg8zuzfhxdtmfj9v5gk8d414uh5rbzb
6347398
6347377
2026-08-31T16:23:23Z
Wikihez
7344
6347398
css
text/css
/* Gadget-DefSideBoxes.css
Skin-agnostic (vector, vector2022, minerva); no :hover-only reveal, no absolute positioning.
Visual layer matches MediaWiki:Gadget-wiktku-start/styles.css ("SÊWIRANA NÛ"); those tokens are
re-declared here under a --dsb-* prefix since they live on #wiktku-start-form, which doesn't
exist on an article page. */
:root {
--dsb-card: #fffdf8;
--dsb-card-sunken: #fbf8f1;
--dsb-rule: #ded6c8;
--dsb-rule-soft: #efe8db;
--dsb-card-edge: #e6dfd2;
--dsb-field-edge: #cfc7b8;
--dsb-field-bg: #fff;
--dsb-ink: #1c1a17;
--dsb-ink-2: #3d3830;
--dsb-ink-3: #57514a;
--dsb-muted: #8a8378;
--dsb-placeholder: #b3ab9e;
--dsb-accent: #2a5db0;
--dsb-accent-deep: #22406f;
--dsb-accent-tint: #eef2fa;
--dsb-accent-edge: #d5def0;
--dsb-ok: #3d8a55;
--dsb-danger: #9c3a28;
--dsb-r-field: 10px;
--dsb-r-card: 12px;
--dsb-r-pill: 999px;
--dsb-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--dsb-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── The pencil toggle on a definition ─────────────────────────────────
A bare stroked pencil glyph, no background/border box, sized to sit quietly next to the definition text. */
.dsb-toolbar {
display: inline-block;
margin-right: 8px;
font-family: var(--dsb-sans);
vertical-align: baseline;
}
.dsb-toggle {
display: inline-grid;
place-items: center;
width: 13px;
height: 13px;
color: var(--dsb-accent);
text-decoration: none;
cursor: pointer;
transition: color 0.12s ease;
}
.dsb-toggle svg {
display: block;
width: 100%;
height: 100%;
fill: none;
stroke: currentColor;
stroke-width: 2.6;
stroke-linecap: round;
stroke-linejoin: round;
}
.dsb-toggle:hover,
.dsb-toggle:focus {
color: var(--dsb-accent-deep);
text-decoration: none;
}
/* ── "Guhartina pêşketî" (advanced editing) panel ──────────────────────
Revealed by the pencil toggle above: every per-sense action this gadget offers, queued together with one
"Lê zêde bike". A plain inline row, not a bordered/background card. */
.dsb-quick-row {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
box-sizing: border-box;
max-width: 520px;
margin: 4px 0 4px 26px;
font-family: var(--dsb-sans);
font-size: 12px;
color: var(--dsb-ink-2);
}
.dsb-quick-link {
align-self: flex-start;
margin-bottom: 10px;
color: var(--dsb-accent);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
}
.dsb-quick-link:hover,
.dsb-quick-link:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* The picker row: gloss + the two primary word groups as direct "+ <field>" links, plus a "Zêdetir" toggle
for the rest -- clicking a link opens its box below and hides the link; .dsb-box-remove un-hides it. */
.dsb-field-picker {
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-bottom: 10px;
}
.dsb-field-picker .dsb-quick-link {
margin-bottom: 0;
}
/* The "Zêdetir" dropdown: every non-primary field link (plus Nimûne/jêgirtin, which sits first) stacked as a
plain vertical list, hidden until the toggle is clicked. A thin border + soft shadow (no card background)
keeps it reading as a distinct menu; align-self: flex-start hugs its own content width instead of
stretching to .dsb-quick-row's max-width. */
.dsb-more-menu {
display: flex;
flex-direction: column;
align-items: flex-start;
align-self: flex-start;
gap: 6px;
margin: 2px 0 10px 4px;
padding: 8px 12px;
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-field);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dsb-more-menu .dsb-quick-link {
margin-bottom: 0;
}
/* Boxes the user has actually opened, stacked in the order they were added -- several can be open at once. */
.dsb-open-boxes {
display: flex;
flex-direction: column;
}
/* One field (its label + input) within the panel -- always a currently-open, removable box. */
.dsb-adv-group {
position: relative;
margin-bottom: 14px;
padding-right: 20px;
}
.dsb-adv-label {
margin-bottom: 4px;
font-size: 12px;
font-weight: 600;
color: var(--dsb-ink-3);
}
.dsb-box-remove {
position: absolute;
top: 0;
right: 0;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-box-remove:hover,
.dsb-box-remove:focus {
color: var(--dsb-accent-deep);
}
.dsb-form-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.dsb-input {
box-sizing: border-box;
min-width: 16em;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-input::placeholder {
color: var(--dsb-placeholder);
opacity: 1;
}
.dsb-input:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
/* ── Plain tag field (Etîket, Kategorî) ────────────────────────────────
Plain type-and-commit tags with no suggestion panel; unlike Hevmane/Dijmane/etc., these carry no modifiers. */
.dsb-tagfield {
box-sizing: border-box;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
min-width: 16em;
padding: 4px 6px;
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-tagfield:focus-within {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
}
.dsb-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
padding: 3px 6px 3px 10px;
}
.dsb-tag-remove {
border: 0;
background: transparent;
color: var(--dsb-muted);
font-size: 13px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
}
.dsb-tag-remove:hover {
color: var(--dsb-danger);
}
.dsb-tagfield .dsb-input {
flex: 1 1 8em;
min-width: 8em;
border: 0;
padding: 3px 2px;
background: transparent;
box-shadow: none;
}
.dsb-tagfield .dsb-input:focus {
box-shadow: none;
}
/* ── Word list with modifier pills ───────────────────────────────────
Every word is its own always-visible row: a word box plus a "+" that attaches one of the 10 WORD_MODIFIERS
as a small pill shown above the box. A fresh empty row is appended once the current last one gets text. */
.dsb-wordlist {
margin: 0;
padding-left: 0;
list-style: none;
}
.dsb-word-li {
margin-bottom: 6px;
}
.dsb-word-li:last-child {
margin-bottom: 0;
}
.dsb-word-mods {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
}
.dsb-word-mod-chip {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 11.5px;
padding: 3px 4px 3px 10px;
cursor: pointer;
}
.dsb-word-mod-chip-remove {
border: 0;
background: transparent;
color: var(--dsb-accent-deep);
font-size: 12px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
opacity: 0.7;
}
.dsb-word-mod-chip-remove:hover {
color: var(--dsb-danger);
opacity: 1;
}
.dsb-word-box-row {
display: flex;
align-items: center;
gap: 6px;
}
.dsb-word-box-row .dsb-word-input {
flex: 1 1 auto;
min-width: 0;
}
.dsb-mod-btn,
.dsb-word-remove {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.dsb-mod-btn {
border: 1px solid var(--dsb-accent-edge);
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
}
.dsb-mod-btn:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-word-remove {
border: 1px solid var(--dsb-field-edge);
background: var(--dsb-field-bg);
color: var(--dsb-muted);
}
.dsb-word-remove:hover {
border-color: var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-mod-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
margin-top: 6px;
padding: 8px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-card);
box-shadow: none;
}
.dsb-mod-pill {
font-family: var(--dsb-sans);
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
white-space: nowrap;
padding: 5px 10px;
cursor: pointer;
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.dsb-mod-pill:hover {
border-color: var(--dsb-accent);
background: var(--dsb-accent);
color: #fff;
}
.dsb-mod-pill:disabled,
.dsb-mod-pill.dsb-mod-pill-used {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
cursor: not-allowed;
opacity: 0.7;
}
.dsb-mod-pill:disabled:hover,
.dsb-mod-pill.dsb-mod-pill-used:hover {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
}
.dsb-mod-val-wrap {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
margin-top: 6px;
}
.dsb-mod-val-input {
flex: 1 1 auto;
min-width: 0;
max-width: 16em;
}
.dsb-mod-confirm,
.dsb-mod-cancel {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
background: var(--dsb-accent-tint);
cursor: pointer;
}
.dsb-mod-confirm {
border: 1px solid var(--dsb-ok);
color: var(--dsb-ok);
}
.dsb-mod-cancel {
border: 1px solid var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-save,
.dsb-cancel,
.dsb-autolink {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
/* One filled pill per row — the same rule the form's footer follows. */
.dsb-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-cancel {
background: transparent;
border: 1px solid transparent;
color: var(--dsb-ink-3);
}
.dsb-cancel:hover {
border-color: var(--dsb-field-edge);
color: var(--dsb-ink);
}
/* An outline pill, distinct from both the filled .dsb-save and the plain-text .dsb-cancel -- a secondary
utility action, not the primary save nor a dismissal. */
.dsb-autolink {
background: transparent;
border: 1px solid var(--dsb-accent-edge);
color: var(--dsb-accent);
}
.dsb-autolink:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-autolink:disabled {
opacity: 0.55;
cursor: progress;
}
/* Status line. Color comes from .dsb-status-ok/.dsb-status-error (added by the .js on success/failure)
rather than an inline style, so these tokens (and dark mode) apply. */
.dsb-status {
font-family: var(--dsb-sans);
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-status-ok { color: var(--dsb-ok); }
.dsb-status-error { color: var(--dsb-danger); }
/* ── "+ Beşek lê zêde bike" ──────────────────────────────────────────
An accent-coloured action link, like the form's .wiktku-adv-toggle:
it opens something, so it is not muted grey. */
.dsb-add-subsection,
.dsb-convert-pos-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-family: var(--dsb-sans);
font-size: 14px;
font-weight: 500;
color: var(--dsb-accent);
text-decoration: none;
border-bottom: 0;
cursor: pointer;
}
.dsb-add-subsection:hover,
.dsb-add-subsection:focus,
.dsb-convert-pos-trigger:hover,
.dsb-convert-pos-trigger:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* ── Subsection panel ────────────────────────────────────────────────
A sunken card rather than a grey utility box; fields stack so the
picker and its input are not competing for one narrow row. */
.dsb-subsection-panel,
.dsb-convert-pos-panel {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
box-sizing: border-box;
max-width: 520px;
margin: 6px 0 14px;
padding: 14px 16px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card-sunken);
border: 1px solid var(--dsb-card-edge);
border-radius: var(--dsb-r-card);
}
.dsb-subsection-select,
.dsb-convert-pos-select {
box-sizing: border-box;
width: 100%;
max-width: 100%;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
}
.dsb-subsection-select:focus,
.dsb-convert-pos-select:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
.dsb-subsection-field {
min-width: 0;
}
.dsb-subsection-words,
.dsb-subsection-text {
box-sizing: border-box;
width: 100%;
min-width: 0;
}
.dsb-subsection-text {
line-height: 1.6;
resize: vertical;
}
/* ── Gloss field inside the advanced-editing panel ────────────────────
Same shape as .dsb-subsection-text. */
.dsb-edit-gloss {
width: 100%;
line-height: 1.6;
resize: vertical;
}
/* ── Live "not saved yet" previews ─────────────────────────────────────
Dropped into the rendered page at the change's own spot. Dashed edge + a small badge mark them as
pending, not real content; they disappear on "Betal bike" or once the real save lands. */
.dsb-preview-block,
.dsb-preview-inline {
margin: 8px 0;
padding: 8px 12px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-accent-tint);
border: 1px dashed var(--dsb-accent-edge);
border-radius: var(--dsb-r-field);
}
.dsb-preview-inline {
margin-left: 26px;
max-width: 520px;
}
.dsb-preview-heading {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-preview-badge {
display: inline-block;
margin-bottom: 6px;
padding: 1px 8px;
font-size: 11px;
font-weight: 500;
color: var(--dsb-accent-deep);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
}
.dsb-preview-badge-inline {
margin-left: 8px;
margin-bottom: 0;
vertical-align: middle;
}
.dsb-preview-list,
.dsb-preview-text {
margin: 0;
padding-left: 18px;
}
.dsb-preview-text {
padding-left: 0;
}
/* ── Floating save-queue widget ─────────────────────────────────────
This gadget's own small floating box. One "Lê zêde bike" click anywhere on the page adds a line here;
"Guhertinan qeyd bike" makes the one real save; "Betal bike" drops everything queued without touching the page. */
.dsb-queue-box {
position: fixed;
top: 60px;
right: 16px;
z-index: 1000;
box-sizing: border-box;
width: 280px;
max-width: calc(100vw - 32px);
max-height: calc(100vh - 90px);
overflow-y: auto;
padding: 12px 14px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent);
border-radius: var(--dsb-r-card);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.16);
}
.dsb-queue-title {
margin-right: 20px;
font-size: 13px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-queue-close {
float: right;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-queue-close:hover,
.dsb-queue-close:focus {
color: var(--dsb-accent-deep);
}
.dsb-queue-list {
margin: 8px 0;
padding-left: 18px;
max-height: 160px;
overflow-y: auto;
}
.dsb-queue-list li {
margin-bottom: 4px;
}
.dsb-queue-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 4px;
}
.dsb-queue-save,
.dsb-queue-cancel {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.dsb-queue-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-queue-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-queue-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-queue-cancel {
background: transparent;
border: 1px solid var(--dsb-field-edge);
color: var(--dsb-ink-3);
}
.dsb-queue-cancel:hover {
border-color: var(--dsb-ink-3);
color: var(--dsb-ink);
}
.dsb-queue-status {
margin-top: 6px;
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-queue-status.dsb-status-ok { color: var(--dsb-ok); }
.dsb-queue-status.dsb-status-error { color: var(--dsb-danger); }
/* ── Minerva (mobile) ────────────────────────────────────────────────
Narrower viewport: keep the panel on screen and give every tap
target the form's 44px minimum. */
.skin-minerva .dsb-quick-row,
.skin-minerva .dsb-subsection-panel,
.skin-minerva .dsb-convert-pos-panel {
max-width: 100%;
}
@media (max-width: 720px), (pointer: coarse) {
.dsb-toggle {
width: 20px;
height: 20px;
}
.dsb-quick-row {
font-size: 13px;
margin-left: 20px;
}
.dsb-input,
.dsb-subsection-select,
.dsb-convert-pos-select {
min-height: 40px;
/* >=16px stops iOS Safari zooming the page on focus. */
font-size: 16px;
}
.dsb-mod-btn,
.dsb-word-remove,
.dsb-mod-confirm,
.dsb-mod-cancel {
width: 36px;
height: 36px;
font-size: 15px;
}
.dsb-mod-pill {
padding: 8px 12px;
}
.dsb-mod-val-input {
max-width: none;
}
.dsb-tagfield .dsb-input {
min-height: 32px;
}
.dsb-tag-remove {
padding: 0 6px;
}
.dsb-save,
.dsb-cancel,
.dsb-autolink,
.dsb-queue-save,
.dsb-queue-cancel {
min-height: 40px;
padding: 8px 16px;
}
.dsb-queue-box {
top: auto;
bottom: 8px;
right: 8px;
left: 8px;
width: auto;
}
}
/* ── Dark mode ───────────────────────────────────────────────────────
Same warm dark palette and same explicit-signal-only rule as the
form's stylesheet: no bare prefers-color-scheme fallback, since
legacy Vector sets no theme class and would go dark on its own. */
html.skin-theme-clientpref-night,
html.skin-nightmode {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-night .dsb-save,
html.skin-nightmode .dsb-save,
html.skin-theme-clientpref-night .dsb-queue-save,
html.skin-nightmode .dsb-queue-save {
color: #14213a;
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-os .dsb-save,
html.skin-theme-clientpref-os .dsb-queue-save {
color: #14213a;
}
}
8vjuxvertt64dhsaq30dnr4qcbctu10
6347408
6347398
2026-08-31T16:42:20Z
Wikihez
7344
6347408
css
text/css
/* Gadget-DefSideBoxes.css
Skin-agnostic (vector, vector2022, minerva); no :hover-only reveal, no absolute positioning.
Visual layer matches MediaWiki:Gadget-wiktku-start/styles.css ("SÊWIRANA NÛ"); those tokens are
re-declared here under a --dsb-* prefix since they live on #wiktku-start-form, which doesn't
exist on an article page. */
:root {
--dsb-card: #fffdf8;
--dsb-card-sunken: #fbf8f1;
--dsb-rule: #ded6c8;
--dsb-rule-soft: #efe8db;
--dsb-card-edge: #e6dfd2;
--dsb-field-edge: #cfc7b8;
--dsb-field-bg: #fff;
--dsb-ink: #1c1a17;
--dsb-ink-2: #3d3830;
--dsb-ink-3: #57514a;
--dsb-muted: #8a8378;
--dsb-placeholder: #b3ab9e;
--dsb-accent: #2a5db0;
--dsb-accent-deep: #22406f;
--dsb-accent-tint: #eef2fa;
--dsb-accent-edge: #d5def0;
--dsb-ok: #3d8a55;
--dsb-danger: #9c3a28;
--dsb-r-field: 10px;
--dsb-r-card: 12px;
--dsb-r-pill: 999px;
--dsb-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--dsb-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── The pencil toggle on a definition ─────────────────────────────────
The classic MediaWiki interlanguage-links edit pencil (same asset as defEditButton), not a hand-drawn glyph. */
.dsb-toolbar {
display: inline-block;
margin-right: 8px;
font-family: var(--dsb-sans);
vertical-align: baseline;
}
.dsb-toggle {
display: inline-block;
width: 13px;
height: 13px;
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d3/InterlanguageLinks-Asset-Pencil.gif);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
text-decoration: none;
cursor: pointer;
}
.dsb-toggle:hover,
.dsb-toggle:focus {
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d1/InterlanguageLinks-Asset-Pencil-Hover.gif);
}
/* ── "Guhartina pêşketî" (advanced editing) panel ──────────────────────
Revealed by the pencil toggle above: every per-sense action this gadget offers, queued together with one
"Lê zêde bike". A plain inline row, not a bordered/background card. */
.dsb-quick-row {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
box-sizing: border-box;
max-width: 520px;
margin: 4px 0 4px 26px;
font-family: var(--dsb-sans);
font-size: 12px;
color: var(--dsb-ink-2);
}
.dsb-quick-link {
align-self: flex-start;
margin-bottom: 10px;
color: var(--dsb-accent);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
}
.dsb-quick-link:hover,
.dsb-quick-link:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* The picker row: gloss + the two primary word groups as direct "+ <field>" links, plus a "Zêdetir" toggle
for the rest -- clicking a link opens its box below and hides the link; .dsb-box-remove un-hides it.
position: relative anchors .dsb-more-menu's overlay below (see there). */
.dsb-field-picker {
position: relative;
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-bottom: 10px;
}
.dsb-field-picker .dsb-quick-link {
margin-bottom: 0;
}
/* The "Zêdetir" dropdown: every non-primary field link (plus Nimûne/jêgirtin, which sits first) stacked as a
plain vertical list. Floats over the page as an overlay (positioned against .dsb-field-picker) instead of
pushing $openBoxes/the rest of the definition down when it opens. */
.dsb-more-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 10;
display: flex;
flex-direction: column;
align-items: flex-start;
width: max-content;
max-width: min(320px, calc(100vw - 40px));
gap: 6px;
margin: 2px 0 0 4px;
padding: 8px 12px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-field);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dsb-more-menu .dsb-quick-link {
margin-bottom: 0;
}
/* Boxes the user has actually opened, stacked in the order they were added -- several can be open at once. */
.dsb-open-boxes {
display: flex;
flex-direction: column;
}
/* One field (its label + input) within the panel -- always a currently-open, removable box. */
.dsb-adv-group {
position: relative;
margin-bottom: 14px;
padding-right: 20px;
}
.dsb-adv-label {
margin-bottom: 4px;
font-size: 12px;
font-weight: 600;
color: var(--dsb-ink-3);
}
.dsb-box-remove {
position: absolute;
top: 0;
right: 0;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-box-remove:hover,
.dsb-box-remove:focus {
color: var(--dsb-accent-deep);
}
.dsb-form-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.dsb-input {
box-sizing: border-box;
min-width: 16em;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-input::placeholder {
color: var(--dsb-placeholder);
opacity: 1;
}
.dsb-input:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
/* ── Plain tag field (Etîket, Kategorî) ────────────────────────────────
Plain type-and-commit tags with no suggestion panel; unlike Hevmane/Dijmane/etc., these carry no modifiers. */
.dsb-tagfield {
box-sizing: border-box;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
min-width: 16em;
padding: 4px 6px;
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-tagfield:focus-within {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
}
.dsb-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
padding: 3px 6px 3px 10px;
}
.dsb-tag-remove {
border: 0;
background: transparent;
color: var(--dsb-muted);
font-size: 13px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
}
.dsb-tag-remove:hover {
color: var(--dsb-danger);
}
.dsb-tagfield .dsb-input {
flex: 1 1 8em;
min-width: 8em;
border: 0;
padding: 3px 2px;
background: transparent;
box-shadow: none;
}
.dsb-tagfield .dsb-input:focus {
box-shadow: none;
}
/* ── Word list with modifier pills ───────────────────────────────────
Every word is its own always-visible row: a word box plus a "+" that attaches one of the 10 WORD_MODIFIERS
as a small pill shown above the box. A fresh empty row is appended once the current last one gets text. */
.dsb-wordlist {
margin: 0;
padding-left: 0;
list-style: none;
}
.dsb-word-li {
margin-bottom: 6px;
}
.dsb-word-li:last-child {
margin-bottom: 0;
}
.dsb-word-mods {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
}
.dsb-word-mod-chip {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 11.5px;
padding: 3px 4px 3px 10px;
cursor: pointer;
}
.dsb-word-mod-chip-remove {
border: 0;
background: transparent;
color: var(--dsb-accent-deep);
font-size: 12px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
opacity: 0.7;
}
.dsb-word-mod-chip-remove:hover {
color: var(--dsb-danger);
opacity: 1;
}
.dsb-word-box-row {
display: flex;
align-items: center;
gap: 6px;
}
.dsb-word-box-row .dsb-word-input {
flex: 1 1 auto;
min-width: 0;
}
.dsb-mod-btn,
.dsb-word-remove {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.dsb-mod-btn {
border: 1px solid var(--dsb-accent-edge);
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
}
.dsb-mod-btn:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-word-remove {
border: 1px solid var(--dsb-field-edge);
background: var(--dsb-field-bg);
color: var(--dsb-muted);
}
.dsb-word-remove:hover {
border-color: var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-mod-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
margin-top: 6px;
padding: 8px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-card);
box-shadow: none;
}
.dsb-mod-pill {
font-family: var(--dsb-sans);
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
white-space: nowrap;
padding: 5px 10px;
cursor: pointer;
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.dsb-mod-pill:hover {
border-color: var(--dsb-accent);
background: var(--dsb-accent);
color: #fff;
}
.dsb-mod-pill:disabled,
.dsb-mod-pill.dsb-mod-pill-used {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
cursor: not-allowed;
opacity: 0.7;
}
.dsb-mod-pill:disabled:hover,
.dsb-mod-pill.dsb-mod-pill-used:hover {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
}
.dsb-mod-val-wrap {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
margin-top: 6px;
}
.dsb-mod-val-input {
flex: 1 1 auto;
min-width: 0;
max-width: 16em;
}
.dsb-mod-confirm,
.dsb-mod-cancel {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
background: var(--dsb-accent-tint);
cursor: pointer;
}
.dsb-mod-confirm {
border: 1px solid var(--dsb-ok);
color: var(--dsb-ok);
}
.dsb-mod-cancel {
border: 1px solid var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-save,
.dsb-cancel,
.dsb-autolink {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
/* One filled pill per row — the same rule the form's footer follows. */
.dsb-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-cancel {
background: transparent;
border: 1px solid transparent;
color: var(--dsb-ink-3);
}
.dsb-cancel:hover {
border-color: var(--dsb-field-edge);
color: var(--dsb-ink);
}
/* An outline pill, distinct from both the filled .dsb-save and the plain-text .dsb-cancel -- a secondary
utility action, not the primary save nor a dismissal. */
.dsb-autolink {
background: transparent;
border: 1px solid var(--dsb-accent-edge);
color: var(--dsb-accent);
}
.dsb-autolink:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-autolink:disabled {
opacity: 0.55;
cursor: progress;
}
/* Status line. Color comes from .dsb-status-ok/.dsb-status-error (added by the .js on success/failure)
rather than an inline style, so these tokens (and dark mode) apply. */
.dsb-status {
font-family: var(--dsb-sans);
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-status-ok { color: var(--dsb-ok); }
.dsb-status-error { color: var(--dsb-danger); }
/* ── "+ Beşek lê zêde bike" ──────────────────────────────────────────
An accent-coloured action link, like the form's .wiktku-adv-toggle:
it opens something, so it is not muted grey. */
.dsb-add-subsection,
.dsb-convert-pos-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-family: var(--dsb-sans);
font-size: 14px;
font-weight: 500;
color: var(--dsb-accent);
text-decoration: none;
border-bottom: 0;
cursor: pointer;
}
.dsb-add-subsection:hover,
.dsb-add-subsection:focus,
.dsb-convert-pos-trigger:hover,
.dsb-convert-pos-trigger:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* ── Subsection panel ────────────────────────────────────────────────
A sunken card rather than a grey utility box; fields stack so the
picker and its input are not competing for one narrow row. */
.dsb-subsection-panel,
.dsb-convert-pos-panel {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
box-sizing: border-box;
max-width: 520px;
margin: 6px 0 14px;
padding: 14px 16px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card-sunken);
border: 1px solid var(--dsb-card-edge);
border-radius: var(--dsb-r-card);
}
.dsb-subsection-select,
.dsb-convert-pos-select {
box-sizing: border-box;
width: 100%;
max-width: 100%;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
}
.dsb-subsection-select:focus,
.dsb-convert-pos-select:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
.dsb-subsection-field {
min-width: 0;
}
.dsb-subsection-words,
.dsb-subsection-text {
box-sizing: border-box;
width: 100%;
min-width: 0;
}
.dsb-subsection-text {
line-height: 1.6;
resize: vertical;
}
/* ── Gloss field inside the advanced-editing panel ────────────────────
Same shape as .dsb-subsection-text. */
.dsb-edit-gloss {
width: 100%;
line-height: 1.6;
resize: vertical;
}
/* ── Live "not saved yet" previews ─────────────────────────────────────
Dropped into the rendered page at the change's own spot. Dashed edge + a small badge mark them as
pending, not real content; they disappear on "Betal bike" or once the real save lands. */
.dsb-preview-block,
.dsb-preview-inline {
margin: 8px 0;
padding: 8px 12px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-accent-tint);
border: 1px dashed var(--dsb-accent-edge);
border-radius: var(--dsb-r-field);
}
.dsb-preview-inline {
margin-left: 26px;
max-width: 520px;
}
.dsb-preview-heading {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-preview-badge {
display: inline-block;
margin-bottom: 6px;
padding: 1px 8px;
font-size: 11px;
font-weight: 500;
color: var(--dsb-accent-deep);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
}
.dsb-preview-badge-inline {
margin-left: 8px;
margin-bottom: 0;
vertical-align: middle;
}
.dsb-preview-list,
.dsb-preview-text {
margin: 0;
padding-left: 18px;
}
.dsb-preview-text {
padding-left: 0;
}
/* ── Floating save-queue widget ─────────────────────────────────────
This gadget's own small floating box. One "Lê zêde bike" click anywhere on the page adds a line here;
"Guhertinan qeyd bike" makes the one real save; "Betal bike" drops everything queued without touching the page. */
.dsb-queue-box {
position: fixed;
top: 60px;
right: 16px;
z-index: 1000;
box-sizing: border-box;
width: 280px;
max-width: calc(100vw - 32px);
max-height: calc(100vh - 90px);
overflow-y: auto;
padding: 12px 14px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent);
border-radius: var(--dsb-r-card);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.16);
}
.dsb-queue-title {
margin-right: 20px;
font-size: 13px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-queue-close {
float: right;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-queue-close:hover,
.dsb-queue-close:focus {
color: var(--dsb-accent-deep);
}
.dsb-queue-list {
margin: 8px 0;
padding-left: 18px;
max-height: 160px;
overflow-y: auto;
}
.dsb-queue-list li {
margin-bottom: 4px;
}
.dsb-queue-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 4px;
}
.dsb-queue-save,
.dsb-queue-cancel {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.dsb-queue-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-queue-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-queue-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-queue-cancel {
background: transparent;
border: 1px solid var(--dsb-field-edge);
color: var(--dsb-ink-3);
}
.dsb-queue-cancel:hover {
border-color: var(--dsb-ink-3);
color: var(--dsb-ink);
}
.dsb-queue-status {
margin-top: 6px;
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-queue-status.dsb-status-ok { color: var(--dsb-ok); }
.dsb-queue-status.dsb-status-error { color: var(--dsb-danger); }
/* ── Minerva (mobile) ────────────────────────────────────────────────
Narrower viewport: keep the panel on screen and give every tap
target the form's 44px minimum. */
.skin-minerva .dsb-quick-row,
.skin-minerva .dsb-subsection-panel,
.skin-minerva .dsb-convert-pos-panel {
max-width: 100%;
}
@media (max-width: 720px), (pointer: coarse) {
.dsb-toggle {
width: 20px;
height: 20px;
}
.dsb-quick-row {
font-size: 13px;
margin-left: 20px;
}
.dsb-input,
.dsb-subsection-select,
.dsb-convert-pos-select {
min-height: 40px;
/* >=16px stops iOS Safari zooming the page on focus. */
font-size: 16px;
}
.dsb-mod-btn,
.dsb-word-remove,
.dsb-mod-confirm,
.dsb-mod-cancel {
width: 36px;
height: 36px;
font-size: 15px;
}
.dsb-mod-pill {
padding: 8px 12px;
}
.dsb-mod-val-input {
max-width: none;
}
.dsb-tagfield .dsb-input {
min-height: 32px;
}
.dsb-tag-remove {
padding: 0 6px;
}
.dsb-save,
.dsb-cancel,
.dsb-autolink,
.dsb-queue-save,
.dsb-queue-cancel {
min-height: 40px;
padding: 8px 16px;
}
.dsb-queue-box {
top: auto;
bottom: 8px;
right: 8px;
left: 8px;
width: auto;
}
}
/* ── Dark mode ───────────────────────────────────────────────────────
Same warm dark palette and same explicit-signal-only rule as the
form's stylesheet: no bare prefers-color-scheme fallback, since
legacy Vector sets no theme class and would go dark on its own. */
html.skin-theme-clientpref-night,
html.skin-nightmode {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-night .dsb-save,
html.skin-nightmode .dsb-save,
html.skin-theme-clientpref-night .dsb-queue-save,
html.skin-nightmode .dsb-queue-save {
color: #14213a;
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-os .dsb-save,
html.skin-theme-clientpref-os .dsb-queue-save {
color: #14213a;
}
}
fo1rao74yhhy47cdd9a8547x33ddjen
6347443
6347408
2026-08-31T19:14:54Z
Wikihez
7344
6347443
css
text/css
/* Gadget-DefSideBoxes.css
Skin-agnostic (vector, vector2022, minerva). Visual layer matches MediaWiki:Gadget-wiktku-start/styles.css
("SÊWIRANA NÛ"); those tokens are re-declared here under a --dsb-* prefix since they live on
#wiktku-start-form, which doesn't exist on an article page. */
:root {
--dsb-card: #fffdf8;
--dsb-card-sunken: #fbf8f1;
--dsb-rule: #ded6c8;
--dsb-rule-soft: #efe8db;
--dsb-card-edge: #e6dfd2;
--dsb-field-edge: #cfc7b8;
--dsb-field-bg: #fff;
--dsb-ink: #1c1a17;
--dsb-ink-2: #3d3830;
--dsb-ink-3: #57514a;
--dsb-muted: #8a8378;
--dsb-placeholder: #b3ab9e;
--dsb-accent: #2a5db0;
--dsb-accent-deep: #22406f;
--dsb-accent-tint: #eef2fa;
--dsb-accent-edge: #d5def0;
--dsb-ok: #3d8a55;
--dsb-danger: #9c3a28;
--dsb-r-field: 10px;
--dsb-r-card: 12px;
--dsb-r-pill: 999px;
--dsb-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--dsb-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── The pencil toggle on a definition ─────────────────────────────────
The classic MediaWiki interlanguage-links edit pencil (same asset as defEditButton), not a hand-drawn glyph.
Hidden by default like defEditButton: revealed by hovering the line on desktop, or by tapping it on touch
(.dsb-revealed, added by attachToolbar()'s own click handler) -- keeps the definition list uncluttered. */
.dsb-toolbar {
display: inline-block;
margin-right: 8px;
font-family: var(--dsb-sans);
vertical-align: baseline;
}
.dsb-toggle {
display: inline-block;
width: 13px;
height: 13px;
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d3/InterlanguageLinks-Asset-Pencil.gif);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
text-decoration: none;
cursor: pointer;
opacity: 0;
transition: opacity 0.15s ease;
}
.dsb-toggle:hover,
.dsb-toggle:focus {
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d1/InterlanguageLinks-Asset-Pencil-Hover.gif);
}
li:hover .dsb-toolbar .dsb-toggle,
.dsb-toggle:focus {
opacity: 1;
}
@media (hover: none), (pointer: coarse) {
.dsb-toolbar.dsb-revealed .dsb-toggle {
opacity: 1;
}
}
/* ── "Guhartina pêşketî" (advanced editing) panel ──────────────────────
Revealed by the pencil toggle above: every per-sense action this gadget offers, queued together with one
"Lê zêde bike". A plain inline row, not a bordered/background card. */
.dsb-quick-row {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
box-sizing: border-box;
max-width: 520px;
margin: 4px 0 4px 26px;
font-family: var(--dsb-sans);
font-size: 12px;
color: var(--dsb-ink-2);
}
.dsb-quick-link {
align-self: flex-start;
margin-bottom: 10px;
color: var(--dsb-accent);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
}
.dsb-quick-link:hover,
.dsb-quick-link:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* The picker row: gloss + the two primary word groups as direct "+ <field>" links, plus a "Zêdetir" toggle
for the rest -- clicking a link opens its box below and hides the link; .dsb-box-remove un-hides it.
position: relative anchors .dsb-more-menu's overlay below (see there). */
.dsb-field-picker {
position: relative;
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-bottom: 10px;
}
.dsb-field-picker .dsb-quick-link {
margin-bottom: 0;
}
/* The "Zêdetir" dropdown: every non-primary field link (plus Nimûne/jêgirtin, which sits first) stacked as a
plain vertical list. Floats over the page as an overlay (positioned against .dsb-field-picker) instead of
pushing $openBoxes/the rest of the definition down when it opens. */
.dsb-more-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 10;
display: flex;
flex-direction: column;
align-items: flex-start;
width: max-content;
max-width: min(320px, calc(100vw - 40px));
gap: 6px;
margin: 2px 0 0 4px;
padding: 8px 12px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-field);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dsb-more-menu .dsb-quick-link {
margin-bottom: 0;
}
/* Boxes the user has actually opened, stacked in the order they were added -- several can be open at once. */
.dsb-open-boxes {
display: flex;
flex-direction: column;
}
/* One field (its label + input) within the panel -- always a currently-open, removable box. */
.dsb-adv-group {
position: relative;
margin-bottom: 14px;
padding-right: 20px;
}
.dsb-adv-label {
margin-bottom: 4px;
font-size: 12px;
font-weight: 600;
color: var(--dsb-ink-3);
}
.dsb-box-remove {
position: absolute;
top: 0;
right: 0;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-box-remove:hover,
.dsb-box-remove:focus {
color: var(--dsb-accent-deep);
}
.dsb-form-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.dsb-input {
box-sizing: border-box;
min-width: 16em;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-input::placeholder {
color: var(--dsb-placeholder);
opacity: 1;
}
.dsb-input:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
/* ── Plain tag field (Etîket, Kategorî) ────────────────────────────────
Plain type-and-commit tags with no suggestion panel; unlike Hevmane/Dijmane/etc., these carry no modifiers. */
.dsb-tagfield {
box-sizing: border-box;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
min-width: 16em;
padding: 4px 6px;
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-tagfield:focus-within {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
}
.dsb-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
padding: 3px 6px 3px 10px;
}
.dsb-tag-remove {
border: 0;
background: transparent;
color: var(--dsb-muted);
font-size: 13px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
}
.dsb-tag-remove:hover {
color: var(--dsb-danger);
}
.dsb-tagfield .dsb-input {
flex: 1 1 8em;
min-width: 8em;
border: 0;
padding: 3px 2px;
background: transparent;
box-shadow: none;
}
.dsb-tagfield .dsb-input:focus {
box-shadow: none;
}
/* ── Word list with modifier pills ───────────────────────────────────
Every word is its own always-visible row: a word box plus a "+" that attaches one of the 10 WORD_MODIFIERS
as a small pill shown above the box. A fresh empty row is appended once the current last one gets text. */
.dsb-wordlist {
margin: 0;
padding-left: 0;
list-style: none;
}
.dsb-word-li {
margin-bottom: 6px;
}
.dsb-word-li:last-child {
margin-bottom: 0;
}
.dsb-word-mods {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
}
.dsb-word-mod-chip {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 11.5px;
padding: 3px 4px 3px 10px;
cursor: pointer;
}
.dsb-word-mod-chip-remove {
border: 0;
background: transparent;
color: var(--dsb-accent-deep);
font-size: 12px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
opacity: 0.7;
}
.dsb-word-mod-chip-remove:hover {
color: var(--dsb-danger);
opacity: 1;
}
.dsb-word-box-row {
display: flex;
align-items: center;
gap: 6px;
}
.dsb-word-box-row .dsb-word-input {
flex: 1 1 auto;
min-width: 0;
}
.dsb-mod-btn,
.dsb-word-remove {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.dsb-mod-btn {
border: 1px solid var(--dsb-accent-edge);
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
}
.dsb-mod-btn:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-word-remove {
border: 1px solid var(--dsb-field-edge);
background: var(--dsb-field-bg);
color: var(--dsb-muted);
}
.dsb-word-remove:hover {
border-color: var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-mod-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
margin-top: 6px;
padding: 8px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-card);
box-shadow: none;
}
.dsb-mod-pill {
font-family: var(--dsb-sans);
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
white-space: nowrap;
padding: 5px 10px;
cursor: pointer;
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.dsb-mod-pill:hover {
border-color: var(--dsb-accent);
background: var(--dsb-accent);
color: #fff;
}
.dsb-mod-pill:disabled,
.dsb-mod-pill.dsb-mod-pill-used {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
cursor: not-allowed;
opacity: 0.7;
}
.dsb-mod-pill:disabled:hover,
.dsb-mod-pill.dsb-mod-pill-used:hover {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
}
.dsb-mod-val-wrap {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
margin-top: 6px;
}
.dsb-mod-val-input {
flex: 1 1 auto;
min-width: 0;
max-width: 16em;
}
.dsb-mod-confirm,
.dsb-mod-cancel {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
background: var(--dsb-accent-tint);
cursor: pointer;
}
.dsb-mod-confirm {
border: 1px solid var(--dsb-ok);
color: var(--dsb-ok);
}
.dsb-mod-cancel {
border: 1px solid var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-save,
.dsb-cancel,
.dsb-autolink {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
/* One filled pill per row — the same rule the form's footer follows. */
.dsb-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-cancel {
background: transparent;
border: 1px solid transparent;
color: var(--dsb-ink-3);
}
.dsb-cancel:hover {
border-color: var(--dsb-field-edge);
color: var(--dsb-ink);
}
/* An outline pill, distinct from both the filled .dsb-save and the plain-text .dsb-cancel -- a secondary
utility action, not the primary save nor a dismissal. */
.dsb-autolink {
background: transparent;
border: 1px solid var(--dsb-accent-edge);
color: var(--dsb-accent);
}
.dsb-autolink:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-autolink:disabled {
opacity: 0.55;
cursor: progress;
}
/* Status line. Color comes from .dsb-status-ok/.dsb-status-error (added by the .js on success/failure)
rather than an inline style, so these tokens (and dark mode) apply. */
.dsb-status {
font-family: var(--dsb-sans);
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-status-ok { color: var(--dsb-ok); }
.dsb-status-error { color: var(--dsb-danger); }
/* ── "+ Beşek lê zêde bike" ──────────────────────────────────────────
An accent-coloured action link, like the form's .wiktku-adv-toggle:
it opens something, so it is not muted grey. */
.dsb-add-subsection,
.dsb-convert-pos-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-family: var(--dsb-sans);
font-size: 14px;
font-weight: 500;
color: var(--dsb-accent);
text-decoration: none;
border-bottom: 0;
cursor: pointer;
}
.dsb-add-subsection:hover,
.dsb-add-subsection:focus,
.dsb-convert-pos-trigger:hover,
.dsb-convert-pos-trigger:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* ── Subsection panel ────────────────────────────────────────────────
A sunken card rather than a grey utility box; fields stack so the
picker and its input are not competing for one narrow row. */
.dsb-subsection-panel,
.dsb-convert-pos-panel {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
box-sizing: border-box;
max-width: 520px;
margin: 6px 0 14px;
padding: 14px 16px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card-sunken);
border: 1px solid var(--dsb-card-edge);
border-radius: var(--dsb-r-card);
}
.dsb-subsection-select,
.dsb-convert-pos-select {
box-sizing: border-box;
width: 100%;
max-width: 100%;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
}
.dsb-subsection-select:focus,
.dsb-convert-pos-select:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
.dsb-subsection-field {
min-width: 0;
}
.dsb-subsection-words,
.dsb-subsection-text {
box-sizing: border-box;
width: 100%;
min-width: 0;
}
.dsb-subsection-text {
line-height: 1.6;
resize: vertical;
}
/* ── Gloss field inside the advanced-editing panel ────────────────────
Same shape as .dsb-subsection-text. */
.dsb-edit-gloss {
width: 100%;
line-height: 1.6;
resize: vertical;
}
/* ── Live "not saved yet" previews ─────────────────────────────────────
Dropped into the rendered page at the change's own spot. Dashed edge + a small badge mark them as
pending, not real content; they disappear on "Betal bike" or once the real save lands. */
.dsb-preview-block,
.dsb-preview-inline {
margin: 8px 0;
padding: 8px 12px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-accent-tint);
border: 1px dashed var(--dsb-accent-edge);
border-radius: var(--dsb-r-field);
}
.dsb-preview-inline {
margin-left: 26px;
max-width: 520px;
}
.dsb-preview-heading {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-preview-badge {
display: inline-block;
margin-bottom: 6px;
padding: 1px 8px;
font-size: 11px;
font-weight: 500;
color: var(--dsb-accent-deep);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
}
.dsb-preview-badge-inline {
margin-left: 8px;
margin-bottom: 0;
vertical-align: middle;
}
.dsb-preview-list,
.dsb-preview-text {
margin: 0;
padding-left: 18px;
}
.dsb-preview-text {
padding-left: 0;
}
/* ── Floating save-queue widget ─────────────────────────────────────
This gadget's own small floating box. One "Lê zêde bike" click anywhere on the page adds a line here;
"Guhertinan qeyd bike" makes the one real save; "Betal bike" drops everything queued without touching the page. */
.dsb-queue-box {
position: fixed;
top: 60px;
right: 16px;
z-index: 1000;
box-sizing: border-box;
width: 280px;
max-width: calc(100vw - 32px);
max-height: calc(100vh - 90px);
overflow-y: auto;
padding: 12px 14px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent);
border-radius: var(--dsb-r-card);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.16);
}
.dsb-queue-title {
margin-right: 20px;
font-size: 13px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-queue-close {
float: right;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-queue-close:hover,
.dsb-queue-close:focus {
color: var(--dsb-accent-deep);
}
.dsb-queue-list {
margin: 8px 0;
padding-left: 18px;
max-height: 160px;
overflow-y: auto;
}
.dsb-queue-list li {
margin-bottom: 4px;
}
.dsb-queue-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 4px;
}
.dsb-queue-save,
.dsb-queue-cancel {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.dsb-queue-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-queue-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-queue-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-queue-cancel {
background: transparent;
border: 1px solid var(--dsb-field-edge);
color: var(--dsb-ink-3);
}
.dsb-queue-cancel:hover {
border-color: var(--dsb-ink-3);
color: var(--dsb-ink);
}
.dsb-queue-status {
margin-top: 6px;
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-queue-status.dsb-status-ok { color: var(--dsb-ok); }
.dsb-queue-status.dsb-status-error { color: var(--dsb-danger); }
/* ── Minerva (mobile) ────────────────────────────────────────────────
Narrower viewport: keep the panel on screen and give every tap
target the form's 44px minimum. */
.skin-minerva .dsb-quick-row,
.skin-minerva .dsb-subsection-panel,
.skin-minerva .dsb-convert-pos-panel {
max-width: 100%;
}
@media (max-width: 720px), (pointer: coarse) {
.dsb-toggle {
width: 20px;
height: 20px;
}
.dsb-quick-row {
font-size: 13px;
margin-left: 20px;
}
.dsb-input,
.dsb-subsection-select,
.dsb-convert-pos-select {
min-height: 40px;
/* >=16px stops iOS Safari zooming the page on focus. */
font-size: 16px;
}
.dsb-mod-btn,
.dsb-word-remove,
.dsb-mod-confirm,
.dsb-mod-cancel {
width: 36px;
height: 36px;
font-size: 15px;
}
.dsb-mod-pill {
padding: 8px 12px;
}
.dsb-mod-val-input {
max-width: none;
}
.dsb-tagfield .dsb-input {
min-height: 32px;
}
.dsb-tag-remove {
padding: 0 6px;
}
.dsb-save,
.dsb-cancel,
.dsb-autolink,
.dsb-queue-save,
.dsb-queue-cancel {
min-height: 40px;
padding: 8px 16px;
}
.dsb-queue-box {
top: auto;
bottom: 8px;
right: 8px;
left: 8px;
width: auto;
}
}
/* ── Dark mode ───────────────────────────────────────────────────────
Same warm dark palette and same explicit-signal-only rule as the
form's stylesheet: no bare prefers-color-scheme fallback, since
legacy Vector sets no theme class and would go dark on its own. */
html.skin-theme-clientpref-night,
html.skin-nightmode {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-night .dsb-save,
html.skin-nightmode .dsb-save,
html.skin-theme-clientpref-night .dsb-queue-save,
html.skin-nightmode .dsb-queue-save {
color: #14213a;
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-os .dsb-save,
html.skin-theme-clientpref-os .dsb-queue-save {
color: #14213a;
}
}
9nwkbt77clfu740u390j5qmbh1rwy0w
6347446
6347443
2026-08-31T19:31:25Z
Wikihez
7344
6347446
css
text/css
/* Gadget-DefSideBoxes.css
Skin-agnostic (vector, vector2022, minerva). Visual layer matches MediaWiki:Gadget-wiktku-start/styles.css
("SÊWIRANA NÛ"); those tokens are re-declared here under a --dsb-* prefix since they live on
#wiktku-start-form, which doesn't exist on an article page. */
:root {
--dsb-card: #fffdf8;
--dsb-card-sunken: #fbf8f1;
--dsb-rule: #ded6c8;
--dsb-rule-soft: #efe8db;
--dsb-card-edge: #e6dfd2;
--dsb-field-edge: #cfc7b8;
--dsb-field-bg: #fff;
--dsb-ink: #1c1a17;
--dsb-ink-2: #3d3830;
--dsb-ink-3: #57514a;
--dsb-muted: #8a8378;
--dsb-placeholder: #b3ab9e;
--dsb-accent: #2a5db0;
--dsb-accent-deep: #22406f;
--dsb-accent-tint: #eef2fa;
--dsb-accent-edge: #d5def0;
--dsb-ok: #3d8a55;
--dsb-danger: #9c3a28;
--dsb-r-field: 10px;
--dsb-r-card: 12px;
--dsb-r-pill: 999px;
--dsb-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--dsb-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── The pencil toggle on a definition ─────────────────────────────────
The classic MediaWiki interlanguage-links edit pencil (same asset as en.wiktionary's defEditButton), not a
hand-drawn glyph. Like defEditButton, this is pulled out of the text flow with position: absolute + a
negative margin-left instead of sitting inline before the gloss -- it pops into the list gutter, to the left
of the "1."/"#" marker, rather than pushing the definition text over. No positioned ancestor is needed: with
no top/left/right/bottom set, absolute positioning falls back to the element's own static (in-flow) position,
so the negative margin shifts it left from wherever it would otherwise have started, li nesting and all.
Hidden by default: revealed by hovering the line on desktop, or by tapping it on touch (.dsb-revealed, added
by attachToolbar()'s own click handler) -- keeps the definition list uncluttered. */
.dsb-toolbar {
position: absolute;
margin-left: -22px;
width: 22px;
height: 20px;
font-family: var(--dsb-sans);
}
.dsb-toggle {
display: block;
margin-top: 3px;
margin-left: 7px;
width: 13px;
height: 13px;
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d3/InterlanguageLinks-Asset-Pencil.gif);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
text-decoration: none;
cursor: pointer;
opacity: 0;
transition: opacity 0.15s ease;
}
.dsb-toggle:hover,
.dsb-toggle:focus {
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d1/InterlanguageLinks-Asset-Pencil-Hover.gif);
}
li:hover .dsb-toolbar .dsb-toggle,
.dsb-toggle:focus {
opacity: 1;
}
@media (hover: none), (pointer: coarse) {
.dsb-toolbar.dsb-revealed .dsb-toggle {
opacity: 1;
}
}
/* ── "Guhartina pêşketî" (advanced editing) panel ──────────────────────
Revealed by the pencil toggle above: every per-sense action this gadget offers, queued together with one
"Lê zêde bike". A plain inline row, not a bordered/background card. */
.dsb-quick-row {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
box-sizing: border-box;
max-width: 520px;
margin: 4px 0 4px 26px;
font-family: var(--dsb-sans);
font-size: 12px;
color: var(--dsb-ink-2);
}
.dsb-quick-link {
align-self: flex-start;
margin-bottom: 10px;
color: var(--dsb-accent);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
}
.dsb-quick-link:hover,
.dsb-quick-link:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* The picker row: gloss + the two primary word groups as direct "+ <field>" links, plus a "Zêdetir" toggle
for the rest -- clicking a link opens its box below and hides the link; .dsb-box-remove un-hides it.
position: relative anchors .dsb-more-menu's overlay below (see there). */
.dsb-field-picker {
position: relative;
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-bottom: 10px;
}
.dsb-field-picker .dsb-quick-link {
margin-bottom: 0;
}
/* The "Zêdetir" dropdown: every non-primary field link (plus Nimûne/jêgirtin, which sits first) stacked as a
plain vertical list. Floats over the page as an overlay (positioned against .dsb-field-picker) instead of
pushing $openBoxes/the rest of the definition down when it opens. */
.dsb-more-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 10;
display: flex;
flex-direction: column;
align-items: flex-start;
width: max-content;
max-width: min(320px, calc(100vw - 40px));
gap: 6px;
margin: 2px 0 0 4px;
padding: 8px 12px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-field);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dsb-more-menu .dsb-quick-link {
margin-bottom: 0;
}
/* Boxes the user has actually opened, stacked in the order they were added -- several can be open at once. */
.dsb-open-boxes {
display: flex;
flex-direction: column;
}
/* One field (its label + input) within the panel -- always a currently-open, removable box. */
.dsb-adv-group {
position: relative;
margin-bottom: 14px;
padding-right: 20px;
}
.dsb-adv-label {
margin-bottom: 4px;
font-size: 12px;
font-weight: 600;
color: var(--dsb-ink-3);
}
.dsb-box-remove {
position: absolute;
top: 0;
right: 0;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-box-remove:hover,
.dsb-box-remove:focus {
color: var(--dsb-accent-deep);
}
.dsb-form-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.dsb-input {
box-sizing: border-box;
min-width: 16em;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-input::placeholder {
color: var(--dsb-placeholder);
opacity: 1;
}
.dsb-input:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
/* ── Plain tag field (Etîket, Kategorî) ────────────────────────────────
Plain type-and-commit tags with no suggestion panel; unlike Hevmane/Dijmane/etc., these carry no modifiers. */
.dsb-tagfield {
box-sizing: border-box;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
min-width: 16em;
padding: 4px 6px;
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-tagfield:focus-within {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
}
.dsb-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
padding: 3px 6px 3px 10px;
}
.dsb-tag-remove {
border: 0;
background: transparent;
color: var(--dsb-muted);
font-size: 13px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
}
.dsb-tag-remove:hover {
color: var(--dsb-danger);
}
.dsb-tagfield .dsb-input {
flex: 1 1 8em;
min-width: 8em;
border: 0;
padding: 3px 2px;
background: transparent;
box-shadow: none;
}
.dsb-tagfield .dsb-input:focus {
box-shadow: none;
}
/* ── Word list with modifier pills ───────────────────────────────────
Every word is its own always-visible row: a word box plus a "+" that attaches one of the 10 WORD_MODIFIERS
as a small pill shown above the box. A fresh empty row is appended once the current last one gets text. */
.dsb-wordlist {
margin: 0;
padding-left: 0;
list-style: none;
}
.dsb-word-li {
margin-bottom: 6px;
}
.dsb-word-li:last-child {
margin-bottom: 0;
}
.dsb-word-mods {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
}
.dsb-word-mod-chip {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 11.5px;
padding: 3px 4px 3px 10px;
cursor: pointer;
}
.dsb-word-mod-chip-remove {
border: 0;
background: transparent;
color: var(--dsb-accent-deep);
font-size: 12px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
opacity: 0.7;
}
.dsb-word-mod-chip-remove:hover {
color: var(--dsb-danger);
opacity: 1;
}
.dsb-word-box-row {
display: flex;
align-items: center;
gap: 6px;
}
.dsb-word-box-row .dsb-word-input {
flex: 1 1 auto;
min-width: 0;
}
.dsb-mod-btn,
.dsb-word-remove {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.dsb-mod-btn {
border: 1px solid var(--dsb-accent-edge);
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
}
.dsb-mod-btn:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-word-remove {
border: 1px solid var(--dsb-field-edge);
background: var(--dsb-field-bg);
color: var(--dsb-muted);
}
.dsb-word-remove:hover {
border-color: var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-mod-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
margin-top: 6px;
padding: 8px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-card);
box-shadow: none;
}
.dsb-mod-pill {
font-family: var(--dsb-sans);
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
white-space: nowrap;
padding: 5px 10px;
cursor: pointer;
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.dsb-mod-pill:hover {
border-color: var(--dsb-accent);
background: var(--dsb-accent);
color: #fff;
}
.dsb-mod-pill:disabled,
.dsb-mod-pill.dsb-mod-pill-used {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
cursor: not-allowed;
opacity: 0.7;
}
.dsb-mod-pill:disabled:hover,
.dsb-mod-pill.dsb-mod-pill-used:hover {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
}
.dsb-mod-val-wrap {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
margin-top: 6px;
}
.dsb-mod-val-input {
flex: 1 1 auto;
min-width: 0;
max-width: 16em;
}
.dsb-mod-confirm,
.dsb-mod-cancel {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
background: var(--dsb-accent-tint);
cursor: pointer;
}
.dsb-mod-confirm {
border: 1px solid var(--dsb-ok);
color: var(--dsb-ok);
}
.dsb-mod-cancel {
border: 1px solid var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-save,
.dsb-cancel,
.dsb-autolink {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
/* One filled pill per row — the same rule the form's footer follows. */
.dsb-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-cancel {
background: transparent;
border: 1px solid transparent;
color: var(--dsb-ink-3);
}
.dsb-cancel:hover {
border-color: var(--dsb-field-edge);
color: var(--dsb-ink);
}
/* An outline pill, distinct from both the filled .dsb-save and the plain-text .dsb-cancel -- a secondary
utility action, not the primary save nor a dismissal. */
.dsb-autolink {
background: transparent;
border: 1px solid var(--dsb-accent-edge);
color: var(--dsb-accent);
}
.dsb-autolink:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-autolink:disabled {
opacity: 0.55;
cursor: progress;
}
/* Status line. Color comes from .dsb-status-ok/.dsb-status-error (added by the .js on success/failure)
rather than an inline style, so these tokens (and dark mode) apply. */
.dsb-status {
font-family: var(--dsb-sans);
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-status-ok { color: var(--dsb-ok); }
.dsb-status-error { color: var(--dsb-danger); }
/* ── "+ Beşek lê zêde bike" ──────────────────────────────────────────
An accent-coloured action link, like the form's .wiktku-adv-toggle:
it opens something, so it is not muted grey. */
.dsb-add-subsection,
.dsb-convert-pos-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-family: var(--dsb-sans);
font-size: 14px;
font-weight: 500;
color: var(--dsb-accent);
text-decoration: none;
border-bottom: 0;
cursor: pointer;
}
.dsb-add-subsection:hover,
.dsb-add-subsection:focus,
.dsb-convert-pos-trigger:hover,
.dsb-convert-pos-trigger:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* ── Subsection panel ────────────────────────────────────────────────
A sunken card rather than a grey utility box; fields stack so the
picker and its input are not competing for one narrow row. */
.dsb-subsection-panel,
.dsb-convert-pos-panel {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
box-sizing: border-box;
max-width: 520px;
margin: 6px 0 14px;
padding: 14px 16px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card-sunken);
border: 1px solid var(--dsb-card-edge);
border-radius: var(--dsb-r-card);
}
.dsb-subsection-select,
.dsb-convert-pos-select {
box-sizing: border-box;
width: 100%;
max-width: 100%;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
}
.dsb-subsection-select:focus,
.dsb-convert-pos-select:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
.dsb-subsection-field {
min-width: 0;
}
.dsb-subsection-words,
.dsb-subsection-text {
box-sizing: border-box;
width: 100%;
min-width: 0;
}
.dsb-subsection-text {
line-height: 1.6;
resize: vertical;
}
/* ── Gloss field inside the advanced-editing panel ────────────────────
Same shape as .dsb-subsection-text. */
.dsb-edit-gloss {
width: 100%;
line-height: 1.6;
resize: vertical;
}
/* ── Live "not saved yet" previews ─────────────────────────────────────
Dropped into the rendered page at the change's own spot. Dashed edge + a small badge mark them as
pending, not real content; they disappear on "Betal bike" or once the real save lands. */
.dsb-preview-block,
.dsb-preview-inline {
margin: 8px 0;
padding: 8px 12px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-accent-tint);
border: 1px dashed var(--dsb-accent-edge);
border-radius: var(--dsb-r-field);
}
.dsb-preview-inline {
margin-left: 26px;
max-width: 520px;
}
.dsb-preview-heading {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-preview-badge {
display: inline-block;
margin-bottom: 6px;
padding: 1px 8px;
font-size: 11px;
font-weight: 500;
color: var(--dsb-accent-deep);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
}
.dsb-preview-badge-inline {
margin-left: 8px;
margin-bottom: 0;
vertical-align: middle;
}
.dsb-preview-list,
.dsb-preview-text {
margin: 0;
padding-left: 18px;
}
.dsb-preview-text {
padding-left: 0;
}
/* ── Floating save-queue widget ─────────────────────────────────────
This gadget's own small floating box. One "Lê zêde bike" click anywhere on the page adds a line here;
"Guhertinan qeyd bike" makes the one real save; "Betal bike" drops everything queued without touching the page. */
.dsb-queue-box {
position: fixed;
top: 60px;
right: 16px;
z-index: 1000;
box-sizing: border-box;
width: 280px;
max-width: calc(100vw - 32px);
max-height: calc(100vh - 90px);
overflow-y: auto;
padding: 12px 14px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent);
border-radius: var(--dsb-r-card);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.16);
}
.dsb-queue-title {
margin-right: 20px;
font-size: 13px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-queue-close {
float: right;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-queue-close:hover,
.dsb-queue-close:focus {
color: var(--dsb-accent-deep);
}
.dsb-queue-list {
margin: 8px 0;
padding-left: 18px;
max-height: 160px;
overflow-y: auto;
}
.dsb-queue-list li {
margin-bottom: 4px;
}
.dsb-queue-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 4px;
}
.dsb-queue-save,
.dsb-queue-cancel {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.dsb-queue-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-queue-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-queue-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-queue-cancel {
background: transparent;
border: 1px solid var(--dsb-field-edge);
color: var(--dsb-ink-3);
}
.dsb-queue-cancel:hover {
border-color: var(--dsb-ink-3);
color: var(--dsb-ink);
}
.dsb-queue-status {
margin-top: 6px;
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-queue-status.dsb-status-ok { color: var(--dsb-ok); }
.dsb-queue-status.dsb-status-error { color: var(--dsb-danger); }
/* ── Minerva (mobile) ────────────────────────────────────────────────
Narrower viewport: keep the panel on screen and give every tap
target the form's 44px minimum. */
.skin-minerva .dsb-quick-row,
.skin-minerva .dsb-subsection-panel,
.skin-minerva .dsb-convert-pos-panel {
max-width: 100%;
}
@media (max-width: 720px), (pointer: coarse) {
.dsb-toolbar {
margin-left: -28px;
width: 28px;
}
.dsb-toggle {
width: 20px;
height: 20px;
margin-top: 0;
margin-left: 6px;
}
.dsb-quick-row {
font-size: 13px;
margin-left: 20px;
}
.dsb-input,
.dsb-subsection-select,
.dsb-convert-pos-select {
min-height: 40px;
/* >=16px stops iOS Safari zooming the page on focus. */
font-size: 16px;
}
.dsb-mod-btn,
.dsb-word-remove,
.dsb-mod-confirm,
.dsb-mod-cancel {
width: 36px;
height: 36px;
font-size: 15px;
}
.dsb-mod-pill {
padding: 8px 12px;
}
.dsb-mod-val-input {
max-width: none;
}
.dsb-tagfield .dsb-input {
min-height: 32px;
}
.dsb-tag-remove {
padding: 0 6px;
}
.dsb-save,
.dsb-cancel,
.dsb-autolink,
.dsb-queue-save,
.dsb-queue-cancel {
min-height: 40px;
padding: 8px 16px;
}
.dsb-queue-box {
top: auto;
bottom: 8px;
right: 8px;
left: 8px;
width: auto;
}
}
/* ── Dark mode ───────────────────────────────────────────────────────
Same warm dark palette and same explicit-signal-only rule as the
form's stylesheet: no bare prefers-color-scheme fallback, since
legacy Vector sets no theme class and would go dark on its own. */
html.skin-theme-clientpref-night,
html.skin-nightmode {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-night .dsb-save,
html.skin-nightmode .dsb-save,
html.skin-theme-clientpref-night .dsb-queue-save,
html.skin-nightmode .dsb-queue-save {
color: #14213a;
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-os .dsb-save,
html.skin-theme-clientpref-os .dsb-queue-save {
color: #14213a;
}
}
edf16j79hxdexfrug334s2g4ycd5k07
6347447
6347446
2026-08-31T19:34:27Z
Wikihez
7344
6347447
css
text/css
/* Gadget-DefSideBoxes.css
Skin-agnostic (vector, vector2022, minerva). Visual layer matches MediaWiki:Gadget-wiktku-start/styles.css
("SÊWIRANA NÛ"); those tokens are re-declared here under a --dsb-* prefix since they live on
#wiktku-start-form, which doesn't exist on an article page. */
:root {
--dsb-card: #fffdf8;
--dsb-card-sunken: #fbf8f1;
--dsb-rule: #ded6c8;
--dsb-rule-soft: #efe8db;
--dsb-card-edge: #e6dfd2;
--dsb-field-edge: #cfc7b8;
--dsb-field-bg: #fff;
--dsb-ink: #1c1a17;
--dsb-ink-2: #3d3830;
--dsb-ink-3: #57514a;
--dsb-muted: #8a8378;
--dsb-placeholder: #b3ab9e;
--dsb-accent: #2a5db0;
--dsb-accent-deep: #22406f;
--dsb-accent-tint: #eef2fa;
--dsb-accent-edge: #d5def0;
--dsb-ok: #3d8a55;
--dsb-danger: #9c3a28;
--dsb-r-field: 10px;
--dsb-r-card: 12px;
--dsb-r-pill: 999px;
--dsb-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--dsb-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── The pencil toggle on a definition ─────────────────────────────────
The classic MediaWiki interlanguage-links edit pencil (same asset as defEditButton), not a hand-drawn glyph.
Hidden by default like defEditButton: revealed by hovering the line on desktop, or by tapping it on touch
(.dsb-revealed, added by attachToolbar()'s own click handler) -- keeps the definition list uncluttered. */
/* .dsb-has-toolbar gives the <li> an explicit containing block so .dsb-toolbar's "top" is predictable -- relying on the no-top static-position fallback (en.wiktionary's defEditButton trick) placed it above the line here instead. */
.dsb-has-toolbar {
position: relative;
}
.dsb-toolbar {
position: absolute;
top: 2px;
margin-left: -22px;
width: 22px;
height: 20px;
font-family: var(--dsb-sans);
}
.dsb-toggle {
display: block;
margin-top: 3px;
margin-left: 7px;
width: 13px;
height: 13px;
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d3/InterlanguageLinks-Asset-Pencil.gif);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
text-decoration: none;
cursor: pointer;
opacity: 0;
transition: opacity 0.15s ease;
}
.dsb-toggle:hover,
.dsb-toggle:focus {
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d1/InterlanguageLinks-Asset-Pencil-Hover.gif);
}
li:hover .dsb-toolbar .dsb-toggle,
.dsb-toggle:focus {
opacity: 1;
}
@media (hover: none), (pointer: coarse) {
.dsb-toolbar.dsb-revealed .dsb-toggle {
opacity: 1;
}
}
/* ── "Guhartina pêşketî" (advanced editing) panel ──────────────────────
Revealed by the pencil toggle above: every per-sense action this gadget offers, queued together with one
"Lê zêde bike". A plain inline row, not a bordered/background card. */
.dsb-quick-row {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
box-sizing: border-box;
max-width: 520px;
margin: 4px 0 4px 26px;
font-family: var(--dsb-sans);
font-size: 12px;
color: var(--dsb-ink-2);
}
.dsb-quick-link {
align-self: flex-start;
margin-bottom: 10px;
color: var(--dsb-accent);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
}
.dsb-quick-link:hover,
.dsb-quick-link:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* The picker row: gloss + the two primary word groups as direct "+ <field>" links, plus a "Zêdetir" toggle
for the rest -- clicking a link opens its box below and hides the link; .dsb-box-remove un-hides it.
position: relative anchors .dsb-more-menu's overlay below (see there). */
.dsb-field-picker {
position: relative;
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-bottom: 10px;
}
.dsb-field-picker .dsb-quick-link {
margin-bottom: 0;
}
/* The "Zêdetir" dropdown: every non-primary field link (plus Nimûne/jêgirtin, which sits first) stacked as a
plain vertical list. Floats over the page as an overlay (positioned against .dsb-field-picker) instead of
pushing $openBoxes/the rest of the definition down when it opens. */
.dsb-more-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 10;
display: flex;
flex-direction: column;
align-items: flex-start;
width: max-content;
max-width: min(320px, calc(100vw - 40px));
gap: 6px;
margin: 2px 0 0 4px;
padding: 8px 12px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-field);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dsb-more-menu .dsb-quick-link {
margin-bottom: 0;
}
/* Boxes the user has actually opened, stacked in the order they were added -- several can be open at once. */
.dsb-open-boxes {
display: flex;
flex-direction: column;
}
/* One field (its label + input) within the panel -- always a currently-open, removable box. */
.dsb-adv-group {
position: relative;
margin-bottom: 14px;
padding-right: 20px;
}
.dsb-adv-label {
margin-bottom: 4px;
font-size: 12px;
font-weight: 600;
color: var(--dsb-ink-3);
}
.dsb-box-remove {
position: absolute;
top: 0;
right: 0;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-box-remove:hover,
.dsb-box-remove:focus {
color: var(--dsb-accent-deep);
}
.dsb-form-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.dsb-input {
box-sizing: border-box;
min-width: 16em;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-input::placeholder {
color: var(--dsb-placeholder);
opacity: 1;
}
.dsb-input:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
/* ── Plain tag field (Etîket, Kategorî) ────────────────────────────────
Plain type-and-commit tags with no suggestion panel; unlike Hevmane/Dijmane/etc., these carry no modifiers. */
.dsb-tagfield {
box-sizing: border-box;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
min-width: 16em;
padding: 4px 6px;
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-tagfield:focus-within {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
}
.dsb-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
padding: 3px 6px 3px 10px;
}
.dsb-tag-remove {
border: 0;
background: transparent;
color: var(--dsb-muted);
font-size: 13px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
}
.dsb-tag-remove:hover {
color: var(--dsb-danger);
}
.dsb-tagfield .dsb-input {
flex: 1 1 8em;
min-width: 8em;
border: 0;
padding: 3px 2px;
background: transparent;
box-shadow: none;
}
.dsb-tagfield .dsb-input:focus {
box-shadow: none;
}
/* ── Word list with modifier pills ───────────────────────────────────
Every word is its own always-visible row: a word box plus a "+" that attaches one of the 10 WORD_MODIFIERS
as a small pill shown above the box. A fresh empty row is appended once the current last one gets text. */
.dsb-wordlist {
margin: 0;
padding-left: 0;
list-style: none;
}
.dsb-word-li {
margin-bottom: 6px;
}
.dsb-word-li:last-child {
margin-bottom: 0;
}
.dsb-word-mods {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
}
.dsb-word-mod-chip {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 11.5px;
padding: 3px 4px 3px 10px;
cursor: pointer;
}
.dsb-word-mod-chip-remove {
border: 0;
background: transparent;
color: var(--dsb-accent-deep);
font-size: 12px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
opacity: 0.7;
}
.dsb-word-mod-chip-remove:hover {
color: var(--dsb-danger);
opacity: 1;
}
.dsb-word-box-row {
display: flex;
align-items: center;
gap: 6px;
}
.dsb-word-box-row .dsb-word-input {
flex: 1 1 auto;
min-width: 0;
}
.dsb-mod-btn,
.dsb-word-remove {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.dsb-mod-btn {
border: 1px solid var(--dsb-accent-edge);
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
}
.dsb-mod-btn:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-word-remove {
border: 1px solid var(--dsb-field-edge);
background: var(--dsb-field-bg);
color: var(--dsb-muted);
}
.dsb-word-remove:hover {
border-color: var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-mod-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
margin-top: 6px;
padding: 8px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-card);
box-shadow: none;
}
.dsb-mod-pill {
font-family: var(--dsb-sans);
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
white-space: nowrap;
padding: 5px 10px;
cursor: pointer;
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.dsb-mod-pill:hover {
border-color: var(--dsb-accent);
background: var(--dsb-accent);
color: #fff;
}
.dsb-mod-pill:disabled,
.dsb-mod-pill.dsb-mod-pill-used {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
cursor: not-allowed;
opacity: 0.7;
}
.dsb-mod-pill:disabled:hover,
.dsb-mod-pill.dsb-mod-pill-used:hover {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
}
.dsb-mod-val-wrap {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
margin-top: 6px;
}
.dsb-mod-val-input {
flex: 1 1 auto;
min-width: 0;
max-width: 16em;
}
.dsb-mod-confirm,
.dsb-mod-cancel {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
background: var(--dsb-accent-tint);
cursor: pointer;
}
.dsb-mod-confirm {
border: 1px solid var(--dsb-ok);
color: var(--dsb-ok);
}
.dsb-mod-cancel {
border: 1px solid var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-save,
.dsb-cancel,
.dsb-autolink {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
/* One filled pill per row — the same rule the form's footer follows. */
.dsb-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-cancel {
background: transparent;
border: 1px solid transparent;
color: var(--dsb-ink-3);
}
.dsb-cancel:hover {
border-color: var(--dsb-field-edge);
color: var(--dsb-ink);
}
/* An outline pill, distinct from both the filled .dsb-save and the plain-text .dsb-cancel -- a secondary
utility action, not the primary save nor a dismissal. */
.dsb-autolink {
background: transparent;
border: 1px solid var(--dsb-accent-edge);
color: var(--dsb-accent);
}
.dsb-autolink:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-autolink:disabled {
opacity: 0.55;
cursor: progress;
}
/* Status line. Color comes from .dsb-status-ok/.dsb-status-error (added by the .js on success/failure)
rather than an inline style, so these tokens (and dark mode) apply. */
.dsb-status {
font-family: var(--dsb-sans);
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-status-ok { color: var(--dsb-ok); }
.dsb-status-error { color: var(--dsb-danger); }
/* ── "+ Beşek lê zêde bike" ──────────────────────────────────────────
An accent-coloured action link, like the form's .wiktku-adv-toggle:
it opens something, so it is not muted grey. */
.dsb-add-subsection,
.dsb-convert-pos-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-family: var(--dsb-sans);
font-size: 14px;
font-weight: 500;
color: var(--dsb-accent);
text-decoration: none;
border-bottom: 0;
cursor: pointer;
}
.dsb-add-subsection:hover,
.dsb-add-subsection:focus,
.dsb-convert-pos-trigger:hover,
.dsb-convert-pos-trigger:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* ── Subsection panel ────────────────────────────────────────────────
A sunken card rather than a grey utility box; fields stack so the
picker and its input are not competing for one narrow row. */
.dsb-subsection-panel,
.dsb-convert-pos-panel {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
box-sizing: border-box;
max-width: 520px;
margin: 6px 0 14px;
padding: 14px 16px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card-sunken);
border: 1px solid var(--dsb-card-edge);
border-radius: var(--dsb-r-card);
}
.dsb-subsection-select,
.dsb-convert-pos-select {
box-sizing: border-box;
width: 100%;
max-width: 100%;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
}
.dsb-subsection-select:focus,
.dsb-convert-pos-select:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
.dsb-subsection-field {
min-width: 0;
}
.dsb-subsection-words,
.dsb-subsection-text {
box-sizing: border-box;
width: 100%;
min-width: 0;
}
.dsb-subsection-text {
line-height: 1.6;
resize: vertical;
}
/* ── Gloss field inside the advanced-editing panel ────────────────────
Same shape as .dsb-subsection-text. */
.dsb-edit-gloss {
width: 100%;
line-height: 1.6;
resize: vertical;
}
/* ── Live "not saved yet" previews ─────────────────────────────────────
Dropped into the rendered page at the change's own spot. Dashed edge + a small badge mark them as
pending, not real content; they disappear on "Betal bike" or once the real save lands. */
.dsb-preview-block,
.dsb-preview-inline {
margin: 8px 0;
padding: 8px 12px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-accent-tint);
border: 1px dashed var(--dsb-accent-edge);
border-radius: var(--dsb-r-field);
}
.dsb-preview-inline {
margin-left: 26px;
max-width: 520px;
}
.dsb-preview-heading {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-preview-badge {
display: inline-block;
margin-bottom: 6px;
padding: 1px 8px;
font-size: 11px;
font-weight: 500;
color: var(--dsb-accent-deep);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
}
.dsb-preview-badge-inline {
margin-left: 8px;
margin-bottom: 0;
vertical-align: middle;
}
.dsb-preview-list,
.dsb-preview-text {
margin: 0;
padding-left: 18px;
}
.dsb-preview-text {
padding-left: 0;
}
/* ── Floating save-queue widget ─────────────────────────────────────
This gadget's own small floating box. One "Lê zêde bike" click anywhere on the page adds a line here;
"Guhertinan qeyd bike" makes the one real save; "Betal bike" drops everything queued without touching the page. */
.dsb-queue-box {
position: fixed;
top: 60px;
right: 16px;
z-index: 1000;
box-sizing: border-box;
width: 280px;
max-width: calc(100vw - 32px);
max-height: calc(100vh - 90px);
overflow-y: auto;
padding: 12px 14px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent);
border-radius: var(--dsb-r-card);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.16);
}
.dsb-queue-title {
margin-right: 20px;
font-size: 13px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-queue-close {
float: right;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-queue-close:hover,
.dsb-queue-close:focus {
color: var(--dsb-accent-deep);
}
.dsb-queue-list {
margin: 8px 0;
padding-left: 18px;
max-height: 160px;
overflow-y: auto;
}
.dsb-queue-list li {
margin-bottom: 4px;
}
.dsb-queue-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 4px;
}
.dsb-queue-save,
.dsb-queue-cancel {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.dsb-queue-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-queue-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-queue-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-queue-cancel {
background: transparent;
border: 1px solid var(--dsb-field-edge);
color: var(--dsb-ink-3);
}
.dsb-queue-cancel:hover {
border-color: var(--dsb-ink-3);
color: var(--dsb-ink);
}
.dsb-queue-status {
margin-top: 6px;
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-queue-status.dsb-status-ok { color: var(--dsb-ok); }
.dsb-queue-status.dsb-status-error { color: var(--dsb-danger); }
/* ── Minerva (mobile) ────────────────────────────────────────────────
Narrower viewport: keep the panel on screen and give every tap
target the form's 44px minimum. */
.skin-minerva .dsb-quick-row,
.skin-minerva .dsb-subsection-panel,
.skin-minerva .dsb-convert-pos-panel {
max-width: 100%;
}
@media (max-width: 720px), (pointer: coarse) {
.dsb-toolbar {
margin-left: -28px;
width: 28px;
}
.dsb-toggle {
width: 20px;
height: 20px;
margin-top: 0;
margin-left: 6px;
}
.dsb-quick-row {
font-size: 13px;
margin-left: 20px;
}
.dsb-input,
.dsb-subsection-select,
.dsb-convert-pos-select {
min-height: 40px;
/* >=16px stops iOS Safari zooming the page on focus. */
font-size: 16px;
}
.dsb-mod-btn,
.dsb-word-remove,
.dsb-mod-confirm,
.dsb-mod-cancel {
width: 36px;
height: 36px;
font-size: 15px;
}
.dsb-mod-pill {
padding: 8px 12px;
}
.dsb-mod-val-input {
max-width: none;
}
.dsb-tagfield .dsb-input {
min-height: 32px;
}
.dsb-tag-remove {
padding: 0 6px;
}
.dsb-save,
.dsb-cancel,
.dsb-autolink,
.dsb-queue-save,
.dsb-queue-cancel {
min-height: 40px;
padding: 8px 16px;
}
.dsb-queue-box {
top: auto;
bottom: 8px;
right: 8px;
left: 8px;
width: auto;
}
}
/* ── Dark mode ───────────────────────────────────────────────────────
Same warm dark palette and same explicit-signal-only rule as the
form's stylesheet: no bare prefers-color-scheme fallback, since
legacy Vector sets no theme class and would go dark on its own. */
html.skin-theme-clientpref-night,
html.skin-nightmode {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-night .dsb-save,
html.skin-nightmode .dsb-save,
html.skin-theme-clientpref-night .dsb-queue-save,
html.skin-nightmode .dsb-queue-save {
color: #14213a;
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-os .dsb-save,
html.skin-theme-clientpref-os .dsb-queue-save {
color: #14213a;
}
}
lr7d64f2wsot4mdua910d1l0i84lfu6
6347451
6347447
2026-08-31T19:40:32Z
Wikihez
7344
6347451
css
text/css
/* Gadget-DefSideBoxes.css
Skin-agnostic (vector, vector2022, minerva). Visual layer matches MediaWiki:Gadget-wiktku-start/styles.css
("SÊWIRANA NÛ"); those tokens are re-declared here under a --dsb-* prefix since they live on
#wiktku-start-form, which doesn't exist on an article page. */
:root {
--dsb-card: #fffdf8;
--dsb-card-sunken: #fbf8f1;
--dsb-rule: #ded6c8;
--dsb-rule-soft: #efe8db;
--dsb-card-edge: #e6dfd2;
--dsb-field-edge: #cfc7b8;
--dsb-field-bg: #fff;
--dsb-ink: #1c1a17;
--dsb-ink-2: #3d3830;
--dsb-ink-3: #57514a;
--dsb-muted: #8a8378;
--dsb-placeholder: #b3ab9e;
--dsb-accent: #2a5db0;
--dsb-accent-deep: #22406f;
--dsb-accent-tint: #eef2fa;
--dsb-accent-edge: #d5def0;
--dsb-ok: #3d8a55;
--dsb-danger: #9c3a28;
--dsb-r-field: 10px;
--dsb-r-card: 12px;
--dsb-r-pill: 999px;
--dsb-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--dsb-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── The pencil toggle on a definition ─────────────────────────────────
The classic MediaWiki interlanguage-links edit pencil (same asset as defEditButton), not a hand-drawn glyph.
Hidden by default like defEditButton: revealed by hovering the line on desktop, or by tapping it on touch
(.dsb-revealed, added by attachToolbar()'s own click handler) -- keeps the definition list uncluttered. */
/* Zero-width + overflow:visible keeps .dsb-toolbar in normal inline flow (so it vertical-aligns with the text baseline automatically, unlike position:absolute's fragile top-guessing) while the negative margin on .dsb-toggle lets the icon spill left into the gutter without the zero-width box itself taking any line space. */
.dsb-toolbar {
display: inline-block;
width: 0;
height: 0;
overflow: visible;
vertical-align: middle;
font-family: var(--dsb-sans);
}
.dsb-toggle {
display: inline-block;
margin-left: -22px;
width: 13px;
height: 13px;
vertical-align: middle;
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d3/InterlanguageLinks-Asset-Pencil.gif);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
text-decoration: none;
cursor: pointer;
opacity: 0;
transition: opacity 0.15s ease;
}
.dsb-toggle:hover,
.dsb-toggle:focus {
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d1/InterlanguageLinks-Asset-Pencil-Hover.gif);
}
li:hover .dsb-toolbar .dsb-toggle,
.dsb-toggle:focus {
opacity: 1;
}
@media (hover: none), (pointer: coarse) {
.dsb-toolbar.dsb-revealed .dsb-toggle {
opacity: 1;
}
}
/* ── "Guhartina pêşketî" (advanced editing) panel ──────────────────────
Revealed by the pencil toggle above: every per-sense action this gadget offers, queued together with one
"Lê zêde bike". A plain inline row, not a bordered/background card. */
.dsb-quick-row {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
box-sizing: border-box;
max-width: 520px;
margin: 4px 0 4px 26px;
font-family: var(--dsb-sans);
font-size: 12px;
color: var(--dsb-ink-2);
}
.dsb-quick-link {
align-self: flex-start;
margin-bottom: 10px;
color: var(--dsb-accent);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
}
.dsb-quick-link:hover,
.dsb-quick-link:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* The picker row: gloss + the two primary word groups as direct "+ <field>" links, plus a "Zêdetir" toggle
for the rest -- clicking a link opens its box below and hides the link; .dsb-box-remove un-hides it.
position: relative anchors .dsb-more-menu's overlay below (see there). */
.dsb-field-picker {
position: relative;
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-bottom: 10px;
}
.dsb-field-picker .dsb-quick-link {
margin-bottom: 0;
}
/* The "Zêdetir" dropdown: every non-primary field link (plus Nimûne/jêgirtin, which sits first) stacked as a
plain vertical list. Floats over the page as an overlay (positioned against .dsb-field-picker) instead of
pushing $openBoxes/the rest of the definition down when it opens. */
.dsb-more-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 10;
display: flex;
flex-direction: column;
align-items: flex-start;
width: max-content;
max-width: min(320px, calc(100vw - 40px));
gap: 6px;
margin: 2px 0 0 4px;
padding: 8px 12px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-field);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dsb-more-menu .dsb-quick-link {
margin-bottom: 0;
}
/* Boxes the user has actually opened, stacked in the order they were added -- several can be open at once. */
.dsb-open-boxes {
display: flex;
flex-direction: column;
}
/* One field (its label + input) within the panel -- always a currently-open, removable box. */
.dsb-adv-group {
position: relative;
margin-bottom: 14px;
padding-right: 20px;
}
.dsb-adv-label {
margin-bottom: 4px;
font-size: 12px;
font-weight: 600;
color: var(--dsb-ink-3);
}
.dsb-box-remove {
position: absolute;
top: 0;
right: 0;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-box-remove:hover,
.dsb-box-remove:focus {
color: var(--dsb-accent-deep);
}
.dsb-form-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.dsb-input {
box-sizing: border-box;
min-width: 16em;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-input::placeholder {
color: var(--dsb-placeholder);
opacity: 1;
}
.dsb-input:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
/* ── Plain tag field (Etîket, Kategorî) ────────────────────────────────
Plain type-and-commit tags with no suggestion panel; unlike Hevmane/Dijmane/etc., these carry no modifiers. */
.dsb-tagfield {
box-sizing: border-box;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
min-width: 16em;
padding: 4px 6px;
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-tagfield:focus-within {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
}
.dsb-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
padding: 3px 6px 3px 10px;
}
.dsb-tag-remove {
border: 0;
background: transparent;
color: var(--dsb-muted);
font-size: 13px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
}
.dsb-tag-remove:hover {
color: var(--dsb-danger);
}
.dsb-tagfield .dsb-input {
flex: 1 1 8em;
min-width: 8em;
border: 0;
padding: 3px 2px;
background: transparent;
box-shadow: none;
}
.dsb-tagfield .dsb-input:focus {
box-shadow: none;
}
/* ── Word list with modifier pills ───────────────────────────────────
Every word is its own always-visible row: a word box plus a "+" that attaches one of the 10 WORD_MODIFIERS
as a small pill shown above the box. A fresh empty row is appended once the current last one gets text. */
.dsb-wordlist {
margin: 0;
padding-left: 0;
list-style: none;
}
.dsb-word-li {
margin-bottom: 6px;
}
.dsb-word-li:last-child {
margin-bottom: 0;
}
.dsb-word-mods {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
}
.dsb-word-mod-chip {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 11.5px;
padding: 3px 4px 3px 10px;
cursor: pointer;
}
.dsb-word-mod-chip-remove {
border: 0;
background: transparent;
color: var(--dsb-accent-deep);
font-size: 12px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
opacity: 0.7;
}
.dsb-word-mod-chip-remove:hover {
color: var(--dsb-danger);
opacity: 1;
}
.dsb-word-box-row {
display: flex;
align-items: center;
gap: 6px;
}
.dsb-word-box-row .dsb-word-input {
flex: 1 1 auto;
min-width: 0;
}
.dsb-mod-btn,
.dsb-word-remove {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.dsb-mod-btn {
border: 1px solid var(--dsb-accent-edge);
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
}
.dsb-mod-btn:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-word-remove {
border: 1px solid var(--dsb-field-edge);
background: var(--dsb-field-bg);
color: var(--dsb-muted);
}
.dsb-word-remove:hover {
border-color: var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-mod-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
margin-top: 6px;
padding: 8px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-card);
box-shadow: none;
}
.dsb-mod-pill {
font-family: var(--dsb-sans);
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
white-space: nowrap;
padding: 5px 10px;
cursor: pointer;
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.dsb-mod-pill:hover {
border-color: var(--dsb-accent);
background: var(--dsb-accent);
color: #fff;
}
.dsb-mod-pill:disabled,
.dsb-mod-pill.dsb-mod-pill-used {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
cursor: not-allowed;
opacity: 0.7;
}
.dsb-mod-pill:disabled:hover,
.dsb-mod-pill.dsb-mod-pill-used:hover {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
}
.dsb-mod-val-wrap {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
margin-top: 6px;
}
.dsb-mod-val-input {
flex: 1 1 auto;
min-width: 0;
max-width: 16em;
}
.dsb-mod-confirm,
.dsb-mod-cancel {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
background: var(--dsb-accent-tint);
cursor: pointer;
}
.dsb-mod-confirm {
border: 1px solid var(--dsb-ok);
color: var(--dsb-ok);
}
.dsb-mod-cancel {
border: 1px solid var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-save,
.dsb-cancel,
.dsb-autolink {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
/* One filled pill per row — the same rule the form's footer follows. */
.dsb-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-cancel {
background: transparent;
border: 1px solid transparent;
color: var(--dsb-ink-3);
}
.dsb-cancel:hover {
border-color: var(--dsb-field-edge);
color: var(--dsb-ink);
}
/* An outline pill, distinct from both the filled .dsb-save and the plain-text .dsb-cancel -- a secondary
utility action, not the primary save nor a dismissal. */
.dsb-autolink {
background: transparent;
border: 1px solid var(--dsb-accent-edge);
color: var(--dsb-accent);
}
.dsb-autolink:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-autolink:disabled {
opacity: 0.55;
cursor: progress;
}
/* Status line. Color comes from .dsb-status-ok/.dsb-status-error (added by the .js on success/failure)
rather than an inline style, so these tokens (and dark mode) apply. */
.dsb-status {
font-family: var(--dsb-sans);
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-status-ok { color: var(--dsb-ok); }
.dsb-status-error { color: var(--dsb-danger); }
/* ── "+ Beşek lê zêde bike" ──────────────────────────────────────────
An accent-coloured action link, like the form's .wiktku-adv-toggle:
it opens something, so it is not muted grey. */
.dsb-add-subsection,
.dsb-convert-pos-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-family: var(--dsb-sans);
font-size: 14px;
font-weight: 500;
color: var(--dsb-accent);
text-decoration: none;
border-bottom: 0;
cursor: pointer;
}
.dsb-add-subsection:hover,
.dsb-add-subsection:focus,
.dsb-convert-pos-trigger:hover,
.dsb-convert-pos-trigger:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* ── Subsection panel ────────────────────────────────────────────────
A sunken card rather than a grey utility box; fields stack so the
picker and its input are not competing for one narrow row. */
.dsb-subsection-panel,
.dsb-convert-pos-panel {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
box-sizing: border-box;
max-width: 520px;
margin: 6px 0 14px;
padding: 14px 16px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card-sunken);
border: 1px solid var(--dsb-card-edge);
border-radius: var(--dsb-r-card);
}
.dsb-subsection-select,
.dsb-convert-pos-select {
box-sizing: border-box;
width: 100%;
max-width: 100%;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
}
.dsb-subsection-select:focus,
.dsb-convert-pos-select:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
.dsb-subsection-field {
min-width: 0;
}
.dsb-subsection-words,
.dsb-subsection-text {
box-sizing: border-box;
width: 100%;
min-width: 0;
}
.dsb-subsection-text {
line-height: 1.6;
resize: vertical;
}
/* ── Gloss field inside the advanced-editing panel ────────────────────
Same shape as .dsb-subsection-text. */
.dsb-edit-gloss {
width: 100%;
line-height: 1.6;
resize: vertical;
}
/* ── Live "not saved yet" previews ─────────────────────────────────────
Dropped into the rendered page at the change's own spot. Dashed edge + a small badge mark them as
pending, not real content; they disappear on "Betal bike" or once the real save lands. */
.dsb-preview-block,
.dsb-preview-inline {
margin: 8px 0;
padding: 8px 12px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-accent-tint);
border: 1px dashed var(--dsb-accent-edge);
border-radius: var(--dsb-r-field);
}
.dsb-preview-inline {
margin-left: 26px;
max-width: 520px;
}
.dsb-preview-heading {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-preview-badge {
display: inline-block;
margin-bottom: 6px;
padding: 1px 8px;
font-size: 11px;
font-weight: 500;
color: var(--dsb-accent-deep);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
}
.dsb-preview-badge-inline {
margin-left: 8px;
margin-bottom: 0;
vertical-align: middle;
}
.dsb-preview-list,
.dsb-preview-text {
margin: 0;
padding-left: 18px;
}
.dsb-preview-text {
padding-left: 0;
}
/* ── Floating save-queue widget ─────────────────────────────────────
This gadget's own small floating box. One "Lê zêde bike" click anywhere on the page adds a line here;
"Guhertinan qeyd bike" makes the one real save; "Betal bike" drops everything queued without touching the page. */
.dsb-queue-box {
position: fixed;
top: 60px;
right: 16px;
z-index: 1000;
box-sizing: border-box;
width: 280px;
max-width: calc(100vw - 32px);
max-height: calc(100vh - 90px);
overflow-y: auto;
padding: 12px 14px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent);
border-radius: var(--dsb-r-card);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.16);
}
.dsb-queue-title {
margin-right: 20px;
font-size: 13px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-queue-close {
float: right;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-queue-close:hover,
.dsb-queue-close:focus {
color: var(--dsb-accent-deep);
}
.dsb-queue-list {
margin: 8px 0;
padding-left: 18px;
max-height: 160px;
overflow-y: auto;
}
.dsb-queue-list li {
margin-bottom: 4px;
}
.dsb-queue-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 4px;
}
.dsb-queue-save,
.dsb-queue-cancel {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.dsb-queue-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-queue-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-queue-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-queue-cancel {
background: transparent;
border: 1px solid var(--dsb-field-edge);
color: var(--dsb-ink-3);
}
.dsb-queue-cancel:hover {
border-color: var(--dsb-ink-3);
color: var(--dsb-ink);
}
.dsb-queue-status {
margin-top: 6px;
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-queue-status.dsb-status-ok { color: var(--dsb-ok); }
.dsb-queue-status.dsb-status-error { color: var(--dsb-danger); }
/* ── Minerva (mobile) ────────────────────────────────────────────────
Narrower viewport: keep the panel on screen and give every tap
target the form's 44px minimum. */
.skin-minerva .dsb-quick-row,
.skin-minerva .dsb-subsection-panel,
.skin-minerva .dsb-convert-pos-panel {
max-width: 100%;
}
@media (max-width: 720px), (pointer: coarse) {
.dsb-toggle {
width: 20px;
height: 20px;
margin-left: -28px;
}
.dsb-quick-row {
font-size: 13px;
margin-left: 20px;
}
.dsb-input,
.dsb-subsection-select,
.dsb-convert-pos-select {
min-height: 40px;
/* >=16px stops iOS Safari zooming the page on focus. */
font-size: 16px;
}
.dsb-mod-btn,
.dsb-word-remove,
.dsb-mod-confirm,
.dsb-mod-cancel {
width: 36px;
height: 36px;
font-size: 15px;
}
.dsb-mod-pill {
padding: 8px 12px;
}
.dsb-mod-val-input {
max-width: none;
}
.dsb-tagfield .dsb-input {
min-height: 32px;
}
.dsb-tag-remove {
padding: 0 6px;
}
.dsb-save,
.dsb-cancel,
.dsb-autolink,
.dsb-queue-save,
.dsb-queue-cancel {
min-height: 40px;
padding: 8px 16px;
}
.dsb-queue-box {
top: auto;
bottom: 8px;
right: 8px;
left: 8px;
width: auto;
}
}
/* ── Dark mode ───────────────────────────────────────────────────────
Same warm dark palette and same explicit-signal-only rule as the
form's stylesheet: no bare prefers-color-scheme fallback, since
legacy Vector sets no theme class and would go dark on its own. */
html.skin-theme-clientpref-night,
html.skin-nightmode {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-night .dsb-save,
html.skin-nightmode .dsb-save,
html.skin-theme-clientpref-night .dsb-queue-save,
html.skin-nightmode .dsb-queue-save {
color: #14213a;
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-os .dsb-save,
html.skin-theme-clientpref-os .dsb-queue-save {
color: #14213a;
}
}
6fwqhg4dt75d7bgqlk81jvryhn4magp
6347460
6347451
2026-08-31T19:48:56Z
Wikihez
7344
6347460
css
text/css
/* Gadget-DefSideBoxes.css
Skin-agnostic (vector, vector2022, minerva). Visual layer matches MediaWiki:Gadget-wiktku-start/styles.css
("SÊWIRANA NÛ"); those tokens are re-declared here under a --dsb-* prefix since they live on
#wiktku-start-form, which doesn't exist on an article page. */
:root {
--dsb-card: #fffdf8;
--dsb-card-sunken: #fbf8f1;
--dsb-rule: #ded6c8;
--dsb-rule-soft: #efe8db;
--dsb-card-edge: #e6dfd2;
--dsb-field-edge: #cfc7b8;
--dsb-field-bg: #fff;
--dsb-ink: #1c1a17;
--dsb-ink-2: #3d3830;
--dsb-ink-3: #57514a;
--dsb-muted: #8a8378;
--dsb-placeholder: #b3ab9e;
--dsb-accent: #2a5db0;
--dsb-accent-deep: #22406f;
--dsb-accent-tint: #eef2fa;
--dsb-accent-edge: #d5def0;
--dsb-ok: #3d8a55;
--dsb-danger: #9c3a28;
--dsb-r-field: 10px;
--dsb-r-card: 12px;
--dsb-r-pill: 999px;
--dsb-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--dsb-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── The pencil toggle on a definition ─────────────────────────────────
The classic MediaWiki interlanguage-links edit pencil (same asset as defEditButton), not a hand-drawn glyph.
Hidden by default like defEditButton: revealed by hovering the line on desktop, or by tapping it on touch
(.dsb-revealed, added by attachToolbar()'s own click handler) -- keeps the definition list uncluttered. */
/* float:left anchors .dsb-toolbar to the top of the line it starts on (a well-defined algorithm, unlike position:absolute's static-position guesswork); the negative margin equal to its own width then pulls it fully into the gutter, so its right edge lands flush with the text instead of eating into it. */
.dsb-toolbar {
float: left;
margin-left: -22px;
width: 22px;
height: 20px;
font-family: var(--dsb-sans);
}
.dsb-toggle {
display: block;
margin-top: 3px;
margin-left: 7px;
width: 13px;
height: 13px;
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d3/InterlanguageLinks-Asset-Pencil.gif);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
text-decoration: none;
cursor: pointer;
opacity: 0;
transition: opacity 0.15s ease;
}
.dsb-toggle:hover,
.dsb-toggle:focus {
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d1/InterlanguageLinks-Asset-Pencil-Hover.gif);
}
li:hover .dsb-toolbar .dsb-toggle,
.dsb-toggle:focus {
opacity: 1;
}
@media (hover: none), (pointer: coarse) {
.dsb-toolbar.dsb-revealed .dsb-toggle {
opacity: 1;
}
}
/* ── "Guhartina pêşketî" (advanced editing) panel ──────────────────────
Revealed by the pencil toggle above: every per-sense action this gadget offers, queued together with one
"Lê zêde bike". A plain inline row, not a bordered/background card. */
.dsb-quick-row {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
box-sizing: border-box;
max-width: 520px;
margin: 4px 0 4px 26px;
font-family: var(--dsb-sans);
font-size: 12px;
color: var(--dsb-ink-2);
}
.dsb-quick-link {
align-self: flex-start;
margin-bottom: 10px;
color: var(--dsb-accent);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
}
.dsb-quick-link:hover,
.dsb-quick-link:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* The picker row: gloss + the two primary word groups as direct "+ <field>" links, plus a "Zêdetir" toggle
for the rest -- clicking a link opens its box below and hides the link; .dsb-box-remove un-hides it.
position: relative anchors .dsb-more-menu's overlay below (see there). */
.dsb-field-picker {
position: relative;
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-bottom: 10px;
}
.dsb-field-picker .dsb-quick-link {
margin-bottom: 0;
}
/* The "Zêdetir" dropdown: every non-primary field link (plus Nimûne/jêgirtin, which sits first) stacked as a
plain vertical list. Floats over the page as an overlay (positioned against .dsb-field-picker) instead of
pushing $openBoxes/the rest of the definition down when it opens. */
.dsb-more-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 10;
display: flex;
flex-direction: column;
align-items: flex-start;
width: max-content;
max-width: min(320px, calc(100vw - 40px));
gap: 6px;
margin: 2px 0 0 4px;
padding: 8px 12px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-field);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dsb-more-menu .dsb-quick-link {
margin-bottom: 0;
}
/* Boxes the user has actually opened, stacked in the order they were added -- several can be open at once. */
.dsb-open-boxes {
display: flex;
flex-direction: column;
}
/* One field (its label + input) within the panel -- always a currently-open, removable box. */
.dsb-adv-group {
position: relative;
margin-bottom: 14px;
padding-right: 20px;
}
.dsb-adv-label {
margin-bottom: 4px;
font-size: 12px;
font-weight: 600;
color: var(--dsb-ink-3);
}
.dsb-box-remove {
position: absolute;
top: 0;
right: 0;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-box-remove:hover,
.dsb-box-remove:focus {
color: var(--dsb-accent-deep);
}
.dsb-form-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.dsb-input {
box-sizing: border-box;
min-width: 16em;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-input::placeholder {
color: var(--dsb-placeholder);
opacity: 1;
}
.dsb-input:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
/* ── Plain tag field (Etîket, Kategorî) ────────────────────────────────
Plain type-and-commit tags with no suggestion panel; unlike Hevmane/Dijmane/etc., these carry no modifiers. */
.dsb-tagfield {
box-sizing: border-box;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
min-width: 16em;
padding: 4px 6px;
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-tagfield:focus-within {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
}
.dsb-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
padding: 3px 6px 3px 10px;
}
.dsb-tag-remove {
border: 0;
background: transparent;
color: var(--dsb-muted);
font-size: 13px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
}
.dsb-tag-remove:hover {
color: var(--dsb-danger);
}
.dsb-tagfield .dsb-input {
flex: 1 1 8em;
min-width: 8em;
border: 0;
padding: 3px 2px;
background: transparent;
box-shadow: none;
}
.dsb-tagfield .dsb-input:focus {
box-shadow: none;
}
/* ── Word list with modifier pills ───────────────────────────────────
Every word is its own always-visible row: a word box plus a "+" that attaches one of the 10 WORD_MODIFIERS
as a small pill shown above the box. A fresh empty row is appended once the current last one gets text. */
.dsb-wordlist {
margin: 0;
padding-left: 0;
list-style: none;
}
.dsb-word-li {
margin-bottom: 6px;
}
.dsb-word-li:last-child {
margin-bottom: 0;
}
.dsb-word-mods {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
}
.dsb-word-mod-chip {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 11.5px;
padding: 3px 4px 3px 10px;
cursor: pointer;
}
.dsb-word-mod-chip-remove {
border: 0;
background: transparent;
color: var(--dsb-accent-deep);
font-size: 12px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
opacity: 0.7;
}
.dsb-word-mod-chip-remove:hover {
color: var(--dsb-danger);
opacity: 1;
}
.dsb-word-box-row {
display: flex;
align-items: center;
gap: 6px;
}
.dsb-word-box-row .dsb-word-input {
flex: 1 1 auto;
min-width: 0;
}
.dsb-mod-btn,
.dsb-word-remove {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.dsb-mod-btn {
border: 1px solid var(--dsb-accent-edge);
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
}
.dsb-mod-btn:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-word-remove {
border: 1px solid var(--dsb-field-edge);
background: var(--dsb-field-bg);
color: var(--dsb-muted);
}
.dsb-word-remove:hover {
border-color: var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-mod-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
margin-top: 6px;
padding: 8px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-card);
box-shadow: none;
}
.dsb-mod-pill {
font-family: var(--dsb-sans);
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
white-space: nowrap;
padding: 5px 10px;
cursor: pointer;
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.dsb-mod-pill:hover {
border-color: var(--dsb-accent);
background: var(--dsb-accent);
color: #fff;
}
.dsb-mod-pill:disabled,
.dsb-mod-pill.dsb-mod-pill-used {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
cursor: not-allowed;
opacity: 0.7;
}
.dsb-mod-pill:disabled:hover,
.dsb-mod-pill.dsb-mod-pill-used:hover {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
}
.dsb-mod-val-wrap {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
margin-top: 6px;
}
.dsb-mod-val-input {
flex: 1 1 auto;
min-width: 0;
max-width: 16em;
}
.dsb-mod-confirm,
.dsb-mod-cancel {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
background: var(--dsb-accent-tint);
cursor: pointer;
}
.dsb-mod-confirm {
border: 1px solid var(--dsb-ok);
color: var(--dsb-ok);
}
.dsb-mod-cancel {
border: 1px solid var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-save,
.dsb-cancel,
.dsb-autolink {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
/* One filled pill per row — the same rule the form's footer follows. */
.dsb-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-cancel {
background: transparent;
border: 1px solid transparent;
color: var(--dsb-ink-3);
}
.dsb-cancel:hover {
border-color: var(--dsb-field-edge);
color: var(--dsb-ink);
}
/* An outline pill, distinct from both the filled .dsb-save and the plain-text .dsb-cancel -- a secondary
utility action, not the primary save nor a dismissal. */
.dsb-autolink {
background: transparent;
border: 1px solid var(--dsb-accent-edge);
color: var(--dsb-accent);
}
.dsb-autolink:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-autolink:disabled {
opacity: 0.55;
cursor: progress;
}
/* Status line. Color comes from .dsb-status-ok/.dsb-status-error (added by the .js on success/failure)
rather than an inline style, so these tokens (and dark mode) apply. */
.dsb-status {
font-family: var(--dsb-sans);
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-status-ok { color: var(--dsb-ok); }
.dsb-status-error { color: var(--dsb-danger); }
/* ── "+ Beşek lê zêde bike" ──────────────────────────────────────────
An accent-coloured action link, like the form's .wiktku-adv-toggle:
it opens something, so it is not muted grey. */
.dsb-add-subsection,
.dsb-convert-pos-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-family: var(--dsb-sans);
font-size: 14px;
font-weight: 500;
color: var(--dsb-accent);
text-decoration: none;
border-bottom: 0;
cursor: pointer;
}
.dsb-add-subsection:hover,
.dsb-add-subsection:focus,
.dsb-convert-pos-trigger:hover,
.dsb-convert-pos-trigger:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* ── Subsection panel ────────────────────────────────────────────────
A sunken card rather than a grey utility box; fields stack so the
picker and its input are not competing for one narrow row. */
.dsb-subsection-panel,
.dsb-convert-pos-panel {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
box-sizing: border-box;
max-width: 520px;
margin: 6px 0 14px;
padding: 14px 16px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card-sunken);
border: 1px solid var(--dsb-card-edge);
border-radius: var(--dsb-r-card);
}
.dsb-subsection-select,
.dsb-convert-pos-select {
box-sizing: border-box;
width: 100%;
max-width: 100%;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
}
.dsb-subsection-select:focus,
.dsb-convert-pos-select:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
.dsb-subsection-field {
min-width: 0;
}
.dsb-subsection-words,
.dsb-subsection-text {
box-sizing: border-box;
width: 100%;
min-width: 0;
}
.dsb-subsection-text {
line-height: 1.6;
resize: vertical;
}
/* ── Gloss field inside the advanced-editing panel ────────────────────
Same shape as .dsb-subsection-text. */
.dsb-edit-gloss {
width: 100%;
line-height: 1.6;
resize: vertical;
}
/* ── Live "not saved yet" previews ─────────────────────────────────────
Dropped into the rendered page at the change's own spot. Dashed edge + a small badge mark them as
pending, not real content; they disappear on "Betal bike" or once the real save lands. */
.dsb-preview-block,
.dsb-preview-inline {
margin: 8px 0;
padding: 8px 12px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-accent-tint);
border: 1px dashed var(--dsb-accent-edge);
border-radius: var(--dsb-r-field);
}
.dsb-preview-inline {
margin-left: 26px;
max-width: 520px;
}
.dsb-preview-heading {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-preview-badge {
display: inline-block;
margin-bottom: 6px;
padding: 1px 8px;
font-size: 11px;
font-weight: 500;
color: var(--dsb-accent-deep);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
}
.dsb-preview-badge-inline {
margin-left: 8px;
margin-bottom: 0;
vertical-align: middle;
}
.dsb-preview-list,
.dsb-preview-text {
margin: 0;
padding-left: 18px;
}
.dsb-preview-text {
padding-left: 0;
}
/* ── Floating save-queue widget ─────────────────────────────────────
This gadget's own small floating box. One "Lê zêde bike" click anywhere on the page adds a line here;
"Guhertinan qeyd bike" makes the one real save; "Betal bike" drops everything queued without touching the page. */
.dsb-queue-box {
position: fixed;
top: 60px;
right: 16px;
z-index: 1000;
box-sizing: border-box;
width: 280px;
max-width: calc(100vw - 32px);
max-height: calc(100vh - 90px);
overflow-y: auto;
padding: 12px 14px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent);
border-radius: var(--dsb-r-card);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.16);
}
.dsb-queue-title {
margin-right: 20px;
font-size: 13px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-queue-close {
float: right;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-queue-close:hover,
.dsb-queue-close:focus {
color: var(--dsb-accent-deep);
}
.dsb-queue-list {
margin: 8px 0;
padding-left: 18px;
max-height: 160px;
overflow-y: auto;
}
.dsb-queue-list li {
margin-bottom: 4px;
}
.dsb-queue-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 4px;
}
.dsb-queue-save,
.dsb-queue-cancel {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.dsb-queue-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-queue-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-queue-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-queue-cancel {
background: transparent;
border: 1px solid var(--dsb-field-edge);
color: var(--dsb-ink-3);
}
.dsb-queue-cancel:hover {
border-color: var(--dsb-ink-3);
color: var(--dsb-ink);
}
.dsb-queue-status {
margin-top: 6px;
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-queue-status.dsb-status-ok { color: var(--dsb-ok); }
.dsb-queue-status.dsb-status-error { color: var(--dsb-danger); }
/* ── Minerva (mobile) ────────────────────────────────────────────────
Narrower viewport: keep the panel on screen and give every tap
target the form's 44px minimum. */
.skin-minerva .dsb-quick-row,
.skin-minerva .dsb-subsection-panel,
.skin-minerva .dsb-convert-pos-panel {
max-width: 100%;
}
@media (max-width: 720px), (pointer: coarse) {
.dsb-toolbar {
margin-left: -28px;
width: 28px;
height: 26px;
}
.dsb-toggle {
width: 20px;
height: 20px;
margin-left: 8px;
}
.dsb-quick-row {
font-size: 13px;
margin-left: 20px;
}
.dsb-input,
.dsb-subsection-select,
.dsb-convert-pos-select {
min-height: 40px;
/* >=16px stops iOS Safari zooming the page on focus. */
font-size: 16px;
}
.dsb-mod-btn,
.dsb-word-remove,
.dsb-mod-confirm,
.dsb-mod-cancel {
width: 36px;
height: 36px;
font-size: 15px;
}
.dsb-mod-pill {
padding: 8px 12px;
}
.dsb-mod-val-input {
max-width: none;
}
.dsb-tagfield .dsb-input {
min-height: 32px;
}
.dsb-tag-remove {
padding: 0 6px;
}
.dsb-save,
.dsb-cancel,
.dsb-autolink,
.dsb-queue-save,
.dsb-queue-cancel {
min-height: 40px;
padding: 8px 16px;
}
.dsb-queue-box {
top: auto;
bottom: 8px;
right: 8px;
left: 8px;
width: auto;
}
}
/* ── Dark mode ───────────────────────────────────────────────────────
Same warm dark palette and same explicit-signal-only rule as the
form's stylesheet: no bare prefers-color-scheme fallback, since
legacy Vector sets no theme class and would go dark on its own. */
html.skin-theme-clientpref-night,
html.skin-nightmode {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-night .dsb-save,
html.skin-nightmode .dsb-save,
html.skin-theme-clientpref-night .dsb-queue-save,
html.skin-nightmode .dsb-queue-save {
color: #14213a;
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-os .dsb-save,
html.skin-theme-clientpref-os .dsb-queue-save {
color: #14213a;
}
}
qk3guq79qojw8o2im2ztv0gt8p7c3lo
6347461
6347460
2026-08-31T19:50:00Z
Wikihez
7344
Restored revision 6347451 by [[Special:Contributions/Wikihez|Wikihez]] ([[User talk:Wikihez|talk]]) ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]])
6347461
css
text/css
/* Gadget-DefSideBoxes.css
Skin-agnostic (vector, vector2022, minerva). Visual layer matches MediaWiki:Gadget-wiktku-start/styles.css
("SÊWIRANA NÛ"); those tokens are re-declared here under a --dsb-* prefix since they live on
#wiktku-start-form, which doesn't exist on an article page. */
:root {
--dsb-card: #fffdf8;
--dsb-card-sunken: #fbf8f1;
--dsb-rule: #ded6c8;
--dsb-rule-soft: #efe8db;
--dsb-card-edge: #e6dfd2;
--dsb-field-edge: #cfc7b8;
--dsb-field-bg: #fff;
--dsb-ink: #1c1a17;
--dsb-ink-2: #3d3830;
--dsb-ink-3: #57514a;
--dsb-muted: #8a8378;
--dsb-placeholder: #b3ab9e;
--dsb-accent: #2a5db0;
--dsb-accent-deep: #22406f;
--dsb-accent-tint: #eef2fa;
--dsb-accent-edge: #d5def0;
--dsb-ok: #3d8a55;
--dsb-danger: #9c3a28;
--dsb-r-field: 10px;
--dsb-r-card: 12px;
--dsb-r-pill: 999px;
--dsb-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--dsb-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── The pencil toggle on a definition ─────────────────────────────────
The classic MediaWiki interlanguage-links edit pencil (same asset as defEditButton), not a hand-drawn glyph.
Hidden by default like defEditButton: revealed by hovering the line on desktop, or by tapping it on touch
(.dsb-revealed, added by attachToolbar()'s own click handler) -- keeps the definition list uncluttered. */
/* Zero-width + overflow:visible keeps .dsb-toolbar in normal inline flow (so it vertical-aligns with the text baseline automatically, unlike position:absolute's fragile top-guessing) while the negative margin on .dsb-toggle lets the icon spill left into the gutter without the zero-width box itself taking any line space. */
.dsb-toolbar {
display: inline-block;
width: 0;
height: 0;
overflow: visible;
vertical-align: middle;
font-family: var(--dsb-sans);
}
.dsb-toggle {
display: inline-block;
margin-left: -22px;
width: 13px;
height: 13px;
vertical-align: middle;
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d3/InterlanguageLinks-Asset-Pencil.gif);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
text-decoration: none;
cursor: pointer;
opacity: 0;
transition: opacity 0.15s ease;
}
.dsb-toggle:hover,
.dsb-toggle:focus {
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d1/InterlanguageLinks-Asset-Pencil-Hover.gif);
}
li:hover .dsb-toolbar .dsb-toggle,
.dsb-toggle:focus {
opacity: 1;
}
@media (hover: none), (pointer: coarse) {
.dsb-toolbar.dsb-revealed .dsb-toggle {
opacity: 1;
}
}
/* ── "Guhartina pêşketî" (advanced editing) panel ──────────────────────
Revealed by the pencil toggle above: every per-sense action this gadget offers, queued together with one
"Lê zêde bike". A plain inline row, not a bordered/background card. */
.dsb-quick-row {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
box-sizing: border-box;
max-width: 520px;
margin: 4px 0 4px 26px;
font-family: var(--dsb-sans);
font-size: 12px;
color: var(--dsb-ink-2);
}
.dsb-quick-link {
align-self: flex-start;
margin-bottom: 10px;
color: var(--dsb-accent);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
}
.dsb-quick-link:hover,
.dsb-quick-link:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* The picker row: gloss + the two primary word groups as direct "+ <field>" links, plus a "Zêdetir" toggle
for the rest -- clicking a link opens its box below and hides the link; .dsb-box-remove un-hides it.
position: relative anchors .dsb-more-menu's overlay below (see there). */
.dsb-field-picker {
position: relative;
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-bottom: 10px;
}
.dsb-field-picker .dsb-quick-link {
margin-bottom: 0;
}
/* The "Zêdetir" dropdown: every non-primary field link (plus Nimûne/jêgirtin, which sits first) stacked as a
plain vertical list. Floats over the page as an overlay (positioned against .dsb-field-picker) instead of
pushing $openBoxes/the rest of the definition down when it opens. */
.dsb-more-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 10;
display: flex;
flex-direction: column;
align-items: flex-start;
width: max-content;
max-width: min(320px, calc(100vw - 40px));
gap: 6px;
margin: 2px 0 0 4px;
padding: 8px 12px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-field);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dsb-more-menu .dsb-quick-link {
margin-bottom: 0;
}
/* Boxes the user has actually opened, stacked in the order they were added -- several can be open at once. */
.dsb-open-boxes {
display: flex;
flex-direction: column;
}
/* One field (its label + input) within the panel -- always a currently-open, removable box. */
.dsb-adv-group {
position: relative;
margin-bottom: 14px;
padding-right: 20px;
}
.dsb-adv-label {
margin-bottom: 4px;
font-size: 12px;
font-weight: 600;
color: var(--dsb-ink-3);
}
.dsb-box-remove {
position: absolute;
top: 0;
right: 0;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-box-remove:hover,
.dsb-box-remove:focus {
color: var(--dsb-accent-deep);
}
.dsb-form-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.dsb-input {
box-sizing: border-box;
min-width: 16em;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-input::placeholder {
color: var(--dsb-placeholder);
opacity: 1;
}
.dsb-input:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
/* ── Plain tag field (Etîket, Kategorî) ────────────────────────────────
Plain type-and-commit tags with no suggestion panel; unlike Hevmane/Dijmane/etc., these carry no modifiers. */
.dsb-tagfield {
box-sizing: border-box;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
min-width: 16em;
padding: 4px 6px;
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-tagfield:focus-within {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
}
.dsb-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
padding: 3px 6px 3px 10px;
}
.dsb-tag-remove {
border: 0;
background: transparent;
color: var(--dsb-muted);
font-size: 13px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
}
.dsb-tag-remove:hover {
color: var(--dsb-danger);
}
.dsb-tagfield .dsb-input {
flex: 1 1 8em;
min-width: 8em;
border: 0;
padding: 3px 2px;
background: transparent;
box-shadow: none;
}
.dsb-tagfield .dsb-input:focus {
box-shadow: none;
}
/* ── Word list with modifier pills ───────────────────────────────────
Every word is its own always-visible row: a word box plus a "+" that attaches one of the 10 WORD_MODIFIERS
as a small pill shown above the box. A fresh empty row is appended once the current last one gets text. */
.dsb-wordlist {
margin: 0;
padding-left: 0;
list-style: none;
}
.dsb-word-li {
margin-bottom: 6px;
}
.dsb-word-li:last-child {
margin-bottom: 0;
}
.dsb-word-mods {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
}
.dsb-word-mod-chip {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 11.5px;
padding: 3px 4px 3px 10px;
cursor: pointer;
}
.dsb-word-mod-chip-remove {
border: 0;
background: transparent;
color: var(--dsb-accent-deep);
font-size: 12px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
opacity: 0.7;
}
.dsb-word-mod-chip-remove:hover {
color: var(--dsb-danger);
opacity: 1;
}
.dsb-word-box-row {
display: flex;
align-items: center;
gap: 6px;
}
.dsb-word-box-row .dsb-word-input {
flex: 1 1 auto;
min-width: 0;
}
.dsb-mod-btn,
.dsb-word-remove {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.dsb-mod-btn {
border: 1px solid var(--dsb-accent-edge);
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
}
.dsb-mod-btn:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-word-remove {
border: 1px solid var(--dsb-field-edge);
background: var(--dsb-field-bg);
color: var(--dsb-muted);
}
.dsb-word-remove:hover {
border-color: var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-mod-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
margin-top: 6px;
padding: 8px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-card);
box-shadow: none;
}
.dsb-mod-pill {
font-family: var(--dsb-sans);
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
white-space: nowrap;
padding: 5px 10px;
cursor: pointer;
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.dsb-mod-pill:hover {
border-color: var(--dsb-accent);
background: var(--dsb-accent);
color: #fff;
}
.dsb-mod-pill:disabled,
.dsb-mod-pill.dsb-mod-pill-used {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
cursor: not-allowed;
opacity: 0.7;
}
.dsb-mod-pill:disabled:hover,
.dsb-mod-pill.dsb-mod-pill-used:hover {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
}
.dsb-mod-val-wrap {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
margin-top: 6px;
}
.dsb-mod-val-input {
flex: 1 1 auto;
min-width: 0;
max-width: 16em;
}
.dsb-mod-confirm,
.dsb-mod-cancel {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
background: var(--dsb-accent-tint);
cursor: pointer;
}
.dsb-mod-confirm {
border: 1px solid var(--dsb-ok);
color: var(--dsb-ok);
}
.dsb-mod-cancel {
border: 1px solid var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-save,
.dsb-cancel,
.dsb-autolink {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
/* One filled pill per row — the same rule the form's footer follows. */
.dsb-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-cancel {
background: transparent;
border: 1px solid transparent;
color: var(--dsb-ink-3);
}
.dsb-cancel:hover {
border-color: var(--dsb-field-edge);
color: var(--dsb-ink);
}
/* An outline pill, distinct from both the filled .dsb-save and the plain-text .dsb-cancel -- a secondary
utility action, not the primary save nor a dismissal. */
.dsb-autolink {
background: transparent;
border: 1px solid var(--dsb-accent-edge);
color: var(--dsb-accent);
}
.dsb-autolink:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-autolink:disabled {
opacity: 0.55;
cursor: progress;
}
/* Status line. Color comes from .dsb-status-ok/.dsb-status-error (added by the .js on success/failure)
rather than an inline style, so these tokens (and dark mode) apply. */
.dsb-status {
font-family: var(--dsb-sans);
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-status-ok { color: var(--dsb-ok); }
.dsb-status-error { color: var(--dsb-danger); }
/* ── "+ Beşek lê zêde bike" ──────────────────────────────────────────
An accent-coloured action link, like the form's .wiktku-adv-toggle:
it opens something, so it is not muted grey. */
.dsb-add-subsection,
.dsb-convert-pos-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-family: var(--dsb-sans);
font-size: 14px;
font-weight: 500;
color: var(--dsb-accent);
text-decoration: none;
border-bottom: 0;
cursor: pointer;
}
.dsb-add-subsection:hover,
.dsb-add-subsection:focus,
.dsb-convert-pos-trigger:hover,
.dsb-convert-pos-trigger:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* ── Subsection panel ────────────────────────────────────────────────
A sunken card rather than a grey utility box; fields stack so the
picker and its input are not competing for one narrow row. */
.dsb-subsection-panel,
.dsb-convert-pos-panel {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
box-sizing: border-box;
max-width: 520px;
margin: 6px 0 14px;
padding: 14px 16px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card-sunken);
border: 1px solid var(--dsb-card-edge);
border-radius: var(--dsb-r-card);
}
.dsb-subsection-select,
.dsb-convert-pos-select {
box-sizing: border-box;
width: 100%;
max-width: 100%;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
}
.dsb-subsection-select:focus,
.dsb-convert-pos-select:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
.dsb-subsection-field {
min-width: 0;
}
.dsb-subsection-words,
.dsb-subsection-text {
box-sizing: border-box;
width: 100%;
min-width: 0;
}
.dsb-subsection-text {
line-height: 1.6;
resize: vertical;
}
/* ── Gloss field inside the advanced-editing panel ────────────────────
Same shape as .dsb-subsection-text. */
.dsb-edit-gloss {
width: 100%;
line-height: 1.6;
resize: vertical;
}
/* ── Live "not saved yet" previews ─────────────────────────────────────
Dropped into the rendered page at the change's own spot. Dashed edge + a small badge mark them as
pending, not real content; they disappear on "Betal bike" or once the real save lands. */
.dsb-preview-block,
.dsb-preview-inline {
margin: 8px 0;
padding: 8px 12px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-accent-tint);
border: 1px dashed var(--dsb-accent-edge);
border-radius: var(--dsb-r-field);
}
.dsb-preview-inline {
margin-left: 26px;
max-width: 520px;
}
.dsb-preview-heading {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-preview-badge {
display: inline-block;
margin-bottom: 6px;
padding: 1px 8px;
font-size: 11px;
font-weight: 500;
color: var(--dsb-accent-deep);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
}
.dsb-preview-badge-inline {
margin-left: 8px;
margin-bottom: 0;
vertical-align: middle;
}
.dsb-preview-list,
.dsb-preview-text {
margin: 0;
padding-left: 18px;
}
.dsb-preview-text {
padding-left: 0;
}
/* ── Floating save-queue widget ─────────────────────────────────────
This gadget's own small floating box. One "Lê zêde bike" click anywhere on the page adds a line here;
"Guhertinan qeyd bike" makes the one real save; "Betal bike" drops everything queued without touching the page. */
.dsb-queue-box {
position: fixed;
top: 60px;
right: 16px;
z-index: 1000;
box-sizing: border-box;
width: 280px;
max-width: calc(100vw - 32px);
max-height: calc(100vh - 90px);
overflow-y: auto;
padding: 12px 14px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent);
border-radius: var(--dsb-r-card);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.16);
}
.dsb-queue-title {
margin-right: 20px;
font-size: 13px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-queue-close {
float: right;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-queue-close:hover,
.dsb-queue-close:focus {
color: var(--dsb-accent-deep);
}
.dsb-queue-list {
margin: 8px 0;
padding-left: 18px;
max-height: 160px;
overflow-y: auto;
}
.dsb-queue-list li {
margin-bottom: 4px;
}
.dsb-queue-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 4px;
}
.dsb-queue-save,
.dsb-queue-cancel {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.dsb-queue-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-queue-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-queue-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-queue-cancel {
background: transparent;
border: 1px solid var(--dsb-field-edge);
color: var(--dsb-ink-3);
}
.dsb-queue-cancel:hover {
border-color: var(--dsb-ink-3);
color: var(--dsb-ink);
}
.dsb-queue-status {
margin-top: 6px;
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-queue-status.dsb-status-ok { color: var(--dsb-ok); }
.dsb-queue-status.dsb-status-error { color: var(--dsb-danger); }
/* ── Minerva (mobile) ────────────────────────────────────────────────
Narrower viewport: keep the panel on screen and give every tap
target the form's 44px minimum. */
.skin-minerva .dsb-quick-row,
.skin-minerva .dsb-subsection-panel,
.skin-minerva .dsb-convert-pos-panel {
max-width: 100%;
}
@media (max-width: 720px), (pointer: coarse) {
.dsb-toggle {
width: 20px;
height: 20px;
margin-left: -28px;
}
.dsb-quick-row {
font-size: 13px;
margin-left: 20px;
}
.dsb-input,
.dsb-subsection-select,
.dsb-convert-pos-select {
min-height: 40px;
/* >=16px stops iOS Safari zooming the page on focus. */
font-size: 16px;
}
.dsb-mod-btn,
.dsb-word-remove,
.dsb-mod-confirm,
.dsb-mod-cancel {
width: 36px;
height: 36px;
font-size: 15px;
}
.dsb-mod-pill {
padding: 8px 12px;
}
.dsb-mod-val-input {
max-width: none;
}
.dsb-tagfield .dsb-input {
min-height: 32px;
}
.dsb-tag-remove {
padding: 0 6px;
}
.dsb-save,
.dsb-cancel,
.dsb-autolink,
.dsb-queue-save,
.dsb-queue-cancel {
min-height: 40px;
padding: 8px 16px;
}
.dsb-queue-box {
top: auto;
bottom: 8px;
right: 8px;
left: 8px;
width: auto;
}
}
/* ── Dark mode ───────────────────────────────────────────────────────
Same warm dark palette and same explicit-signal-only rule as the
form's stylesheet: no bare prefers-color-scheme fallback, since
legacy Vector sets no theme class and would go dark on its own. */
html.skin-theme-clientpref-night,
html.skin-nightmode {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-night .dsb-save,
html.skin-nightmode .dsb-save,
html.skin-theme-clientpref-night .dsb-queue-save,
html.skin-nightmode .dsb-queue-save {
color: #14213a;
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-os .dsb-save,
html.skin-theme-clientpref-os .dsb-queue-save {
color: #14213a;
}
}
6fwqhg4dt75d7bgqlk81jvryhn4magp
6347517
6347461
2026-09-01T08:41:24Z
Wikihez
7344
6347517
css
text/css
/* Gadget-DefSideBoxes.css
Skin-agnostic (vector, vector2022, minerva). Visual layer matches MediaWiki:Gadget-wiktku-start/styles.css
("SÊWIRANA NÛ"); those tokens are re-declared here under a --dsb-* prefix since they live on
#wiktku-start-form, which doesn't exist on an article page. */
:root {
--dsb-card: #fffdf8;
--dsb-card-sunken: #fbf8f1;
--dsb-rule: #ded6c8;
--dsb-rule-soft: #efe8db;
--dsb-card-edge: #e6dfd2;
--dsb-field-edge: #cfc7b8;
--dsb-field-bg: #fff;
--dsb-ink: #1c1a17;
--dsb-ink-2: #3d3830;
--dsb-ink-3: #57514a;
--dsb-muted: #8a8378;
--dsb-placeholder: #b3ab9e;
--dsb-accent: #2a5db0;
--dsb-accent-deep: #22406f;
--dsb-accent-tint: #eef2fa;
--dsb-accent-edge: #d5def0;
--dsb-ok: #3d8a55;
--dsb-danger: #9c3a28;
--dsb-r-field: 10px;
--dsb-r-card: 12px;
--dsb-r-pill: 999px;
--dsb-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--dsb-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── The pencil toggle on a definition ─────────────────────────────────
The classic MediaWiki interlanguage-links edit pencil (same asset as defEditButton), not a hand-drawn glyph.
Hidden by default like defEditButton: revealed by hovering the line on desktop, or by tapping it on touch
(.dsb-revealed, added by attachToolbar()'s own click handler) -- keeps the definition list uncluttered. */
/* The toolbar is taken out of flow with position:absolute but leaves top/left as auto, so it renders at its
static position -- exactly where it would have sat inline -- while stealing no space from the definition
text. The negative margin then slides it left into the list's 3.2em gutter, in front of the "1." marker,
the same trick en.wikt's .defEditButton uses.
The previous zero-height inline-block sank the pencil a full line below the definition instead: with
height:0 and overflow:visible the inner line box overflows the content box, and an inline-block's baseline
is the baseline of its last line box -- so vertical-align:middle was measuring from a baseline about 13px
too low. */
.dsb-toolbar {
position: absolute;
margin-left: -40px;
width: 40px;
height: 26px;
font-family: var(--dsb-sans);
}
.dsb-toggle {
display: block;
/* Centres the 13px icon on the 26px definition line, less the 2px the static position already sits
above the top of the text box. */
margin-top: 8px;
width: 13px;
height: 13px;
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d3/InterlanguageLinks-Asset-Pencil.gif);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
text-decoration: none;
cursor: pointer;
opacity: 0;
transition: opacity 0.15s ease;
}
.dsb-toggle:hover,
.dsb-toggle:focus {
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d1/InterlanguageLinks-Asset-Pencil-Hover.gif);
}
li:hover .dsb-toolbar .dsb-toggle,
.dsb-toggle:focus {
opacity: 1;
}
@media (hover: none), (pointer: coarse) {
.dsb-toolbar.dsb-revealed .dsb-toggle {
opacity: 1;
}
}
/* ── "Guhartina pêşketî" (advanced editing) panel ──────────────────────
Revealed by the pencil toggle above: every per-sense action this gadget offers, queued together with one
"Lê zêde bike". A plain inline row, not a bordered/background card. */
.dsb-quick-row {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
box-sizing: border-box;
max-width: 520px;
margin: 4px 0 4px 26px;
font-family: var(--dsb-sans);
font-size: 12px;
color: var(--dsb-ink-2);
}
.dsb-quick-link {
align-self: flex-start;
margin-bottom: 10px;
color: var(--dsb-accent);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
}
.dsb-quick-link:hover,
.dsb-quick-link:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* The picker row: gloss + the two primary word groups as direct "+ <field>" links, plus a "Zêdetir" toggle
for the rest -- clicking a link opens its box below and hides the link; .dsb-box-remove un-hides it.
position: relative anchors .dsb-more-menu's overlay below (see there). */
.dsb-field-picker {
position: relative;
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-bottom: 10px;
}
.dsb-field-picker .dsb-quick-link {
margin-bottom: 0;
}
/* The "Zêdetir" dropdown: every non-primary field link (plus Nimûne/jêgirtin, which sits first) stacked as a
plain vertical list. Floats over the page as an overlay (positioned against .dsb-field-picker) instead of
pushing $openBoxes/the rest of the definition down when it opens. */
.dsb-more-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 10;
display: flex;
flex-direction: column;
align-items: flex-start;
width: max-content;
max-width: min(320px, calc(100vw - 40px));
gap: 6px;
margin: 2px 0 0 4px;
padding: 8px 12px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-field);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dsb-more-menu .dsb-quick-link {
margin-bottom: 0;
}
/* Boxes the user has actually opened, stacked in the order they were added -- several can be open at once. */
.dsb-open-boxes {
display: flex;
flex-direction: column;
}
/* One field (its label + input) within the panel -- always a currently-open, removable box. */
.dsb-adv-group {
position: relative;
margin-bottom: 14px;
padding-right: 20px;
}
.dsb-adv-label {
margin-bottom: 4px;
font-size: 12px;
font-weight: 600;
color: var(--dsb-ink-3);
}
.dsb-box-remove {
position: absolute;
top: 0;
right: 0;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-box-remove:hover,
.dsb-box-remove:focus {
color: var(--dsb-accent-deep);
}
.dsb-form-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.dsb-input {
box-sizing: border-box;
min-width: 16em;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-input::placeholder {
color: var(--dsb-placeholder);
opacity: 1;
}
.dsb-input:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
/* ── Plain tag field (Etîket, Kategorî) ────────────────────────────────
Plain type-and-commit tags with no suggestion panel; unlike Hevmane/Dijmane/etc., these carry no modifiers. */
.dsb-tagfield {
box-sizing: border-box;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
min-width: 16em;
padding: 4px 6px;
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-tagfield:focus-within {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
}
.dsb-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
padding: 3px 6px 3px 10px;
}
.dsb-tag-remove {
border: 0;
background: transparent;
color: var(--dsb-muted);
font-size: 13px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
}
.dsb-tag-remove:hover {
color: var(--dsb-danger);
}
.dsb-tagfield .dsb-input {
flex: 1 1 8em;
min-width: 8em;
border: 0;
padding: 3px 2px;
background: transparent;
box-shadow: none;
}
.dsb-tagfield .dsb-input:focus {
box-shadow: none;
}
/* ── Word list with modifier pills ───────────────────────────────────
Every word is its own always-visible row: a word box plus a "+" that attaches one of the 10 WORD_MODIFIERS
as a small pill shown above the box. A fresh empty row is appended once the current last one gets text. */
.dsb-wordlist {
margin: 0;
padding-left: 0;
list-style: none;
}
.dsb-word-li {
margin-bottom: 6px;
}
.dsb-word-li:last-child {
margin-bottom: 0;
}
.dsb-word-mods {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
}
.dsb-word-mod-chip {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 11.5px;
padding: 3px 4px 3px 10px;
cursor: pointer;
}
.dsb-word-mod-chip-remove {
border: 0;
background: transparent;
color: var(--dsb-accent-deep);
font-size: 12px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
opacity: 0.7;
}
.dsb-word-mod-chip-remove:hover {
color: var(--dsb-danger);
opacity: 1;
}
.dsb-word-box-row {
display: flex;
align-items: center;
gap: 6px;
}
.dsb-word-box-row .dsb-word-input {
flex: 1 1 auto;
min-width: 0;
}
.dsb-mod-btn,
.dsb-word-remove {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.dsb-mod-btn {
border: 1px solid var(--dsb-accent-edge);
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
}
.dsb-mod-btn:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-word-remove {
border: 1px solid var(--dsb-field-edge);
background: var(--dsb-field-bg);
color: var(--dsb-muted);
}
.dsb-word-remove:hover {
border-color: var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-mod-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
margin-top: 6px;
padding: 8px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-card);
box-shadow: none;
}
.dsb-mod-pill {
font-family: var(--dsb-sans);
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
white-space: nowrap;
padding: 5px 10px;
cursor: pointer;
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.dsb-mod-pill:hover {
border-color: var(--dsb-accent);
background: var(--dsb-accent);
color: #fff;
}
.dsb-mod-pill:disabled,
.dsb-mod-pill.dsb-mod-pill-used {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
cursor: not-allowed;
opacity: 0.7;
}
.dsb-mod-pill:disabled:hover,
.dsb-mod-pill.dsb-mod-pill-used:hover {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
}
.dsb-mod-val-wrap {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
margin-top: 6px;
}
.dsb-mod-val-input {
flex: 1 1 auto;
min-width: 0;
max-width: 16em;
}
.dsb-mod-confirm,
.dsb-mod-cancel {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
background: var(--dsb-accent-tint);
cursor: pointer;
}
.dsb-mod-confirm {
border: 1px solid var(--dsb-ok);
color: var(--dsb-ok);
}
.dsb-mod-cancel {
border: 1px solid var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-save,
.dsb-cancel,
.dsb-autolink {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
/* One filled pill per row — the same rule the form's footer follows. */
.dsb-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-cancel {
background: transparent;
border: 1px solid transparent;
color: var(--dsb-ink-3);
}
.dsb-cancel:hover {
border-color: var(--dsb-field-edge);
color: var(--dsb-ink);
}
/* An outline pill, distinct from both the filled .dsb-save and the plain-text .dsb-cancel -- a secondary
utility action, not the primary save nor a dismissal. */
.dsb-autolink {
background: transparent;
border: 1px solid var(--dsb-accent-edge);
color: var(--dsb-accent);
}
.dsb-autolink:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-autolink:disabled {
opacity: 0.55;
cursor: progress;
}
/* Status line. Color comes from .dsb-status-ok/.dsb-status-error (added by the .js on success/failure)
rather than an inline style, so these tokens (and dark mode) apply. */
.dsb-status {
font-family: var(--dsb-sans);
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-status-ok { color: var(--dsb-ok); }
.dsb-status-error { color: var(--dsb-danger); }
/* ── "+ Beşek lê zêde bike" ──────────────────────────────────────────
An accent-coloured action link, like the form's .wiktku-adv-toggle:
it opens something, so it is not muted grey. */
.dsb-add-subsection,
.dsb-convert-pos-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-family: var(--dsb-sans);
font-size: 14px;
font-weight: 500;
color: var(--dsb-accent);
text-decoration: none;
border-bottom: 0;
cursor: pointer;
}
.dsb-add-subsection:hover,
.dsb-add-subsection:focus,
.dsb-convert-pos-trigger:hover,
.dsb-convert-pos-trigger:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* ── Subsection panel ────────────────────────────────────────────────
A sunken card rather than a grey utility box; fields stack so the
picker and its input are not competing for one narrow row. */
.dsb-subsection-panel,
.dsb-convert-pos-panel {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
box-sizing: border-box;
max-width: 520px;
margin: 6px 0 14px;
padding: 14px 16px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card-sunken);
border: 1px solid var(--dsb-card-edge);
border-radius: var(--dsb-r-card);
}
.dsb-subsection-select,
.dsb-convert-pos-select {
box-sizing: border-box;
width: 100%;
max-width: 100%;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
}
.dsb-subsection-select:focus,
.dsb-convert-pos-select:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
.dsb-subsection-field {
min-width: 0;
}
.dsb-subsection-words,
.dsb-subsection-text {
box-sizing: border-box;
width: 100%;
min-width: 0;
}
.dsb-subsection-text {
line-height: 1.6;
resize: vertical;
}
/* ── Gloss field inside the advanced-editing panel ────────────────────
Same shape as .dsb-subsection-text. */
.dsb-edit-gloss {
width: 100%;
line-height: 1.6;
resize: vertical;
}
/* ── Live "not saved yet" previews ─────────────────────────────────────
Dropped into the rendered page at the change's own spot. Dashed edge + a small badge mark them as
pending, not real content; they disappear on "Betal bike" or once the real save lands. */
.dsb-preview-block,
.dsb-preview-inline {
margin: 8px 0;
padding: 8px 12px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-accent-tint);
border: 1px dashed var(--dsb-accent-edge);
border-radius: var(--dsb-r-field);
}
.dsb-preview-inline {
margin-left: 26px;
max-width: 520px;
}
.dsb-preview-heading {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-preview-badge {
display: inline-block;
margin-bottom: 6px;
padding: 1px 8px;
font-size: 11px;
font-weight: 500;
color: var(--dsb-accent-deep);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
}
.dsb-preview-badge-inline {
margin-left: 8px;
margin-bottom: 0;
vertical-align: middle;
}
.dsb-preview-list,
.dsb-preview-text {
margin: 0;
padding-left: 18px;
}
.dsb-preview-text {
padding-left: 0;
}
/* ── Floating save-queue widget ─────────────────────────────────────
This gadget's own small floating box. One "Lê zêde bike" click anywhere on the page adds a line here;
"Guhertinan qeyd bike" makes the one real save; "Betal bike" drops everything queued without touching the page. */
.dsb-queue-box {
position: fixed;
top: 60px;
right: 16px;
z-index: 1000;
box-sizing: border-box;
width: 280px;
max-width: calc(100vw - 32px);
max-height: calc(100vh - 90px);
overflow-y: auto;
padding: 12px 14px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent);
border-radius: var(--dsb-r-card);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.16);
}
.dsb-queue-title {
margin-right: 20px;
font-size: 13px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-queue-close {
float: right;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-queue-close:hover,
.dsb-queue-close:focus {
color: var(--dsb-accent-deep);
}
.dsb-queue-list {
margin: 8px 0;
padding-left: 18px;
max-height: 160px;
overflow-y: auto;
}
.dsb-queue-list li {
margin-bottom: 4px;
}
.dsb-queue-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 4px;
}
.dsb-queue-save,
.dsb-queue-cancel {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.dsb-queue-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-queue-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-queue-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-queue-cancel {
background: transparent;
border: 1px solid var(--dsb-field-edge);
color: var(--dsb-ink-3);
}
.dsb-queue-cancel:hover {
border-color: var(--dsb-ink-3);
color: var(--dsb-ink);
}
.dsb-queue-status {
margin-top: 6px;
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-queue-status.dsb-status-ok { color: var(--dsb-ok); }
.dsb-queue-status.dsb-status-error { color: var(--dsb-danger); }
/* ── Minerva (mobile) ────────────────────────────────────────────────
Narrower viewport: keep the panel on screen and give every tap
target the form's 44px minimum. */
.skin-minerva .dsb-quick-row,
.skin-minerva .dsb-subsection-panel,
.skin-minerva .dsb-convert-pos-panel {
max-width: 100%;
}
@media (max-width: 720px), (pointer: coarse) {
.dsb-toolbar {
margin-left: -44px;
width: 44px;
}
.dsb-toggle {
width: 20px;
height: 20px;
margin-top: 3px;
}
.dsb-quick-row {
font-size: 13px;
margin-left: 20px;
}
.dsb-input,
.dsb-subsection-select,
.dsb-convert-pos-select {
min-height: 40px;
/* >=16px stops iOS Safari zooming the page on focus. */
font-size: 16px;
}
.dsb-mod-btn,
.dsb-word-remove,
.dsb-mod-confirm,
.dsb-mod-cancel {
width: 36px;
height: 36px;
font-size: 15px;
}
.dsb-mod-pill {
padding: 8px 12px;
}
.dsb-mod-val-input {
max-width: none;
}
.dsb-tagfield .dsb-input {
min-height: 32px;
}
.dsb-tag-remove {
padding: 0 6px;
}
.dsb-save,
.dsb-cancel,
.dsb-autolink,
.dsb-queue-save,
.dsb-queue-cancel {
min-height: 40px;
padding: 8px 16px;
}
.dsb-queue-box {
top: auto;
bottom: 8px;
right: 8px;
left: 8px;
width: auto;
}
}
/* ── Dark mode ───────────────────────────────────────────────────────
Same warm dark palette and same explicit-signal-only rule as the
form's stylesheet: no bare prefers-color-scheme fallback, since
legacy Vector sets no theme class and would go dark on its own. */
html.skin-theme-clientpref-night,
html.skin-nightmode {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-night .dsb-save,
html.skin-nightmode .dsb-save,
html.skin-theme-clientpref-night .dsb-queue-save,
html.skin-nightmode .dsb-queue-save {
color: #14213a;
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-os .dsb-save,
html.skin-theme-clientpref-os .dsb-queue-save {
color: #14213a;
}
}
8389rc7ogj2ymcfj79xx7f5w7qhjp6h
6347518
6347517
2026-09-01T08:47:58Z
Wikihez
7344
6347518
css
text/css
/* Gadget-DefSideBoxes.css
Skin-agnostic (vector, vector2022, minerva). Visual layer matches MediaWiki:Gadget-wiktku-start/styles.css
("SÊWIRANA NÛ"); those tokens are re-declared here under a --dsb-* prefix since they live on
#wiktku-start-form, which doesn't exist on an article page. */
:root {
--dsb-card: #fffdf8;
--dsb-card-sunken: #fbf8f1;
--dsb-rule: #ded6c8;
--dsb-rule-soft: #efe8db;
--dsb-card-edge: #e6dfd2;
--dsb-field-edge: #cfc7b8;
--dsb-field-bg: #fff;
--dsb-ink: #1c1a17;
--dsb-ink-2: #3d3830;
--dsb-ink-3: #57514a;
--dsb-muted: #8a8378;
--dsb-placeholder: #b3ab9e;
--dsb-accent: #2a5db0;
--dsb-accent-deep: #22406f;
--dsb-accent-tint: #eef2fa;
--dsb-accent-edge: #d5def0;
--dsb-ok: #3d8a55;
--dsb-danger: #9c3a28;
--dsb-r-field: 10px;
--dsb-r-card: 12px;
--dsb-r-pill: 999px;
--dsb-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--dsb-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── The pencil toggle on a definition ─────────────────────────────────
The classic MediaWiki interlanguage-links edit pencil (same asset as defEditButton), not a hand-drawn glyph.
Hidden by default like defEditButton: revealed by hovering the line on desktop, or by tapping it on touch
(.dsb-revealed, added by attachToolbar()'s own click handler) -- keeps the definition list uncluttered. */
/* position:absolute with top/left auto keeps the static position but drops the box out of flow; the negative margin then slides the pencil into the list gutter, in front of the marker (en.wikt's .defEditButton trick). */
.dsb-toolbar {
position: absolute;
margin-left: -40px;
width: 40px;
height: 26px;
font-family: var(--dsb-sans);
}
.dsb-toggle {
display: block;
margin-top: 8px; /* centres the 13px icon on the 26px line */
width: 13px;
height: 13px;
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d3/InterlanguageLinks-Asset-Pencil.gif);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
text-decoration: none;
cursor: pointer;
opacity: 0;
transition: opacity 0.15s ease;
}
.dsb-toggle:hover,
.dsb-toggle:focus {
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d1/InterlanguageLinks-Asset-Pencil-Hover.gif);
}
li:hover .dsb-toolbar .dsb-toggle,
.dsb-toggle:focus {
opacity: 1;
}
@media (hover: none), (pointer: coarse) {
.dsb-toolbar.dsb-revealed .dsb-toggle {
opacity: 1;
}
}
/* ── "Guhartina pêşketî" (advanced editing) panel ──────────────────────
Revealed by the pencil toggle above: every per-sense action this gadget offers, queued together with one
"Lê zêde bike". A plain inline row, not a bordered/background card. */
.dsb-quick-row {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
box-sizing: border-box;
max-width: 520px;
margin: 4px 0 4px 26px;
font-family: var(--dsb-sans);
font-size: 12px;
color: var(--dsb-ink-2);
}
.dsb-quick-link {
align-self: flex-start;
margin-bottom: 10px;
color: var(--dsb-accent);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
}
.dsb-quick-link:hover,
.dsb-quick-link:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* The picker row: gloss + the two primary word groups as direct "+ <field>" links, plus a "Zêdetir" toggle
for the rest -- clicking a link opens its box below and hides the link; .dsb-box-remove un-hides it.
position: relative anchors .dsb-more-menu's overlay below (see there). */
.dsb-field-picker {
position: relative;
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-bottom: 10px;
}
.dsb-field-picker .dsb-quick-link {
margin-bottom: 0;
}
/* The "Zêdetir" dropdown: every non-primary field link (plus Nimûne/jêgirtin, which sits first) stacked as a
plain vertical list. Floats over the page as an overlay (positioned against .dsb-field-picker) instead of
pushing $openBoxes/the rest of the definition down when it opens. */
.dsb-more-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 10;
display: flex;
flex-direction: column;
align-items: flex-start;
width: max-content;
max-width: min(320px, calc(100vw - 40px));
gap: 6px;
margin: 2px 0 0 4px;
padding: 8px 12px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-field);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dsb-more-menu .dsb-quick-link {
margin-bottom: 0;
}
/* Boxes the user has actually opened, stacked in the order they were added -- several can be open at once. */
.dsb-open-boxes {
display: flex;
flex-direction: column;
}
/* One field (its label + input) within the panel -- always a currently-open, removable box. */
.dsb-adv-group {
position: relative;
margin-bottom: 14px;
padding-right: 20px;
}
.dsb-adv-label {
margin-bottom: 4px;
font-size: 12px;
font-weight: 600;
color: var(--dsb-ink-3);
}
.dsb-box-remove {
position: absolute;
top: 0;
right: 0;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-box-remove:hover,
.dsb-box-remove:focus {
color: var(--dsb-accent-deep);
}
.dsb-form-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.dsb-input {
box-sizing: border-box;
min-width: 16em;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-input::placeholder {
color: var(--dsb-placeholder);
opacity: 1;
}
.dsb-input:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
/* ── Plain tag field (Etîket, Kategorî) ────────────────────────────────
Plain type-and-commit tags with no suggestion panel; unlike Hevmane/Dijmane/etc., these carry no modifiers. */
.dsb-tagfield {
box-sizing: border-box;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
min-width: 16em;
padding: 4px 6px;
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-tagfield:focus-within {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
}
.dsb-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
padding: 3px 6px 3px 10px;
}
.dsb-tag-remove {
border: 0;
background: transparent;
color: var(--dsb-muted);
font-size: 13px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
}
.dsb-tag-remove:hover {
color: var(--dsb-danger);
}
.dsb-tagfield .dsb-input {
flex: 1 1 8em;
min-width: 8em;
border: 0;
padding: 3px 2px;
background: transparent;
box-shadow: none;
}
.dsb-tagfield .dsb-input:focus {
box-shadow: none;
}
/* ── Word list with modifier pills ───────────────────────────────────
Every word is its own always-visible row: a word box plus a "+" that attaches one of the 10 WORD_MODIFIERS
as a small pill shown above the box. A fresh empty row is appended once the current last one gets text. */
.dsb-wordlist {
margin: 0;
padding-left: 0;
list-style: none;
}
.dsb-word-li {
margin-bottom: 6px;
}
.dsb-word-li:last-child {
margin-bottom: 0;
}
.dsb-word-mods {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
}
.dsb-word-mod-chip {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 11.5px;
padding: 3px 4px 3px 10px;
cursor: pointer;
}
.dsb-word-mod-chip-remove {
border: 0;
background: transparent;
color: var(--dsb-accent-deep);
font-size: 12px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
opacity: 0.7;
}
.dsb-word-mod-chip-remove:hover {
color: var(--dsb-danger);
opacity: 1;
}
.dsb-word-box-row {
display: flex;
align-items: center;
gap: 6px;
}
.dsb-word-box-row .dsb-word-input {
flex: 1 1 auto;
min-width: 0;
}
.dsb-mod-btn,
.dsb-word-remove {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.dsb-mod-btn {
border: 1px solid var(--dsb-accent-edge);
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
}
.dsb-mod-btn:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-word-remove {
border: 1px solid var(--dsb-field-edge);
background: var(--dsb-field-bg);
color: var(--dsb-muted);
}
.dsb-word-remove:hover {
border-color: var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-mod-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
margin-top: 6px;
padding: 8px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-card);
box-shadow: none;
}
.dsb-mod-pill {
font-family: var(--dsb-sans);
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
white-space: nowrap;
padding: 5px 10px;
cursor: pointer;
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.dsb-mod-pill:hover {
border-color: var(--dsb-accent);
background: var(--dsb-accent);
color: #fff;
}
.dsb-mod-pill:disabled,
.dsb-mod-pill.dsb-mod-pill-used {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
cursor: not-allowed;
opacity: 0.7;
}
.dsb-mod-pill:disabled:hover,
.dsb-mod-pill.dsb-mod-pill-used:hover {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
}
.dsb-mod-val-wrap {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
margin-top: 6px;
}
.dsb-mod-val-input {
flex: 1 1 auto;
min-width: 0;
max-width: 16em;
}
.dsb-mod-confirm,
.dsb-mod-cancel {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
background: var(--dsb-accent-tint);
cursor: pointer;
}
.dsb-mod-confirm {
border: 1px solid var(--dsb-ok);
color: var(--dsb-ok);
}
.dsb-mod-cancel {
border: 1px solid var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-save,
.dsb-cancel,
.dsb-autolink {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
/* One filled pill per row — the same rule the form's footer follows. */
.dsb-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-cancel {
background: transparent;
border: 1px solid transparent;
color: var(--dsb-ink-3);
}
.dsb-cancel:hover {
border-color: var(--dsb-field-edge);
color: var(--dsb-ink);
}
/* An outline pill, distinct from both the filled .dsb-save and the plain-text .dsb-cancel -- a secondary
utility action, not the primary save nor a dismissal. */
.dsb-autolink {
background: transparent;
border: 1px solid var(--dsb-accent-edge);
color: var(--dsb-accent);
}
.dsb-autolink:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-autolink:disabled {
opacity: 0.55;
cursor: progress;
}
/* Status line. Color comes from .dsb-status-ok/.dsb-status-error (added by the .js on success/failure)
rather than an inline style, so these tokens (and dark mode) apply. */
.dsb-status {
font-family: var(--dsb-sans);
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-status-ok { color: var(--dsb-ok); }
.dsb-status-error { color: var(--dsb-danger); }
/* ── "+ Beşek lê zêde bike" ──────────────────────────────────────────
An accent-coloured action link, like the form's .wiktku-adv-toggle:
it opens something, so it is not muted grey. */
.dsb-add-subsection,
.dsb-convert-pos-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-family: var(--dsb-sans);
font-size: 14px;
font-weight: 500;
color: var(--dsb-accent);
text-decoration: none;
border-bottom: 0;
cursor: pointer;
}
.dsb-add-subsection:hover,
.dsb-add-subsection:focus,
.dsb-convert-pos-trigger:hover,
.dsb-convert-pos-trigger:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* ── Subsection panel ────────────────────────────────────────────────
A sunken card rather than a grey utility box; fields stack so the
picker and its input are not competing for one narrow row. */
.dsb-subsection-panel,
.dsb-convert-pos-panel {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
box-sizing: border-box;
max-width: 520px;
margin: 6px 0 14px;
padding: 14px 16px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card-sunken);
border: 1px solid var(--dsb-card-edge);
border-radius: var(--dsb-r-card);
}
.dsb-subsection-select,
.dsb-convert-pos-select {
box-sizing: border-box;
width: 100%;
max-width: 100%;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
}
.dsb-subsection-select:focus,
.dsb-convert-pos-select:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
.dsb-subsection-field {
min-width: 0;
}
.dsb-subsection-words,
.dsb-subsection-text {
box-sizing: border-box;
width: 100%;
min-width: 0;
}
.dsb-subsection-text {
line-height: 1.6;
resize: vertical;
}
/* ── Gloss field inside the advanced-editing panel ────────────────────
Same shape as .dsb-subsection-text. */
.dsb-edit-gloss {
width: 100%;
line-height: 1.6;
resize: vertical;
}
/* ── Live "not saved yet" previews ─────────────────────────────────────
Dropped into the rendered page at the change's own spot. Dashed edge + a small badge mark them as
pending, not real content; they disappear on "Betal bike" or once the real save lands. */
.dsb-preview-block,
.dsb-preview-inline {
margin: 8px 0;
padding: 8px 12px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-accent-tint);
border: 1px dashed var(--dsb-accent-edge);
border-radius: var(--dsb-r-field);
}
.dsb-preview-inline {
margin-left: 26px;
max-width: 520px;
}
.dsb-preview-heading {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-preview-badge {
display: inline-block;
margin-bottom: 6px;
padding: 1px 8px;
font-size: 11px;
font-weight: 500;
color: var(--dsb-accent-deep);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
}
.dsb-preview-badge-inline {
margin-left: 8px;
margin-bottom: 0;
vertical-align: middle;
}
.dsb-preview-list,
.dsb-preview-text {
margin: 0;
padding-left: 18px;
}
.dsb-preview-text {
padding-left: 0;
}
/* ── Floating save-queue widget ─────────────────────────────────────
This gadget's own small floating box. One "Lê zêde bike" click anywhere on the page adds a line here;
"Guhertinan qeyd bike" makes the one real save; "Betal bike" drops everything queued without touching the page. */
.dsb-queue-box {
position: fixed;
top: 60px;
right: 16px;
z-index: 1000;
box-sizing: border-box;
width: 280px;
max-width: calc(100vw - 32px);
max-height: calc(100vh - 90px);
overflow-y: auto;
padding: 12px 14px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent);
border-radius: var(--dsb-r-card);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.16);
}
.dsb-queue-title {
margin-right: 20px;
font-size: 13px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-queue-close {
float: right;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-queue-close:hover,
.dsb-queue-close:focus {
color: var(--dsb-accent-deep);
}
.dsb-queue-list {
margin: 8px 0;
padding-left: 18px;
max-height: 160px;
overflow-y: auto;
}
.dsb-queue-list li {
margin-bottom: 4px;
}
.dsb-queue-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 4px;
}
.dsb-queue-save,
.dsb-queue-cancel {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.dsb-queue-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-queue-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-queue-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-queue-cancel {
background: transparent;
border: 1px solid var(--dsb-field-edge);
color: var(--dsb-ink-3);
}
.dsb-queue-cancel:hover {
border-color: var(--dsb-ink-3);
color: var(--dsb-ink);
}
.dsb-queue-status {
margin-top: 6px;
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-queue-status.dsb-status-ok { color: var(--dsb-ok); }
.dsb-queue-status.dsb-status-error { color: var(--dsb-danger); }
/* ── Minerva (mobile) ────────────────────────────────────────────────
Narrower viewport: keep the panel on screen and give every tap
target the form's 44px minimum. */
.skin-minerva .dsb-quick-row,
.skin-minerva .dsb-subsection-panel,
.skin-minerva .dsb-convert-pos-panel {
max-width: 100%;
}
@media (max-width: 720px), (pointer: coarse) {
/* Keep the glyph at 13px -- the asset is only 10px, so scaling it up just blurs it. Grow the tap target invisibly instead. */
.dsb-toggle {
position: relative;
}
.dsb-toggle::after {
content: "";
position: absolute;
inset: -10px;
}
.dsb-quick-row {
font-size: 13px;
margin-left: 20px;
}
.dsb-input,
.dsb-subsection-select,
.dsb-convert-pos-select {
min-height: 40px;
/* >=16px stops iOS Safari zooming the page on focus. */
font-size: 16px;
}
.dsb-mod-btn,
.dsb-word-remove,
.dsb-mod-confirm,
.dsb-mod-cancel {
width: 36px;
height: 36px;
font-size: 15px;
}
.dsb-mod-pill {
padding: 8px 12px;
}
.dsb-mod-val-input {
max-width: none;
}
.dsb-tagfield .dsb-input {
min-height: 32px;
}
.dsb-tag-remove {
padding: 0 6px;
}
.dsb-save,
.dsb-cancel,
.dsb-autolink,
.dsb-queue-save,
.dsb-queue-cancel {
min-height: 40px;
padding: 8px 16px;
}
.dsb-queue-box {
top: auto;
bottom: 8px;
right: 8px;
left: 8px;
width: auto;
}
}
/* ── Dark mode ───────────────────────────────────────────────────────
Same warm dark palette and same explicit-signal-only rule as the
form's stylesheet: no bare prefers-color-scheme fallback, since
legacy Vector sets no theme class and would go dark on its own. */
html.skin-theme-clientpref-night,
html.skin-nightmode {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-night .dsb-save,
html.skin-nightmode .dsb-save,
html.skin-theme-clientpref-night .dsb-queue-save,
html.skin-nightmode .dsb-queue-save {
color: #14213a;
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-os .dsb-save,
html.skin-theme-clientpref-os .dsb-queue-save {
color: #14213a;
}
}
d6q78brdytzrdwv6qrphl6eqg1v32y6
6347557
6347518
2026-09-01T09:59:49Z
Wikihez
7344
6347557
css
text/css
/* Gadget-DefSideBoxes.css
Skin-agnostic (vector, vector2022, minerva). Visual layer matches MediaWiki:Gadget-wiktku-start/styles.css
("SÊWIRANA NÛ"); those tokens are re-declared here under a --dsb-* prefix since they live on
#wiktku-start-form, which doesn't exist on an article page. */
:root {
--dsb-card: #fffdf8;
--dsb-card-sunken: #fbf8f1;
--dsb-rule: #ded6c8;
--dsb-rule-soft: #efe8db;
--dsb-card-edge: #e6dfd2;
--dsb-field-edge: #cfc7b8;
--dsb-field-bg: #fff;
--dsb-ink: #1c1a17;
--dsb-ink-2: #3d3830;
--dsb-ink-3: #57514a;
--dsb-muted: #8a8378;
--dsb-placeholder: #b3ab9e;
--dsb-accent: #2a5db0;
--dsb-accent-deep: #22406f;
--dsb-accent-tint: #eef2fa;
--dsb-accent-edge: #d5def0;
--dsb-ok: #3d8a55;
--dsb-danger: #9c3a28;
--dsb-r-field: 10px;
--dsb-r-card: 12px;
--dsb-r-pill: 999px;
--dsb-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--dsb-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── The pencil toggle on a definition ─────────────────────────────────
The classic MediaWiki interlanguage-links edit pencil (same asset as defEditButton), not a hand-drawn glyph.
Hidden by default like defEditButton: revealed by hovering the line on desktop, or by tapping it on touch
(.dsb-revealed, added by attachToolbar()'s own click handler) -- keeps the definition list uncluttered. */
/* position:absolute with top/left auto keeps the static position but drops the box out of flow; the negative margin then slides the pencil into the list gutter, in front of the marker (en.wikt's .defEditButton trick). */
.dsb-toolbar {
position: absolute;
margin-left: -40px;
width: 40px;
height: 26px;
font-family: var(--dsb-sans);
}
.dsb-toggle {
display: block;
margin-top: 8px; /* centres the 13px icon on the 26px line */
width: 13px;
height: 13px;
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d3/InterlanguageLinks-Asset-Pencil.gif);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
text-decoration: none;
cursor: pointer;
opacity: 0;
transition: opacity 0.15s ease;
}
.dsb-toggle:hover,
.dsb-toggle:focus {
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d1/InterlanguageLinks-Asset-Pencil-Hover.gif);
}
li:hover .dsb-toolbar .dsb-toggle,
.dsb-toggle:focus {
opacity: 1;
}
@media (hover: none), (pointer: coarse) {
.dsb-toolbar.dsb-revealed .dsb-toggle {
opacity: 1;
}
}
/* Same pencil on a "====" subsection heading: no list gutter to sit in, so it stays inline before the text. */
.dsb-toolbar-heading {
position: static;
display: inline-block;
width: auto;
height: auto;
margin-left: 0;
vertical-align: middle;
}
.dsb-toolbar-heading .dsb-toggle {
display: inline-block;
margin: 0 6px 0 0;
vertical-align: middle;
}
.mw-heading4:hover .dsb-toolbar-heading .dsb-toggle,
h4:hover .dsb-toolbar-heading .dsb-toggle,
.dsb-toolbar-heading.dsb-revealed .dsb-toggle {
opacity: 1;
}
/* ── "Guhartina pêşketî" (advanced editing) panel ──────────────────────
Revealed by the pencil toggle above: every per-sense action this gadget offers, queued together with one
"Lê zêde bike". A plain inline row, not a bordered/background card. */
.dsb-quick-row {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
box-sizing: border-box;
max-width: 520px;
margin: 4px 0 4px 26px;
font-family: var(--dsb-sans);
font-size: 12px;
color: var(--dsb-ink-2);
}
.dsb-quick-link {
align-self: flex-start;
margin-bottom: 10px;
color: var(--dsb-accent);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
}
.dsb-quick-link:hover,
.dsb-quick-link:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* The picker row: gloss + the two primary word groups as direct "+ <field>" links, plus a "Zêdetir" toggle
for the rest -- clicking a link opens its box below and hides the link; .dsb-box-remove un-hides it.
position: relative anchors .dsb-more-menu's overlay below (see there). */
.dsb-field-picker {
position: relative;
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-bottom: 10px;
}
.dsb-field-picker .dsb-quick-link {
margin-bottom: 0;
}
/* The "Zêdetir" dropdown: every non-primary field link (plus Nimûne/jêgirtin, which sits first) stacked as a
plain vertical list. Floats over the page as an overlay (positioned against .dsb-field-picker) instead of
pushing $openBoxes/the rest of the definition down when it opens. */
.dsb-more-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 10;
display: flex;
flex-direction: column;
align-items: flex-start;
width: max-content;
max-width: min(320px, calc(100vw - 40px));
gap: 6px;
margin: 2px 0 0 4px;
padding: 8px 12px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-field);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dsb-more-menu .dsb-quick-link {
margin-bottom: 0;
}
/* Boxes the user has actually opened, stacked in the order they were added -- several can be open at once. */
.dsb-open-boxes {
display: flex;
flex-direction: column;
}
/* One field (its label + input) within the panel -- always a currently-open, removable box. */
.dsb-adv-group {
position: relative;
margin-bottom: 14px;
padding-right: 20px;
}
.dsb-adv-label {
margin-bottom: 4px;
font-size: 12px;
font-weight: 600;
color: var(--dsb-ink-3);
}
.dsb-box-remove {
position: absolute;
top: 0;
right: 0;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-box-remove:hover,
.dsb-box-remove:focus {
color: var(--dsb-accent-deep);
}
.dsb-form-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.dsb-input {
box-sizing: border-box;
min-width: 16em;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-input::placeholder {
color: var(--dsb-placeholder);
opacity: 1;
}
.dsb-input:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
/* ── Plain tag field (Etîket, Kategorî) ────────────────────────────────
Plain type-and-commit tags with no suggestion panel; unlike Hevmane/Dijmane/etc., these carry no modifiers. */
.dsb-tagfield {
box-sizing: border-box;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
min-width: 16em;
padding: 4px 6px;
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-tagfield:focus-within {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
}
.dsb-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
padding: 3px 6px 3px 10px;
}
.dsb-tag-remove {
border: 0;
background: transparent;
color: var(--dsb-muted);
font-size: 13px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
}
.dsb-tag-remove:hover {
color: var(--dsb-danger);
}
.dsb-tagfield .dsb-input {
flex: 1 1 8em;
min-width: 8em;
border: 0;
padding: 3px 2px;
background: transparent;
box-shadow: none;
}
.dsb-tagfield .dsb-input:focus {
box-shadow: none;
}
/* ── Word list with modifier pills ───────────────────────────────────
Every word is its own always-visible row: a word box plus a "+" that attaches one of the 10 WORD_MODIFIERS
as a small pill shown above the box. A fresh empty row is appended once the current last one gets text. */
.dsb-wordlist {
margin: 0;
padding-left: 0;
list-style: none;
}
.dsb-word-li {
margin-bottom: 6px;
}
.dsb-word-li:last-child {
margin-bottom: 0;
}
.dsb-word-mods {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
}
.dsb-word-mod-chip {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 11.5px;
padding: 3px 4px 3px 10px;
cursor: pointer;
}
.dsb-word-mod-chip-remove {
border: 0;
background: transparent;
color: var(--dsb-accent-deep);
font-size: 12px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
opacity: 0.7;
}
.dsb-word-mod-chip-remove:hover {
color: var(--dsb-danger);
opacity: 1;
}
.dsb-word-box-row {
display: flex;
align-items: center;
gap: 6px;
}
.dsb-word-box-row .dsb-word-input {
flex: 1 1 auto;
min-width: 0;
}
.dsb-mod-btn,
.dsb-word-remove {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.dsb-mod-btn {
border: 1px solid var(--dsb-accent-edge);
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
}
.dsb-mod-btn:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-word-remove {
border: 1px solid var(--dsb-field-edge);
background: var(--dsb-field-bg);
color: var(--dsb-muted);
}
.dsb-word-remove:hover {
border-color: var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-mod-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
margin-top: 6px;
padding: 8px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-card);
box-shadow: none;
}
.dsb-mod-pill {
font-family: var(--dsb-sans);
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
white-space: nowrap;
padding: 5px 10px;
cursor: pointer;
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.dsb-mod-pill:hover {
border-color: var(--dsb-accent);
background: var(--dsb-accent);
color: #fff;
}
.dsb-mod-pill:disabled,
.dsb-mod-pill.dsb-mod-pill-used {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
cursor: not-allowed;
opacity: 0.7;
}
.dsb-mod-pill:disabled:hover,
.dsb-mod-pill.dsb-mod-pill-used:hover {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
}
.dsb-mod-val-wrap {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
margin-top: 6px;
}
.dsb-mod-val-input {
flex: 1 1 auto;
min-width: 0;
max-width: 16em;
}
.dsb-mod-confirm,
.dsb-mod-cancel {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
background: var(--dsb-accent-tint);
cursor: pointer;
}
.dsb-mod-confirm {
border: 1px solid var(--dsb-ok);
color: var(--dsb-ok);
}
.dsb-mod-cancel {
border: 1px solid var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-save,
.dsb-cancel,
.dsb-autolink {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
/* One filled pill per row — the same rule the form's footer follows. */
.dsb-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-cancel {
background: transparent;
border: 1px solid transparent;
color: var(--dsb-ink-3);
}
.dsb-cancel:hover {
border-color: var(--dsb-field-edge);
color: var(--dsb-ink);
}
/* An outline pill, distinct from both the filled .dsb-save and the plain-text .dsb-cancel -- a secondary
utility action, not the primary save nor a dismissal. */
.dsb-autolink {
background: transparent;
border: 1px solid var(--dsb-accent-edge);
color: var(--dsb-accent);
}
.dsb-autolink:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-autolink:disabled {
opacity: 0.55;
cursor: progress;
}
/* Status line. Color comes from .dsb-status-ok/.dsb-status-error (added by the .js on success/failure)
rather than an inline style, so these tokens (and dark mode) apply. */
.dsb-status {
font-family: var(--dsb-sans);
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-status-ok { color: var(--dsb-ok); }
.dsb-status-error { color: var(--dsb-danger); }
/* ── "+ Beşek lê zêde bike" ──────────────────────────────────────────
An accent-coloured action link, like the form's .wiktku-adv-toggle:
it opens something, so it is not muted grey. */
.dsb-add-subsection,
.dsb-convert-pos-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-family: var(--dsb-sans);
font-size: 14px;
font-weight: 500;
color: var(--dsb-accent);
text-decoration: none;
border-bottom: 0;
cursor: pointer;
}
.dsb-add-subsection:hover,
.dsb-add-subsection:focus,
.dsb-convert-pos-trigger:hover,
.dsb-convert-pos-trigger:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* ── Subsection panel ────────────────────────────────────────────────
A sunken card rather than a grey utility box; fields stack so the
picker and its input are not competing for one narrow row. */
.dsb-subsection-panel,
.dsb-convert-pos-panel {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
box-sizing: border-box;
max-width: 520px;
margin: 6px 0 14px;
padding: 14px 16px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card-sunken);
border: 1px solid var(--dsb-card-edge);
border-radius: var(--dsb-r-card);
}
.dsb-subsection-select,
.dsb-convert-pos-select {
box-sizing: border-box;
width: 100%;
max-width: 100%;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
}
.dsb-subsection-select:focus,
.dsb-convert-pos-select:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
.dsb-subsection-field {
min-width: 0;
}
.dsb-subsection-words,
.dsb-subsection-text {
box-sizing: border-box;
width: 100%;
min-width: 0;
}
.dsb-subsection-text {
line-height: 1.6;
resize: vertical;
}
/* ── Gloss field inside the advanced-editing panel ────────────────────
Same shape as .dsb-subsection-text. */
.dsb-edit-gloss {
width: 100%;
line-height: 1.6;
resize: vertical;
}
/* ── Live "not saved yet" previews ─────────────────────────────────────
Dropped into the rendered page at the change's own spot. Dashed edge + a small badge mark them as
pending, not real content; they disappear on "Betal bike" or once the real save lands. */
.dsb-preview-block,
.dsb-preview-inline {
margin: 8px 0;
padding: 8px 12px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-accent-tint);
border: 1px dashed var(--dsb-accent-edge);
border-radius: var(--dsb-r-field);
}
.dsb-preview-inline {
margin-left: 26px;
max-width: 520px;
}
.dsb-preview-heading {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-preview-badge {
display: inline-block;
margin-bottom: 6px;
padding: 1px 8px;
font-size: 11px;
font-weight: 500;
color: var(--dsb-accent-deep);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
}
.dsb-preview-badge-inline {
margin-left: 8px;
margin-bottom: 0;
vertical-align: middle;
}
.dsb-preview-list,
.dsb-preview-text {
margin: 0;
padding-left: 18px;
}
.dsb-preview-text {
padding-left: 0;
}
/* ── Floating save-queue widget ─────────────────────────────────────
This gadget's own small floating box. One "Lê zêde bike" click anywhere on the page adds a line here;
"Guhertinan qeyd bike" makes the one real save; "Betal bike" drops everything queued without touching the page. */
.dsb-queue-box {
position: fixed;
top: 60px;
right: 16px;
z-index: 1000;
box-sizing: border-box;
width: 280px;
max-width: calc(100vw - 32px);
max-height: calc(100vh - 90px);
overflow-y: auto;
padding: 12px 14px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent);
border-radius: var(--dsb-r-card);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.16);
}
.dsb-queue-title {
margin-right: 20px;
font-size: 13px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-queue-close {
float: right;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-queue-close:hover,
.dsb-queue-close:focus {
color: var(--dsb-accent-deep);
}
.dsb-queue-list {
margin: 8px 0;
padding-left: 18px;
max-height: 160px;
overflow-y: auto;
}
.dsb-queue-list li {
margin-bottom: 4px;
}
.dsb-queue-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 4px;
}
.dsb-queue-save,
.dsb-queue-cancel {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.dsb-queue-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-queue-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-queue-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-queue-cancel {
background: transparent;
border: 1px solid var(--dsb-field-edge);
color: var(--dsb-ink-3);
}
.dsb-queue-cancel:hover {
border-color: var(--dsb-ink-3);
color: var(--dsb-ink);
}
.dsb-queue-status {
margin-top: 6px;
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-queue-status.dsb-status-ok { color: var(--dsb-ok); }
.dsb-queue-status.dsb-status-error { color: var(--dsb-danger); }
/* ── Minerva (mobile) ────────────────────────────────────────────────
Narrower viewport: keep the panel on screen and give every tap
target the form's 44px minimum. */
.skin-minerva .dsb-quick-row,
.skin-minerva .dsb-subsection-panel,
.skin-minerva .dsb-convert-pos-panel {
max-width: 100%;
}
@media (max-width: 720px), (pointer: coarse) {
/* Keep the glyph at 13px -- the asset is only 10px, so scaling it up just blurs it. Grow the tap target invisibly instead. */
.dsb-toggle {
position: relative;
}
.dsb-toggle::after {
content: "";
position: absolute;
inset: -10px;
}
.dsb-quick-row {
font-size: 13px;
margin-left: 20px;
}
.dsb-input,
.dsb-subsection-select,
.dsb-convert-pos-select {
min-height: 40px;
/* >=16px stops iOS Safari zooming the page on focus. */
font-size: 16px;
}
.dsb-mod-btn,
.dsb-word-remove,
.dsb-mod-confirm,
.dsb-mod-cancel {
width: 36px;
height: 36px;
font-size: 15px;
}
.dsb-mod-pill {
padding: 8px 12px;
}
.dsb-mod-val-input {
max-width: none;
}
.dsb-tagfield .dsb-input {
min-height: 32px;
}
.dsb-tag-remove {
padding: 0 6px;
}
.dsb-save,
.dsb-cancel,
.dsb-autolink,
.dsb-queue-save,
.dsb-queue-cancel {
min-height: 40px;
padding: 8px 16px;
}
.dsb-queue-box {
top: auto;
bottom: 8px;
right: 8px;
left: 8px;
width: auto;
}
}
/* ── Dark mode ───────────────────────────────────────────────────────
Same warm dark palette and same explicit-signal-only rule as the
form's stylesheet: no bare prefers-color-scheme fallback, since
legacy Vector sets no theme class and would go dark on its own. */
html.skin-theme-clientpref-night,
html.skin-nightmode {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-night .dsb-save,
html.skin-nightmode .dsb-save,
html.skin-theme-clientpref-night .dsb-queue-save,
html.skin-nightmode .dsb-queue-save {
color: #14213a;
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-os .dsb-save,
html.skin-theme-clientpref-os .dsb-queue-save {
color: #14213a;
}
}
px0sfhig4pvs45h5xfz18c4s9ywp4bc
6347564
6347557
2026-09-01T10:13:37Z
Wikihez
7344
6347564
css
text/css
/* Gadget-DefSideBoxes.css
Skin-agnostic (vector, vector2022, minerva). Visual layer matches MediaWiki:Gadget-wiktku-start/styles.css
("SÊWIRANA NÛ"); those tokens are re-declared here under a --dsb-* prefix since they live on
#wiktku-start-form, which doesn't exist on an article page. */
:root {
--dsb-card: #fffdf8;
--dsb-card-sunken: #fbf8f1;
--dsb-rule: #ded6c8;
--dsb-rule-soft: #efe8db;
--dsb-card-edge: #e6dfd2;
--dsb-field-edge: #cfc7b8;
--dsb-field-bg: #fff;
--dsb-ink: #1c1a17;
--dsb-ink-2: #3d3830;
--dsb-ink-3: #57514a;
--dsb-muted: #8a8378;
--dsb-placeholder: #b3ab9e;
--dsb-accent: #2a5db0;
--dsb-accent-deep: #22406f;
--dsb-accent-tint: #eef2fa;
--dsb-accent-edge: #d5def0;
--dsb-ok: #3d8a55;
--dsb-danger: #9c3a28;
--dsb-r-field: 10px;
--dsb-r-card: 12px;
--dsb-r-pill: 999px;
--dsb-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--dsb-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── The pencil toggle on a definition ─────────────────────────────────
The classic MediaWiki interlanguage-links edit pencil (same asset as defEditButton), not a hand-drawn glyph.
Hidden by default like defEditButton: revealed by hovering the line on desktop, or by tapping it on touch
(.dsb-revealed, added by attachToolbar()'s own click handler) -- keeps the definition list uncluttered. */
/* position:absolute with top/left auto keeps the static position but drops the box out of flow; the negative margin then slides the pencil into the list gutter, in front of the marker (en.wikt's .defEditButton trick). */
.dsb-toolbar {
position: absolute;
margin-left: -40px;
width: 40px;
height: 26px;
font-family: var(--dsb-sans);
}
.dsb-toggle {
display: block;
margin-top: 8px; /* centres the 13px icon on the 26px line */
width: 13px;
height: 13px;
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d3/InterlanguageLinks-Asset-Pencil.gif);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
text-decoration: none;
cursor: pointer;
opacity: 0;
transition: opacity 0.15s ease;
}
.dsb-toggle:hover,
.dsb-toggle:focus {
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d1/InterlanguageLinks-Asset-Pencil-Hover.gif);
}
li:hover .dsb-toolbar .dsb-toggle,
.dsb-toggle:focus {
opacity: 1;
}
@media (hover: none), (pointer: coarse) {
.dsb-toolbar.dsb-revealed .dsb-toggle {
opacity: 1;
}
}
/* Same pencil on a "====" subsection heading: no list gutter to sit in, so it stays inline before the text. */
.dsb-toolbar-heading {
position: static;
display: inline-block;
width: auto;
height: auto;
margin-left: 0;
vertical-align: middle;
}
.dsb-toolbar-heading .dsb-toggle {
display: inline-block;
margin: 0 0 0 6px;
vertical-align: middle;
}
.mw-heading4:hover .dsb-toolbar-heading .dsb-toggle,
h4:hover .dsb-toolbar-heading .dsb-toggle,
.dsb-toolbar-heading.dsb-revealed .dsb-toggle {
opacity: 1;
}
/* ── "Guhartina pêşketî" (advanced editing) panel ──────────────────────
Revealed by the pencil toggle above: every per-sense action this gadget offers, queued together with one
"Lê zêde bike". A plain inline row, not a bordered/background card. */
.dsb-quick-row {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
box-sizing: border-box;
max-width: 520px;
margin: 4px 0 4px 26px;
font-family: var(--dsb-sans);
font-size: 12px;
color: var(--dsb-ink-2);
}
.dsb-quick-link {
align-self: flex-start;
margin-bottom: 10px;
color: var(--dsb-accent);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
}
.dsb-quick-link:hover,
.dsb-quick-link:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* The picker row: gloss + the two primary word groups as direct "+ <field>" links, plus a "Zêdetir" toggle
for the rest -- clicking a link opens its box below and hides the link; .dsb-box-remove un-hides it.
position: relative anchors .dsb-more-menu's overlay below (see there). */
.dsb-field-picker {
position: relative;
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-bottom: 10px;
}
.dsb-field-picker .dsb-quick-link {
margin-bottom: 0;
}
/* The "Zêdetir" dropdown: every non-primary field link (plus Nimûne/jêgirtin, which sits first) stacked as a
plain vertical list. Floats over the page as an overlay (positioned against .dsb-field-picker) instead of
pushing $openBoxes/the rest of the definition down when it opens. */
.dsb-more-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 10;
display: flex;
flex-direction: column;
align-items: flex-start;
width: max-content;
max-width: min(320px, calc(100vw - 40px));
gap: 6px;
margin: 2px 0 0 4px;
padding: 8px 12px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-field);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dsb-more-menu .dsb-quick-link {
margin-bottom: 0;
}
/* Boxes the user has actually opened, stacked in the order they were added -- several can be open at once. */
.dsb-open-boxes {
display: flex;
flex-direction: column;
}
/* One field (its label + input) within the panel -- always a currently-open, removable box. */
.dsb-adv-group {
position: relative;
margin-bottom: 14px;
padding-right: 20px;
}
.dsb-adv-label {
margin-bottom: 4px;
font-size: 12px;
font-weight: 600;
color: var(--dsb-ink-3);
}
.dsb-box-remove {
position: absolute;
top: 0;
right: 0;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-box-remove:hover,
.dsb-box-remove:focus {
color: var(--dsb-accent-deep);
}
.dsb-form-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.dsb-input {
box-sizing: border-box;
min-width: 16em;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-input::placeholder {
color: var(--dsb-placeholder);
opacity: 1;
}
.dsb-input:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
/* ── Plain tag field (Etîket, Kategorî) ────────────────────────────────
Plain type-and-commit tags with no suggestion panel; unlike Hevmane/Dijmane/etc., these carry no modifiers. */
.dsb-tagfield {
box-sizing: border-box;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
min-width: 16em;
padding: 4px 6px;
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-tagfield:focus-within {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
}
.dsb-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
padding: 3px 6px 3px 10px;
}
.dsb-tag-remove {
border: 0;
background: transparent;
color: var(--dsb-muted);
font-size: 13px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
}
.dsb-tag-remove:hover {
color: var(--dsb-danger);
}
.dsb-tagfield .dsb-input {
flex: 1 1 8em;
min-width: 8em;
border: 0;
padding: 3px 2px;
background: transparent;
box-shadow: none;
}
.dsb-tagfield .dsb-input:focus {
box-shadow: none;
}
/* ── Word list with modifier pills ───────────────────────────────────
Every word is its own always-visible row: a word box plus a "+" that attaches one of the 10 WORD_MODIFIERS
as a small pill shown above the box. A fresh empty row is appended once the current last one gets text. */
.dsb-wordlist {
margin: 0;
padding-left: 0;
list-style: none;
}
.dsb-word-li {
margin-bottom: 6px;
}
.dsb-word-li:last-child {
margin-bottom: 0;
}
.dsb-word-mods {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
}
.dsb-word-mod-chip {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 11.5px;
padding: 3px 4px 3px 10px;
cursor: pointer;
}
.dsb-word-mod-chip-remove {
border: 0;
background: transparent;
color: var(--dsb-accent-deep);
font-size: 12px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
opacity: 0.7;
}
.dsb-word-mod-chip-remove:hover {
color: var(--dsb-danger);
opacity: 1;
}
.dsb-word-box-row {
display: flex;
align-items: center;
gap: 6px;
}
.dsb-word-box-row .dsb-word-input {
flex: 1 1 auto;
min-width: 0;
}
.dsb-mod-btn,
.dsb-word-remove {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.dsb-mod-btn {
border: 1px solid var(--dsb-accent-edge);
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
}
.dsb-mod-btn:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-word-remove {
border: 1px solid var(--dsb-field-edge);
background: var(--dsb-field-bg);
color: var(--dsb-muted);
}
.dsb-word-remove:hover {
border-color: var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-mod-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
margin-top: 6px;
padding: 8px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-card);
box-shadow: none;
}
.dsb-mod-pill {
font-family: var(--dsb-sans);
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
white-space: nowrap;
padding: 5px 10px;
cursor: pointer;
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.dsb-mod-pill:hover {
border-color: var(--dsb-accent);
background: var(--dsb-accent);
color: #fff;
}
.dsb-mod-pill:disabled,
.dsb-mod-pill.dsb-mod-pill-used {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
cursor: not-allowed;
opacity: 0.7;
}
.dsb-mod-pill:disabled:hover,
.dsb-mod-pill.dsb-mod-pill-used:hover {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
}
.dsb-mod-val-wrap {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
margin-top: 6px;
}
.dsb-mod-val-input {
flex: 1 1 auto;
min-width: 0;
max-width: 16em;
}
.dsb-mod-confirm,
.dsb-mod-cancel {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
background: var(--dsb-accent-tint);
cursor: pointer;
}
.dsb-mod-confirm {
border: 1px solid var(--dsb-ok);
color: var(--dsb-ok);
}
.dsb-mod-cancel {
border: 1px solid var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-save,
.dsb-cancel,
.dsb-autolink {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
/* One filled pill per row — the same rule the form's footer follows. */
.dsb-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-cancel {
background: transparent;
border: 1px solid transparent;
color: var(--dsb-ink-3);
}
.dsb-cancel:hover {
border-color: var(--dsb-field-edge);
color: var(--dsb-ink);
}
/* An outline pill, distinct from both the filled .dsb-save and the plain-text .dsb-cancel -- a secondary
utility action, not the primary save nor a dismissal. */
.dsb-autolink {
background: transparent;
border: 1px solid var(--dsb-accent-edge);
color: var(--dsb-accent);
}
.dsb-autolink:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-autolink:disabled {
opacity: 0.55;
cursor: progress;
}
/* Status line. Color comes from .dsb-status-ok/.dsb-status-error (added by the .js on success/failure)
rather than an inline style, so these tokens (and dark mode) apply. */
.dsb-status {
font-family: var(--dsb-sans);
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-status-ok { color: var(--dsb-ok); }
.dsb-status-error { color: var(--dsb-danger); }
/* ── "+ Beşek lê zêde bike" ──────────────────────────────────────────
An accent-coloured action link, like the form's .wiktku-adv-toggle:
it opens something, so it is not muted grey. */
.dsb-add-subsection,
.dsb-convert-pos-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-family: var(--dsb-sans);
font-size: 14px;
font-weight: 500;
color: var(--dsb-accent);
text-decoration: none;
border-bottom: 0;
cursor: pointer;
}
.dsb-add-subsection:hover,
.dsb-add-subsection:focus,
.dsb-convert-pos-trigger:hover,
.dsb-convert-pos-trigger:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* ── Subsection panel ────────────────────────────────────────────────
A sunken card rather than a grey utility box; fields stack so the
picker and its input are not competing for one narrow row. */
.dsb-subsection-panel,
.dsb-convert-pos-panel {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
box-sizing: border-box;
max-width: 520px;
margin: 6px 0 14px;
padding: 14px 16px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card-sunken);
border: 1px solid var(--dsb-card-edge);
border-radius: var(--dsb-r-card);
}
.dsb-subsection-select,
.dsb-convert-pos-select {
box-sizing: border-box;
width: 100%;
max-width: 100%;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
}
.dsb-subsection-select:focus,
.dsb-convert-pos-select:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
.dsb-subsection-field {
min-width: 0;
}
.dsb-subsection-words,
.dsb-subsection-text {
box-sizing: border-box;
width: 100%;
min-width: 0;
}
.dsb-subsection-text {
line-height: 1.6;
resize: vertical;
}
/* ── Gloss field inside the advanced-editing panel ────────────────────
Same shape as .dsb-subsection-text. */
.dsb-edit-gloss {
width: 100%;
line-height: 1.6;
resize: vertical;
}
/* ── Live "not saved yet" previews ─────────────────────────────────────
Dropped into the rendered page at the change's own spot. Dashed edge + a small badge mark them as
pending, not real content; they disappear on "Betal bike" or once the real save lands. */
.dsb-preview-block,
.dsb-preview-inline {
margin: 8px 0;
padding: 8px 12px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-accent-tint);
border: 1px dashed var(--dsb-accent-edge);
border-radius: var(--dsb-r-field);
}
.dsb-preview-inline {
margin-left: 26px;
max-width: 520px;
}
.dsb-preview-heading {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-preview-badge {
display: inline-block;
margin-bottom: 6px;
padding: 1px 8px;
font-size: 11px;
font-weight: 500;
color: var(--dsb-accent-deep);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
}
.dsb-preview-badge-inline {
margin-left: 8px;
margin-bottom: 0;
vertical-align: middle;
}
.dsb-preview-list,
.dsb-preview-text {
margin: 0;
padding-left: 18px;
}
.dsb-preview-text {
padding-left: 0;
}
/* ── Floating save-queue widget ─────────────────────────────────────
This gadget's own small floating box. One "Lê zêde bike" click anywhere on the page adds a line here;
"Guhertinan qeyd bike" makes the one real save; "Betal bike" drops everything queued without touching the page. */
.dsb-queue-box {
position: fixed;
top: 60px;
right: 16px;
z-index: 1000;
box-sizing: border-box;
width: 280px;
max-width: calc(100vw - 32px);
max-height: calc(100vh - 90px);
overflow-y: auto;
padding: 12px 14px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent);
border-radius: var(--dsb-r-card);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.16);
}
.dsb-queue-title {
margin-right: 20px;
font-size: 13px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-queue-close {
float: right;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-queue-close:hover,
.dsb-queue-close:focus {
color: var(--dsb-accent-deep);
}
.dsb-queue-list {
margin: 8px 0;
padding-left: 18px;
max-height: 160px;
overflow-y: auto;
}
.dsb-queue-list li {
margin-bottom: 4px;
}
.dsb-queue-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 4px;
}
.dsb-queue-save,
.dsb-queue-cancel {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.dsb-queue-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-queue-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-queue-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-queue-cancel {
background: transparent;
border: 1px solid var(--dsb-field-edge);
color: var(--dsb-ink-3);
}
.dsb-queue-cancel:hover {
border-color: var(--dsb-ink-3);
color: var(--dsb-ink);
}
.dsb-queue-status {
margin-top: 6px;
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-queue-status.dsb-status-ok { color: var(--dsb-ok); }
.dsb-queue-status.dsb-status-error { color: var(--dsb-danger); }
/* ── Minerva (mobile) ────────────────────────────────────────────────
Narrower viewport: keep the panel on screen and give every tap
target the form's 44px minimum. */
.skin-minerva .dsb-quick-row,
.skin-minerva .dsb-subsection-panel,
.skin-minerva .dsb-convert-pos-panel {
max-width: 100%;
}
@media (max-width: 720px), (pointer: coarse) {
/* Keep the glyph at 13px -- the asset is only 10px, so scaling it up just blurs it. Grow the tap target invisibly instead. */
.dsb-toggle {
position: relative;
}
.dsb-toggle::after {
content: "";
position: absolute;
inset: -10px;
}
.dsb-quick-row {
font-size: 13px;
margin-left: 20px;
}
.dsb-input,
.dsb-subsection-select,
.dsb-convert-pos-select {
min-height: 40px;
/* >=16px stops iOS Safari zooming the page on focus. */
font-size: 16px;
}
.dsb-mod-btn,
.dsb-word-remove,
.dsb-mod-confirm,
.dsb-mod-cancel {
width: 36px;
height: 36px;
font-size: 15px;
}
.dsb-mod-pill {
padding: 8px 12px;
}
.dsb-mod-val-input {
max-width: none;
}
.dsb-tagfield .dsb-input {
min-height: 32px;
}
.dsb-tag-remove {
padding: 0 6px;
}
.dsb-save,
.dsb-cancel,
.dsb-autolink,
.dsb-queue-save,
.dsb-queue-cancel {
min-height: 40px;
padding: 8px 16px;
}
.dsb-queue-box {
top: auto;
bottom: 8px;
right: 8px;
left: 8px;
width: auto;
}
}
/* ── Dark mode ───────────────────────────────────────────────────────
Same warm dark palette and same explicit-signal-only rule as the
form's stylesheet: no bare prefers-color-scheme fallback, since
legacy Vector sets no theme class and would go dark on its own. */
html.skin-theme-clientpref-night,
html.skin-nightmode {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-night .dsb-save,
html.skin-nightmode .dsb-save,
html.skin-theme-clientpref-night .dsb-queue-save,
html.skin-nightmode .dsb-queue-save {
color: #14213a;
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-os .dsb-save,
html.skin-theme-clientpref-os .dsb-queue-save {
color: #14213a;
}
}
b4pul11yulqb3glzkcojbn5otqld6ze
6347583
6347564
2026-09-01T10:37:50Z
Wikihez
7344
6347583
css
text/css
/* Gadget-DefSideBoxes.css
Skin-agnostic (vector, vector2022, minerva). Visual layer matches MediaWiki:Gadget-wiktku-start/styles.css
("SÊWIRANA NÛ"); those tokens are re-declared here under a --dsb-* prefix since they live on
#wiktku-start-form, which doesn't exist on an article page. */
:root {
--dsb-card: #fffdf8;
--dsb-card-sunken: #fbf8f1;
--dsb-rule: #ded6c8;
--dsb-rule-soft: #efe8db;
--dsb-card-edge: #e6dfd2;
--dsb-field-edge: #cfc7b8;
--dsb-field-bg: #fff;
--dsb-ink: #1c1a17;
--dsb-ink-2: #3d3830;
--dsb-ink-3: #57514a;
--dsb-muted: #8a8378;
--dsb-placeholder: #b3ab9e;
--dsb-accent: #2a5db0;
--dsb-accent-deep: #22406f;
--dsb-accent-tint: #eef2fa;
--dsb-accent-edge: #d5def0;
--dsb-ok: #3d8a55;
--dsb-danger: #9c3a28;
--dsb-r-field: 10px;
--dsb-r-card: 12px;
--dsb-r-pill: 999px;
--dsb-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--dsb-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── The pencil toggle on a definition ─────────────────────────────────
The classic MediaWiki interlanguage-links edit pencil (same asset as defEditButton), not a hand-drawn glyph.
Hidden by default like defEditButton: revealed by hovering the line on desktop, or by tapping it on touch
(.dsb-revealed, added by attachToolbar()'s own click handler) -- keeps the definition list uncluttered. */
/* position:absolute with top/left auto keeps the static position but drops the box out of flow; the negative margin then slides the pencil into the list gutter, in front of the marker (en.wikt's .defEditButton trick). */
.dsb-toolbar {
position: absolute;
margin-left: -40px;
width: 40px;
height: 26px;
font-family: var(--dsb-sans);
}
.dsb-toggle {
display: block;
margin-top: 8px; /* centres the 13px icon on the 26px line */
width: 13px;
height: 13px;
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d3/InterlanguageLinks-Asset-Pencil.gif);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
text-decoration: none;
cursor: pointer;
opacity: 0;
transition: opacity 0.15s ease;
}
.dsb-toggle:hover,
.dsb-toggle:focus {
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d1/InterlanguageLinks-Asset-Pencil-Hover.gif);
}
li:hover .dsb-toolbar .dsb-toggle,
.dsb-toggle:focus {
opacity: 1;
}
@media (hover: none), (pointer: coarse) {
.dsb-toolbar.dsb-revealed .dsb-toggle {
opacity: 1;
}
}
/* The add-examples gadget's own inline trigger. The quick row's "Nimûne/jêgirtin lê zêde bike" drives it now,
un-hiding this <li> with an inline style before clicking it so the form's caption still appears. */
li:has(> .add-example-form-title) {
display: none;
}
/* Same pencil on a "====" subsection heading: no list gutter to sit in, so it stays inline before the text. */
.dsb-toolbar-heading {
position: static;
display: inline-block;
width: auto;
height: auto;
margin-left: 0;
vertical-align: middle;
}
.dsb-toolbar-heading .dsb-toggle {
display: inline-block;
margin: 0 0 0 6px;
vertical-align: middle;
}
.mw-heading4:hover .dsb-toolbar-heading .dsb-toggle,
h4:hover .dsb-toolbar-heading .dsb-toggle,
.dsb-toolbar-heading.dsb-revealed .dsb-toggle {
opacity: 1;
}
/* ── "Guhartina pêşketî" (advanced editing) panel ──────────────────────
Revealed by the pencil toggle above: every per-sense action this gadget offers, queued together with one
"Lê zêde bike". A plain inline row, not a bordered/background card. */
.dsb-quick-row {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
box-sizing: border-box;
max-width: 520px;
margin: 4px 0 4px 26px;
font-family: var(--dsb-sans);
font-size: 12px;
color: var(--dsb-ink-2);
}
.dsb-quick-link {
align-self: flex-start;
margin-bottom: 10px;
color: var(--dsb-accent);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
}
.dsb-quick-link:hover,
.dsb-quick-link:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* The picker row: gloss + the two primary word groups as direct "+ <field>" links, plus a "Zêdetir" toggle
for the rest -- clicking a link opens its box below and hides the link; .dsb-box-remove un-hides it.
position: relative anchors .dsb-more-menu's overlay below (see there). */
.dsb-field-picker {
position: relative;
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-bottom: 10px;
}
.dsb-field-picker .dsb-quick-link {
margin-bottom: 0;
}
/* The "Zêdetir" dropdown: every non-primary field link (plus Nimûne/jêgirtin, which sits first) stacked as a
plain vertical list. Floats over the page as an overlay (positioned against .dsb-field-picker) instead of
pushing $openBoxes/the rest of the definition down when it opens. */
.dsb-more-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 10;
display: flex;
flex-direction: column;
align-items: flex-start;
width: max-content;
max-width: min(320px, calc(100vw - 40px));
gap: 6px;
margin: 2px 0 0 4px;
padding: 8px 12px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-field);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dsb-more-menu .dsb-quick-link {
margin-bottom: 0;
}
/* Boxes the user has actually opened, stacked in the order they were added -- several can be open at once. */
.dsb-open-boxes {
display: flex;
flex-direction: column;
}
/* One field (its label + input) within the panel -- always a currently-open, removable box. */
.dsb-adv-group {
position: relative;
margin-bottom: 14px;
padding-right: 20px;
}
.dsb-adv-label {
margin-bottom: 4px;
font-size: 12px;
font-weight: 600;
color: var(--dsb-ink-3);
}
.dsb-box-remove {
position: absolute;
top: 0;
right: 0;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-box-remove:hover,
.dsb-box-remove:focus {
color: var(--dsb-accent-deep);
}
.dsb-form-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.dsb-input {
box-sizing: border-box;
min-width: 16em;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-input::placeholder {
color: var(--dsb-placeholder);
opacity: 1;
}
.dsb-input:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
/* ── Plain tag field (Etîket, Kategorî) ────────────────────────────────
Plain type-and-commit tags with no suggestion panel; unlike Hevmane/Dijmane/etc., these carry no modifiers. */
.dsb-tagfield {
box-sizing: border-box;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
min-width: 16em;
padding: 4px 6px;
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-tagfield:focus-within {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
}
.dsb-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
padding: 3px 6px 3px 10px;
}
.dsb-tag-remove {
border: 0;
background: transparent;
color: var(--dsb-muted);
font-size: 13px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
}
.dsb-tag-remove:hover {
color: var(--dsb-danger);
}
.dsb-tagfield .dsb-input {
flex: 1 1 8em;
min-width: 8em;
border: 0;
padding: 3px 2px;
background: transparent;
box-shadow: none;
}
.dsb-tagfield .dsb-input:focus {
box-shadow: none;
}
/* ── Word list with modifier pills ───────────────────────────────────
Every word is its own always-visible row: a word box plus a "+" that attaches one of the 10 WORD_MODIFIERS
as a small pill shown above the box. A fresh empty row is appended once the current last one gets text. */
.dsb-wordlist {
margin: 0;
padding-left: 0;
list-style: none;
}
.dsb-word-li {
margin-bottom: 6px;
}
.dsb-word-li:last-child {
margin-bottom: 0;
}
.dsb-word-mods {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
}
.dsb-word-mod-chip {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 11.5px;
padding: 3px 4px 3px 10px;
cursor: pointer;
}
.dsb-word-mod-chip-remove {
border: 0;
background: transparent;
color: var(--dsb-accent-deep);
font-size: 12px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
opacity: 0.7;
}
.dsb-word-mod-chip-remove:hover {
color: var(--dsb-danger);
opacity: 1;
}
.dsb-word-box-row {
display: flex;
align-items: center;
gap: 6px;
}
.dsb-word-box-row .dsb-word-input {
flex: 1 1 auto;
min-width: 0;
}
.dsb-mod-btn,
.dsb-word-remove {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.dsb-mod-btn {
border: 1px solid var(--dsb-accent-edge);
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
}
.dsb-mod-btn:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-word-remove {
border: 1px solid var(--dsb-field-edge);
background: var(--dsb-field-bg);
color: var(--dsb-muted);
}
.dsb-word-remove:hover {
border-color: var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-mod-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
margin-top: 6px;
padding: 8px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-card);
box-shadow: none;
}
.dsb-mod-pill {
font-family: var(--dsb-sans);
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
white-space: nowrap;
padding: 5px 10px;
cursor: pointer;
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.dsb-mod-pill:hover {
border-color: var(--dsb-accent);
background: var(--dsb-accent);
color: #fff;
}
.dsb-mod-pill:disabled,
.dsb-mod-pill.dsb-mod-pill-used {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
cursor: not-allowed;
opacity: 0.7;
}
.dsb-mod-pill:disabled:hover,
.dsb-mod-pill.dsb-mod-pill-used:hover {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
}
.dsb-mod-val-wrap {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
margin-top: 6px;
}
.dsb-mod-val-input {
flex: 1 1 auto;
min-width: 0;
max-width: 16em;
}
.dsb-mod-confirm,
.dsb-mod-cancel {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
background: var(--dsb-accent-tint);
cursor: pointer;
}
.dsb-mod-confirm {
border: 1px solid var(--dsb-ok);
color: var(--dsb-ok);
}
.dsb-mod-cancel {
border: 1px solid var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-save,
.dsb-cancel,
.dsb-autolink {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
/* One filled pill per row — the same rule the form's footer follows. */
.dsb-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-cancel {
background: transparent;
border: 1px solid transparent;
color: var(--dsb-ink-3);
}
.dsb-cancel:hover {
border-color: var(--dsb-field-edge);
color: var(--dsb-ink);
}
/* An outline pill, distinct from both the filled .dsb-save and the plain-text .dsb-cancel -- a secondary
utility action, not the primary save nor a dismissal. */
.dsb-autolink {
background: transparent;
border: 1px solid var(--dsb-accent-edge);
color: var(--dsb-accent);
}
.dsb-autolink:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-autolink:disabled {
opacity: 0.55;
cursor: progress;
}
/* Status line. Color comes from .dsb-status-ok/.dsb-status-error (added by the .js on success/failure)
rather than an inline style, so these tokens (and dark mode) apply. */
.dsb-status {
font-family: var(--dsb-sans);
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-status-ok { color: var(--dsb-ok); }
.dsb-status-error { color: var(--dsb-danger); }
/* ── "+ Beşek lê zêde bike" ──────────────────────────────────────────
An accent-coloured action link, like the form's .wiktku-adv-toggle:
it opens something, so it is not muted grey. */
.dsb-add-subsection,
.dsb-convert-pos-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-family: var(--dsb-sans);
font-size: 14px;
font-weight: 500;
color: var(--dsb-accent);
text-decoration: none;
border-bottom: 0;
cursor: pointer;
}
.dsb-add-subsection:hover,
.dsb-add-subsection:focus,
.dsb-convert-pos-trigger:hover,
.dsb-convert-pos-trigger:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* ── Subsection panel ────────────────────────────────────────────────
A sunken card rather than a grey utility box; fields stack so the
picker and its input are not competing for one narrow row. */
.dsb-subsection-panel,
.dsb-convert-pos-panel {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
box-sizing: border-box;
max-width: 520px;
margin: 6px 0 14px;
padding: 14px 16px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card-sunken);
border: 1px solid var(--dsb-card-edge);
border-radius: var(--dsb-r-card);
}
.dsb-subsection-select,
.dsb-convert-pos-select {
box-sizing: border-box;
width: 100%;
max-width: 100%;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
}
.dsb-subsection-select:focus,
.dsb-convert-pos-select:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
.dsb-subsection-field {
min-width: 0;
}
.dsb-subsection-words,
.dsb-subsection-text {
box-sizing: border-box;
width: 100%;
min-width: 0;
}
.dsb-subsection-text {
line-height: 1.6;
resize: vertical;
}
/* ── Gloss field inside the advanced-editing panel ────────────────────
Same shape as .dsb-subsection-text. */
.dsb-edit-gloss {
width: 100%;
line-height: 1.6;
resize: vertical;
}
/* ── Live "not saved yet" previews ─────────────────────────────────────
Dropped into the rendered page at the change's own spot. Dashed edge + a small badge mark them as
pending, not real content; they disappear on "Betal bike" or once the real save lands. */
.dsb-preview-block,
.dsb-preview-inline {
margin: 8px 0;
padding: 8px 12px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-accent-tint);
border: 1px dashed var(--dsb-accent-edge);
border-radius: var(--dsb-r-field);
}
.dsb-preview-inline {
margin-left: 26px;
max-width: 520px;
}
.dsb-preview-heading {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-preview-badge {
display: inline-block;
margin-bottom: 6px;
padding: 1px 8px;
font-size: 11px;
font-weight: 500;
color: var(--dsb-accent-deep);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
}
.dsb-preview-badge-inline {
margin-left: 8px;
margin-bottom: 0;
vertical-align: middle;
}
.dsb-preview-list,
.dsb-preview-text {
margin: 0;
padding-left: 18px;
}
.dsb-preview-text {
padding-left: 0;
}
/* ── Floating save-queue widget ─────────────────────────────────────
This gadget's own small floating box. One "Lê zêde bike" click anywhere on the page adds a line here;
"Guhertinan qeyd bike" makes the one real save; "Betal bike" drops everything queued without touching the page. */
.dsb-queue-box {
position: fixed;
top: 60px;
right: 16px;
z-index: 1000;
box-sizing: border-box;
width: 280px;
max-width: calc(100vw - 32px);
max-height: calc(100vh - 90px);
overflow-y: auto;
padding: 12px 14px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent);
border-radius: var(--dsb-r-card);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.16);
}
.dsb-queue-title {
margin-right: 20px;
font-size: 13px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-queue-close {
float: right;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-queue-close:hover,
.dsb-queue-close:focus {
color: var(--dsb-accent-deep);
}
.dsb-queue-list {
margin: 8px 0;
padding-left: 18px;
max-height: 160px;
overflow-y: auto;
}
.dsb-queue-list li {
margin-bottom: 4px;
}
.dsb-queue-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 4px;
}
.dsb-queue-save,
.dsb-queue-cancel {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.dsb-queue-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-queue-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-queue-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-queue-cancel {
background: transparent;
border: 1px solid var(--dsb-field-edge);
color: var(--dsb-ink-3);
}
.dsb-queue-cancel:hover {
border-color: var(--dsb-ink-3);
color: var(--dsb-ink);
}
.dsb-queue-status {
margin-top: 6px;
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-queue-status.dsb-status-ok { color: var(--dsb-ok); }
.dsb-queue-status.dsb-status-error { color: var(--dsb-danger); }
/* ── Minerva (mobile) ────────────────────────────────────────────────
Narrower viewport: keep the panel on screen and give every tap
target the form's 44px minimum. */
.skin-minerva .dsb-quick-row,
.skin-minerva .dsb-subsection-panel,
.skin-minerva .dsb-convert-pos-panel {
max-width: 100%;
}
@media (max-width: 720px), (pointer: coarse) {
/* Keep the glyph at 13px -- the asset is only 10px, so scaling it up just blurs it. Grow the tap target invisibly instead. */
.dsb-toggle {
position: relative;
}
.dsb-toggle::after {
content: "";
position: absolute;
inset: -10px;
}
.dsb-quick-row {
font-size: 13px;
margin-left: 20px;
}
.dsb-input,
.dsb-subsection-select,
.dsb-convert-pos-select {
min-height: 40px;
/* >=16px stops iOS Safari zooming the page on focus. */
font-size: 16px;
}
.dsb-mod-btn,
.dsb-word-remove,
.dsb-mod-confirm,
.dsb-mod-cancel {
width: 36px;
height: 36px;
font-size: 15px;
}
.dsb-mod-pill {
padding: 8px 12px;
}
.dsb-mod-val-input {
max-width: none;
}
.dsb-tagfield .dsb-input {
min-height: 32px;
}
.dsb-tag-remove {
padding: 0 6px;
}
.dsb-save,
.dsb-cancel,
.dsb-autolink,
.dsb-queue-save,
.dsb-queue-cancel {
min-height: 40px;
padding: 8px 16px;
}
.dsb-queue-box {
top: auto;
bottom: 8px;
right: 8px;
left: 8px;
width: auto;
}
}
/* ── Dark mode ───────────────────────────────────────────────────────
Same warm dark palette and same explicit-signal-only rule as the
form's stylesheet: no bare prefers-color-scheme fallback, since
legacy Vector sets no theme class and would go dark on its own. */
html.skin-theme-clientpref-night,
html.skin-nightmode {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-night .dsb-save,
html.skin-nightmode .dsb-save,
html.skin-theme-clientpref-night .dsb-queue-save,
html.skin-nightmode .dsb-queue-save {
color: #14213a;
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-os .dsb-save,
html.skin-theme-clientpref-os .dsb-queue-save {
color: #14213a;
}
}
7yh79rz4cxz8k1jwp79jzw32zu5w2m4
6347590
6347583
2026-09-01T10:55:36Z
Wikihez
7344
6347590
css
text/css
/* Gadget-DefSideBoxes.css
Skin-agnostic (vector, vector2022, minerva). Visual layer matches MediaWiki:Gadget-wiktku-start/styles.css
("SÊWIRANA NÛ"); those tokens are re-declared here under a --dsb-* prefix since they live on
#wiktku-start-form, which doesn't exist on an article page. */
:root {
--dsb-card: #fffdf8;
--dsb-card-sunken: #fbf8f1;
--dsb-rule: #ded6c8;
--dsb-rule-soft: #efe8db;
--dsb-card-edge: #e6dfd2;
--dsb-field-edge: #cfc7b8;
--dsb-field-bg: #fff;
--dsb-ink: #1c1a17;
--dsb-ink-2: #3d3830;
--dsb-ink-3: #57514a;
--dsb-muted: #8a8378;
--dsb-placeholder: #b3ab9e;
--dsb-accent: #2a5db0;
--dsb-accent-deep: #22406f;
--dsb-accent-tint: #eef2fa;
--dsb-accent-edge: #d5def0;
--dsb-ok: #3d8a55;
--dsb-danger: #9c3a28;
--dsb-r-field: 10px;
--dsb-r-card: 12px;
--dsb-r-pill: 999px;
--dsb-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--dsb-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── The pencil toggle on a definition ─────────────────────────────────
The classic MediaWiki interlanguage-links edit pencil (same asset as defEditButton), not a hand-drawn glyph.
Hidden by default like defEditButton: revealed by hovering the line on desktop, or by tapping it on touch
(.dsb-revealed, added by attachToolbar()'s own click handler) -- keeps the definition list uncluttered. */
/* position:absolute with top/left auto keeps the static position but drops the box out of flow; the negative margin then slides the pencil into the list gutter, in front of the marker (en.wikt's .defEditButton trick). */
.dsb-toolbar {
position: absolute;
margin-left: -40px;
width: 40px;
height: 26px;
font-family: var(--dsb-sans);
}
.dsb-toggle {
display: block;
margin-top: 8px; /* centres the 13px icon on the 26px line */
width: 13px;
height: 13px;
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d3/InterlanguageLinks-Asset-Pencil.gif);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
text-decoration: none;
cursor: pointer;
opacity: 0;
transition: opacity 0.15s ease;
}
.dsb-toggle:hover,
.dsb-toggle:focus {
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d1/InterlanguageLinks-Asset-Pencil-Hover.gif);
}
li:hover .dsb-toolbar .dsb-toggle,
.dsb-toggle:focus {
opacity: 1;
}
@media (hover: none), (pointer: coarse) {
.dsb-toolbar.dsb-revealed .dsb-toggle {
opacity: 1;
}
}
/* The add-examples gadget's own inline trigger. The quick row's "Nimûne/jêgirtin lê zêde bike" drives it now,
un-hiding this <li> with an inline style before clicking it so the form's caption still appears. */
li:has(> .add-example-form-title) {
display: none;
}
/* Same pencil on a "====" subsection heading: no list gutter to sit in, so it stays inline before the text. */
.dsb-toolbar-heading {
position: static;
display: inline-block;
width: auto;
height: auto;
margin-left: 0;
vertical-align: middle;
}
.dsb-toolbar-heading .dsb-toggle {
display: inline-block;
margin: 0 0 0 6px;
vertical-align: middle;
}
.mw-heading4:hover .dsb-toolbar-heading .dsb-toggle,
h4:hover .dsb-toolbar-heading .dsb-toggle,
.dsb-toolbar-heading.dsb-revealed .dsb-toggle {
opacity: 1;
}
/* ── "Guhartina pêşketî" (advanced editing) panel ──────────────────────
Revealed by the pencil toggle above: every per-sense action this gadget offers, queued together with one
"Lê zêde bike". A plain inline row, not a bordered/background card. */
.dsb-quick-row {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
box-sizing: border-box;
max-width: 520px;
margin: 4px 0 4px 26px;
font-family: var(--dsb-sans);
font-size: 12px;
color: var(--dsb-ink-2);
}
.dsb-quick-link {
align-self: flex-start;
margin-bottom: 10px;
color: var(--dsb-accent);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
}
.dsb-quick-link:hover,
.dsb-quick-link:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* The picker row: gloss + the two primary word groups as direct "+ <field>" links, plus a "Zêdetir" toggle
for the rest -- clicking a link opens its box below and hides the link; .dsb-box-remove un-hides it.
position: relative anchors .dsb-more-menu's overlay below (see there). */
.dsb-field-picker {
position: relative;
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-bottom: 10px;
}
.dsb-field-picker .dsb-quick-link {
margin-bottom: 0;
}
/* The "Zêdetir" dropdown: every non-primary field link (plus Nimûne/jêgirtin, which sits first) stacked as a
plain vertical list. Floats over the page as an overlay (positioned against .dsb-field-picker) instead of
pushing $openBoxes/the rest of the definition down when it opens. */
.dsb-more-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 10;
display: flex;
flex-direction: column;
align-items: flex-start;
width: max-content;
max-width: min(320px, calc(100vw - 40px));
gap: 6px;
margin: 2px 0 0 4px;
padding: 8px 12px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-field);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dsb-more-menu .dsb-quick-link {
margin-bottom: 0;
}
/* Boxes the user has actually opened, stacked in the order they were added -- several can be open at once. */
.dsb-open-boxes {
display: flex;
flex-direction: column;
}
/* One field (its label + input) within the panel -- always a currently-open, removable box. */
.dsb-adv-group {
position: relative;
margin-bottom: 14px;
padding-right: 20px;
}
.dsb-adv-label {
margin-bottom: 4px;
font-size: 12px;
font-weight: 600;
color: var(--dsb-ink-3);
}
.dsb-box-remove {
position: absolute;
top: 0;
right: 0;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-box-remove:hover,
.dsb-box-remove:focus {
color: var(--dsb-accent-deep);
}
.dsb-form-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.dsb-input {
box-sizing: border-box;
min-width: 16em;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-input::placeholder {
color: var(--dsb-placeholder);
opacity: 1;
}
.dsb-input:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
/* ── Plain tag field (Etîket, Kategorî) ────────────────────────────────
Plain type-and-commit tags with no suggestion panel; unlike Hevmane/Dijmane/etc., these carry no modifiers. */
.dsb-tagfield {
box-sizing: border-box;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
min-width: 16em;
padding: 4px 6px;
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-tagfield:focus-within {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
}
.dsb-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
padding: 3px 6px 3px 10px;
}
.dsb-tag-remove {
border: 0;
background: transparent;
color: var(--dsb-muted);
font-size: 13px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
}
.dsb-tag-remove:hover {
color: var(--dsb-danger);
}
.dsb-tagfield .dsb-input {
flex: 1 1 8em;
min-width: 8em;
border: 0;
padding: 3px 2px;
background: transparent;
box-shadow: none;
}
.dsb-tagfield .dsb-input:focus {
box-shadow: none;
}
/* ── Word list with modifier pills ───────────────────────────────────
Every word is its own always-visible row: a word box plus a "+" that attaches one of the 10 WORD_MODIFIERS
as a small pill shown above the box. A fresh empty row is appended once the current last one gets text. */
.dsb-wordlist {
margin: 0;
padding-left: 0;
list-style: none;
}
.dsb-word-li {
margin-bottom: 6px;
}
.dsb-word-li:last-child {
margin-bottom: 0;
}
.dsb-word-mods {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
}
.dsb-word-mod-chip {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 11.5px;
padding: 3px 4px 3px 10px;
cursor: pointer;
}
.dsb-word-mod-chip-remove {
border: 0;
background: transparent;
color: var(--dsb-accent-deep);
font-size: 12px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
opacity: 0.7;
}
.dsb-word-mod-chip-remove:hover {
color: var(--dsb-danger);
opacity: 1;
}
.dsb-word-box-row {
display: flex;
align-items: center;
gap: 6px;
}
.dsb-word-box-row .dsb-word-input {
flex: 1 1 auto;
min-width: 0;
}
.dsb-mod-btn,
.dsb-word-remove {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.dsb-mod-btn {
border: 1px solid var(--dsb-accent-edge);
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
}
.dsb-mod-btn:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-word-remove {
border: 1px solid var(--dsb-field-edge);
background: var(--dsb-field-bg);
color: var(--dsb-muted);
}
.dsb-word-remove:hover {
border-color: var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-mod-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
margin-top: 6px;
padding: 8px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-card);
box-shadow: none;
}
.dsb-mod-pill {
font-family: var(--dsb-sans);
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
white-space: nowrap;
padding: 5px 10px;
cursor: pointer;
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.dsb-mod-pill:hover {
border-color: var(--dsb-accent);
background: var(--dsb-accent);
color: #fff;
}
.dsb-mod-pill:disabled,
.dsb-mod-pill.dsb-mod-pill-used {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
cursor: not-allowed;
opacity: 0.7;
}
.dsb-mod-pill:disabled:hover,
.dsb-mod-pill.dsb-mod-pill-used:hover {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
}
.dsb-mod-val-wrap {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
margin-top: 6px;
}
.dsb-mod-val-input {
flex: 1 1 auto;
min-width: 0;
max-width: 16em;
}
.dsb-mod-confirm,
.dsb-mod-cancel {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
background: var(--dsb-accent-tint);
cursor: pointer;
}
.dsb-mod-confirm {
border: 1px solid var(--dsb-ok);
color: var(--dsb-ok);
}
.dsb-mod-cancel {
border: 1px solid var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-save,
.dsb-cancel,
.dsb-autolink {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
/* One filled pill per row — the same rule the form's footer follows. */
.dsb-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-cancel {
background: transparent;
border: 1px solid transparent;
color: var(--dsb-ink-3);
}
.dsb-cancel:hover {
border-color: var(--dsb-field-edge);
color: var(--dsb-ink);
}
/* An outline pill, distinct from both the filled .dsb-save and the plain-text .dsb-cancel -- a secondary
utility action, not the primary save nor a dismissal. */
.dsb-autolink {
background: transparent;
border: 1px solid var(--dsb-accent-edge);
color: var(--dsb-accent);
}
.dsb-autolink:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-autolink:disabled {
opacity: 0.55;
cursor: progress;
}
/* Status line. Color comes from .dsb-status-ok/.dsb-status-error (added by the .js on success/failure)
rather than an inline style, so these tokens (and dark mode) apply. */
.dsb-status {
font-family: var(--dsb-sans);
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-status-ok { color: var(--dsb-ok); }
.dsb-status-error { color: var(--dsb-danger); }
/* ── "+ Beşek lê zêde bike" ──────────────────────────────────────────
An accent-coloured action link, like the form's .wiktku-adv-toggle:
it opens something, so it is not muted grey. */
/* Matched to the add-examples gadget's own "Nimûneyeke bikaranînê lê zêde bike" link: a quiet subtle-grey
secondary action at the page's own font and size, not an accent-coloured one. Deliberately no --dsb-sans,
so it inherits the page font the way that link does. */
.dsb-add-subsection,
.dsb-convert-pos-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-size: inherit;
font-weight: 400;
color: var( --color-subtle, #54595d );
text-decoration: none;
border-bottom: 0;
cursor: pointer;
}
.dsb-add-subsection:hover,
.dsb-add-subsection:focus,
.dsb-convert-pos-trigger:hover,
.dsb-convert-pos-trigger:focus {
color: var( --color-base, #202122 );
text-decoration: underline;
}
/* ── Subsection panel ────────────────────────────────────────────────
A sunken card rather than a grey utility box; fields stack so the
picker and its input are not competing for one narrow row. */
.dsb-subsection-panel,
.dsb-convert-pos-panel {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
box-sizing: border-box;
max-width: 520px;
margin: 6px 0 14px;
padding: 14px 16px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card-sunken);
border: 1px solid var(--dsb-card-edge);
border-radius: var(--dsb-r-card);
}
.dsb-subsection-select,
.dsb-convert-pos-select {
box-sizing: border-box;
width: 100%;
max-width: 100%;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
}
.dsb-subsection-select:focus,
.dsb-convert-pos-select:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
.dsb-subsection-field {
min-width: 0;
}
.dsb-subsection-words,
.dsb-subsection-text {
box-sizing: border-box;
width: 100%;
min-width: 0;
}
.dsb-subsection-text {
line-height: 1.6;
resize: vertical;
}
/* ── Gloss field inside the advanced-editing panel ────────────────────
Same shape as .dsb-subsection-text. */
.dsb-edit-gloss {
width: 100%;
line-height: 1.6;
resize: vertical;
}
/* ── Live "not saved yet" previews ─────────────────────────────────────
Dropped into the rendered page at the change's own spot. Dashed edge + a small badge mark them as
pending, not real content; they disappear on "Betal bike" or once the real save lands. */
.dsb-preview-block,
.dsb-preview-inline {
margin: 8px 0;
padding: 8px 12px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-accent-tint);
border: 1px dashed var(--dsb-accent-edge);
border-radius: var(--dsb-r-field);
}
.dsb-preview-inline {
margin-left: 26px;
max-width: 520px;
}
.dsb-preview-heading {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-preview-badge {
display: inline-block;
margin-bottom: 6px;
padding: 1px 8px;
font-size: 11px;
font-weight: 500;
color: var(--dsb-accent-deep);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
}
.dsb-preview-badge-inline {
margin-left: 8px;
margin-bottom: 0;
vertical-align: middle;
}
.dsb-preview-list,
.dsb-preview-text {
margin: 0;
padding-left: 18px;
}
.dsb-preview-text {
padding-left: 0;
}
/* ── Floating save-queue widget ─────────────────────────────────────
This gadget's own small floating box. One "Lê zêde bike" click anywhere on the page adds a line here;
"Guhertinan qeyd bike" makes the one real save; "Betal bike" drops everything queued without touching the page. */
.dsb-queue-box {
position: fixed;
top: 60px;
right: 16px;
z-index: 1000;
box-sizing: border-box;
width: 280px;
max-width: calc(100vw - 32px);
max-height: calc(100vh - 90px);
overflow-y: auto;
padding: 12px 14px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent);
border-radius: var(--dsb-r-card);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.16);
}
.dsb-queue-title {
margin-right: 20px;
font-size: 13px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-queue-close {
float: right;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-queue-close:hover,
.dsb-queue-close:focus {
color: var(--dsb-accent-deep);
}
.dsb-queue-list {
margin: 8px 0;
padding-left: 18px;
max-height: 160px;
overflow-y: auto;
}
.dsb-queue-list li {
margin-bottom: 4px;
}
.dsb-queue-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 4px;
}
.dsb-queue-save,
.dsb-queue-cancel {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.dsb-queue-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-queue-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-queue-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-queue-cancel {
background: transparent;
border: 1px solid var(--dsb-field-edge);
color: var(--dsb-ink-3);
}
.dsb-queue-cancel:hover {
border-color: var(--dsb-ink-3);
color: var(--dsb-ink);
}
.dsb-queue-status {
margin-top: 6px;
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-queue-status.dsb-status-ok { color: var(--dsb-ok); }
.dsb-queue-status.dsb-status-error { color: var(--dsb-danger); }
/* ── Minerva (mobile) ────────────────────────────────────────────────
Narrower viewport: keep the panel on screen and give every tap
target the form's 44px minimum. */
.skin-minerva .dsb-quick-row,
.skin-minerva .dsb-subsection-panel,
.skin-minerva .dsb-convert-pos-panel {
max-width: 100%;
}
@media (max-width: 720px), (pointer: coarse) {
/* Keep the glyph at 13px -- the asset is only 10px, so scaling it up just blurs it. Grow the tap target invisibly instead. */
.dsb-toggle {
position: relative;
}
.dsb-toggle::after {
content: "";
position: absolute;
inset: -10px;
}
.dsb-quick-row {
font-size: 13px;
margin-left: 20px;
}
.dsb-input,
.dsb-subsection-select,
.dsb-convert-pos-select {
min-height: 40px;
/* >=16px stops iOS Safari zooming the page on focus. */
font-size: 16px;
}
.dsb-mod-btn,
.dsb-word-remove,
.dsb-mod-confirm,
.dsb-mod-cancel {
width: 36px;
height: 36px;
font-size: 15px;
}
.dsb-mod-pill {
padding: 8px 12px;
}
.dsb-mod-val-input {
max-width: none;
}
.dsb-tagfield .dsb-input {
min-height: 32px;
}
.dsb-tag-remove {
padding: 0 6px;
}
.dsb-save,
.dsb-cancel,
.dsb-autolink,
.dsb-queue-save,
.dsb-queue-cancel {
min-height: 40px;
padding: 8px 16px;
}
.dsb-queue-box {
top: auto;
bottom: 8px;
right: 8px;
left: 8px;
width: auto;
}
}
/* ── Dark mode ───────────────────────────────────────────────────────
Same warm dark palette and same explicit-signal-only rule as the
form's stylesheet: no bare prefers-color-scheme fallback, since
legacy Vector sets no theme class and would go dark on its own. */
html.skin-theme-clientpref-night,
html.skin-nightmode {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-night .dsb-save,
html.skin-nightmode .dsb-save,
html.skin-theme-clientpref-night .dsb-queue-save,
html.skin-nightmode .dsb-queue-save {
color: #14213a;
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-os .dsb-save,
html.skin-theme-clientpref-os .dsb-queue-save {
color: #14213a;
}
}
pvy8ba5wxazrelhosbu0jc28xgyfm51
6347609
6347590
2026-09-01T11:24:02Z
Wikihez
7344
6347609
css
text/css
/* Gadget-DefSideBoxes.css
Skin-agnostic (vector, vector2022, minerva). Visual layer matches MediaWiki:Gadget-wiktku-start/styles.css
("SÊWIRANA NÛ"); those tokens are re-declared here under a --dsb-* prefix since they live on
#wiktku-start-form, which doesn't exist on an article page. */
:root {
--dsb-card: #fffdf8;
--dsb-card-sunken: #fbf8f1;
--dsb-rule: #ded6c8;
--dsb-rule-soft: #efe8db;
--dsb-card-edge: #e6dfd2;
--dsb-field-edge: #cfc7b8;
--dsb-field-bg: #fff;
--dsb-ink: #1c1a17;
--dsb-ink-2: #3d3830;
--dsb-ink-3: #57514a;
--dsb-muted: #8a8378;
--dsb-placeholder: #b3ab9e;
--dsb-accent: #2a5db0;
--dsb-accent-deep: #22406f;
--dsb-accent-tint: #eef2fa;
--dsb-accent-edge: #d5def0;
--dsb-ok: #3d8a55;
--dsb-danger: #9c3a28;
--dsb-r-field: 10px;
--dsb-r-card: 12px;
--dsb-r-pill: 999px;
--dsb-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--dsb-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* ── The pencil toggle on a definition ─────────────────────────────────
The classic MediaWiki interlanguage-links edit pencil (same asset as defEditButton), not a hand-drawn glyph.
Hidden by default like defEditButton: revealed by hovering the line on desktop, or by tapping it on touch
(.dsb-revealed, added by attachToolbar()'s own click handler) -- keeps the definition list uncluttered. */
/* position:absolute with top/left auto keeps the static position but drops the box out of flow; the negative margin then slides the pencil into the list gutter, in front of the marker (en.wikt's .defEditButton trick). */
.dsb-toolbar {
position: absolute;
margin-left: -40px;
width: 40px;
height: 26px;
font-family: var(--dsb-sans);
}
.dsb-toggle {
display: block;
margin-top: 8px; /* centres the 13px icon on the 26px line */
width: 13px;
height: 13px;
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d3/InterlanguageLinks-Asset-Pencil.gif);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
text-decoration: none;
cursor: pointer;
opacity: 0;
transition: opacity 0.15s ease;
}
.dsb-toggle:hover,
.dsb-toggle:focus {
background-image: url(//upload.wikimedia.org/wikipedia/commons/d/d1/InterlanguageLinks-Asset-Pencil-Hover.gif);
}
li:hover .dsb-toolbar .dsb-toggle,
.dsb-toggle:focus {
opacity: 1;
}
@media (hover: none), (pointer: coarse) {
.dsb-toolbar.dsb-revealed .dsb-toggle {
opacity: 1;
}
}
/* The add-examples gadget's own inline trigger. The quick row's "Nimûne/jêgirtin lê zêde bike" drives it now,
un-hiding this <li> with an inline style before clicking it so the form's caption still appears. */
li:has(> .add-example-form-title) {
display: none;
}
/* The POS panel's follow-up questions (cinsiyet / lektur): label above its select, like the field boxes. */
.dsb-pos-param-row {
display: flex;
flex-direction: column;
gap: 4px;
margin-top: 8px;
}
/* Same pencil on a "====" subsection heading: no list gutter to sit in, so it stays inline before the text. */
.dsb-toolbar-heading {
position: static;
display: inline-block;
width: auto;
height: auto;
margin-left: 0;
vertical-align: middle;
}
.dsb-toolbar-heading .dsb-toggle {
display: inline-block;
margin: 0 0 0 6px;
vertical-align: middle;
}
.mw-heading4:hover .dsb-toolbar-heading .dsb-toggle,
h4:hover .dsb-toolbar-heading .dsb-toggle,
.dsb-toolbar-heading.dsb-revealed .dsb-toggle {
opacity: 1;
}
/* ── "Guhartina pêşketî" (advanced editing) panel ──────────────────────
Revealed by the pencil toggle above: every per-sense action this gadget offers, queued together with one
"Lê zêde bike". A plain inline row, not a bordered/background card. */
.dsb-quick-row {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
box-sizing: border-box;
max-width: 520px;
margin: 4px 0 4px 26px;
font-family: var(--dsb-sans);
font-size: 12px;
color: var(--dsb-ink-2);
}
.dsb-quick-link {
align-self: flex-start;
margin-bottom: 10px;
color: var(--dsb-accent);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
}
.dsb-quick-link:hover,
.dsb-quick-link:focus {
color: var(--dsb-accent-deep);
text-decoration: underline;
}
/* The picker row: gloss + the two primary word groups as direct "+ <field>" links, plus a "Zêdetir" toggle
for the rest -- clicking a link opens its box below and hides the link; .dsb-box-remove un-hides it.
position: relative anchors .dsb-more-menu's overlay below (see there). */
.dsb-field-picker {
position: relative;
display: flex;
flex-wrap: wrap;
gap: 6px 14px;
margin-bottom: 10px;
}
.dsb-field-picker .dsb-quick-link {
margin-bottom: 0;
}
/* The "Zêdetir" dropdown: every non-primary field link (plus Nimûne/jêgirtin, which sits first) stacked as a
plain vertical list. Floats over the page as an overlay (positioned against .dsb-field-picker) instead of
pushing $openBoxes/the rest of the definition down when it opens. */
.dsb-more-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 10;
display: flex;
flex-direction: column;
align-items: flex-start;
width: max-content;
max-width: min(320px, calc(100vw - 40px));
gap: 6px;
margin: 2px 0 0 4px;
padding: 8px 12px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-field);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.dsb-more-menu .dsb-quick-link {
margin-bottom: 0;
}
/* Boxes the user has actually opened, stacked in the order they were added -- several can be open at once. */
.dsb-open-boxes {
display: flex;
flex-direction: column;
}
/* One field (its label + input) within the panel -- always a currently-open, removable box. */
.dsb-adv-group {
position: relative;
margin-bottom: 14px;
padding-right: 20px;
}
.dsb-adv-label {
margin-bottom: 4px;
font-size: 12px;
font-weight: 600;
color: var(--dsb-ink-3);
}
.dsb-box-remove {
position: absolute;
top: 0;
right: 0;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-box-remove:hover,
.dsb-box-remove:focus {
color: var(--dsb-accent-deep);
}
.dsb-form-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.dsb-input {
box-sizing: border-box;
min-width: 16em;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-input::placeholder {
color: var(--dsb-placeholder);
opacity: 1;
}
.dsb-input:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
/* ── Plain tag field (Etîket, Kategorî) ────────────────────────────────
Plain type-and-commit tags with no suggestion panel; unlike Hevmane/Dijmane/etc., these carry no modifiers. */
.dsb-tagfield {
box-sizing: border-box;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
min-width: 16em;
padding: 4px 6px;
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.dsb-tagfield:focus-within {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
}
.dsb-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
padding: 3px 6px 3px 10px;
}
.dsb-tag-remove {
border: 0;
background: transparent;
color: var(--dsb-muted);
font-size: 13px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
}
.dsb-tag-remove:hover {
color: var(--dsb-danger);
}
.dsb-tagfield .dsb-input {
flex: 1 1 8em;
min-width: 8em;
border: 0;
padding: 3px 2px;
background: transparent;
box-shadow: none;
}
.dsb-tagfield .dsb-input:focus {
box-shadow: none;
}
/* ── Word list with modifier pills ───────────────────────────────────
Every word is its own always-visible row: a word box plus a "+" that attaches one of the 10 WORD_MODIFIERS
as a small pill shown above the box. A fresh empty row is appended once the current last one gets text. */
.dsb-wordlist {
margin: 0;
padding-left: 0;
list-style: none;
}
.dsb-word-li {
margin-bottom: 6px;
}
.dsb-word-li:last-child {
margin-bottom: 0;
}
.dsb-word-mods {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
}
.dsb-word-mod-chip {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 11.5px;
padding: 3px 4px 3px 10px;
cursor: pointer;
}
.dsb-word-mod-chip-remove {
border: 0;
background: transparent;
color: var(--dsb-accent-deep);
font-size: 12px;
line-height: 1;
cursor: pointer;
padding: 0 2px;
opacity: 0.7;
}
.dsb-word-mod-chip-remove:hover {
color: var(--dsb-danger);
opacity: 1;
}
.dsb-word-box-row {
display: flex;
align-items: center;
gap: 6px;
}
.dsb-word-box-row .dsb-word-input {
flex: 1 1 auto;
min-width: 0;
}
.dsb-mod-btn,
.dsb-word-remove {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
cursor: pointer;
transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.dsb-mod-btn {
border: 1px solid var(--dsb-accent-edge);
background: var(--dsb-accent-tint);
color: var(--dsb-accent);
}
.dsb-mod-btn:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-word-remove {
border: 1px solid var(--dsb-field-edge);
background: var(--dsb-field-bg);
color: var(--dsb-muted);
}
.dsb-word-remove:hover {
border-color: var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-mod-picker {
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
margin-top: 6px;
padding: 8px;
background: var(--dsb-card);
border: 1px solid var(--dsb-rule);
border-radius: var(--dsb-r-card);
box-shadow: none;
}
.dsb-mod-pill {
font-family: var(--dsb-sans);
background: var(--dsb-accent-tint);
color: var(--dsb-accent-deep);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
font-size: 12px;
white-space: nowrap;
padding: 5px 10px;
cursor: pointer;
transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.dsb-mod-pill:hover {
border-color: var(--dsb-accent);
background: var(--dsb-accent);
color: #fff;
}
.dsb-mod-pill:disabled,
.dsb-mod-pill.dsb-mod-pill-used {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
cursor: not-allowed;
opacity: 0.7;
}
.dsb-mod-pill:disabled:hover,
.dsb-mod-pill.dsb-mod-pill-used:hover {
background: var(--dsb-card-sunken);
border-color: var(--dsb-rule);
color: var(--dsb-muted);
}
.dsb-mod-val-wrap {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
margin-top: 6px;
}
.dsb-mod-val-input {
flex: 1 1 auto;
min-width: 0;
max-width: 16em;
}
.dsb-mod-confirm,
.dsb-mod-cancel {
flex: 0 0 auto;
box-sizing: border-box;
width: 26px;
height: 26px;
padding: 0;
line-height: 1;
font-size: 13px;
border-radius: 7px;
background: var(--dsb-accent-tint);
cursor: pointer;
}
.dsb-mod-confirm {
border: 1px solid var(--dsb-ok);
color: var(--dsb-ok);
}
.dsb-mod-cancel {
border: 1px solid var(--dsb-danger);
color: var(--dsb-danger);
}
.dsb-save,
.dsb-cancel,
.dsb-autolink {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
/* One filled pill per row — the same rule the form's footer follows. */
.dsb-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-cancel {
background: transparent;
border: 1px solid transparent;
color: var(--dsb-ink-3);
}
.dsb-cancel:hover {
border-color: var(--dsb-field-edge);
color: var(--dsb-ink);
}
/* An outline pill, distinct from both the filled .dsb-save and the plain-text .dsb-cancel -- a secondary
utility action, not the primary save nor a dismissal. */
.dsb-autolink {
background: transparent;
border: 1px solid var(--dsb-accent-edge);
color: var(--dsb-accent);
}
.dsb-autolink:hover {
border-color: var(--dsb-accent);
color: var(--dsb-accent-deep);
}
.dsb-autolink:disabled {
opacity: 0.55;
cursor: progress;
}
/* Status line. Color comes from .dsb-status-ok/.dsb-status-error (added by the .js on success/failure)
rather than an inline style, so these tokens (and dark mode) apply. */
.dsb-status {
font-family: var(--dsb-sans);
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-status-ok { color: var(--dsb-ok); }
.dsb-status-error { color: var(--dsb-danger); }
/* ── "+ Beşek lê zêde bike" ──────────────────────────────────────────
An accent-coloured action link, like the form's .wiktku-adv-toggle:
it opens something, so it is not muted grey. */
/* Matched to the add-examples gadget's own "Nimûneyeke bikaranînê lê zêde bike" link: a quiet subtle-grey
secondary action at the page's own font and size, not an accent-coloured one. Deliberately no --dsb-sans,
so it inherits the page font the way that link does. */
.dsb-add-subsection,
.dsb-convert-pos-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
margin: 8px 0;
font-size: inherit;
font-weight: 400;
color: var( --color-subtle, #54595d );
text-decoration: none;
border-bottom: 0;
cursor: pointer;
}
.dsb-add-subsection:hover,
.dsb-add-subsection:focus,
.dsb-convert-pos-trigger:hover,
.dsb-convert-pos-trigger:focus {
color: var( --color-base, #202122 );
text-decoration: underline;
}
/* ── Subsection panel ────────────────────────────────────────────────
A sunken card rather than a grey utility box; fields stack so the
picker and its input are not competing for one narrow row. */
.dsb-subsection-panel,
.dsb-convert-pos-panel {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 10px;
box-sizing: border-box;
max-width: 520px;
margin: 6px 0 14px;
padding: 14px 16px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card-sunken);
border: 1px solid var(--dsb-card-edge);
border-radius: var(--dsb-r-card);
}
.dsb-subsection-select,
.dsb-convert-pos-select {
box-sizing: border-box;
width: 100%;
max-width: 100%;
padding: 6px 10px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink);
background: var(--dsb-field-bg);
border: 1px solid var(--dsb-field-edge);
border-radius: var(--dsb-r-field);
}
.dsb-subsection-select:focus,
.dsb-convert-pos-select:focus {
border-color: var(--dsb-accent);
box-shadow: 0 0 0 3px var(--dsb-accent-tint);
outline: 0;
}
.dsb-subsection-field {
min-width: 0;
}
.dsb-subsection-words,
.dsb-subsection-text {
box-sizing: border-box;
width: 100%;
min-width: 0;
}
.dsb-subsection-text {
line-height: 1.6;
resize: vertical;
}
/* ── Gloss field inside the advanced-editing panel ────────────────────
Same shape as .dsb-subsection-text. */
.dsb-edit-gloss {
width: 100%;
line-height: 1.6;
resize: vertical;
}
/* ── Live "not saved yet" previews ─────────────────────────────────────
Dropped into the rendered page at the change's own spot. Dashed edge + a small badge mark them as
pending, not real content; they disappear on "Betal bike" or once the real save lands. */
.dsb-preview-block,
.dsb-preview-inline {
margin: 8px 0;
padding: 8px 12px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-accent-tint);
border: 1px dashed var(--dsb-accent-edge);
border-radius: var(--dsb-r-field);
}
.dsb-preview-inline {
margin-left: 26px;
max-width: 520px;
}
.dsb-preview-heading {
margin: 0 0 4px;
font-size: 15px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-preview-badge {
display: inline-block;
margin-bottom: 6px;
padding: 1px 8px;
font-size: 11px;
font-weight: 500;
color: var(--dsb-accent-deep);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent-edge);
border-radius: var(--dsb-r-pill);
}
.dsb-preview-badge-inline {
margin-left: 8px;
margin-bottom: 0;
vertical-align: middle;
}
.dsb-preview-list,
.dsb-preview-text {
margin: 0;
padding-left: 18px;
}
.dsb-preview-text {
padding-left: 0;
}
/* ── Floating save-queue widget ─────────────────────────────────────
This gadget's own small floating box. One "Lê zêde bike" click anywhere on the page adds a line here;
"Guhertinan qeyd bike" makes the one real save; "Betal bike" drops everything queued without touching the page. */
.dsb-queue-box {
position: fixed;
top: 60px;
right: 16px;
z-index: 1000;
box-sizing: border-box;
width: 280px;
max-width: calc(100vw - 32px);
max-height: calc(100vh - 90px);
overflow-y: auto;
padding: 12px 14px;
font-family: var(--dsb-sans);
font-size: 13px;
color: var(--dsb-ink-2);
background: var(--dsb-card);
border: 1px solid var(--dsb-accent);
border-radius: var(--dsb-r-card);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.16);
}
.dsb-queue-title {
margin-right: 20px;
font-size: 13px;
font-weight: 600;
color: var(--dsb-ink);
}
.dsb-queue-close {
float: right;
color: var(--dsb-ink-3);
text-decoration: none;
font-size: 14px;
line-height: 1;
cursor: pointer;
}
.dsb-queue-close:hover,
.dsb-queue-close:focus {
color: var(--dsb-accent-deep);
}
.dsb-queue-list {
margin: 8px 0;
padding-left: 18px;
max-height: 160px;
overflow-y: auto;
}
.dsb-queue-list li {
margin-bottom: 4px;
}
.dsb-queue-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 4px;
}
.dsb-queue-save,
.dsb-queue-cancel {
font-family: var(--dsb-sans);
font-size: 13px;
font-weight: 500;
padding: 6px 14px;
border-radius: var(--dsb-r-pill);
cursor: pointer;
transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.dsb-queue-save {
background: var(--dsb-accent);
border: 1px solid var(--dsb-accent);
color: #fff;
}
.dsb-queue-save:hover {
background: var(--dsb-accent-deep);
border-color: var(--dsb-accent-deep);
}
.dsb-queue-save:disabled {
opacity: 0.55;
cursor: progress;
}
.dsb-queue-cancel {
background: transparent;
border: 1px solid var(--dsb-field-edge);
color: var(--dsb-ink-3);
}
.dsb-queue-cancel:hover {
border-color: var(--dsb-ink-3);
color: var(--dsb-ink);
}
.dsb-queue-status {
margin-top: 6px;
font-size: 12.5px;
color: var(--dsb-muted);
}
.dsb-queue-status.dsb-status-ok { color: var(--dsb-ok); }
.dsb-queue-status.dsb-status-error { color: var(--dsb-danger); }
/* ── Minerva (mobile) ────────────────────────────────────────────────
Narrower viewport: keep the panel on screen and give every tap
target the form's 44px minimum. */
.skin-minerva .dsb-quick-row,
.skin-minerva .dsb-subsection-panel,
.skin-minerva .dsb-convert-pos-panel {
max-width: 100%;
}
@media (max-width: 720px), (pointer: coarse) {
/* Keep the glyph at 13px -- the asset is only 10px, so scaling it up just blurs it. Grow the tap target invisibly instead. */
.dsb-toggle {
position: relative;
}
.dsb-toggle::after {
content: "";
position: absolute;
inset: -10px;
}
.dsb-quick-row {
font-size: 13px;
margin-left: 20px;
}
.dsb-input,
.dsb-subsection-select,
.dsb-convert-pos-select {
min-height: 40px;
/* >=16px stops iOS Safari zooming the page on focus. */
font-size: 16px;
}
.dsb-mod-btn,
.dsb-word-remove,
.dsb-mod-confirm,
.dsb-mod-cancel {
width: 36px;
height: 36px;
font-size: 15px;
}
.dsb-mod-pill {
padding: 8px 12px;
}
.dsb-mod-val-input {
max-width: none;
}
.dsb-tagfield .dsb-input {
min-height: 32px;
}
.dsb-tag-remove {
padding: 0 6px;
}
.dsb-save,
.dsb-cancel,
.dsb-autolink,
.dsb-queue-save,
.dsb-queue-cancel {
min-height: 40px;
padding: 8px 16px;
}
.dsb-queue-box {
top: auto;
bottom: 8px;
right: 8px;
left: 8px;
width: auto;
}
}
/* ── Dark mode ───────────────────────────────────────────────────────
Same warm dark palette and same explicit-signal-only rule as the
form's stylesheet: no bare prefers-color-scheme fallback, since
legacy Vector sets no theme class and would go dark on its own. */
html.skin-theme-clientpref-night,
html.skin-nightmode {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-night .dsb-save,
html.skin-nightmode .dsb-save,
html.skin-theme-clientpref-night .dsb-queue-save,
html.skin-nightmode .dsb-queue-save {
color: #14213a;
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os {
--dsb-card: #201e1a;
--dsb-card-sunken: #1a1916;
--dsb-card-edge: #322e28;
--dsb-rule: #3a3630;
--dsb-rule-soft: #2c2924;
--dsb-field-edge: #4a453d;
--dsb-field-bg: #191815;
--dsb-ink: #ece7dd;
--dsb-ink-2: #d5cfc4;
--dsb-ink-3: #b3aca1;
--dsb-muted: #8f887c;
--dsb-placeholder: #6d675e;
--dsb-accent: #7ba7e8;
--dsb-accent-deep: #cfe0f8;
--dsb-accent-tint: #1c2839;
--dsb-accent-edge: #35496b;
--dsb-ok: #7cc094;
--dsb-danger: #e5907c;
}
html.skin-theme-clientpref-os .dsb-save,
html.skin-theme-clientpref-os .dsb-queue-save {
color: #14213a;
}
}
f46u863j0a2kqn0fjd5dyunrpnxuyhy
Wîkîferheng:Rêveber/Wikihez
4
1358877
6347342
6347341
2026-08-31T12:08:03Z
Ghybu
1393
6347342
wikitext
text/x-wiki
== Wikihez ==
Merheba,
Ez, {{b|Wikihez}}, dixwazim amûrên din ên JS/CSSê çêkim daku guhartina rûpelan hêsantir be, amûrên heyî nû bikim yan baştir bikim. Ji bo ku rûpelên JS û CSSê bi hêsanî biguherînim ji min re heqên [[:meta:Interface administrators|Interface Admin]] lazim e. Mala wî ava hevalê {{b|Bikarhêner}} gelek alîkariya min kir di vî warî de lê xwestina alîkariyê her daîm ne tiştekî xweş e û naxwazim wî zêdetir aciz bikim loma dixwazim li vir bibim Interface admîn. Hûn dikarin şirove û dengên xwe li jêr binivîsin.[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:34, 30 tebax 2026 (UTC)
=== Dengdan ===
{{dengdan|destpêk=31.08.2026|dawî=07.09.2026}} <!-- piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. -->
==== Bo ====
<!-- Li jêr '# {{erê}} ~~~~' binivîse ji bo dengê erênî. -->
# {{erê}} Ji karên teknîkî baş fam dike. Lewma hewce ye ku bibe admîn. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:30, 30 tebax 2026 (UTC)
==== Dij ====
<!-- Li jêr '# {{na}} ~~~~' binivîse ji bo dengê neyînî. -->
* {{na}} Mixabin, nikare xwe kontrol bike, bnr. [https://ku.wiktionary.org/w/index.php?title=Got%C3%BBb%C3%AAj:helbest&oldid=6236598#Advocacy], [https://ku.wiktionary.org/w/index.php?title=Got%C3%BBb%C3%AAj:tarih%C3%A7i&oldid=6240164], [https://ku.wikipedia.org/w/index.php?title=W%C3%AEk%C3%AEpediya:R%C3%AAveber/Balyozxane&diff=prev&oldid=1131978]. Rêveberên ku li vira ne jî tiştekî nawên. Bi vî awayî, mafên wekî vitira di destên wî de, di demên bê de dikarin biproblem bin. --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 11:49, 31 tebax 2026 (UTC)
==== Bêalî ====
<!-- Li jêr '# {{bêalî}} ~~~~' binivîse ji bo dengê bêalî. -->
=== Gotûbêj ===
<!-- Fikrên xwe bi şablona {{şirove}} li jêr binivîse. -->
[[Kategorî:Dengdan|Wikihez]]
rs1axkjo3x879wu9iffwljmmja8briw
Şablon:deprecated lang param usage
10
1358878
6347346
2026-08-31T12:41:17Z
Wikihez
7344
[[:en:Template:deprecated lang param usage]] hat kopîkirin ([[Bikarhêner:Wikihez/skrîpt/js/kopi-enWikt.js|kopi-enWikt.js]])
6347346
wikitext
text/x-wiki
{{deprecated code|active={{#if:{{{lang|}}}|yes|no}}|text=deprecated use of {{para|lang}} parameter|tooltip=This template call uses the deprecated 'lang' parameter. Use '1' instead.|{{{1}}}}}<!--
--><noinclude>{{documentation}}</noinclude>
nsym6z8ah5z53122s7pzrubji9ljwx8
Şablon:check deprecated lang param usage
10
1358879
6347347
2026-08-31T12:41:17Z
Wikihez
7344
Ji bo [[Şablon:deprecated lang param usage]] hat beralîkirin ([[Bikarhêner:Wikihez/skrîpt/js/kopi-enWikt.js|kopi-enWikt.js]])
6347347
wikitext
text/x-wiki
#BERALÎKIRIN [[Şablon:deprecated lang param usage]]
p53a741qusg4f8wqm7411eyzpiq5jud
Şablon:deprecated lang param usage/belge
10
1358880
6347348
2026-08-31T12:41:18Z
Wikihez
7344
[[:en:Template:deprecated lang param usage/documentation]] hat kopîkirin ([[Bikarhêner:Wikihez/skrîpt/js/kopi-enWikt.js|kopi-enWikt.js]])
6347348
wikitext
text/x-wiki
{{documentation subpage}}
This template should be used in conjunction with templates that accept the {{para|lang}} parameter as a deprecated alternative to {{para|1}} and have [[:Category:Successfully deprecated templates|successfully eliminated]] all such usages. Use is as follows:
<pre>{{ {{#if:{{{lang|}}}|deprecated lang param usage|no deprecated lang param usage}}|lang={{{lang|}}}|<TEMPLATE-CALL>}}</pre>
If the <code>lang</code> parameter is in usage, this formats the output of the template call with the <code>.deprecated</code> CSS class (which by default displays the output in olive green), precedes it with the text "deprecated use of {{para|lang}} parameter", adds a tooltip "This template call uses the deprecated 'lang' parameter. Use '1' instead." and categorizes the page in [[:Category:Pages using deprecated templates]]. Otherwise, the output is simply returned as normal.
''Note: the space between the two sets of <code><nowiki>{{</nowiki></code> at the beginning is mandatory, or else the parser will interpret it as <code><nowiki>{ {{{</nowiki></code>, which will not work.''
==Parameters==
* {{para|1}}: The template call.
* {{para|lang}}: Pass-through of the {{para|lang}} parameter.
==See also==
* {{şx|deprecated code}}
* {{şx|no deprecated lang param usage}}
<includeonly>
[[Category:Maintenance templates]]
[[Category:Metatemplates]]
</includeonly>
oow1f6onaqfcg2ge9ygur2dptho5w1r
Şablon:deprecated code
10
1358881
6347349
2026-08-31T12:41:53Z
Wikihez
7344
[[:en:Template:deprecated code]] hat kopîkirin ([[Bikarhêner:Wikihez/skrîpt/js/kopi-enWikt.js|kopi-enWikt.js]])
6347349
wikitext
text/x-wiki
{{#ifeq:{{{active|}}}|no|{{{1}}}|<span class="deprecated" title="{{#if:{{{tooltip|}}}|{{{tooltip}}}|This is a deprecated template usage.}}">''([[:Category:Successfully deprecated templates|{{#if:{{{text|}}}|{{{text}}}|deprecated template usage}}]])'' {{{1}}}</span><includeonly>[[Category:Pages using deprecated templates{{#switch:{{NAMESPACE}}|Appendix|Reconstruction|Thesaurus|Sign gloss|Citations|=|#default=/other}}]]</includeonly>}}<!--
--><noinclude>{{documentation}}</noinclude>
sbklorazzvj1bljd6402e0f7vxjwog3
Şablon:deprecated code/belge
10
1358882
6347350
2026-08-31T12:41:53Z
Wikihez
7344
[[:en:Template:deprecated code/documentation]] hat kopîkirin ([[Bikarhêner:Wikihez/skrîpt/js/kopi-enWikt.js|kopi-enWikt.js]])
6347350
wikitext
text/x-wiki
{{documentation subpage}}
This template should be used in conjunction with [[:Category:Successfully deprecated templates|successfully deprecated templates]], i.e. templates that are deprecated and where all uses of the template have been eliminated. It can also be used with conditionally-deprecated templates, i.e. where certain uses of the template (e.g. using the {{para|lang}} parameter instead of {{para|1}}) have been deprecated and all such uses eliminated. It formats the output of the template call with the <code>.deprecated</code> CSS class (which by default displays the output in olive green), precedes it with some text (by default "deprecated template usage") and categorizes the page in [[:Category:Pages using deprecated templates]] (for entries and content pages) or [[:Category:Pages using deprecated templates/other]] (for other pages, such as talk pages).
==Parameters==
* {{para|1}}: The template call.
* {{para|active|opt=1}}: Control whether deprecation is active. Use this in conjunction with conditionally-deprecated templates. If the value is <code>no</code>, the deprecation is inactive; otherwise it's active.
* {{para|text|opt=1}}: Text to display before the template output (by default "deprecated template usage").
* {{para|tooltip|opt=1}}: Tooltip text to display when the user hovers over the template output (by default "This is a deprecated template usage.").
==See also==
* {{temp|check deprecated lang param usage}}
<includeonly>
[[Category:Metatemplates]]
</includeonly>
6u89q1jma5z37irp3wnxv8hsj3xzwgj
çoyê sist li serê xwediyan dikeve
0
1358885
6347453
2026-08-31T19:42:41Z
Muzaffercky
11833
([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +ku:gotineke pêşiyan:Ger mirov di kar, biryar an parastina xwe de sist be, zerar û zirana herî mezin digehije mirov bi xwe.
6347453
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Gotineke pêşiyan ===
{{gotineke pêşiyan|ku}}
# {{dever|Riha}} [[ger|Ger]] [[mirov|mirov]] di [[kar|kar]], [[biryar|biryar]] an [[parastin|parastina]] [[xwe|xwe]] de [[sist|sist]] be, [[zerar|zerar]] û [[ziran|zirana]] [[herî|herî]] [[mezin|mezin]] [[digehije|digehije]] mirov [[bi xwe]].
#* {{nimûne?|ku}}
==== Bi zaravayên din ====
{{werger-ser|ger mirov di kar, biryar an parastina xwe de sist be, zerar û zirana herî mezin digehije mirov bi xwe|1}}
{{werger-bin}}
==== Werger ====
{{werger-ser|ger mirov di kar, biryar an parastina xwe de sist be, zerar û zirana herî mezin digehije mirov bi xwe|1}}
{{werger-bin}}
8cibrmk8e0fycthy7z2u60qh0alsmiq
6347455
6347453
2026-08-31T19:42:58Z
Muzaffercky
11833
6347455
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Gotineke pêşiyan ===
{{gotineke pêşiyan|ku}}
# {{dever|Riha}} [[ger|Ger]] [[mirov|mirov]] di [[kar|kar]], [[biryar|biryar]] an [[parastin|parastina]] [[xwe|xwe]] de [[sist|sist]] be, [[zerar|zerar]] û [[ziran|zirana]] [[herî|herî]] [[mezin|mezin]] [[digehije|digehije]] mirov [[bi xwe]].
#* {{nimûne?|ku}}
3kve4slwr8152l3u9a9lap1hlwctabt
6347456
6347455
2026-08-31T19:44:17Z
Muzaffercky
11833
6347456
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Gotineke pêşiyan ===
{{gotineke pêşiyan|ku}}
# {{dever|Riha}} [[ger|Ger]] [[mirov|mirov]] di [[kar|kar]], [[biryar|biryar]] an [[parastin|parastina]] [[xwe|xwe]] de [[sist|sist]] be, [[zerar|zerar]] û [[ziran|zirana]] [[herî|herî]] [[mezin|mezin]] [[digehêje|digehêje]] mirov [[bi xwe]].
#* {{nimûne?|ku}}
hvnwr43rx9x89iiecurczu3g2urj8ox
6347491
6347456
2026-08-31T21:12:14Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347491
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Gotineke pêşiyan ===
{{gotineke pêşiyan|ku}}
# {{dever|Riha}} [[ger|Ger]] [[mirov]] di [[kar]], [[biryar]] an [[parastin]]a [[xwe]] de [[sist]] be, [[zerar]] û [[ziran]]a [[herî]] [[mezin]] [[digehêje]] mirov [[bi xwe]].
#* {{nimûne?|ku}}
p30h0t27wflyzbi57od86hi9mezna91
şilşilûk
0
1358886
6347479
2026-08-31T20:54:08Z
Dûrzan
875
([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +ku:navdêr:[[hilûtirşik]], [[hincasa bej]]
6347479
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Navdêr ===
{{navdêr|ku|c=m}}
# {{dever|Mêrdîn}} [[hilûtirşik|Hilûtirşik]], [[hincas|hincas]]a [[bej|bej]].
#* {{nimûne?|ku}}
==== Etîmolojî ====
{{ji?|ku}}
==== Bi zaravayên din ====
{{werger-ser|hilûtirşik, hincasa bej|1}}
{{werger-bin}}
==== Werger ====
{{werger-ser|hilûtirşik, hincasa bej|1}}
* {{Z|tr}}: {{W|tr|yaban eriği}}
{{werger-bin}}
lnkfdz6kvlo5m3sc7krbadbfo9vu2ut
6347499
6347479
2026-08-31T21:26:27Z
Wikihez
7344
guhartina pêşketî (DefSideBoxes)
6347499
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Navdêr ===
{{navdêr|ku|c=m}}
# {{K|ku|fêkî}} {{dever|Mêrdîn}} [[hincas|Hincas]]a [[bej|bej]].
#: {{hevmane|ku|hilûtirşik}}
#* {{nimûne?|ku}}
==== Etîmolojî ====
{{ji?|ku}}
==== Bi zaravayên din ====
{{werger-ser|hilûtirşik, hincasa bej|1}}
{{werger-bin}}
==== Werger ====
{{werger-ser|hilûtirşik, hincasa bej|1}}
* {{Z|tr}}: {{W|tr|yaban eriği}}
{{werger-bin}}
rarbu7y6yyryvhs1jr69b8acpg8iara
6347503
6347499
2026-08-31T22:12:11Z
Balyozbot
7867
Bot: Paqijiyên kozmetîk (Lînk paqij kir.)
6347503
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Navdêr ===
{{navdêr|ku|c=m}}
# {{K|ku|fêkî}} {{dever|Mêrdîn}} [[hincas|Hincasa]] [[bej]].
#: {{hevmane|ku|hilûtirşik}}
#* {{nimûne?|ku}}
==== Etîmolojî ====
{{ji?|ku}}
==== Bi zaravayên din ====
{{werger-ser|hilûtirşik, hincasa bej|1}}
{{werger-bin}}
==== Werger ====
{{werger-ser|hilûtirşik, hincasa bej|1}}
* {{Z|tr}}: {{W|tr|yaban eriği}}
{{werger-bin}}
hftx2tkas0iykeh1lv6ptm7ykupdzlb
Freundschaftsspiel
0
1358887
6347510
2026-09-01T05:06:15Z
Kurdistanov
15290
([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +de:navdêr:maça dostaniyê
6347510
wikitext
text/x-wiki
== {{ziman|de}} ==
=== Navdêr ===
{{navdêr|de|c=nt}}
# maça [[dostanî|dostaniyê]]
#* {{nimûne?|de}}
==== Etîmolojî ====
{{ji?|de}}
howhyjwh7krgfl02799f5em75sqg9sc
6347511
6347510
2026-09-01T05:07:34Z
Kurdistanov
15290
6347511
wikitext
text/x-wiki
== {{ziman|de}} ==
=== Navdêr ===
{{navdêr|de|c=nt}}
# [[maça dostaniyê]]
#* {{nimûne?|de}}
==== Etîmolojî ====
{{ji?|de}}
nxrno2va37or226zdvcwtatf2f0w378
dostluk maçı
0
1358888
6347512
2026-09-01T05:09:12Z
Kurdistanov
15290
([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +tr:navdêr:maça dostaniyê
6347512
wikitext
text/x-wiki
== {{ziman|tr}} ==
=== Navdêr ===
{{navdêr|tr}}
# [[maça dostaniyê]]
#* {{nimûne?|tr}}
qlawnm991q5iddfoymzcwsxlrx9mb3n
match amical
0
1358889
6347513
2026-09-01T05:11:49Z
Kurdistanov
15290
([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +fr:navdêr:maça dostaniyê
6347513
wikitext
text/x-wiki
== {{ziman|fr}} ==
=== Navdêr ===
{{navdêr|fr|c=n}}
# [[maça dostaniyê]]
#* {{nimûne?|fr}}
ht5zdnd0xo9bg5ccexy830ysdfrj98t
friendly match
0
1358890
6347514
2026-09-01T05:13:51Z
Kurdistanov
15290
([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +en:navdêr:maça dostaniyê
6347514
wikitext
text/x-wiki
== {{ziman|en}} ==
=== Navdêr ===
{{navdêr|en}}
# [[maça dostaniyê]]
#* {{nimûne?|en}}
i25rnlfmdqmuphguy74q2ir8lf2oa89
xwediyan
0
1358891
6347516
2026-09-01T08:37:54Z
Wikihez
7344
([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +ku:navdêr:{{ku-tewîna-nav|xwedî|mê û nêr}}
6347516
wikitext
text/x-wiki
== {{ziman|ku}} ==
=== Formeke navdêrê ===
{{ku-tew-nav|xwedî|mê û nêr}}
{{navdêr|ku|form=erê}}
# {{ku-tewîna-nav|xwedî|mê û nêr}}
s1n9yvjbq51viazpy2ptmtrjozqknfe