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 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 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 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 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 î&#59; 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&#59; 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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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'>&#215;</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'>&#8853;</button>").hide(); var $removeRow = $("<button type='button' class='dsb-word-remove' title='Vê kelîmeyê jê bibe'>&#215;</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'>&#215;</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ê'>&#10003;</button>"); var $cancel = $("<button type='button' class='dsb-mod-cancel' title='Betal'>&#10005;</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'>&#215;</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