Wîkîferheng kuwiktionary https://ku.wiktionary.org/wiki/Destp%C3%AAk MediaWiki 1.47.0-wmf.15 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 firoşxane 0 3832 6333941 6314252 2026-08-15T23:19:24Z Wikihez 7344 /* Etîmolojî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333941 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === [[Wêne:Comercio en la plaza del 9 de abril de 1947, Tánger, Marruecos, 2015-12-11, DD 78.JPG|thumb|Firoşxaneyek.]] {{navdêr|ku|z=m}} # Cihê ([[kirîn]] û) [[firotin]]ê. #: {{hevmane|ku|dikan}} #* {{bêmînak|ku}} # Xaniyê gelek [[dikan]] lê hene. #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê|guherto=hemû}} ==== Hevmane ==== * [[firoşgeh]] ==== Binêre herwiha ==== {{kol3|ku | bikir | firoşer | firoşerî | firoşkar | firoşkarî | kiryar | kiryarî }} ==== Etîmolojî ==== Ji {{qf|ku|firoş-|-xane}}. ==== Werger ==== {{werger-ser}} {{werger-bin}} 4n6c6csqf29xz2i39lpahg2sm3o3e3s 6333975 6333941 2026-08-15T23:41:32Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333975 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === [[Wêne:Comercio en la plaza del 9 de abril de 1947, Tánger, Marruecos, 2015-12-11, DD 78.JPG|thumb|Firoşxaneyek.]] {{navdêr|ku|z=m}} # Cihê ([[kirîn]] û) [[firotin]]ê. #: {{hevmane|ku|dikan}} #* {{bêmînak|ku}} # Xaniyê gelek [[dikan]] lê hene. #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê|guherto=hemû}} ==== Hevmane ==== * [[firoşgeh]] ==== Etîmolojî ==== Ji {{qf|ku|firoş-|-xane}}. ==== Herwiha binêre ==== {{kol3|ku | bikir | firoşer | firoşerî | firoşkar | firoşkarî | kiryar | kiryarî }} ==== Werger ==== {{werger-ser}} {{werger-bin}} 0omy446dyv1zll37awxvxdbq9p7m90i pir 0 4115 6334026 6324488 2026-08-16T01:40:56Z Wikihez 7344 /* Diyarker */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334026 wikitext text/x-wiki {{bnr-h|pirr|pîr}} == {{ziman|ku}} == === Bilêvkirin === * {{beş|Navdêr 1}}: {{IPA|ku|/pʰɪɾ/}}, {{ku-Arab|پر}} ** {{deng|ku|LL-Q36163_(kmr)-Key Mîrza-pir-2.wav|dever=Wan}} * {{beş|Hoker|Diyarker}} {{beş|Rengdêr|Navdêr 2}}: {{IPA|ku|/pʰɪr/}}, {{ku-Arab|پڕ}} ** {{deng|ku|LL-Q36163_(kmr)-Key Mîrza-pir.wav|dever=Wan}} === Navdêr === [[Wêne:Pira Delal, Kurdistan.jpg|thumb|250px|'''Pira''' Delal ([[Zaxo]])]] {{navdêr|ku|z=m}}, {{p-ya req}}, {{r-ya nerm}} # {{maneid|ku|avahî}} [[rê|Rêya]] ku hatiye avakirin daku mirov pê di ser [[av]]ekê re [[borîn|bibore]] anku [[derbas]] bibe (bi taybetî di ser [[çem]]ekî yan [[robar]]ekî re). #: {{hevmaneyên peyvê|ku|kuprî|cisir}} #* {{jêder|ku|jêgirtin=Gava ew gihîşt ber '''pirê''', dengê zûrîna trênê hat.|{{Jêgirtin/Firat Cewerî/Girtî}}}} #* {{jêder|ku|{{Jêgirtin/Melayê Cizîrî/Dîwana Melayê Cizirî}}|jêgirtin=Terka dilê ehbab-i da<br />Mehbûb û reyhan '''pir''' gulav<br />Ker kir li min cerg û hinav}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|پر}} ==== Formên alternatîv ==== * {{g|ku|pire}} ==== Etîmolojî ==== Hevreha soranî {{g|ckb|پرد}} (pird), zazakî [[pird]], hewramî [[pirdî]], farisî {{g|fa|پل}} (pol), pehlewî [[𐭯𐭥𐭧𐭫𐭩]] (puhl), partî ''purt'', avestayî [[𐬞𐬆𐬭𐬆𐬙𐬎]] (pərətu), sanskrîtî [[पर]] (para: [[di ser re borîn]]), latînî [[portus]] ([[lîman]], [[bender]], [[keştîgeh]] > gelek zimanên ewropî [[port]]), yûnaniya kevn [[πόρος]] (póros: [[buhir]], [[derbaz]], [[derbend]]), îngilîzî [[ford]] ([[meyav]], [[derbazgeh]]a avê), almanî [[Furt]] (meyav, derbazgeh), îngilîzî [[firth]] ([[derbend]]), zimanên skandinavî [[fjord]] (derbend)... hemû ji {{ji|ine-pro|ku|-}} *[[pértus]] ([[derbaz]]bûn). Binêre herwiha [[borîn]], [[borandin]]. :<font style="font-size:10px">'''Çavkanî:''' [[Şablon:Horn|Horn p.72]], [[Şablon:Watkins|Watkins p.65]], [[Şablon:MacKenzie|MacKenzie P.118]], [[Şablon:Etymonline|Etymonline]] </font> | <font style="font-size:10px">'''Pokorny:''' 816 - 817</font> ==== Bi zaravayên din ==== * {{Z|ckb}}: [[pird]] * {{Z|zza}}: [[pird]] * {{Z|hac}}: [[pirdî]] ==== Werger ==== {{werger-ser|riya di ser avekê re}} * {{Z|ab}}: {{W-|ab|ацҳа}} * {{Z|ady}}: {{W-|ady|лъэмыдж}} * {{Z|af}}: {{W+|af|brug}} * {{Z|ak}}: {{W-|ak|twene}} * {{Z|sq}}: {{W+|sq|urë|m}} * {{Z|pdc}}: {{W-|pdc|Brick|m}} * {{Z|de}}: {{W+|de|Brücke|m}} *: {{Z|gsw}}: {{W-|gsw|Brugg|m}} * {{Z|alt}}: {{W-|alt|кӱр}} * {{Z|am}}: {{W-|am|ድልድይ}} * {{Z|ani}}: {{W-|ani|кьир}} * {{Z|an}}: {{W+|an|puent|n}} * {{Z|arc}}: *: {{Z|syc}}: {{W-|syc|ܓܫܪܐ|n|tr=gešrā}} *: Îbranî: {{W-|arc|גִּשְׁרָא|n|tr=gišrā}} * {{Z|agj}}: {{W-|agj|ድልድይ|tr=dǝldǝy}} * {{Z|rup}}: {{W-|rup|punti|m}}, {{W-|rup|pumhi|m}} * {{Z|as}}: {{W-|as|দলং}}, {{W-|as|সাঁকো}} * {{Z|ast}}: {{W+|ast|ponte|m}}, {{W+|ast|puente|n}} * {{Z|av}}: {{W-|av|кьо}} * {{Z|az}}: {{W+|az|körpü}} * {{Z|eu}}: {{W+|eu|zubi}} * {{Z|ba}}: {{W-|ba|күпер}} * {{Z|bbl}}: {{W-|bbl|ტივ}} * {{Z|be}}: {{W-|be|мост|n}} * {{Z|bn}}: {{W+|bn|পুল}} * {{Z|kap}}: {{W-|kap|тӏийо}} * {{Z|bcl}}: {{W-|bcl|tulay}} * {{Z|br}}: {{W+|br|pont|n}} * {{Z|bg}}: {{W+|bg|мост|n}} * {{Z|my}}: {{W+|my|တံတား}} * {{Z|bua}}: {{W-|bua|хүүргэ}} * {{Z|ccc}}: {{W-|ccc|pwente}} * {{Z|ce}}: {{W-|ce|тӏай}} * {{Z|cs}}: {{W+|cs|most|n}} * {{Z|chr}}: {{W-|chr|ᎠᏒᏢᎢ}} * {{Z|zh}}: *: {{Z|yue}}: {{W-|yue|橋|tr=kiu4, kiu4-2}} *: {{Z|dng}}: {{W-|dng|чё}} *: {{Z|hak}}: {{W-|hak|橋|tr=khièu}} *: {{Z|cmn}}: {{W+|cmn|橋|tr=qiáo}}, {{W+|cmn|橋樑|tr=qiáoliáng}} *: {{Z|cdo}}: {{W-|cdo|橋|tr=giò}} *: {{Z|nan}}: {{W+|nan|橋|tr=kiâu / kiô}} *: {{Z|wuu}}: {{W-|wuu|橋}} * {{Z|cv}}: {{W-|cv|кӗпер}} * {{Z|dlm}}: {{W-|dlm|puant|n}} * {{Z|da}}: {{W+|da|bro|g}} * {{Z|dv}}: {{W-|dv|ފާލަން}} * {{Z|ovd}}: {{W-|ovd|bru|m}} * {{Z|id}}: {{W+|id|jembatan}} * {{Z|ar}}: {{W-|ar|جِسْر|n}}, {{W-|ar|قَنْطَرَة|m}} *: {{Z|arz}}: {{W-|arz|كوبري|n|tr=kōbrī}} *: {{Z|acw}}: {{W-|acw|جسر|n|tr=jisir}} *: {{Z|ary}}: {{W-|ary|قنطرة|m|tr=qanṭra}} * {{Z|hy}}: {{W+|hy|կամուրջ}} * {{Z|myv}}: {{W-|myv|сэдь}} * {{Z|eo}}: {{W+|eo|ponto}} * {{Z|et}}: {{W+|et|sild}} * {{Z|gez}}: {{W-|gez|ድልድይ}} * {{Z|ext}}: {{W-|ext|puenti}} * {{Z|gur}}: {{W-|gur|kʋl-lasɩŋa}} * {{Z|fa}}: {{W+|fa|پل|tr=pol}} * {{Z|fo}}: {{W-|fo|brúgv|m}} * {{Z|fi}}: {{W+|fi|silta}} * {{Z|fr}}: {{W+|fr|pont|n}} * {{Z|fur}}: {{W-|fur|puint|n}} * {{Z|frr}}: {{W-|frr|brag|m}} * {{Z|stq}}: {{W-|stq|Brääch|m}} * {{Z|fy}}: {{W-|fy|brêge}} * {{Z|gd}}: {{W-|gd|drochaid|m}} * {{Z|gl}}: {{W+|gl|ponte|m}} * {{Z|gu}}: {{W-|gu|પુલ}} * {{Z|ka}}: {{W+|ka|ხიდი}} * {{Z|ht}}: {{W-|ht|pon}} * {{Z|haw}}: {{W-|haw|uapo}} * {{Z|ha}}: {{W-|ha|kadarko}} * {{Z|hi}}: {{W+|hi|पुल|n}} * {{Z|gin}}: {{W-|gin|лӏено}} * {{Z|mww}}: {{W-|mww|choj}} * {{Z|odt}}: {{W-|odt|brugga|m}} * {{Z|nl}}: {{W+|nl|brug|n|m}} * {{Z|hrx}}: {{W-|hrx|Brick|m}} * {{Z|he}}: {{W+|he|גֶשֶׁר|n|tr=gésher}} * {{Z|io}}: {{W+|io|ponto}} * {{Z|ang}}: {{W-|ang|brycg|m}} * {{Z|en}}: {{W+|en|bridge}} * {{Z|inh}}: {{W-|inh|тӏий}} * {{Z|ia}}: {{W-|ia|ponte}} * {{Z|ga}}: {{W+|ga|droichead|n}} *: {{Z|sga}}: {{W-|sga|drochet|nt}} * {{Z|ist}}: {{W-|ist|ponto|n}} * {{Z|it}}: {{W+|it|ponte|n}} * {{Z|is}}: {{W+|is|brú|m}} * {{Z|ja}}: {{W+|ja|橋|tr=はし, hashi}}, {{W+|ja|橋梁|tr=きょうりょう, kyōryō}} * {{Z|jv}}: {{W-|jv|kreteg}} * {{Z|kbd}}: {{W-|kbd|лъэмыж}} * {{Z|kl}}: {{W-|kl|ikaartarfik}} * {{Z|xbr}}: {{W-|xbr|mbatang}} * {{Z|kn}}: {{W+|kn|ಸೇತುವೆ}} * {{Z|krc}}: {{W-|krc|кёпюр|tr=köpür}} * {{Z|kdr}}: {{W-|kdr|kiopriu}} * {{Z|kaa}}: {{W-|kaa|көпир|tr=köpir}} * {{Z|krl}}: {{W-|krl|sildu}} * {{Z|csb}}: {{W-|csb|mòst|n}} * {{Z|ca}}: {{W+|ca|pont|n}} * {{Z|kgp}}: {{W-|kgp|kagma}} * {{Z|qu}}: {{W-|qu|caka}}, {{W-|qu|zaka}} * {{Z|khv}}: {{W-|khv|тӏеро}} * {{Z|ky}}: {{W+|ky|көпүрө}} * {{Z|si}}: {{W-|si|පාලම}} * {{Z|ko}}: {{W+|ko|다리}}, {{W-|ko|-교}} * {{Z|co}}: {{W-|co|ponte|n}} * {{Z|kum}}: {{W-|kum|кёпюр|tr=köpür}} * {{Z|lbe}}: {{W-|lbe|ламу}} * {{Z|lmy}}: {{W-|lmy|lede}} * {{Z|ltg}}: {{W-|ltg|tylts}} * {{Z|la}}: {{W+|la|pons|n}} * {{Z|lv}}: {{W+|lv|tilts|n}} * {{Z|lo}}: {{W+|lo|ຂົວ}}, {{W-|lo|ສະພານ}} * {{Z|lzz}}: {{W-|lzz|ხინჯი}} * {{Z|ln}}: {{W-|ln|gwagwa}}, {{W-|ln|gbagba}} * {{Z|lt}}: {{W+|lt|tiltas|n}} * {{Z|liv}}: {{W-|liv|sīlda}} * {{Z|khb}}: {{W-|khb|ᦷᦃ}} * {{Z|lg}}: {{W-|lg|olutindo}} * {{Z|lb}}: {{W+|lb|Bréck|m}} * {{Z|lnd}}: {{W-|lnd|afir}} * {{Z|mk}}: {{W-|mk|мост|n}}, {{W-|mk|каменик|n}} * {{Z|mg}}: {{W+|mg|tetezana}} * {{Z|ml}}: {{W+|ml|പാലം}} * {{Z|ms}}: {{W+|ms|jambatan}}, {{W+|ms|titi}}, {{W+|ms|titian}}, {{W-|ms|jambat}} * {{Z|mt}}: {{W-|mt|pont|n}} * {{Z|mnc}}: {{W-|mnc|ᡩᠣᠣᡥᠠᠨ}} * {{Z|gv}}: {{W-|gv|droghad|n}} * {{Z|mi}}: {{W-|mi|piriti}}, {{W-|mi|arawhata}}, {{W-|mi|arawhiti}}, {{W-|mi|arahanga}} * {{Z|mrw}}: {{W-|mrw|titay}} * {{Z|mr}}: {{W-|mr|पूल|n}}, {{W-|mr|सेतू|n}} * {{Z|hu}}: {{W+|hu|híd}} * {{Z|xmf}}: {{W-|xmf|ხინჯი}} * {{Z|mwl}}: {{W-|mwl|puonte}} * {{Z|mdf}}: {{W-|mdf|седь}} * {{Z|mn}}: *: {{W+|mn|гүүр}} {{W-|mn|ᠭᠦᠭᠦᠷᠭᠡ}} *: {{W+|mn|хөөрөг}} {{W-|mn|ᠬᠥᠭᠥᠷᠭᠡ}} * {{Z|nv}}: {{W-|nv|naʼníʼá}} * {{Z|nds}}: *: {{Z|nds-de}}: {{W-|nds-de|Brügge|m}} * {{Z|ne}}: {{W-|ne|पुल}} * {{Z|nog}}: {{W-|nog|коьпир}} * {{Z|nrf}}: {{W-|nrf|pont|n}} * {{Z|no}}: *: {{Z|nb}}: {{W+|nb|bro|n|m}}, {{W+|nb|bru|n|m}} *: {{Z|nn}}: {{W-|nn|bru|m}} * {{Z|ryu}}: {{W-|ryu|ぱし|tr=pashi}} * {{Z|oc}}: {{W+|oc|pònt|n}} * {{Z|or}}: {{W+|or|ପୋଲ}} * {{Z|om}}: {{W-|om|riqicha}} * {{Z|os}}: {{W-|os|хид}} * {{Z|ota}}: {{W-|ota|كوپری|tr=köprü}} * {{Z|ug}}: {{W+|ug|كۆۋرۈك}} * {{Z|uz}}: {{W+|uz|koʻprik}} * {{Z|ps}}: {{W+|ps|پل|tr=pul}} * {{Z|pdt}}: {{W-|pdt|Brigj|m}} * {{Z|pl}}: {{W+|pl|most|n}} * {{Z|pt}}: {{W+|pt|ponte|m}} * {{Z|pa}}: {{W-|pa|ਪੁਲ}} * {{Z|kk}}: {{W-|kk|көпір}} * {{Z|rm}}: {{W-|rm|punt|n}} * {{Z|ro}}: {{W+|ro|pod|nt}}, {{W+|ro|punte|m}} * {{Z|ru}}: {{W+|ru|мост|n}} * {{Z|rue}}: {{W-|rue|міст|n}}, {{W-|rue|мост|n}} * {{Z|se}}: {{W-|se|šaldi}} * {{Z|sms}}: {{W-|sms|mostt}} * {{Z|sm}}: {{W-|sm|faiā}}, {{W-|sm|alaniu}} * {{Z|sa}}: {{W+|sa|सेतु|n}} * {{Z|sc}}: {{W-|sc|ponte}}, {{W-|sc|ponti}} * {{Z|ceb}}: {{W-|ceb|tulay}} * {{Z|scn}}: {{W+|scn|ponti}}, {{W-|scn|punti}} * {{Z|sd}}: {{W-|sd|پل|tr=puli|cuda=پُلِ}} * {{Z|sh}}: {{W+|sh|bȓv}}, {{W+|sh|brvno}} *: Kirîlî: {{W-|sh|мо̑ст|n}}, {{W-|sh|ћу̀прија|m}} *: Latînî: {{W+|sh|mȏst|n}}, {{W+|sh|ćùprija|m}} * {{Z|syl}}: {{W-|syl|ꠢꠣꠇꠝ}}, {{W-|syl|ꠙꠥꠟ}} * {{Z|cu}}: *: Kirîlî: {{W-|cu|мостъ|n}} * {{Z|orv}}: {{W-|orv|мостъ|n}} * {{Z|sk}}: {{W+|sk|most|n}} * {{Z|sl}}: {{W+|sl|most|n}} * {{Z|so}}: {{W-|so|kaabad|m}} * Sorbî: *: {{Z|dsb}}: {{W-|dsb|móst|n}} *: {{Z|hsb}}: {{W-|hsb|móst|n}} * {{Z|es}}: {{W+|es|puente|n}}, {{W+|es|bóveda|m}} * {{Z|su}}: {{W-|su|cukang}} * {{Z|sva}}: {{W-|sva|ბოგ}} * {{Z|sw}}: {{W+|sw|daraja}} * {{Z|sv}}: {{W+|sv|bro|g}} * {{Z|tab}}: {{W-|tab|гъяд}} * {{Z|tg}}: {{W+|tg|пул}}, {{W-|tg|кӯпрук}} * {{Z|tl}}: {{W-|tl|tulay}} * {{Z|ty}}: {{W-|ty|'ē'a turu}} * {{Z|ta}}: {{W+|ta|பாலம்}} * {{Z|tsg}}: {{W-|tsg|taytayan}} * {{Z|th}}: {{W+|th|สะพาน}} * {{Z|tbl}}: {{W-|tbl|kitay}} * {{Z|ctd}}: {{W-|ctd|lei}} * {{Z|te}}: {{W+|te|వంతెన}}, {{W+|te|వారధి}}, {{W+|te|సేతువు}} * {{Z|tzm}}: {{W-|tzm|ⵜⵉⵍⴳⴳⵯⵉⵜ|m}} * {{Z|crh}}: {{W-|crh|köpür}} * {{Z|tt}}: {{W+|tt|күпер}} * {{Z|ti}}: {{W-|ti|ድልድል}} * {{Z|tr}}: {{W+|tr|köprü}} * {{Z|tk}}: {{W-|tk|köpri}} * {{Z|bo}}: {{W-|bo|ཟམ་པ}} * {{Z|kim}}: {{W-|kim|кеъприғ|tr=képriġ}} * {{Z|to}}: {{W-|to|hale kavakava}} * {{Z|trw}}: {{W-|trw|سیہ}} * {{Z|tn}}: {{W-|tn|borogo}} * {{Z|tum}}: {{W-|tum|ulalo}} * {{Z|tyv}}: {{W-|tyv|көвүрүг}} * {{Z|udm}}: {{W-|udm|выж}} * {{Z|ur}}: {{W-|ur|پل|n|tr=pul}} * {{Z|uk}}: {{W-|uk|міст|n}} * {{Z|vec}}: {{W-|vec|pónte}}, {{W-|vec|ponte}}, {{W-|vec|pónt}}, {{W+|vec|pont}} * {{Z|vi}}: {{W+|vi|cầu}} * {{Z|vo}}: {{W+|vo|pon}} * {{Z|wa}}: {{W+|wa|pont|n}} * {{Z|war}}: {{W-|war|tulay}} * {{Z|cy}}: {{W+|cy|pont|m}} * {{Z|wym}}: {{W-|wym|bryk|m}} * {{Z|wo}}: {{W-|wo|pom}} * {{Z|km}}: {{W+|km|ស្ពាន}} * {{Z|xh}}: {{W-|xh|umchankcatho}}, {{W-|xh|ibrorho}} * {{Z|yai}}: {{W-|yai|етк}} * {{Z|sah}}: {{W-|sah|муоста}}, {{W-|sah|күргэ}} * {{Z|yi}}: {{W-|yi|בריק|m}} * {{Z|yo}}: {{W-|yo|afárá}} * {{Z|el}}: {{W+|el|γέφυρα|m}} *: Kevn: {{W-|grc|γέφυρα|m}} * {{Z|za}}: {{W-|za|giuz}} * {{Z|zom}}: {{W-|zom|lei}} * {{Z|zu}}: {{W-|zu|ibhuloho}} {{werger-bin}} :{{werger çavkanî|en|bridge|beş=Ev qismê Wergerê|oldid=75873888}} === Hoker === {{hoker|ku}}, {{p-ya req}}, {{r-ya req}} # [[gelek]], [[gelekî]], [[zehf]], [[zêde]] #: {{nimûne|ku|Ev '''pir''' xweş e.|Ev gelekî xweş e.|rêz=1}} #: {{nimûne|ku|'''Pir''' dibêje lê kêm dike.|Tenê bo axiftinê zîrek e, bo kirinê tembel e.|rêz=1}} #* {{jêder|ku|{{Jêgirtin/Feqiyê Teyran}}|jêgirtin=Gunahê min bixufranî</br>“Mîm û Hê” '''pir''' gunehkar e</br>Belê navê te xeffar e}} #* {{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}} # {{f|ku|sormancî}} [[tijî]], [[dagirtî]], [[mişt]] #: {{nimûne|ku|Ev qazan pir e.|Ev qazan tijî ye.|rêz=1}} ==== Bi alfabeyên din ==== * {{ku-ar|پڕ}} ==== Formên alternatîv ==== * {{g|ku|pirr}} ==== Hevmane ==== {{kol3|ku |gelek |çendîn |mişe |zaf |zehf |zêde |zor }} ==== Dijmane ==== {{kol3|ku |kêm |piçek |hindik }} ==== Jê ==== {{kol3|ku|cure=Jê |piranî |pirî |pirbêj |pir kirin<q:lêker> |pir bûn<q:lêker> |pir xwarin |pirbûn<q:navdêr> |pirkirin<q:navdêr> |pirxwarin }} ==== Etîmolojî ==== {{ji|ine-pro|ku|-}}: *'''pel'''- / *'''ple'''- ("dagirtin, [[tijî]] kirin") :{{ji|ira-pro||-}} *'''per'''- ("tijî kirin") ::avestayî: '''pirine'''- ("tijî"), '''pir'''- ("tijî kirin") ::{{peo}}: '''peru''' ("tijî") ::{{ho}}: '''p'r''' ("tijî") ::{{fa}}: '''pur''' ("tijî") ::{{bal}}: '''pur''' ("pir") ... ::{{kmr}}: '''pir''' ("pir, gelek") ::{{ckb}}: '''pirr''' ("tijî") ::{{zza}}: '''pirr''' ("tijî") :{{sa}}: '''pûrna'''- ("tijî"), '''per'''- ("dagirtin, tijî kirin") :{{el}}: '''plethos''', '''poly'''- ("tijî, pir") :{{la}}: '''plēnus''' ("tijî") :{{de}}: '''voll''' ("tijî") :{{en}}: '''full''' ("tijî"), '''fill''' ("tijî kirin") ... ;{{biçûk|Çavkanî: * {{Cheung|r=295}} * {{Horn|r=66}} * {{Watkins|r=64}} * {{Etymonline}} * {{Pokorny|r=798 - 801}} }} ==== Werger ==== {{werger-ser|gelek, zehf}} * {{Z|ab}}: {{W-|ab|даара}}, {{W-|ab|даараӡа}} * {{Z|ady}}: {{W-|ady|дэд}} * {{Z|af}}: {{W+|af|baie}} * {{Z|sq}}: {{W+|sq|shumë}} * {{Z|de}}: {{W+|de|sehr}}, {{W+|de|ganz}}, {{W+|de|wahrlich}} *: {{Z|gsw}}: {{W-|gsw|schüüli}} * {{Z|am}}: {{W-|am|በጣም}} * {{Z|as}}: {{W-|as|বৰ}}, {{W-|as|খুব}}, {{W-|as|নিচেই}} * {{Z|ast}}: {{W+|ast|mui}}, {{W+|ast|per-}}, {{W+|ast|muncho}} * {{Z|az}}: {{W+|az|çox}}, {{W-|az|olduqca}}, {{W+|az|xeyli}} * {{Z|eu}}: {{W+|eu|oso}} * {{Z|ba}}: {{W-|ba|бик}}, {{W-|ba|бигерәк}}, {{W-|ba|үтә}} * {{Z|be}}: {{W+|be|ве́льмі}}, {{W-|be|ду́жа}} * {{Z|bn}}: {{W+|bn|খুব}} * {{Z|bth}}: {{W-|bth|paŭh}} * {{Z|bcl}}: {{W-|bcl|marhay}} * {{Z|bg}}: {{W+|bg|мно́го}}, {{W+|bg|бая́}} * {{Z|my}}: {{W+|my|တယ်}}, {{W+|my|အလွန်}}, {{W+|my|အရမ်း}}, {{W+|my|သိပ်}} * {{Z|ce}}: {{W-|ce|чӀогӀа}} * {{Z|cs}}: {{W+|cs|velmi}} * {{Z|chr}}: {{W-|chr|ᏙᎯᏳ}} * {{Z|cic}}: {{W-|cic|kani̠hka̠}} * {{Z|zh}}: *: {{Z|yue}}: {{W-|yue|好|tr=hou2}}, {{W-|yue|非常|tr=fei1 soeng4}} *: {{Z|dng}}: {{W-|dng|хын}}, {{W-|dng|-дихын}}, {{W-|dng|дин}}, {{W-|dng|йүә}} *: {{Z|cmn}}: {{W+|cmn|很|tr=hěn}}, {{W+|cmn|太|tr=tài}}, {{W+|cmn|非常|tr=fēicháng}}, {{W+|cmn|超|tr=chāo}} *: {{Z|nan}}: {{W+|nan|真|tr=chin}} *: {{Z|wuu}}: {{W-|wuu|蠻}}, {{W-|wuu|老}}, {{W-|wuu|交關}} * {{Z|da}}: {{W+|da|meget}}, {{W-|da|særlig}}, {{W+|da|vældig}} * {{Z|ovd}}: {{W-|ovd|stur-}} * {{Z|id}}: {{W+|id|sangat}}, {{W+|id|nian}}, {{W+|id|sekali}} * {{Z|ar}}: {{W+|ar|جِدًّا}} *: {{Z|arz}}: {{W-|arz|قوي|tr=ʔawi}}, {{W-|arz|جدا|tr=giddan}}, {{W-|ajp|كتير|tr=ktīr}} *: {{Z|afb}}: {{W-|afb|وايد|tr=wāyid}} *: {{Z|acw}}: {{W-|acw|مَرَّة|tr=marra}} *: {{Z|acm}}: {{W-|acm|كلش|tr=kulliš}}, {{W-|acm|هواية|tr=huwāya}}, {{W-|acm|هواي|tr=huwāy}}, {{W-|acm|حيل|tr=ḥēl}} *: {{Z|ary}}: {{W-|ary|بالزاف|tr=bizzāf}}, {{W-|ary|كتير|tr=ktīr}} *: {{Z|acp}}: {{W-|acp|كتير|tr=ktīr}} *: {{Z|ajp}}: {{W-|ajp|كتير|tr=ktīr}} *: {{Z|apd}}: {{W-|apd|شَدِيْد|tr=shadīd}} *: {{Z|aeb}}: {{W-|aeb|برشا|tr=barsha}} * {{Z|hy}}: {{W+|hy|շատ}} * {{Z|eo}}: {{W+|eo|tre}} * {{Z|et}}: {{W+|et|väga}} * {{Z|fa}}: {{W+|fa|بسیار|tr=besiyâr}}, {{W+|fa|خیلی|tr=xeyli}} * {{Z|fo}}: {{W-|fo|sera}}, {{W-|fo|ógvuliga}}, {{W-|fo|óføra}} * {{Z|fi}}: {{W+|fi|hyvin}}, {{W+|fi|todella}}, {{W+|fi|erittäin}}, {{W+|fi|kovin}}, {{W+|fi|tosi}} * {{Z|fr}}: {{W+|fr|très}} * {{Z|fy}}: {{W-|fy|tige}}, {{W-|fy|frij}} * {{Z|gd}}: {{W-|gd|glè}}, {{W-|gd|ro}}, {{W-|gd|fìor}} * {{Z|gl}}: {{W+|gl|moi}} * {{Z|got}}: {{W-|got|𐍆𐌹𐌻𐌿}} * {{Z|ka}}: {{W-|ka|ძალიან}}, {{W-|ka|ძლიერ}}, {{W-|ka|ძალზე}} * {{Z|gn}}: {{W-|gn|[[-ete]]}} * {{Z|ht}}: {{W-|ht|anpil}} * {{Z|hi}}: {{W+|hi|बहुत}} * {{Z|mww}}: {{W-|mww|heev}} * {{Z|nl}}: {{W+|nl|zeer}}, {{W+|nl|heel}}, {{W+|nl|erg}} * {{Z|hop}}: {{W-|hop|a'ni|n}}, {{W-|hop|hin'ur|m}} * {{Z|he}}: {{W+|he|מאוד|tr=me'ód|cuda=מאוד \ מְאֹד}} * {{Z|io}}: {{W+|io|tre}} * {{Z|ang}}: {{W-|ang|swīþe}} * {{Z|en}}: {{W+|en|very}} * {{Z|ia}}: {{W-|ia|multo}} * {{Z|ga}}: {{W-|ga|an-}}, {{W-|ga|ana-}}, {{W-|ga|iontach}} * {{Z|it}}: {{W+|it|molto}}, {{W+|it|estremamente}} * {{Z|is}}: {{W+|is|mjög}}, {{W-|is|ákaflega}}, {{W-|is|afar}}, {{W-|is|ógeðslega}}, {{W-|is|voða}}, {{W-|is|ýkja}}, {{W-|is|fjarska}}, {{W-|is|einkar}} * {{Z|ja}}: {{W+|ja|とても|tr=totemo}}, {{W+|ja|かなり|tr=kanari}}, {{W+|ja|非常|tr=ひじょうに, hijō ni|cuda=非常に}}, {{W-|ja|凄く|tr=すごく, sugoku}}, {{W+|ja|大変|tr=たいへん, taihen}}, {{W+|ja|大分|tr=だいぶ, daibu}}, {{W+|ja|随分|tr=ずいぶん, zuibun}}, {{W+|ja|ずっと|tr=zutto}}, {{W+|ja|めちゃ|tr=mecha}}, {{W-|ja|めっちゃ|tr=metcha}}, {{W+|ja|超|tr=ちょう, chō}}, {{W-|ja|ばり|tr=bari}}, {{W-|ja|つるつる|tr=tsuru tsuru}}, {{W+|ja|なまら|tr=namara}}, {{W-|ja|どえらい、でら|tr=doerai, dera}}, {{W+|ja|大いに|tr=おおいに, ōini}} * {{Z|kab}}: {{W-|kab|aṭas}} * {{Z|kl}}: {{W-|kl|assut}} * {{Z|kn}}: {{W+|kn|ಬಹಳ}}, {{W+|kn|ತುಂಬಾ}} * {{Z|krc}}: {{W-|krc|бек|tr=bek}} * {{Z|xqa}}: {{W-|xqa|اَيِغْ|tr=ayïɣ}} * {{Z|csb}}: {{W-|csb|barô}} * {{Z|ca}}: {{W+|ca|molt}}, {{W+|ca|força}} * {{Z|ky}}: {{W+|ky|абдан}}, {{W+|ky|өтө}} * {{Z|si}}: {{W-|si|හරි}}, {{W-|si|හුඟක්}} * {{Z|ko}}: {{W+|ko|아주}}, {{W+|ko|매우}}, {{W+|ko|너무}}, {{W+|ko|굉장히}} * {{Z|kum}}: {{W-|kum|кёп}}, {{W-|kum|оьтесиз}}, {{W-|kum|бек}} * {{Z|lld}}: {{W-|lld|scialdi}}, {{W-|lld|drë}}, {{W-|lld|stra}} * {{Z|lad}}: {{W-|lad|muy}} * {{Z|lv}}: {{W+|lv|ļoti}}, {{W-|lv|gluži}}, {{W-|lv|visai}} * {{Z|lo}}: {{W-|lo|ຈັດ}}, {{W-|lo|ຄະເຍີ}}, {{W+|lo|ຄັນ}}, {{W-|lo|ຈຸ່ນພູ່ນ}}, {{W-|lo|ຈ້າ}}, {{W-|lo|ຫຼາຍ}} * Latin: ''use [[superlative]] adjective'', {{W+|la|maximē}}, {{W-|la|summē}}, {{W-|la|valdē}}, {{W-|la|per-}} * {{Z|lzz}}: {{W-|lzz|dido}} * {{Z|lez}}: {{W-|lez|гзаф}}, {{W-|lez|лап}} * {{Z|lt}}: {{W+|lt|labai}} * {{Z|lb}}: {{W-|lb|ganz}} * {{Z|mk}}: {{W+|mk|многу}}, {{W-|mk|мошне}} * {{Z|ml}}: {{W+|ml|വളരെ}} * {{Z|ms}}: {{W+|ms|sangat}} * {{Z|mt}}: {{W+|mt|ħafna}} * {{Z|mnc}}: {{W-|mnc|ᡠᠮᡝᠰᡳ}} * {{Z|mi}}: {{W+|mi|tino}} * {{Z|gun}}: {{W-|gun|vaipa}} * {{Z|hu}}: {{W+|hu|nagyon}}, {{W+|hu|igen}} * {{Z|mn}}: *: Kirîlî: {{W+|mn|жинхэнэ}}, {{W+|mn|үнэн}}, {{W-|sh|вѐома}} * {{Z|nap}}: {{W-|nap|assai}}, {{W-|nap|nu sacco}} * {{Z|nv}}: {{W-|nv|ayóo}}, {{W-|nv|tʼóó báhádzigo}} * {{Z|ne}}: {{W-|ne|एकदमै|tr=ekdamai}} * {{Z|no}}: *: {{Z|nb}}: {{W+|nb|veldig}}, {{W+|nb|meget}} *: {{Z|nn}}: {{W-|nn|veldig}}, {{W-|nn|ovleg}} * {{Z|oc}}: {{W+|oc|fòrça}} * {{Z|or}}: {{W+|or|ବହୁତ}} * {{Z|os}}: {{W-|os|тынг}}, {{W-|os|иттӕг}} * {{Z|ug}}: {{W-|ug|بەك}}, {{W-|ug|ناھايىتى}} * {{Z|uz}}: {{W+|uz|oʻlgunday}}, {{W+|uz|oʻlguncha}}, {{W+|uz|juda}}, {{W+|uz|gʻoyatda}} * {{Z|ps}}: {{W+|ps|ډېر|tr=ḍer}} * {{Z|pdt}}: {{W-|pdt|sea}} * {{Z|pl}}: {{W+|pl|bardzo}}, {{W+|pl|wielce}} * {{Z|roa-opt}}: {{W-|roa-opt|mui}}, {{W-|roa-opt|muito}} * {{Z|pt}}: {{W+|pt|muito}}; {{W+|pt|assaz}} * {{Z|pa}}: {{W-|pa|ਬਹੁਤ|p}} * {{Z|kk}}: {{W-|kk|аса}}, {{W-|kk|өте}}, {{W-|kk|ерен}} * Khanty: *: {{Z|kca}}: {{W-|kca|шєӈк}} * {{Z|rm}}: {{W-|rm|fitg}} * {{Z|ro}}: {{W+|ro|foarte}} * {{Z|ru}}: {{W+|ru|о́чень}}, {{W+|ru|весьма́}}, {{W+|ru|изря́дно}}, {{W+|ru|дю́же}}, {{W+|ru|зело́}}, {{W+|ru|вельми́}} * {{Z|rue}}: {{W-|rue|барз}} * {{Z|se}}: {{W-|se|hui}} * {{Z|sa}}: {{W+|sa|अति|tr=áti}} * {{Z|sei}}: {{W-|sei|áa}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|вр̏ло}} *: Latînî: {{W+|sh|vȑlo}}, {{W+|sh|vèoma}} * {{Z|syl}}: {{W-|syl|ꠛꠃꠔ}} * {{Z|sco}}: {{W-|sco|gey}}, {{W-|sco|unco}}, {{W-|sco|vera}} * {{Z|cu}}: *: Kirîlî: {{W-|cu|ѕѣло}}, {{W-|cu|зѣло}}, {{W-|cu|вельми}}, {{W-|cu|вьсьма}}, {{W-|cu|мъного}} * {{Z|orv}}: {{W-|orv|вельми}}, {{W-|orv|вьсьма}} * {{Z|sk}}: {{W+|sk|veľmi}}, {{W-|sk|mnoho}} * {{Z|sl}}: {{W+|sl|zeló}} * Sorbî: *: {{Z|dsb}}: {{W-|dsb|wjelgin}} *: {{Z|hsb}}: {{W-|hsb|jara}}, {{W-|hsb|wulce}} * {{Z|es}}: {{W+|es|muy}} * {{Z|sva}}: {{W-|sva|გუნ}} * {{Z|sw}}: {{W-|sw|sana}} * {{Z|sv}}: {{W+|sv|mycket}}, {{W+|sv|väldigt}}, {{W+|sv|jätte-}} * {{Z|zdj}}: {{W-|zdj|halisi}}, {{W-|zdj|ha kuu}}, {{W-|zdj|kabisa|cuda=kaɓisa}} * {{Z|tg}}: {{W+|tg|бисёр}}, {{W+|tg|хеле}} * {{Z|tl}}: {{W-|tl|talaga}}, {{W-|tl|talagang}}, {{W-|tl|sobra}}, {{W-|tl|sobrang}} * {{Z|ta}}: {{W+|ta|மிகவும்}}, {{W+|ta|ரொம்ப}}, {{W+|ta|மிக}} * {{Z|th}}: {{W+|th|มาก}}, {{W+|th|แสน}} * {{Z|te}}: {{W+|te|చాలా}} * {{Z|crh}}: {{W-|crh|çoq}} * {{Z|tt}}: {{W+|tt|бик}} * {{Z|otk}}: {{W-|otk|𐰪𐰃𐰍|ts=ańïɣ}} * {{Z|tr}}: {{W+|tr|çok}}, {{W+|tr|pek}} * {{Z|tk}}: {{W-|tk|örän}} * {{Z|bo}}: {{W-|bo|ཞེ་དྲགས}} * {{Z|txb}}: {{W-|txb|tsamo}}, {{W-|txb|tanki}} * {{Z|tyv}}: {{W-|tyv|аажок}}, {{W-|tyv|адак}}, {{W-|tyv|дыка}}, {{W-|tyv|дэндии}}, {{W-|tyv|чүдек}} * {{Z|ur}}: {{W-|ur|بَہُت|tr=bahut}} * {{Z|uk}}: {{W+|uk|ду́же}}, {{W-|uk|ве́льми}} * {{Z|vi}}: {{W+|vi|rất}}, {{W+|vi|lắm}}, {{W+|vi|quá}} * {{Z|vo}}: {{W+|vo|vemo}} * {{Z|cy}}: {{W+|cy|iawn}} * {{Z|wo}}: {{W+|wo|lool}} * {{Z|km}}: {{W+|km|ណាស់|tr=nah}} * {{Z|sah}}: {{W-|sah|олус}}, {{W-|sah|наһаа}}, {{W-|sah|бэрт}} * {{Z|yi}}: {{W-|yi|זייער}} * {{Z|el}}: {{W+|el|πολύ}} *: Kevn: {{W-|grc|λίαν}}, {{W-|grc|πάνυ}}, {{W-|grc|μάλα}}, {{W-|grc|ἀγα-}} {{werger-bin}} :{{werger çavkanî|en|very|beş=Ev qismê Wergerê|oldid=75873155}} === Cînav === {{cînav|ku}} # [[gelek]], [[zehf]], [[hejmar]]eke [[mezin]]: #: ''Pir kes li wê derê bûn.'' ==== Werger ==== {{werger-ser}} * {{Z|ady}}: {{W-|ady|ӏаджэ}} * {{Z|af}}: {{W+|af|baie}}, {{W-|af|menige}} * {{Z|ak}}: {{W-|ak|horow}}, {{W-|ak|ahorow}} * {{Z|sq}}: {{W+|sq|shumë}} * {{Z|de}}: {{W+|de|viele}} * {{Z|am}}: {{W-|am|ብዙ}} * {{Z|an}}: {{W-|an|muitos|n-p}}, {{W-|an|muitas|m-p}} * {{Z|ast}}: {{W+|ast|munchos|n-p}}, {{W+|ast|munches|m-p}} * {{Z|az}}: {{W+|az|çox}} * {{Z|ban}}: {{W-|ban|liu}}, {{W-|ban|akéh}} * {{Z|ba}}: {{W-|ba|күп}} * {{Z|be}}: {{W-|be|мно́гія|sc=Cyrl}}, {{W+|be|шмат|sc=Cyrl}}, {{W-|be|мно́га|sc=Cyrl}}, {{W+|be|бага́та|sc=Cyrl}} * {{Z|bcl}}: {{W-|bcl|dakol}}, {{W-|bcl|kadakol}} * {{Z|bg}}: {{W+|bg|мно́го}} * {{Z|my}}: {{W+|my|များ|sc=Mymr}}, {{W-|my|များကြီး|sc=Mymr}} * {{Z|kac}}: {{W-|kac|law}} * {{Z|ce}}: {{W-|ce|дукха}} * {{Z|cs}}: {{W+|cs|mnoho}} * {{Z|chr}}: {{W-|chr|ᏥᏈᏍᏗ}}, {{W-|chr|ᎤᎪᏗᏗ}} * {{Z|zh}}: *: {{Z|yue}}: {{W-|yue|好多|tr=hou2 do1}} *: {{Z|dng}}: {{W-|dng|дуә}} *: {{Z|hak}}: {{W-|hak|多|tr=tô}} *: {{Z|cmn}}: {{W+|cmn|多|tr=duō}}, {{W+|cmn|很多|tr=hěnduō}}, {{W+|cmn|好多|tr=hǎoduō}}, {{W+|cmn|許多|tr=xǔduō}} *: {{Z|mnp}}: {{W-|mnp|濟|tr=cāi}} *: {{Z|cdo}}: {{W-|cdo|濟|tr=sâ̤}} *: {{Z|nan}}: {{W+|nan|濟|tr=chōe / chē / chǒe / chēre}} *: {{Z|wuu}}: {{W-|wuu|多}} * {{Z|dlm}}: {{W-|dlm|mult}}, {{W-|dlm|muolt}} * {{Z|da}}: {{W+|da|mange}}, {{W-|da|mangen|g}} * {{Z|dlg}}: {{W-|dlg|үгүс}} * {{Z|id}}: {{W+|id|banyak}} * {{Z|ar}}: {{W+|ar|كَثِير}} *: {{Z|egy}}: {{W-|arz|كتير|tr=kitīr}} * {{Z|hy}}: {{W+|hy|շատ}}, {{W+|hy|բազում}} * {{Z|eo}}: {{W+|eo|multaj}} * {{Z|et}}: {{W+|et|palju}} * {{Z|gez}}: {{W-|gez|ብዙኅ}} * {{Z|fa}}: {{W+|fa|زیاد|tr=ziyâd}}, {{W+|fa|چندین|tr=čandin}}, {{W+|fa|بسیار|tr=besiyâr}}, {{W+|fa|خیلی|tr=xeyli}} * {{Z|fo}}: {{W+|fo|mangur}}, {{W-|fo|nógvur}} * {{Z|fi}}: {{W+|fi|moni}}, {{W+|fi|monta}}, ''see also [[Thesaurus:runsaasti]]'' * {{Z|fr}}: {{W+|fr|beaucoup|cuda=beaucoup de}}, {{W+|fr|nombreux|cuda=de nombreux}}, {{W+|fr|plusieurs}} * {{Z|frr}}: {{W-|frr|fuul}} * {{Z|fy}}: {{W-|fy|protte}}, {{W-|fy|folle}} * {{Z|gd}}: {{W-|gd|iomadh}} * {{Z|gl}}: {{W-|gl|moitos|n-p}}, {{W-|gl|moitas|m-p}}, {{W-|gl|muitos|n-p}}, {{W-|gl|muitas|m-p}} * {{Z|got}}: {{W-|got|𐌼𐌰𐌽𐌰𐌲𐍃}} * {{Z|ka}}: {{W-|ka|ბევრი}}, {{W-|ka|მრავალი}} * {{Z|ht}}: {{W-|ht|anpil}} * {{Z|haw}}: {{W-|haw|he nui}} * {{Z|hi}}: {{W+|hi|बहुत}}, {{W+|hi|बहु}}, {{W+|hi|अधिक}}, {{W-|hi|ज़्यादा}} * {{Z|nl}}: {{W+|nl|veel}}, {{W+|nl|vele}}, {{W+|nl|menig}} * {{Z|he}}: {{W-|he|רַבִּים|tr=rabim|sc=Hebr}}, {{W+|he|הַרְבֵּה|tr=harbé|sc=Hebr}} * {{Z|io}}: {{W+|io|multa}} * {{Z|ig}}: {{W-|ig|ìmìlìkiti}} * {{Z|ang}}: {{W-|ang|feolo}}, {{W-|ang|feola}} * {{Z|en}}: {{W+|en|many}} * {{Z|izh}}: {{W-|izh|paljo}}, {{W-|izh|moni}}, {{W-|izh|ussia}}, {{W-|izh|isost}}, {{W-|izh|äijä}} * {{Z|inh}}: {{W-|inh|дуккха}} * {{Z|ia}}: {{W-|ia|multe}} * {{Z|ga}}: {{W-|ga|a lán}}, {{W-|ga|mórán}} *: {{Z|sga}}: {{W-|sga|il}}, {{W-|sga|imdae}} * {{Z|it}}: {{W+|it|molti}}, {{W-|it|un gran numero di}} * {{Z|is}}: {{W+|is|margur}} * {{Z|ja}}: {{W+|ja|多く|tr=おおくの, ōkuno|cuda=多くの|sc=Jpan}}, {{W+|ja|多い|tr=おおい, ōi|sc=Jpan}}, {{W+|ja|沢山|tr=たくさん, takusan|sc=Jpan}} * {{Z|jv}}: *: Karakanî: {{W+|jv|ꦲꦏꦺꦃ}}, {{W+|jv|ꦏꦛꦃ}} *: Latînî: {{W+|jv|akèh}}, {{W+|jv|kathah}} * {{Z|kbd}}: {{W-|kbd|ӏэджэ}}, {{W-|kbd|куэд}} * {{Z|ca}}: {{W+|ca|molt|n-p}}, {{W+|ca|moltes|m-p}} * {{Z|ktu}}: {{W-|ktu|mingi}} * {{Z|kg}}: {{W-|kg|mingi}} * {{Z|ki}}: {{W-|ki|-ingĩ}} * {{Z|swb}}: {{W-|swb|engi|cuda=-engi}} * {{Z|ko}}: {{W+|ko|많은}} * {{Z|la}}: {{W+|la|multi}} * {{Z|lv}}: {{W+|lv|daudz}}, {{W+|lv|daudzi}} * {{Z|lo}}: {{W-|lo|ຫຼາຍ}} * {{Z|ln}}: {{W-|ln|mingi}} * {{Z|lij}}: {{W-|lij|molto}} * {{Z|lt}}: {{W+|lt|daug}}, {{W-|lt|daugelis}} * {{Z|mk}}: {{W+|mk|многу}} * {{Z|ml}}: {{W+|ml|അനേകം}} * {{Z|ms}}: {{W+|ms|banyak}}, {{W+|ms|ramai}} * {{Z|hu}}: {{W+|hu|sok}} * {{Z|egy}}: {{W-egy|ꜥšꜣ|h=aSA:Z2}} * {{Z|mwl}}: {{W-|mwl|muitos|n-p}}, {{W-|mwl|muitas|m-p}} * {{Z|mn}}: {{W+|mn|олон}} * {{Z|gld}}: {{W-|gld|эгди}} * {{Z|nv}}: {{W-|nv|ląʼí}}, {{W-|nv|łą́}}, {{W-|nv|łání}}, {{W-|nv|tʼóó ahayóí}}, {{W-|nv|ahoniiʼyóí}} * {{Z|nds}}: {{W-|nds|männige|p}}, {{W-|nds|männigen|n|nt}}, {{W-|nds|männigene|m}}, {{W-|nds|männigein|n|nt}}, {{W-|nds|männigeine|m}}, {{W-|nds|vęle|p}}, {{W-|nds|vęl}} * {{Z|non}}: {{W-|non|margr}} * {{Z|no}}: {{W+|no|mange}} * {{Z|oc}}: {{W+|oc|fòrça}} * {{Z|or}}: {{W+|or|ବହୁ}} * {{Z|ps}}: {{W+|ps|ډېر|tr=ḍer}}, {{W+|ps|زيات|tr=zyât}} * {{Z|myp}}: {{W-|myp|xaíbái}} * {{Z|pdt}}: {{W-|pdt|väl}} * {{Z|pl}}: {{W+|pl|wiele}}, {{W+|pl|dużo}} * {{Z|pt}}: {{W+|pt|muitos|n-p}}, {{W+|pt|muitas|m-p}} * {{Z|ro}}: {{W+|ro|mulți|n-p}}, {{W-|ro|multe|m-p}} * {{Z|ru}}: {{W+|ru|мно́го}}, {{W+|ru|мно́гие}}, {{W+|ru|мно́гий}} * {{Z|rue}}: {{W-|rue|много}} * {{Z|sms}}: {{W-|sms|mäŋgg}} * {{Z|sa}}: {{W+|sa|बहु}} * {{Z|srn}}: {{W-|srn|furu}} * {{Z|sh}}: {{W+|sh|mnogo|p}}, {{W-|sh|много}}, {{W+|sh|mnogi}}, {{W-|sh|многи}} * {{Z|sco}}: {{W-|sco|mony}} * {{Z|sk}}: {{W-|sk|mnohý|n}}, {{W-|sk|mnohá|m}}, {{W-|sk|mnohé|nt}}, {{W-|sk|mnohí|n-p}}, {{W-|sk|mnohé|m-p|nt-p}}, {{W-|sk|mnoho}}, {{W-|sk|veľa}} * {{Z|sl}}: {{W+|sl|veliko}} * Sorbî: *: {{Z|dsb}}: {{W-|dsb|wjele}} * {{Z|es}}: {{W+|es|muchos|n-p}}, {{W+|es|muchas|m-p}} * {{Z|su}}: {{W-|su|seueur}} * {{Z|sw}}: {{W-|sw|ingi|cuda=-ingi}} * {{Z|sv}}: {{W+|sv|många}} * {{Z|xsr}}: {{W-|xsr|མང་མུ|tr=mangmu}} * {{Z|zdj}}: {{W-|zdj|indji|cuda=-indji}} * {{Z|ta}}: {{W+|ta|நிறைய}}, {{W+|ta|பல}} * {{Z|th}}: {{W+|th|ขนัด}}, {{W+|th|มาก}}, {{W+|th|เยอะ}}, {{W+|th|รุ่ม}}, {{W+|th|หลาย}} * {{Z|te}}: {{W+|te|చాలా}} * {{Z|tr}}: {{W+|tr|çok}}, {{W+|tr|pek çok}}, {{W+|tr|birçok}}, {{W+|tr|fazla}} * {{Z|bo}}: {{W-|bo|མང་པོ}} * {{Z|xto}}: {{W-|xto|māk}} * {{Z|txb}}: {{W-|txb|māka}} * {{Z|ur}}: {{W-|ur|بہت|tr=bahut|sc=ur-Arab}}, {{W-|ur|زیادہ|tr=zyādā|sc=ur-Arab}} * {{Z|uk}}: {{W+|uk|бага́то|sc=Cyrl}}, {{W-|uk|чима́ло|sc=Cyrl}} * {{Z|vi}}: {{W+|vi|nhiều}}, {{W+|vi|lắm}} * {{Z|vo}}: {{W+|vo|mödik}} * {{Z|wa}}: {{W+|wa|bråmint des}} * {{Z|war}}: {{W-|war|da-mo}} * {{Z|cy}}: {{W-|cy|llawer}} * {{Z|km}}: {{W+|km|ច្រើន}} * {{Z|sah}}: {{W-|sah|элбэх}}, {{W-|sah|үгүс}} * {{Z|yi}}: {{W-|yi|אַ סך|tr=a sakh}} * {{Z|el}}: {{W+|el|πολλοί|n-p}} *: Kevn: {{W-|grc|πολλοί|n-p}}, {{W-|grc|πολλαί|m-p}}, {{W-|grc|πολλά|nt-p}} * {{Z|zea}}: {{W-|zea|vee}} * {{Z|za}}: {{W-|za|haujlai}}, {{W-|za|lai}} * {{Z|ase}}: {{W-|ase|S@InsideChesthigh-PalmUp-S@InsideChesthigh-PalmUp 5@InsideChesthigh-PalmUp-5@InsideChesthigh-PalmUp}} {{werger-bin}} :{{werger çavkanî|en|many|beş=Ev qismê Wergerê|oldid=75874306}} === Rengdêr === {{rengdêr|ku}} # [[gelek]], [[zehf]], [[zêde]], [[hejmar]]eke [[mezin]]: #: ''Em pir in, ne hindik in.'' (Em gelek in, ne kêm in.) ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|zahlreich}}, {{W-|de|vielzählig}} * {{Z|az}}: {{W-|az|çoxsaylı}}, {{W+|az|çoxlu}} * {{Z|be}}: {{W-|be|шматлі́кі}} * {{Z|bg}}: {{W+|bg|многобро́ен}}, {{W+|bg|многочи́слен}} * {{Z|cs}}: {{W+|cs|četný}}, {{W+|cs|početný}} * {{Z|zh}}: *: {{Z|cmn}}: {{W-|cmn|眾多|tr=zhòngduō}}, {{W+|cmn|多|tr=duō}} * {{Z|da}}: {{W-|da|talrig}} * {{Z|ar}}: {{W-|ar|عَدِيد}}, {{W+|ar|كَثِير}} * {{Z|hy}}: {{W+|hy|բազմաթիվ}} * {{Z|eo}}: {{W-|eo|multnombra}} * {{Z|et}}: {{W-|et|arvukas}} * {{Z|fi}}: {{W+|fi|lukuisa}} * {{Z|fr}}: {{W+|fr|nombreux}} * {{Z|gl}}: {{W+|gl|numeroso}} * {{Z|ka}}: {{W-|ka|ურიცხვი}}, {{W-|ka|უამრავი}}, {{W-|ka|დიდძალი}} * {{Z|nl}}: {{W+|nl|talrijk}}, {{W+|nl|ontelbaar}}, {{W-|nl|numereus}} * {{Z|he}}: {{W+|he|רַב|tr=rav}} * {{Z|ang}}: {{W-|ang|getælfull}} * {{Z|en}}: {{W+|en|numerous}} * {{Z|ia}}: {{W-|ia|numerose}} * {{Z|ga}}: {{W-|ga|líonmhar}} * {{Z|it}}: {{W+|it|numeroso}} * {{Z|is}}: {{W-|is|fjölmargur}} * {{Z|ja}}: {{W+|ja|多数|tr=たすうの, tasū no|cuda=多数の}}, {{W+|ja|多い|tr=おおい, ōi}} * {{Z|ca}}: {{W+|ca|nombrós}} * {{Z|ko}}: {{W+|ko|수많다}}, {{W+|ko|다수|cuda=다수의}} * {{Z|la}}: {{W-|la|numerōsus}}, {{W-|la|frequens}}, {{W-|la|creber}} * {{Z|lv}}: {{W-|lv|daudzskaitlīgs}} * {{Z|lt}}: {{W-|lt|gausus}} * {{Z|mk}}: {{W-|mk|многуброен}}, {{W-|mk|броен}} * {{Z|ml}}: {{W+|ml|അനേകം}}, {{W+|ml|നിരവധി}}, {{W+|ml|കുറേ}} * {{Z|mi}}: {{W-|mi|makiu}}, {{W-|mi|tini makiu}}, {{W-|mi|maruru}}, {{W-|mi|maha}}, {{W-|mi|ngeangea}}, {{W-|mi|huhua}}, {{W-|mi|tini whāioio}}, {{W-|mi|mahamaha}}, {{W-|mi|tīpatere}}, {{W-|mi|makehua}}, {{W-|mi|tini makehua}} * {{Z|hu}}: {{W+|hu|számos}}, {{W+|hu|nagyszámú}} * {{Z|egy}}: {{W-egy|ꜥšꜣ|h=aSA:Z2}} * {{Z|nds}}: *: {{Z|nds-de}}: {{W-|nds-de|tahlriek}}, {{W-|nds-de|tallriek}} * {{Z|no}}: *: {{Z|nb}}: {{W+|nb|tallrik}} *: {{Z|nn}}: {{W-|nn|talrik}} * {{Z|ota}}: {{W-|ota|چوك|tr=çok}}, {{W-|ota|كثرت اوزره|tr=kesret üzere}} * {{Z|ug}}: {{W-|ug|نۇرغۇن}} * {{Z|pl}}: {{W+|pl|liczny}} * {{Z|pt}}: {{W+|pt|numeroso}} * {{Z|ro}}: {{W+|ro|numeros}} * {{Z|ru}}: {{W+|ru|многочи́сленный}} * {{Z|sa}}: {{W+|sa|बहु}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|бро̑јан}}, {{W-|sh|мно̏гобро̄јан}} *: Latînî: {{W+|sh|brȏjan}}, {{W+|sh|mnȍgobrōjan}} * {{Z|sk}}: {{W-|sk|početný}} * {{Z|sl}}: {{W-|sl|številen}}, {{W-|sl|številčen}} * {{Z|es}}: {{W+|es|numeroso}} * {{Z|sv}}: {{W+|sv|talrik}} * {{Z|tr}}: {{W+|tr|sayısız|lit=without a number}}, {{W-|tr|çok sayıda|lit= in large quantities}}, {{W+|tr|birçok}} * {{Z|uk}}: {{W-|uk|багаточи́сельний}}, {{W+|uk|числе́нний}} * {{Z|vi}}: {{W+|vi|đông}}, {{W+|vi|nhiều}} {{werger-bin}} :{{werger çavkanî|en|numerous|beş=Ev qismê Wergerê|oldid=75881281}} === Navdêr 2 === {{navdêr|ku}} ''[[pirjimar]]'' # [[gelek]], [[zehf]], [[hejmar]]eke [[mezin]]: # ''Pir (kes) dixwazin lê kêm (kes) qebûl dibin.'' (Gelek kes dixwazin lê hindik kes tên qebûlkirin.) ==== Werger ==== {{werger-ser}} * {{Z|ady}}: {{W-|ady|ӏаджэ}} * {{Z|af}}: {{W+|af|baie}}, {{W-|af|menige}} * {{Z|ak}}: {{W-|ak|horow}}, {{W-|ak|ahorow}} * {{Z|sq}}: {{W+|sq|shumë}} * {{Z|de}}: {{W+|de|viele}} * {{Z|am}}: {{W-|am|ብዙ}} * {{Z|an}}: {{W-|an|muitos|n-p}}, {{W-|an|muitas|m-p}} * {{Z|ast}}: {{W+|ast|munchos|n-p}}, {{W+|ast|munches|m-p}} * {{Z|az}}: {{W+|az|çox}} * {{Z|ban}}: {{W-|ban|liu}}, {{W-|ban|akéh}} * {{Z|ba}}: {{W-|ba|күп}} * {{Z|be}}: {{W-|be|мно́гія|sc=Cyrl}}, {{W+|be|шмат|sc=Cyrl}}, {{W-|be|мно́га|sc=Cyrl}}, {{W+|be|бага́та|sc=Cyrl}} * {{Z|bcl}}: {{W-|bcl|dakol}}, {{W-|bcl|kadakol}} * {{Z|bg}}: {{W+|bg|мно́го}} * {{Z|my}}: {{W+|my|များ|sc=Mymr}}, {{W-|my|များကြီး|sc=Mymr}} * {{Z|kac}}: {{W-|kac|law}} * {{Z|ce}}: {{W-|ce|дукха}} * {{Z|cs}}: {{W+|cs|mnoho}} * {{Z|chr}}: {{W-|chr|ᏥᏈᏍᏗ}}, {{W-|chr|ᎤᎪᏗᏗ}} * {{Z|zh}}: *: {{Z|yue}}: {{W-|yue|好多|tr=hou2 do1}} *: {{Z|dng}}: {{W-|dng|дуә}} *: {{Z|hak}}: {{W-|hak|多|tr=tô}} *: {{Z|cmn}}: {{W+|cmn|多|tr=duō}}, {{W+|cmn|很多|tr=hěnduō}}, {{W+|cmn|好多|tr=hǎoduō}}, {{W+|cmn|許多|tr=xǔduō}} *: {{Z|mnp}}: {{W-|mnp|濟|tr=cāi}} *: {{Z|cdo}}: {{W-|cdo|濟|tr=sâ̤}} *: {{Z|nan}}: {{W+|nan|濟|tr=chōe / chē / chǒe / chēre}} *: {{Z|wuu}}: {{W-|wuu|多}} * {{Z|dlm}}: {{W-|dlm|mult}}, {{W-|dlm|muolt}} * {{Z|da}}: {{W+|da|mange}}, {{W-|da|mangen|g}} * {{Z|dlg}}: {{W-|dlg|үгүс}} * {{Z|id}}: {{W+|id|banyak}} * {{Z|ar}}: {{W+|ar|كَثِير}} *: {{Z|egy}}: {{W-|arz|كتير|tr=kitīr}} * {{Z|hy}}: {{W+|hy|շատ}}, {{W+|hy|բազում}} * {{Z|eo}}: {{W+|eo|multaj}} * {{Z|et}}: {{W+|et|palju}} * {{Z|gez}}: {{W-|gez|ብዙኅ}} * {{Z|fa}}: {{W+|fa|زیاد|tr=ziyâd}}, {{W+|fa|چندین|tr=čandin}}, {{W+|fa|بسیار|tr=besiyâr}}, {{W+|fa|خیلی|tr=xeyli}} * {{Z|fo}}: {{W+|fo|mangur}}, {{W-|fo|nógvur}} * {{Z|fi}}: {{W+|fi|moni}}, {{W+|fi|monta}}, ''see also [[Thesaurus:runsaasti]]'' * {{Z|fr}}: {{W+|fr|beaucoup|cuda=beaucoup de}}, {{W+|fr|nombreux|cuda=de nombreux}}, {{W+|fr|plusieurs}} * {{Z|frr}}: {{W-|frr|fuul}} * {{Z|fy}}: {{W-|fy|protte}}, {{W-|fy|folle}} * {{Z|gd}}: {{W-|gd|iomadh}} * {{Z|gl}}: {{W-|gl|moitos|n-p}}, {{W-|gl|moitas|m-p}}, {{W-|gl|muitos|n-p}}, {{W-|gl|muitas|m-p}} * {{Z|got}}: {{W-|got|𐌼𐌰𐌽𐌰𐌲𐍃}} * {{Z|ka}}: {{W-|ka|ბევრი}}, {{W-|ka|მრავალი}} * {{Z|ht}}: {{W-|ht|anpil}} * {{Z|haw}}: {{W-|haw|he nui}} * {{Z|hi}}: {{W+|hi|बहुत}}, {{W+|hi|बहु}}, {{W+|hi|अधिक}}, {{W-|hi|ज़्यादा}} * {{Z|nl}}: {{W+|nl|veel}}, {{W+|nl|vele}}, {{W+|nl|menig}} * {{Z|he}}: {{W-|he|רַבִּים|tr=rabim|sc=Hebr}}, {{W+|he|הַרְבֵּה|tr=harbé|sc=Hebr}} * {{Z|io}}: {{W+|io|multa}} * {{Z|ig}}: {{W-|ig|ìmìlìkiti}} * {{Z|ang}}: {{W-|ang|feolo}}, {{W-|ang|feola}} * {{Z|en}}: {{W+|en|many}} * {{Z|izh}}: {{W-|izh|paljo}}, {{W-|izh|moni}}, {{W-|izh|ussia}}, {{W-|izh|isost}}, {{W-|izh|äijä}} * {{Z|inh}}: {{W-|inh|дуккха}} * {{Z|ia}}: {{W-|ia|multe}} * {{Z|ga}}: {{W-|ga|a lán}}, {{W-|ga|mórán}} *: {{Z|sga}}: {{W-|sga|il}}, {{W-|sga|imdae}} * {{Z|it}}: {{W+|it|molti}}, {{W-|it|un gran numero di}} * {{Z|is}}: {{W+|is|margur}} * {{Z|ja}}: {{W+|ja|多く|tr=おおくの, ōkuno|cuda=多くの|sc=Jpan}}, {{W+|ja|多い|tr=おおい, ōi|sc=Jpan}}, {{W+|ja|沢山|tr=たくさん, takusan|sc=Jpan}} * {{Z|jv}}: *: Karakanî: {{W+|jv|ꦲꦏꦺꦃ}}, {{W+|jv|ꦏꦛꦃ}} *: Latînî: {{W+|jv|akèh}}, {{W+|jv|kathah}} * {{Z|kbd}}: {{W-|kbd|ӏэджэ}}, {{W-|kbd|куэд}} * {{Z|ca}}: {{W+|ca|molt|n-p}}, {{W+|ca|moltes|m-p}} * {{Z|ktu}}: {{W-|ktu|mingi}} * {{Z|kg}}: {{W-|kg|mingi}} * {{Z|ki}}: {{W-|ki|-ingĩ}} * {{Z|swb}}: {{W-|swb|engi|cuda=-engi}} * {{Z|ko}}: {{W+|ko|많은}} * {{Z|la}}: {{W+|la|multi}} * {{Z|lv}}: {{W+|lv|daudz}}, {{W+|lv|daudzi}} * {{Z|lo}}: {{W-|lo|ຫຼາຍ}} * {{Z|ln}}: {{W-|ln|mingi}} * {{Z|lij}}: {{W-|lij|molto}} * {{Z|lt}}: {{W+|lt|daug}}, {{W-|lt|daugelis}} * {{Z|mk}}: {{W+|mk|многу}} * {{Z|ml}}: {{W+|ml|അനേകം}} * {{Z|ms}}: {{W+|ms|banyak}}, {{W+|ms|ramai}} * {{Z|hu}}: {{W+|hu|sok}} * {{Z|egy}}: {{W-egy|ꜥšꜣ|h=aSA:Z2}} * {{Z|mwl}}: {{W-|mwl|muitos|n-p}}, {{W-|mwl|muitas|m-p}} * {{Z|mn}}: {{W+|mn|олон}} * {{Z|gld}}: {{W-|gld|эгди}} * {{Z|nv}}: {{W-|nv|ląʼí}}, {{W-|nv|łą́}}, {{W-|nv|łání}}, {{W-|nv|tʼóó ahayóí}}, {{W-|nv|ahoniiʼyóí}} * {{Z|nds}}: {{W-|nds|männige|p}}, {{W-|nds|männigen|n|nt}}, {{W-|nds|männigene|m}}, {{W-|nds|männigein|n|nt}}, {{W-|nds|männigeine|m}}, {{W-|nds|vęle|p}}, {{W-|nds|vęl}} * {{Z|non}}: {{W-|non|margr}} * {{Z|no}}: {{W+|no|mange}} * {{Z|oc}}: {{W+|oc|fòrça}} * {{Z|or}}: {{W+|or|ବହୁ}} * {{Z|ps}}: {{W+|ps|ډېر|tr=ḍer}}, {{W+|ps|زيات|tr=zyât}} * {{Z|myp}}: {{W-|myp|xaíbái}} * {{Z|pdt}}: {{W-|pdt|väl}} * {{Z|pl}}: {{W+|pl|wiele}}, {{W+|pl|dużo}} * {{Z|pt}}: {{W+|pt|muitos|n-p}}, {{W+|pt|muitas|m-p}} * {{Z|ro}}: {{W+|ro|mulți|n-p}}, {{W-|ro|multe|m-p}} * {{Z|ru}}: {{W+|ru|мно́го}}, {{W+|ru|мно́гие}}, {{W+|ru|мно́гий}} * {{Z|rue}}: {{W-|rue|много}} * {{Z|sms}}: {{W-|sms|mäŋgg}} * {{Z|sa}}: {{W+|sa|बहु}} * {{Z|srn}}: {{W-|srn|furu}} * {{Z|sh}}: {{W+|sh|mnogo|p}}, {{W-|sh|много}}, {{W+|sh|mnogi}}, {{W-|sh|многи}} * {{Z|sco}}: {{W-|sco|mony}} * {{Z|sk}}: {{W-|sk|mnohý|n}}, {{W-|sk|mnohá|m}}, {{W-|sk|mnohé|nt}}, {{W-|sk|mnohí|n-p}}, {{W-|sk|mnohé|m-p|nt-p}}, {{W-|sk|mnoho}}, {{W-|sk|veľa}} * {{Z|sl}}: {{W+|sl|veliko}} * Sorbî: *: {{Z|dsb}}: {{W-|dsb|wjele}} * {{Z|es}}: {{W+|es|muchos|n-p}}, {{W+|es|muchas|m-p}} * {{Z|su}}: {{W-|su|seueur}} * {{Z|sw}}: {{W-|sw|ingi|cuda=-ingi}} * {{Z|sv}}: {{W+|sv|många}} * {{Z|xsr}}: {{W-|xsr|མང་མུ|tr=mangmu}} * {{Z|zdj}}: {{W-|zdj|indji|cuda=-indji}} * {{Z|ta}}: {{W+|ta|நிறைய}}, {{W+|ta|பல}} * {{Z|th}}: {{W+|th|ขนัด}}, {{W+|th|มาก}}, {{W+|th|เยอะ}}, {{W+|th|รุ่ม}}, {{W+|th|หลาย}} * {{Z|te}}: {{W+|te|చాలా}} * {{Z|tr}}: {{W+|tr|çok}}, {{W+|tr|pek çok}}, {{W+|tr|birçok}} * {{Z|bo}}: {{W-|bo|མང་པོ}} * {{Z|xto}}: {{W-|xto|māk}} * {{Z|txb}}: {{W-|txb|māka}} * {{Z|ur}}: {{W-|ur|بہت|tr=bahut|sc=ur-Arab}}, {{W-|ur|زیادہ|tr=zyādā|sc=ur-Arab}} * {{Z|uk}}: {{W+|uk|бага́то|sc=Cyrl}}, {{W-|uk|чима́ло|sc=Cyrl}} * {{Z|vi}}: {{W+|vi|nhiều}}, {{W+|vi|lắm}} * {{Z|vo}}: {{W+|vo|mödik}} * {{Z|wa}}: {{W+|wa|bråmint des}} * {{Z|war}}: {{W-|war|da-mo}} * {{Z|cy}}: {{W-|cy|llawer}} * {{Z|km}}: {{W+|km|ច្រើន}} * {{Z|sah}}: {{W-|sah|элбэх}}, {{W-|sah|үгүс}} * {{Z|yi}}: {{W-|yi|אַ סך|tr=a sakh}} * {{Z|el}}: {{W+|el|πολλοί|n-p}} *: Kevn: {{W-|grc|πολλοί|n-p}}, {{W-|grc|πολλαί|m-p}}, {{W-|grc|πολλά|nt-p}} * {{Z|zea}}: {{W-|zea|vee}} * {{Z|za}}: {{W-|za|haujlai}}, {{W-|za|lai}} * {{Z|ase}}: {{W-|ase|S@InsideChesthigh-PalmUp-S@InsideChesthigh-PalmUp 5@InsideChesthigh-PalmUp-5@InsideChesthigh-PalmUp}} {{werger-bin}} :{{werger çavkanî|en|many|beş=Ev qismê Wergerê|oldid=75874306}} == {{ziman|ckb}} == === Bilêvkirin === * {{IPA|ckb|/pʰɪr/}} === Rengdêr === {{rengdêr|ckb|sc=Latn}} # {{ckb-Arab|پڕ}} == {{ziman|id}} == === Navdêr === {{navdêr|id}} # {{mijar|id|riwek}} {{g|ku|hirmî}} === Çavkanî === {{rûpela wergerê|id|hirmî}} == {{ziman|ms}} == === Navdêr === {{navdêr|ms}} # {{mijar|ms|riwek}} {{g|ku|hirmî}} === Çavkanî === {{rûpela wergerê|ms|hirmî}} == {{ziman|tr}} == === Bilêvkirin === * {{IPA|tr|/pʰiɾ/}} === Navdêr === {{navdêr|tr}} # [[pîr]], [[kal]] # [[mahir]] # têr baş qs63kzkkh59hz2a6zesaxpm3kge3nhj firinde 0 4600 6333914 6325213 2026-08-15T22:10:42Z Wikihez 7344 /* Tewandin */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333914 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA|fiřinde}} * {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-firinde.wav|dever=Bidlîs}} * {{ku-kîte}} === Bi alfabeyên din === * {{ku-ar|فڕندە}} === Etîmolojî === Ji {{qertaf|ku|fir|-inde}}. === Navdêr 1 === [[Wêne:Aeroflot Airbus A330 Kustov.jpg|thumb|Firinde ({{maneno|ku|teyare}})]] {{navdêr|ku|c=m}} # {{maneid|ku|teyare}} [[teyare]], [[balafir]]<ref>{{Ferhenga Farîzov, 1957|r=35}}</ref><ref>{{Ç:ku:Qanetê Kurdo:1960|r=265}}</ref> #* {{jêder-kitêb|ku|jêgirtin=Ew roja sisiya bû, ko evî bajarê nenas de bûm. Ji redakssiya{{sic}} ez şandî bûm, wekî tevî şêwrdariya jûrnalîsta bim, ya ko wî bajarî de derbaz dibû. Şêwrdarî kuta bû, min bilêta '''firindê''' kirrî, wekî roja dinê vegerime Erêwanê.|nivîskar=Baba ê Keleş|amadekar={{w|D. Îzolî}}|sernav=Nîşanî|weşanxane=Kurdish Students Society in Europe|sal=1986|rûpel=10}} #* {{jêder-kovar|ku|jêgirtin=Min bihîst, kurdên Kurdistan Îraqê bi '''firindeke''' xusûsî hatbûne{{sic}} zona erdhejê {{...}}|nivîskar=Têmurê Xelîl Mûradov|kovar=Kurdistan Press|hejmar=75|sernav=Niwênerên dostiya ermenî û kurdan|sal=1989|rûpel=13}} ==== Tewandin ==== {{ku-tewîn-nav|mê|guherto=hemû}} ==== Werger ==== {{werger-bnr|teyare}} === Navdêr 2 === [[Wêne:Superb_fairy_wren2_LiquidGhoul.jpg|thumb|Firindeyek ({{maneno|ku|teyr}})]] {{navdêr|ku|z=mn}} # {{maneid|ku|teyr}} [[candar|Candarên]] [[firîn|difirin]] û [[hêk]]an dikin û [[per]] û [[bask]] hene. #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav|mê}} ==== Formên alternatîv ==== * [[firrende]] * [[firrinde]] ==== Navê zanistî ==== * [[Aves]] ==== Hevmane ==== {{stûn| * [[balinde]] * [[çivîk]] * [[çûçik]] * [[çûk]] * [[terewîl]] * [[teyr]] * [[tilûr]] }} ==== Herwiha binêre ==== {{kol3|ku|sernav=Cûnên teyran |baz |elo |elok |kew |mêkew |mirîşk |qaz |sûsk |tawis |werdek }} ==== Dengê firinde û balindeyan ==== * [[bilbil]] [[fîxan]]ê dike * [[çivîk]]-[[çûçik]] [[şîreşîr]]ê dike * [[kew]] [[qebqeb]]ê dike * [[kevok]]-[[kotir]] [[buxbux]]ê dike ==== Werger ==== {{werger-bnr|teyr}} === Çavkanî === {{çavkanî}} 0qisio6dd3vkbppp4zdf9lw41onlwdv 6333915 6333914 2026-08-15T22:11:06Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333915 wikitext text/x-wiki == {{ziman|ku}} == === Bi alfabeyên din === * {{ku-ar|فڕندە}} === Etîmolojî === Ji {{qertaf|ku|fir|-inde}}. === Bilêvkirin === * {{ku-IPA|fiřinde}} * {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-firinde.wav|dever=Bidlîs}} * {{ku-kîte}} === Navdêr 1 === [[Wêne:Aeroflot Airbus A330 Kustov.jpg|thumb|Firinde ({{maneno|ku|teyare}})]] {{navdêr|ku|c=m}} # {{maneid|ku|teyare}} [[teyare]], [[balafir]]<ref>{{Ferhenga Farîzov, 1957|r=35}}</ref><ref>{{Ç:ku:Qanetê Kurdo:1960|r=265}}</ref> #* {{jêder-kitêb|ku|jêgirtin=Ew roja sisiya bû, ko evî bajarê nenas de bûm. Ji redakssiya{{sic}} ez şandî bûm, wekî tevî şêwrdariya jûrnalîsta bim, ya ko wî bajarî de derbaz dibû. Şêwrdarî kuta bû, min bilêta '''firindê''' kirrî, wekî roja dinê vegerime Erêwanê.|nivîskar=Baba ê Keleş|amadekar={{w|D. Îzolî}}|sernav=Nîşanî|weşanxane=Kurdish Students Society in Europe|sal=1986|rûpel=10}} #* {{jêder-kovar|ku|jêgirtin=Min bihîst, kurdên Kurdistan Îraqê bi '''firindeke''' xusûsî hatbûne{{sic}} zona erdhejê {{...}}|nivîskar=Têmurê Xelîl Mûradov|kovar=Kurdistan Press|hejmar=75|sernav=Niwênerên dostiya ermenî û kurdan|sal=1989|rûpel=13}} ==== Tewandin ==== {{ku-tewîn-nav|mê|guherto=hemû}} ==== Werger ==== {{werger-bnr|teyare}} === Navdêr 2 === [[Wêne:Superb_fairy_wren2_LiquidGhoul.jpg|thumb|Firindeyek ({{maneno|ku|teyr}})]] {{navdêr|ku|z=mn}} # {{maneid|ku|teyr}} [[candar|Candarên]] [[firîn|difirin]] û [[hêk]]an dikin û [[per]] û [[bask]] hene. #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav|mê}} ==== Formên alternatîv ==== * [[firrende]] * [[firrinde]] ==== Navê zanistî ==== * [[Aves]] ==== Hevmane ==== {{stûn| * [[balinde]] * [[çivîk]] * [[çûçik]] * [[çûk]] * [[terewîl]] * [[teyr]] * [[tilûr]] }} ==== Herwiha binêre ==== {{kol3|ku|sernav=Cûnên teyran |baz |elo |elok |kew |mêkew |mirîşk |qaz |sûsk |tawis |werdek }} ==== Dengê firinde û balindeyan ==== * [[bilbil]] [[fîxan]]ê dike * [[çivîk]]-[[çûçik]] [[şîreşîr]]ê dike * [[kew]] [[qebqeb]]ê dike * [[kevok]]-[[kotir]] [[buxbux]]ê dike ==== Werger ==== {{werger-bnr|teyr}} === Çavkanî === {{çavkanî}} lbu4fwrayf9ru5we6q30abyonqj6iyb balinde 0 4602 6333896 6292997 2026-08-15T19:56:36Z Wikihez 7344 /* Jê */ 6333896 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-balinde.wav|dever=Bidlîs}} * {{ku-kîte}} === Navdêr === [[Wêne:Bird Diversity 2013.png|thumb|Balindeyên cure bi cure.]] {{navdêr|ku|z=mn}} # [[candar|Candar]]ên [[firîn|difirin]] û [[hêk]]an dikin û [[per]] û [[bask]] hene. #* {{bêmînak|ku}} ==== Bi alfabeyên din ==== * {{ku-ar|بالندە}} ==== Formên alternatîv ==== * [[balende]] ==== Dengê firinde û balindeyan ==== * [[bilbil]] fixanê dike * [[civîk]]-[[çûçik]] şîreşîrê * [[kew]] qebqebê dike * [[kevok]]-[[kotir]] buxbuxê dike ==== Hevmane ==== {{stûn| * [[firinde]] * [[çivîk]] * [[çûçik]] * [[terewîl]] * [[teyr]] * [[tilûr]] }} ==== Jê ==== {{kol3|ku|cure=Jê |balindegeh<z:m> |balindegir<z:mn> |balindegirî<z:m> |balindeyê dirende |balindezan<z:mn> |balindezanî<z:m> |balindemalî<crz:rengdêr> }} ==== Binêre herwiha ==== {{kol3|ku|sernav=Cûnên teyran |baz |elo |elok |kew |mêkew |mirîşk |qaz |sûsk |tawis |werdek }} ==== Etîmolojî ==== Ji {{deyn|ckb|ku}} ji {{qe|ckb|nekat=1|باڵ<t:bask>|<tr:-inde>}}. ==== Werger ==== {{werger-bnr|teyr}} == {{ziman|zza}} == === Navdêr === {{navdêr|zza}} # [[çûk]], navê teyrekî<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|ckb}} == === Navdêr === {{navdêr|ckb|sc=Latn}} # [[teyr]], [[çûk]], [[balinde]] #* {{bêmînak|ckb}} n65769ggm9vx613p5m7oejpdpzpioz0 6333902 6333896 2026-08-15T20:41:07Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333902 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-balinde.wav|dever=Bidlîs}} * {{ku-kîte}} === Navdêr === [[Wêne:Bird Diversity 2013.png|thumb|Balindeyên cure bi cure.]] {{navdêr|ku|z=mn}} # [[candar|Candar]]ên [[firîn|difirin]] û [[hêk]]an dikin û [[per]] û [[bask]] hene. #* {{bêmînak|ku}} ==== Bi alfabeyên din ==== * {{ku-ar|بالندە}} ==== Formên alternatîv ==== * [[balende]] ==== Hevmane ==== {{stûn| * [[firinde]] * [[çivîk]] * [[çûçik]] * [[terewîl]] * [[teyr]] * [[tilûr]] }} ==== Jê ==== {{kol3|ku|cure=Jê |balindegeh<z:m> |balindegir<z:mn> |balindegirî<z:m> |balindeyê dirende |balindezan<z:mn> |balindezanî<z:m> |balindemalî<crz:rengdêr> }} ==== Etîmolojî ==== Ji {{deyn|ckb|ku}} ji {{qe|ckb|nekat=1|باڵ<t:bask>|<tr:-inde>}}. ==== Herwiha binêre ==== {{kol3|ku|sernav=Cûnên teyran |baz |elo |elok |kew |mêkew |mirîşk |qaz |sûsk |tawis |werdek }} ==== Dengê firinde û balindeyan ==== * [[bilbil]] fixanê dike * [[civîk]]-[[çûçik]] şîreşîrê * [[kew]] qebqebê dike * [[kevok]]-[[kotir]] buxbuxê dike ==== Werger ==== {{werger-bnr|teyr}} == {{ziman|zza}} == === Navdêr === {{navdêr|zza}} # [[çûk]], navê teyrekî<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|ckb}} == === Navdêr === {{navdêr|ckb|sc=Latn}} # [[teyr]], [[çûk]], [[balinde]] #* {{bêmînak|ckb}} jpc3u8to5cp03hna9d3fcny975e6yni 6333904 6333902 2026-08-15T21:12:06Z Balyozbot 7867 Bot: Paqijiyên kozmetîk (Lînk paqij kir.) 6333904 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-balinde.wav|dever=Bidlîs}} * {{ku-kîte}} === Navdêr === [[Wêne:Bird Diversity 2013.png|thumb|Balindeyên cure bi cure.]] {{navdêr|ku|z=mn}} # [[candar|Candarên]] [[firîn|difirin]] û [[hêk]]an dikin û [[per]] û [[bask]] hene. #* {{bêmînak|ku}} ==== Bi alfabeyên din ==== * {{ku-ar|بالندە}} ==== Formên alternatîv ==== * [[balende]] ==== Hevmane ==== {{stûn| * [[firinde]] * [[çivîk]] * [[çûçik]] * [[terewîl]] * [[teyr]] * [[tilûr]] }} ==== Jê ==== {{kol3|ku|cure=Jê |balindegeh<z:m> |balindegir<z:mn> |balindegirî<z:m> |balindeyê dirende |balindezan<z:mn> |balindezanî<z:m> |balindemalî<crz:rengdêr> }} ==== Etîmolojî ==== Ji {{deyn|ckb|ku}} ji {{qe|ckb|nekat=1|باڵ<t:bask>|<tr:-inde>}}. ==== Herwiha binêre ==== {{kol3|ku|sernav=Cûnên teyran |baz |elo |elok |kew |mêkew |mirîşk |qaz |sûsk |tawis |werdek }} ==== Dengê firinde û balindeyan ==== * [[bilbil]] fixanê dike * [[civîk]]-[[çûçik]] şîreşîrê * [[kew]] qebqebê dike * [[kevok]]-[[kotir]] buxbuxê dike ==== Werger ==== {{werger-bnr|teyr}} == {{ziman|zza}} == === Navdêr === {{navdêr|zza}} # [[çûk]], navê teyrekî<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|ckb}} == === Navdêr === {{navdêr|ckb|sc=Latn}} # [[teyr]], [[çûk]], [[balinde]] #* {{bêmînak|ckb}} ljescx6hous7hq54uh8ih6gdw6mmdyx demjimêrk 0 4775 6333925 6304837 2026-08-15T23:07:13Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333925 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[alav|Alav]]ek e bo zanîna ka çi [[dem]] e. #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Notên bikaranînê ==== {{agahdarî}} Carine peyva ''demjimêrk'' yan ''demjimêr'' li şûna "60 [[deqe]]" jî tê bikaranîn lê şaş e!<br> Bo wê mebestê binere: [[seet]] (1). ==== Formên alternatîv ==== * [[demjimêr]] (1) ==== Hevmane ==== * [[seet]] (2) ==== Etîmolojî ==== [[dem]] + [[jimartin|jimêr]] + [[-k|k]] ====Bi zaravayên din ==== * {{Z|ckb}}: [[katjimêr]] ==== Werger ==== {{werger-ser}} * {{Z|de}}: [[Uhr]] (1); [[Tacho]] m (2) * {{Z|br}}: [[horolaj]] -où, [[dihuner]] -ioù alarm clock * {{Z|cs}}: {{W|cs|hodiny}} * {{Z|zh}}: {{W|zh|鐘}}, {{W|zh|時鐘}} * {{Z|id}}: {{W|id|jam}} * {{Z|eo}}: {{W|eo|horloĝo}} * {{Z|fi}}: [[kello]] (1) * {{Z|fr}}: {{W|fr|horloge}} * {{Z|nl}}: {{W|nl|klok}} * {{Z|he}}: {{W|he|שעון}} {{n}} * {{Z|en}}: {{W|en|clock}}, {{W|en|watch}} * {{Z|ia}}: {{W|ia|horologio}} * {{Z|it}}: {{W|it|orologio}} * {{Z|ja}}: {{W|ja|時計|tr=とけい, tokei}} * {{Z|ca}}: {{W|ca|rellotge}} {{n}} * {{Z|la}}: {{W|la|horologium}} {{nt}} * {{Z|ms}}: {{W|ms|jam}} * {{Z|no}}: {{W|no|klokke}} * {{Z|pl}}: {{W|pl|zegar}} {{n}} * {{Z|pt}}: {{W|pt|relógio}} {{n}} * {{Z|ru}}: [[часы]] ''pl'' (chasý) * {{Z|es}}: {{W|es|reloj}} {{n}} * {{Z|tl}}: {{W|tl|relo}}, [[orasan]] (1) * {{Z|tr}}: {{W|tr|saat}} {{werger-bin}} k1zlzejencppxi7hvykjvwzm6fbz8vn 6333983 6333925 2026-08-16T00:12:09Z Balyozbot 7867 Bot: Paqijiyên kozmetîk (Lînk paqij kir, Valahiya beşan rast kir, --Valahiyên nehewce.) 6333983 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[alav|Alavek]] e bo zanîna ka çi [[dem]] e. #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Notên bikaranînê ==== {{agahdarî}} Carine peyva ''demjimêrk'' yan ''demjimêr'' li şûna "60 [[deqe]]" jî tê bikaranîn lê şaş e!<br> Bo wê mebestê binere: [[seet]] (1). ==== Formên alternatîv ==== * [[demjimêr]] (1) ==== Hevmane ==== * [[seet]] (2) ==== Etîmolojî ==== [[dem]] + [[jimartin|jimêr]] + [[-k|k]] ==== Bi zaravayên din ==== * {{Z|ckb}}: [[katjimêr]] ==== Werger ==== {{werger-ser}} * {{Z|de}}: [[Uhr]] (1); [[Tacho]] m (2) * {{Z|br}}: [[horolaj]] -où, [[dihuner]] -ioù alarm clock * {{Z|cs}}: {{W|cs|hodiny}} * {{Z|zh}}: {{W|zh|鐘}}, {{W|zh|時鐘}} * {{Z|id}}: {{W|id|jam}} * {{Z|eo}}: {{W|eo|horloĝo}} * {{Z|fi}}: [[kello]] (1) * {{Z|fr}}: {{W|fr|horloge}} * {{Z|nl}}: {{W|nl|klok}} * {{Z|he}}: {{W|he|שעון}} {{n}} * {{Z|en}}: {{W|en|clock}}, {{W|en|watch}} * {{Z|ia}}: {{W|ia|horologio}} * {{Z|it}}: {{W|it|orologio}} * {{Z|ja}}: {{W|ja|時計|tr=とけい, tokei}} * {{Z|ca}}: {{W|ca|rellotge}} {{n}} * {{Z|la}}: {{W|la|horologium}} {{nt}} * {{Z|ms}}: {{W|ms|jam}} * {{Z|no}}: {{W|no|klokke}} * {{Z|pl}}: {{W|pl|zegar}} {{n}} * {{Z|pt}}: {{W|pt|relógio}} {{n}} * {{Z|ru}}: [[часы]] ''pl'' (chasý) * {{Z|es}}: {{W|es|reloj}} {{n}} * {{Z|tl}}: {{W|tl|relo}}, [[orasan]] (1) * {{Z|tr}}: {{W|tr|saat}} {{werger-bin}} 6d1nvktfcm64pv2grwn3zbeks5kpp5i nexweş 0 5555 6334013 6313335 2026-08-16T01:15:06Z Wikihez 7344 /* Rengêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334013 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{IPA|ku|/nɛxʷɛʃ/}} ** {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-nexweş.wav|dever=Bidlîs}} * {{IPA|ku|/nɛxoːʃ/, /nɛxʷɪʃ/}} ** {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-nexweş-2.wav|dever=Bidlîs}} * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|nexweş}} {{rengdêr|ku}} # Kesa/ê [[êş]]ek yan hin [[êş]] lê hene. #: {{mk|ku|Ew îro '''nexweş''' e.}} #: {{mk|ku|Ez hefteyekê '''nexweş''' bûm.}} #: {{mk|ku|Ew bi xwarineke jehrewî '''nexweş''' bûye/ketiye.}} ==== Hevmane ==== {{kol3|ku | êşewî | nesax | nesaxlem | xeste }} ==== Jê ==== {{kol3|ku | nexweş bûn<q:lêker> | nexweş kirin<q:lêker> | nexweş ketin<q:lêker> | nexweş xistin<q:lêker> | nexweşbûn<q:navdêr> | nexweşkirin<q:navdêr> | nexweşketin<q:navdêr> | nexweşxistin<q:navdêr> | nexweşbûyî<q:rengdêr> | nexweşkirî<q:rengdêr> | nexweşketî | nexweşgeh | nexweşî | nexweşxane }} ==== Bide ber ==== {{kol3|ku | birîndar | kulek | mirî | seqet }} ==== Etîmolojî ==== Ji {{pêş|ku|ne-|xweş}}. ==== Bi zaravayên din ==== * {{Z|ckb}}: {{W-|ckb|نەخۆش|tr=nexoş}} * {{Z|zza}}: {{W-|zza|nêweş|n}}, {{W-|zza|nêwes|n}} ==== Werger ==== {{werger-ser|nesax, biêş, êşewî}} * {{Z|af}}: {{W-|af|siek}} * {{Z|xag}}: {{W-|xag|𐔱𐔰𐕅}} * {{Z|akl}}: {{W-|akl|masakit}} * {{Z|sq}}: {{W+|sq|sëmurë|cuda=i sëmurë}} * {{Z|de}}: {{W+|de|krank}}, {{W+|de|siech}} * {{Z|am}}: {{W-|am|ሕሙም}} * {{Z|rup}}: {{W-|rup|lãndzit}}, {{W-|rup|lãntsid}}, {{W-|rup|lãndzidzãt}}, {{W-|rup|niputut}}, {{W-|rup|shuplicat}}, {{W-|rup|hivrit}} * {{Z|ast}}: {{W-|ast|enfermu}} * {{Z|az}}: {{W+|az|xəstə}}, {{W-|az|naxoş}} * {{Z|eu}}: {{W-|eu|gaixo}} * {{Z|ba}}: {{W-|ba|ауырыу}}, {{W-|ba|сирле}}, {{W-|ba|сырхау}} * {{Z|be}}: {{W-|be|хво́ры}} * {{Z|bn}}: {{W+|bn|অসুস্থ}} * {{Z|bi}}: {{W-|bi|siki}} * {{Z|bg}}: {{W+|bg|бо́лен}} * {{Z|my}}: {{W+|my|နာ}}, {{W+|my|နေထိုင်မကောင်း}} * {{Z|cs}}: {{W+|cs|nemocný}} * {{Z|cic}}: {{W-|cic|abika}} * {{Z|zh}}: *: {{Z|yue}}: {{W-|yue|病|tr=beng6}} *: {{Z|dng}}: {{W-|dng|бин}}, {{W-|dng|бемар}} *: {{Z|cmn}}: {{W+|cmn|病|tr=bìng}} * {{Z|ckt}}: {{W-|ckt|тъытԓьэн|tr=tʺytḷʹėn}} * {{Z|da}}: {{W+|da|syg}} * {{Z|ovd}}: {{W-|ovd|klien}}, {{W-|ovd|siuok}} * {{Z|id}}: {{W+|id|sakit}} * {{Z|ar}}: {{W+|ar|مَرِيض}} *: {{Z|arz}}: {{W-|arz|عيان|tr=ʕayyān}} * {{Z|hy}}: {{W+|hy|հիվանդ}} *: {{Z|xcl}}: {{W-|xcl|հիւանդ}}, {{W-|xcl|խօթ}} * {{Z|eo}}: {{W-|eo|malsana}} * {{Z|et}}: {{W+|et|haige}} * {{Z|fa}}: {{W+|fa|بیمار|tr=bimâr}}, {{W+|fa|مریض|tr=mariz}} * {{Z|fo}}: {{W-|fo|sjúkur}} * {{Z|fi}}: {{W+|fi|sairas}} * {{Z|fr}}: {{W+|fr|malade|n|m}} * {{Z|fy}}: {{W-|fy|siik}} * {{Z|gd}}: {{W-|gd|tinn}} * {{Z|gl}}: {{W+|gl|enfermo}}, {{W+|gl|doente}} * {{Z|got}}: {{W-|got|𐌿𐌽𐌷𐌰𐌹𐌻𐍃}} * {{Z|ka}}: {{W+|ka|ავადმყოფი}}, {{W-|ka|სნეული}} * {{Z|ht}}: {{W-|ht|malad|}} * {{Z|haw}}: {{W-|haw|maʻi}} * {{Z|hi}}: {{W+|hi|बीमार}}, {{W+|hi|रोगी}} * {{Z|mww}}: {{W-|mww|mob}} * {{Z|nl}}: {{W+|nl|ziek}}, {{W+|nl|zieke}}, {{W+|nl|krank}} * {{Z|he}}: {{W+|he|חוֹלֶה|n|tr=kholé}} * {{Z|io}}: {{W+|io|malada}} * {{Z|ang}}: {{W-|ang|seoc}}, {{W-|ang|ādliġ}} * {{Z|en}}: {{W+|en|ill}} * {{Z|izh}}: {{W-|izh|kippiä}} * {{Z|ia}}: {{W-|ia|malade}} * {{Z|ill}}: {{W-|ill|masakit}} * {{Z|ga}}: {{W+|ga|tinn}} * {{Z|it}}: {{W+|it|malato}} * {{Z|is}}: {{W+|is|veikur}}, {{W-|is|lasinn}}, {{W+|is|sjúkur}} * {{Z|ja}}: {{W+|ja|病気|tr=びょうき, byōki}} * {{Z|kaw}}: {{W-|kaw|lara}} * {{Z|jv}}: {{W-|jv|lara}} * {{Z|kl}}: {{W-|kl|napparsimasoq}} * {{Z|ca}}: {{W+|ca|malalt}} * {{Z|ky}}: {{W+|ky|оору}}, {{W+|ky|оорулуу}}, {{W-|ky|ноокас}}, {{W+|ky|сыркоолуу}} * {{Z|si}}: {{W-|si|අසනීප}} * {{Z|ko}}: {{W+|ko|병들다}}, {{W+|ko|앓다}} * {{Z|lad}}: {{W-|lad|hazino|n}}, {{W-|lad|hazinu|n}}, {{W-|lad|hazina|m}}, {{W-|lad|malo|n}} * {{Z|ltg}}: {{W-|ltg|navasals|n}} * {{Z|la}}: {{W-|la|īnfirmus}}, {{W+|la|aeger}}, {{W-|la|aegrōtus}} * {{Z|lv}}: {{W-|lv|slims}}, {{W-|lv|sasirdzis}} * {{Z|lo}}: {{W-|lo|ເຈັບ}}, {{W-|lo|ຕົກອັບ}}, {{W-|lo|ບໍ່ສະບາຍ}} * {{Z|lzz}}: {{W-|lzz|ზაბუნი}} * {{Z|lt}}: {{W-|lt|sergantis}} * {{Z|liv}}: {{W-|liv|rujā}} * {{Z|lb}}: {{W-|lb|krank}} * {{Z|lut}}: {{W-|lut|ʔəsʔi}} * {{Z|mk}}: {{W-|mk|болен}} * {{Z|ms}}: {{W+|ms|sakit}}, {{W+|ms|gering}} * {{Z|mt}}: {{W-|mt|marid}} * {{Z|msk}}: {{W-|msk|masakit}} * {{Z|mi}}: {{W-|mi|wheori}}, {{W-|mi|tarutaruhea}}, {{W-|mi|manauhea}} * {{Z|mrw}}: {{W-|mrw|kasakit}} * {{Z|hu}}: {{W+|hu|beteg}} * {{Z|xmf}}: {{W-|xmf|ლეხიანი}} * {{Z|mn}}: *: Kirîlî: {{W-|mn|өвчтэй}} *: Mongolî: {{W-|mn|ᠥᠪᠡᠳᠴᠢᠲᠡᠢ}} * {{Z|nrf}}: {{W-|nrf|malade}} * {{Z|no}}: *: {{Z|nb}}: {{W+|nb|syk}}, {{W+|nb|sjuk}} *: {{Z|nn}}: {{W-|nn|sjuk}} * {{Z|oj}}: {{W-|oj|aakozi}} * {{Z|oc}}: {{W+|oc|malaut}} * {{Z|or}}: {{W+|or|ବେମାରିଆ}} * {{Z|ug}}: {{W-|ug|كېسەل}} * {{Z|uz}}: {{W+|uz|kasal}}, {{W+|uz|xasta}}, {{W+|uz|bemor}} * {{Z|ps}}: {{W+|ps|بيمار|tr=bimār}}, {{W-|ps|مريض|tr=mariz}} * {{Z|pis}}: {{W-|pis|siki}} * {{Z|pdt}}: {{W-|pdt|krank}} * {{Z|pl}}: {{W+|pl|chory}} * {{Z|pt}}: {{W+|pt|doente|n|m}} * {{Z|kk}}: {{W-|kk|ауру}}, {{W-|kk|науқас}}, {{W-|kk|сырқат}}, {{W-|kk|дімкәс}} * {{Z|rgn}}: {{W-|rgn|mêl}} * {{Z|rm}}: {{W-|rm|malsaun}} * {{Z|rom}}: {{W-|rom|nasvalo}} * {{Z|ro}}: {{W+|ro|bolnav}}, {{W+|ro|abătut}} * {{Z|ru}}: {{W+|ru|больно́й}}, {{W+|ru|хво́рый}} * {{Z|osx}}: {{W-|osx|siok}} * {{Z|se}}: {{W-|se|buohcci}}, {{W-|se|buozas}} * {{Z|sm}}: {{W-|sm|ma'i}} * {{Z|sa}}: {{W+|sa|अस्वस्थ}}, {{W+|sa|रुग्ण}} * {{Z|sd}}: {{W-|sd|بیمار}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|бо̏лестан}} *: Latînî: {{W+|sh|bȍlestan}} * {{Z|cu}}: *: Kirîlî: {{W-|cu|больнъ}} * {{Z|sk}}: {{W+|sk|chorý}}, {{W-|sk|nemocný}} * {{Z|sl}}: {{W+|sl|bolan}} * {{Z|so}}: {{W+|so|bukaan}}, {{W-|so|xanuun}} * Sorbî: *: {{Z|dsb}}: {{W-|dsb|chóry}} *: {{Z|hsb}}: {{W-|hsb|chory}} * {{Z|es}}: {{W+|es|enfermo}}, {{W+|es|mareado}} * {{Z|sw}}: {{W-|sw|-[[gonjwa]]}} * {{Z|sv}}: {{W+|sv|sjuk}} * {{Z|tg}}: {{W+|tg|бемор}}, {{W+|tg|мариз}}, {{W+|tg|касал}} * Talysh: *: {{Z|tly}}: {{W-|tly|مریض|tr=mariz}} * {{Z|tl}}: {{W-|tl|may sakit}} * {{Z|th}}: {{W+|th|ป่วย}}, {{W+|th|ไม่สบาย}} * {{Z|tt}}: {{W+|tt|авыру}} * {{Z|tet}}: {{W-|tet|moras}} * {{Z|ti}}: {{W+|ti|ሕሙም}} * {{Z|tr}}: {{W+|tr|hasta}}, {{W+|tr|sayrı}} * {{Z|tk}}: {{W-|tk|syrkaw}}, {{W-|tk|hassa}}, {{W-|tk|kesel}}, {{W-|tk|näsag}} * {{Z|bo}}: {{W-|bo|ན}}, {{W-|bo|ནན་ཏེ}} * {{Z|tpi}}: {{W-|tpi|sik}} * {{Z|to}}: {{W-|to|puke}} * {{Z|txb}}: {{W-|txb|tekiññe}} * {{Z|ur}}: {{W-|ur|بیمار|tr=bīmār}}, {{W+|ur|مریض|tr=marīz}}, {{W-|ur|علیل|tr=alīl}} * {{Z|uk}}: {{W-|uk|хво́рий}} * {{Z|vi}}: {{W+|vi|bệnh}}, {{W+|vi|ốm}} * {{Z|vo}}: {{W+|vo|malädik}} * {{Z|cy}}: {{W+|cy|sâl}} * {{Z|km}}: {{W+|km|ឈឺ}}, {{W+|km|ថ្កាត់}} * {{Z|yi}}: {{W-|yi|קראַנק}}, {{W-|yi|קרענקלעך}}, {{W-|yi|געלעגן צו בעט}} * {{Z|el}}: {{W+|el|άρρωστος}} *: Kevn: {{W-|grc|ἄρρωστος}} * {{Z|za}}: {{W-|za|bingh}} {{werger-bin}} :{{werger çavkanî|en|ill|beş=Ev qismê Wergerê|oldid=75878299}} {{werger-ser}} * {{Z|de}}: {{W+|de|unbequem}}, {{W+|de|ungemütlich}} * {{Z|az}}: {{W-|az|rahatsız}}, {{W-|az|naqolay}} * {{Z|bg}}: {{W+|bg|неудо́бен}} * {{Z|cs}}: {{W-|cs|nepohodlný}} * {{Z|zh}}: *: {{Z|cmn}}: {{W+|cmn|不舒服|tr=bùshūfu}} * {{Z|ar}}: {{W-|ar|غَيْر مُرِيح}} * {{Z|hy}}: {{W+|hy|անհարմար}} * {{Z|fi}}: {{W+|fi|epämukava}} * {{Z|fr}}: {{W+|fr|inconfortable}} * {{Z|gd}}: {{W-|gd|mì-shuaimhneach}} * {{Z|gl}}: {{W-|gl|incómodo}} * {{Z|ka}}: {{W-|ka|არაკეთილმოწყობილი}} * {{Z|nl}}: {{W+|nl|ongemakkelijk}} * {{Z|en}}: {{W+|en|uncomfortable}}, {{W+|en|unconvenient}} * {{Z|ga}}: {{W-|ga|anacair}}, {{W-|ga|aineascair}} * {{Z|is}}: {{W+|is|óþægilegur}} * {{Z|ja}}: {{W-|ja|心地よい|tr=ここちよくない, kokochiyokunai|cuda=心地よくない}} * {{Z|ca}}: {{W+|ca|incòmode}} * {{Z|ko}}: {{W+|ko|불편하다}} * {{Z|lld}}: {{W-|lld|ncomper}} * {{Z|la}}: {{W-|la|incommodus}} * {{Z|mk}}: {{W-|mk|неу́добен}}, {{W-|mk|непри́јатен}} * {{Z|hu}}: {{W+|hu|kényelmetlen}} * {{Z|oc}}: {{W+|oc|incomòde}} * {{Z|pdt}}: {{W-|pdt|Forcht|m}} * {{Z|pl}}: {{W+|pl|niewygodny}}, {{W+|pl|niekomfortowy}} * {{Z|pt}}: {{W+|pt|desconfortável}}, {{W+|pt|incómodo}}, {{W+|pt|incômodo}} * {{Z|ru}}: {{W+|ru|неудо́бный}}, {{W+|ru|некомфорта́бельный}} * {{Z|sa}}: {{W+|sa|दुःख}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|не̏удобан}} *: Latînî: {{W+|sh|nȅudoban}} * {{Z|es}}: {{W+|es|incómodo}} * {{Z|th}}: {{W-|th|ไม่สะดวก|tr=mâi sàdùak}} * {{Z|uk}}: {{W-|uk|незру́чний}} * {{Z|el}}: {{W+|el|άβολο}} {{werger-bin}} :{{werger çavkanî|en|uncomfortable|beş=Ev qismê Wergerê|oldid=75702492}} === Navdêr === {{navdêr|ku|z=mn}} # Kesa/ê [[êş]]ek yan hin [[êş]] lê hene. #: {{mk|ku|'''Nexweşek'''.}} #: {{mk|ku|'''Nexweşa''' şekirê.}} #* {{jêder|ku|{{Jêgirtin/Melayê Cizîrî/Dîwana Melayê Cizirî}}|jêgirtin=Lê ji bo nekhê dehanî<br>'''Nexweşan''' ew lê şifa ye<br>Mawera belgên gulê bû}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê û nêr}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Kranker|n}}, {{W+|de|Kranke|m}} * {{Z|fr}}: {{W+|fr|malade|mn}} * {{Z|en}}: {{W+|en|invalid}}, {{W-|en|sick person}}, {{W-|en|ill person}} * {{Z|es}}: {{W+|es|enfermo|n}} * {{Z|tr}}: {{W+|tr|hasta}} {{werger-bin}} nik9netbpx368jp4gtap8ra2m37qiuo 6334029 6334013 2026-08-16T01:41:15Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6334029 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{IPA|ku|/nɛxʷɛʃ/}} ** {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-nexweş.wav|dever=Bidlîs}} * {{IPA|ku|/nɛxoːʃ/, /nɛxʷɪʃ/}} ** {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-nexweş-2.wav|dever=Bidlîs}} * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|nexweş}} {{rengdêr|ku}} # Kesa/ê [[êş]]ek yan hin [[êş]] lê hene. #: {{mk|ku|Ew îro '''nexweş''' e.}} #: {{mk|ku|Ez hefteyekê '''nexweş''' bûm.}} #: {{mk|ku|Ew bi xwarineke jehrewî '''nexweş''' bûye/ketiye.}} ==== Hevmane ==== {{kol3|ku | êşewî | nesax | nesaxlem | xeste }} ==== Jê ==== {{kol3|ku | nexweş bûn<q:lêker> | nexweş kirin<q:lêker> | nexweş ketin<q:lêker> | nexweş xistin<q:lêker> | nexweşbûn<q:navdêr> | nexweşkirin<q:navdêr> | nexweşketin<q:navdêr> | nexweşxistin<q:navdêr> | nexweşbûyî<q:rengdêr> | nexweşkirî<q:rengdêr> | nexweşketî | nexweşgeh | nexweşî | nexweşxane }} ==== Etîmolojî ==== Ji {{pêş|ku|ne-|xweş}}. ==== Bide ber ==== {{kol3|ku | birîndar | kulek | mirî | seqet }} ==== Bi zaravayên din ==== * {{Z|ckb}}: {{W-|ckb|نەخۆش|tr=nexoş}} * {{Z|zza}}: {{W-|zza|nêweş|n}}, {{W-|zza|nêwes|n}} ==== Werger ==== {{werger-ser|nesax, biêş, êşewî}} * {{Z|af}}: {{W-|af|siek}} * {{Z|xag}}: {{W-|xag|𐔱𐔰𐕅}} * {{Z|akl}}: {{W-|akl|masakit}} * {{Z|sq}}: {{W+|sq|sëmurë|cuda=i sëmurë}} * {{Z|de}}: {{W+|de|krank}}, {{W+|de|siech}} * {{Z|am}}: {{W-|am|ሕሙም}} * {{Z|rup}}: {{W-|rup|lãndzit}}, {{W-|rup|lãntsid}}, {{W-|rup|lãndzidzãt}}, {{W-|rup|niputut}}, {{W-|rup|shuplicat}}, {{W-|rup|hivrit}} * {{Z|ast}}: {{W-|ast|enfermu}} * {{Z|az}}: {{W+|az|xəstə}}, {{W-|az|naxoş}} * {{Z|eu}}: {{W-|eu|gaixo}} * {{Z|ba}}: {{W-|ba|ауырыу}}, {{W-|ba|сирле}}, {{W-|ba|сырхау}} * {{Z|be}}: {{W-|be|хво́ры}} * {{Z|bn}}: {{W+|bn|অসুস্থ}} * {{Z|bi}}: {{W-|bi|siki}} * {{Z|bg}}: {{W+|bg|бо́лен}} * {{Z|my}}: {{W+|my|နာ}}, {{W+|my|နေထိုင်မကောင်း}} * {{Z|cs}}: {{W+|cs|nemocný}} * {{Z|cic}}: {{W-|cic|abika}} * {{Z|zh}}: *: {{Z|yue}}: {{W-|yue|病|tr=beng6}} *: {{Z|dng}}: {{W-|dng|бин}}, {{W-|dng|бемар}} *: {{Z|cmn}}: {{W+|cmn|病|tr=bìng}} * {{Z|ckt}}: {{W-|ckt|тъытԓьэн|tr=tʺytḷʹėn}} * {{Z|da}}: {{W+|da|syg}} * {{Z|ovd}}: {{W-|ovd|klien}}, {{W-|ovd|siuok}} * {{Z|id}}: {{W+|id|sakit}} * {{Z|ar}}: {{W+|ar|مَرِيض}} *: {{Z|arz}}: {{W-|arz|عيان|tr=ʕayyān}} * {{Z|hy}}: {{W+|hy|հիվանդ}} *: {{Z|xcl}}: {{W-|xcl|հիւանդ}}, {{W-|xcl|խօթ}} * {{Z|eo}}: {{W-|eo|malsana}} * {{Z|et}}: {{W+|et|haige}} * {{Z|fa}}: {{W+|fa|بیمار|tr=bimâr}}, {{W+|fa|مریض|tr=mariz}} * {{Z|fo}}: {{W-|fo|sjúkur}} * {{Z|fi}}: {{W+|fi|sairas}} * {{Z|fr}}: {{W+|fr|malade|n|m}} * {{Z|fy}}: {{W-|fy|siik}} * {{Z|gd}}: {{W-|gd|tinn}} * {{Z|gl}}: {{W+|gl|enfermo}}, {{W+|gl|doente}} * {{Z|got}}: {{W-|got|𐌿𐌽𐌷𐌰𐌹𐌻𐍃}} * {{Z|ka}}: {{W+|ka|ავადმყოფი}}, {{W-|ka|სნეული}} * {{Z|ht}}: {{W-|ht|malad|}} * {{Z|haw}}: {{W-|haw|maʻi}} * {{Z|hi}}: {{W+|hi|बीमार}}, {{W+|hi|रोगी}} * {{Z|mww}}: {{W-|mww|mob}} * {{Z|nl}}: {{W+|nl|ziek}}, {{W+|nl|zieke}}, {{W+|nl|krank}} * {{Z|he}}: {{W+|he|חוֹלֶה|n|tr=kholé}} * {{Z|io}}: {{W+|io|malada}} * {{Z|ang}}: {{W-|ang|seoc}}, {{W-|ang|ādliġ}} * {{Z|en}}: {{W+|en|ill}} * {{Z|izh}}: {{W-|izh|kippiä}} * {{Z|ia}}: {{W-|ia|malade}} * {{Z|ill}}: {{W-|ill|masakit}} * {{Z|ga}}: {{W+|ga|tinn}} * {{Z|it}}: {{W+|it|malato}} * {{Z|is}}: {{W+|is|veikur}}, {{W-|is|lasinn}}, {{W+|is|sjúkur}} * {{Z|ja}}: {{W+|ja|病気|tr=びょうき, byōki}} * {{Z|kaw}}: {{W-|kaw|lara}} * {{Z|jv}}: {{W-|jv|lara}} * {{Z|kl}}: {{W-|kl|napparsimasoq}} * {{Z|ca}}: {{W+|ca|malalt}} * {{Z|ky}}: {{W+|ky|оору}}, {{W+|ky|оорулуу}}, {{W-|ky|ноокас}}, {{W+|ky|сыркоолуу}} * {{Z|si}}: {{W-|si|අසනීප}} * {{Z|ko}}: {{W+|ko|병들다}}, {{W+|ko|앓다}} * {{Z|lad}}: {{W-|lad|hazino|n}}, {{W-|lad|hazinu|n}}, {{W-|lad|hazina|m}}, {{W-|lad|malo|n}} * {{Z|ltg}}: {{W-|ltg|navasals|n}} * {{Z|la}}: {{W-|la|īnfirmus}}, {{W+|la|aeger}}, {{W-|la|aegrōtus}} * {{Z|lv}}: {{W-|lv|slims}}, {{W-|lv|sasirdzis}} * {{Z|lo}}: {{W-|lo|ເຈັບ}}, {{W-|lo|ຕົກອັບ}}, {{W-|lo|ບໍ່ສະບາຍ}} * {{Z|lzz}}: {{W-|lzz|ზაბუნი}} * {{Z|lt}}: {{W-|lt|sergantis}} * {{Z|liv}}: {{W-|liv|rujā}} * {{Z|lb}}: {{W-|lb|krank}} * {{Z|lut}}: {{W-|lut|ʔəsʔi}} * {{Z|mk}}: {{W-|mk|болен}} * {{Z|ms}}: {{W+|ms|sakit}}, {{W+|ms|gering}} * {{Z|mt}}: {{W-|mt|marid}} * {{Z|msk}}: {{W-|msk|masakit}} * {{Z|mi}}: {{W-|mi|wheori}}, {{W-|mi|tarutaruhea}}, {{W-|mi|manauhea}} * {{Z|mrw}}: {{W-|mrw|kasakit}} * {{Z|hu}}: {{W+|hu|beteg}} * {{Z|xmf}}: {{W-|xmf|ლეხიანი}} * {{Z|mn}}: *: Kirîlî: {{W-|mn|өвчтэй}} *: Mongolî: {{W-|mn|ᠥᠪᠡᠳᠴᠢᠲᠡᠢ}} * {{Z|nrf}}: {{W-|nrf|malade}} * {{Z|no}}: *: {{Z|nb}}: {{W+|nb|syk}}, {{W+|nb|sjuk}} *: {{Z|nn}}: {{W-|nn|sjuk}} * {{Z|oj}}: {{W-|oj|aakozi}} * {{Z|oc}}: {{W+|oc|malaut}} * {{Z|or}}: {{W+|or|ବେମାରିଆ}} * {{Z|ug}}: {{W-|ug|كېسەل}} * {{Z|uz}}: {{W+|uz|kasal}}, {{W+|uz|xasta}}, {{W+|uz|bemor}} * {{Z|ps}}: {{W+|ps|بيمار|tr=bimār}}, {{W-|ps|مريض|tr=mariz}} * {{Z|pis}}: {{W-|pis|siki}} * {{Z|pdt}}: {{W-|pdt|krank}} * {{Z|pl}}: {{W+|pl|chory}} * {{Z|pt}}: {{W+|pt|doente|n|m}} * {{Z|kk}}: {{W-|kk|ауру}}, {{W-|kk|науқас}}, {{W-|kk|сырқат}}, {{W-|kk|дімкәс}} * {{Z|rgn}}: {{W-|rgn|mêl}} * {{Z|rm}}: {{W-|rm|malsaun}} * {{Z|rom}}: {{W-|rom|nasvalo}} * {{Z|ro}}: {{W+|ro|bolnav}}, {{W+|ro|abătut}} * {{Z|ru}}: {{W+|ru|больно́й}}, {{W+|ru|хво́рый}} * {{Z|osx}}: {{W-|osx|siok}} * {{Z|se}}: {{W-|se|buohcci}}, {{W-|se|buozas}} * {{Z|sm}}: {{W-|sm|ma'i}} * {{Z|sa}}: {{W+|sa|अस्वस्थ}}, {{W+|sa|रुग्ण}} * {{Z|sd}}: {{W-|sd|بیمار}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|бо̏лестан}} *: Latînî: {{W+|sh|bȍlestan}} * {{Z|cu}}: *: Kirîlî: {{W-|cu|больнъ}} * {{Z|sk}}: {{W+|sk|chorý}}, {{W-|sk|nemocný}} * {{Z|sl}}: {{W+|sl|bolan}} * {{Z|so}}: {{W+|so|bukaan}}, {{W-|so|xanuun}} * Sorbî: *: {{Z|dsb}}: {{W-|dsb|chóry}} *: {{Z|hsb}}: {{W-|hsb|chory}} * {{Z|es}}: {{W+|es|enfermo}}, {{W+|es|mareado}} * {{Z|sw}}: {{W-|sw|-[[gonjwa]]}} * {{Z|sv}}: {{W+|sv|sjuk}} * {{Z|tg}}: {{W+|tg|бемор}}, {{W+|tg|мариз}}, {{W+|tg|касал}} * Talysh: *: {{Z|tly}}: {{W-|tly|مریض|tr=mariz}} * {{Z|tl}}: {{W-|tl|may sakit}} * {{Z|th}}: {{W+|th|ป่วย}}, {{W+|th|ไม่สบาย}} * {{Z|tt}}: {{W+|tt|авыру}} * {{Z|tet}}: {{W-|tet|moras}} * {{Z|ti}}: {{W+|ti|ሕሙም}} * {{Z|tr}}: {{W+|tr|hasta}}, {{W+|tr|sayrı}} * {{Z|tk}}: {{W-|tk|syrkaw}}, {{W-|tk|hassa}}, {{W-|tk|kesel}}, {{W-|tk|näsag}} * {{Z|bo}}: {{W-|bo|ན}}, {{W-|bo|ནན་ཏེ}} * {{Z|tpi}}: {{W-|tpi|sik}} * {{Z|to}}: {{W-|to|puke}} * {{Z|txb}}: {{W-|txb|tekiññe}} * {{Z|ur}}: {{W-|ur|بیمار|tr=bīmār}}, {{W+|ur|مریض|tr=marīz}}, {{W-|ur|علیل|tr=alīl}} * {{Z|uk}}: {{W-|uk|хво́рий}} * {{Z|vi}}: {{W+|vi|bệnh}}, {{W+|vi|ốm}} * {{Z|vo}}: {{W+|vo|malädik}} * {{Z|cy}}: {{W+|cy|sâl}} * {{Z|km}}: {{W+|km|ឈឺ}}, {{W+|km|ថ្កាត់}} * {{Z|yi}}: {{W-|yi|קראַנק}}, {{W-|yi|קרענקלעך}}, {{W-|yi|געלעגן צו בעט}} * {{Z|el}}: {{W+|el|άρρωστος}} *: Kevn: {{W-|grc|ἄρρωστος}} * {{Z|za}}: {{W-|za|bingh}} {{werger-bin}} :{{werger çavkanî|en|ill|beş=Ev qismê Wergerê|oldid=75878299}} {{werger-ser}} * {{Z|de}}: {{W+|de|unbequem}}, {{W+|de|ungemütlich}} * {{Z|az}}: {{W-|az|rahatsız}}, {{W-|az|naqolay}} * {{Z|bg}}: {{W+|bg|неудо́бен}} * {{Z|cs}}: {{W-|cs|nepohodlný}} * {{Z|zh}}: *: {{Z|cmn}}: {{W+|cmn|不舒服|tr=bùshūfu}} * {{Z|ar}}: {{W-|ar|غَيْر مُرِيح}} * {{Z|hy}}: {{W+|hy|անհարմար}} * {{Z|fi}}: {{W+|fi|epämukava}} * {{Z|fr}}: {{W+|fr|inconfortable}} * {{Z|gd}}: {{W-|gd|mì-shuaimhneach}} * {{Z|gl}}: {{W-|gl|incómodo}} * {{Z|ka}}: {{W-|ka|არაკეთილმოწყობილი}} * {{Z|nl}}: {{W+|nl|ongemakkelijk}} * {{Z|en}}: {{W+|en|uncomfortable}}, {{W+|en|unconvenient}} * {{Z|ga}}: {{W-|ga|anacair}}, {{W-|ga|aineascair}} * {{Z|is}}: {{W+|is|óþægilegur}} * {{Z|ja}}: {{W-|ja|心地よい|tr=ここちよくない, kokochiyokunai|cuda=心地よくない}} * {{Z|ca}}: {{W+|ca|incòmode}} * {{Z|ko}}: {{W+|ko|불편하다}} * {{Z|lld}}: {{W-|lld|ncomper}} * {{Z|la}}: {{W-|la|incommodus}} * {{Z|mk}}: {{W-|mk|неу́добен}}, {{W-|mk|непри́јатен}} * {{Z|hu}}: {{W+|hu|kényelmetlen}} * {{Z|oc}}: {{W+|oc|incomòde}} * {{Z|pdt}}: {{W-|pdt|Forcht|m}} * {{Z|pl}}: {{W+|pl|niewygodny}}, {{W+|pl|niekomfortowy}} * {{Z|pt}}: {{W+|pt|desconfortável}}, {{W+|pt|incómodo}}, {{W+|pt|incômodo}} * {{Z|ru}}: {{W+|ru|неудо́бный}}, {{W+|ru|некомфорта́бельный}} * {{Z|sa}}: {{W+|sa|दुःख}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|не̏удобан}} *: Latînî: {{W+|sh|nȅudoban}} * {{Z|es}}: {{W+|es|incómodo}} * {{Z|th}}: {{W-|th|ไม่สะดวก|tr=mâi sàdùak}} * {{Z|uk}}: {{W-|uk|незру́чний}} * {{Z|el}}: {{W+|el|άβολο}} {{werger-bin}} :{{werger çavkanî|en|uncomfortable|beş=Ev qismê Wergerê|oldid=75702492}} === Navdêr === {{navdêr|ku|z=mn}} # Kesa/ê [[êş]]ek yan hin [[êş]] lê hene. #: {{mk|ku|'''Nexweşek'''.}} #: {{mk|ku|'''Nexweşa''' şekirê.}} #* {{jêder|ku|{{Jêgirtin/Melayê Cizîrî/Dîwana Melayê Cizirî}}|jêgirtin=Lê ji bo nekhê dehanî<br>'''Nexweşan''' ew lê şifa ye<br>Mawera belgên gulê bû}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê û nêr}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Kranker|n}}, {{W+|de|Kranke|m}} * {{Z|fr}}: {{W+|fr|malade|mn}} * {{Z|en}}: {{W+|en|invalid}}, {{W-|en|sick person}}, {{W-|en|ill person}} * {{Z|es}}: {{W+|es|enfermo|n}} * {{Z|tr}}: {{W+|tr|hasta}} {{werger-bin}} i908teq0560hua40lt63xu8w33x628z pîrek 0 10262 6334053 6315269 2026-08-16T02:09:42Z Wikihez 7344 /* 3. kesa ne keç */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334053 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[jin]], [[kebanî]], [[bermalî]], [[afret]], [[kuflet]], [[kulfet]], [[kabanî]], [[kavanî]], [[kevanî]] # [[hevjîn]]a kesekê ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Jê ==== * [[pîrekî]] * [[pîrekîtî]] * [[pîrektî]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W+|ar|امرأة|guman=erê}}, {{W+|ar|مرأة|guman=erê}} * {{Z|fa}}: {{W+|fa|زن}}, {{W+|fa|همسر}} * {{Z|en}}: {{W+|en|woman|guman=erê}}, {{W+|en|old woman|guman=erê}} wife * {{Z|tr}}: {{W+|tr|avrat}}, {{W+|tr|familya}}, {{W+|tr|kadın}}, {{W+|tr|karı}}, {{W+|tr|refika}}, {{W-|tr|ev şenliği|guman=erê}} {{werger-bin}} === Formeke navdêrê === {{navdêr|ku|form=erê}} # [[form|Formek]] ji peyva '''[[pîr]]''' #: '''''Pîrek''' û du zarok bûn.'' # [[dapîr]]ek #: '''''Pîrek''' û neviyê xwe.'' === Navdêr === {{navdêr|ku}} # [[kes|Kesa]] ku ji [[keçanî]]yê derketiye. f13yltchx9gqr7rguf5plujxkjmchsd pêlîstik 0 15274 6334044 6315078 2026-08-16T01:53:05Z Wikihez 7344 /* Cûnên pêlistikan */ [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6334044 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[yarîk]], tiştên pê têt [[lîstin]], <br>tiştên mirov pê [[lîstin|dilîzin]], <br>tiştên mirov pê [[yarî|yariyan]] dikin #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== {{stûn| * [[pêlehîstik]] * [[pêlehîztik]] * [[pêlehîzik]] * [[pêleyîstik]] * [[pêleyîztik]] * [[pêleyizik]] * [[pêleyîzik]] * [[pêlîzik]] * [[pêlîztik]] * [[pêlehîstok]] * [[pêlehîztok]] * [[pêlehîzok]] * [[pêleyîstok]] * [[pêleyîztok]] * [[pêleyizok]] * [[pêleyîzok]] * [[pêlîstok]] * [[pêlîzok]] * [[pêlîztok]] }} ==== Herwiha binêre === {{kol3|ku|sernav=Cûnên pêlistikan |berik |hol |gog |lego |kaşok |kompûter |nîntendo |tepik |tirimpêlk |vîdyo }} ==== Etîmolojî ==== Ji {{qf|ku|pê|lîstin<cuda:lîst>|-ik}}. ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|اسباب بازی}} * {{Z|en}}: {{W+|en|toy}} * {{Z|tr}}: {{W+|tr|kukla}}, {{W+|tr|oyuncak}} {{werger-bin}} 7akmmez2ww3gh1hdpm6in9frcwbieee 6334045 6334044 2026-08-16T01:53:18Z Wikihez 7344 /* = Herwiha binêre */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334045 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[yarîk]], tiştên pê têt [[lîstin]], <br>tiştên mirov pê [[lîstin|dilîzin]], <br>tiştên mirov pê [[yarî|yariyan]] dikin #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== {{stûn| * [[pêlehîstik]] * [[pêlehîztik]] * [[pêlehîzik]] * [[pêleyîstik]] * [[pêleyîztik]] * [[pêleyizik]] * [[pêleyîzik]] * [[pêlîzik]] * [[pêlîztik]] * [[pêlehîstok]] * [[pêlehîztok]] * [[pêlehîzok]] * [[pêleyîstok]] * [[pêleyîztok]] * [[pêleyizok]] * [[pêleyîzok]] * [[pêlîstok]] * [[pêlîzok]] * [[pêlîztok]] }} ==== Herwiha binêre ==== {{kol3|ku|sernav=Cûnên pêlistikan |berik |hol |gog |lego |kaşok |kompûter |nîntendo |tepik |tirimpêlk |vîdyo }} ==== Etîmolojî ==== Ji {{qf|ku|pê|lîstin<cuda:lîst>|-ik}}. ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|اسباب بازی}} * {{Z|en}}: {{W+|en|toy}} * {{Z|tr}}: {{W+|tr|kukla}}, {{W+|tr|oyuncak}} {{werger-bin}} 1jxlpykqrhvr53es5cqa9pvfzbggmb0 6334046 6334045 2026-08-16T01:53:42Z Wikihez 7344 /* Formên alternatîv */ 6334046 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[yarîk]], tiştên pê têt [[lîstin]], <br>tiştên mirov pê [[lîstin|dilîzin]], <br>tiştên mirov pê [[yarî|yariyan]] dikin #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== {{kol3|ku|cure=Formên alternatîv |pêlehîstik |pêlehîztik |pêlehîzik |pêleyîstik |pêleyîztik |pêleyizik |pêleyîzik |pêlîzik |pêlîztik |pêlehîstok |pêlehîztok |pêlehîzok |pêleyîstok |pêleyîztok |pêleyizok |pêleyîzok |pêlîstok |pêlîzok |pêlîztok }} ==== Herwiha binêre ==== {{kol3|ku|sernav=Cûnên pêlistikan |berik |hol |gog |lego |kaşok |kompûter |nîntendo |tepik |tirimpêlk |vîdyo }} ==== Etîmolojî ==== Ji {{qf|ku|pê|lîstin<cuda:lîst>|-ik}}. ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|اسباب بازی}} * {{Z|en}}: {{W+|en|toy}} * {{Z|tr}}: {{W+|tr|kukla}}, {{W+|tr|oyuncak}} {{werger-bin}} kgdk5tx6xn8obglnnzy5h66syrjkrfl 6334067 6334046 2026-08-16T02:41:16Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6334067 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[yarîk]], tiştên pê têt [[lîstin]], <br>tiştên mirov pê [[lîstin|dilîzin]], <br>tiştên mirov pê [[yarî|yariyan]] dikin #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== {{kol3|ku|cure=Formên alternatîv |pêlehîstik |pêlehîztik |pêlehîzik |pêleyîstik |pêleyîztik |pêleyizik |pêleyîzik |pêlîzik |pêlîztik |pêlehîstok |pêlehîztok |pêlehîzok |pêleyîstok |pêleyîztok |pêleyizok |pêleyîzok |pêlîstok |pêlîzok |pêlîztok }} ==== Etîmolojî ==== Ji {{qf|ku|pê|lîstin<cuda:lîst>|-ik}}. ==== Herwiha binêre ==== {{kol3|ku|sernav=Cûnên pêlistikan |berik |hol |gog |lego |kaşok |kompûter |nîntendo |tepik |tirimpêlk |vîdyo }} ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|اسباب بازی}} * {{Z|en}}: {{W+|en|toy}} * {{Z|tr}}: {{W+|tr|kukla}}, {{W+|tr|oyuncak}} {{werger-bin}} ct3rhl9rb0hzfcvb85puxvkqn3brp5v lûlav 0 16165 6333920 6311489 2026-08-15T23:02:16Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6333920 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{IPA|ku|/luːˈlɑːv/}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[av|Av]] û [[berf]] di nav hev de, [[berf]] û [[baran]] [[têkil]]. #: {{hevmane|ku|şilope}} #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * {{g|ku|lîlav}} * {{g|ku|lwîlav}} * {{g|ku|lîlovir}} ==== Bide ber ==== {kol3|ku |av |bahoz |baran |barove |berf |gijlok |po |savarok |terg |teyrok |nixte |zîpik }} ==== Binêre herwiha ==== * {{g|ku|lûle}} ==== Jê ==== * {{g|ku|şilopeyî}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|kar suyu}}, {{W+|tr|kargın}}, {{W+|tr|kayan}} {{werger-bin}} qy5zbqqxgzt16s6tggdsrny7qsoytph 6333932 6333920 2026-08-15T23:12:24Z Ghybu 1393 /* Bide ber */ 6333932 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{IPA|ku|/luːˈlɑːv/}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[av|Av]] û [[berf]] di nav hev de, [[berf]] û [[baran]] [[têkil]]. #: {{hevmane|ku|şilope}} #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * {{g|ku|lîlav}} * {{g|ku|lwîlav}} * {{g|ku|lîlovir}} ==== Bide ber ==== {{kol3|ku |av |bahoz |baran |barove |berf |gijlok |po |savarok |terg |teyrok |nixte |zîpik }} ==== Binêre herwiha ==== * {{g|ku|lûle}} ==== Jê ==== * {{g|ku|şilopeyî}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|kar suyu}}, {{W+|tr|kargın}}, {{W+|tr|kayan}} {{werger-bin}} 3yaqbthecyipxnifn21u1o188822wgz 6333979 6333932 2026-08-15T23:41:44Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333979 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{IPA|ku|/luːˈlɑːv/}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[av|Av]] û [[berf]] di nav hev de, [[berf]] û [[baran]] [[têkil]]. #: {{hevmane|ku|şilope}} #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * {{g|ku|lîlav}} * {{g|ku|lwîlav}} * {{g|ku|lîlovir}} ==== Jê ==== * {{g|ku|şilopeyî}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Bide ber ==== {{kol3|ku |av |bahoz |baran |barove |berf |gijlok |po |savarok |terg |teyrok |nixte |zîpik }} ==== Herwiha binêre ==== * {{g|ku|lûle}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|kar suyu}}, {{W+|tr|kargın}}, {{W+|tr|kayan}} {{werger-bin}} acpfg3bm794t6q0mdxa8y27tkngcxzb veciniqîn 0 17053 6334074 6319698 2026-08-16T06:51:22Z ~2026-44707-21 15258 +nimûneya bikaranînê bi amûra « [[Mediawiki:Gadget-wikt.add-examples|Nimûne zêde bike]] » (v1.7). 6334074 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Lêker === {{ku-tewîn-lk|veciniqîn|form=negerguhêz|niha=ciniq|borî=ciniqî|borî2=ciniqiya|pêşgir=ve}} # [[terqilîn]], [[varqilîn]], [[hilceniqîn]], <br>[[ji nişkê ve]] [[hay]] ji tiştekê/î bûn, <br>[[ji nişkê ve]] [[hişyar]] bûn, ji nişkê ve tirsîn lê tirsek mezin, bi surprîz yan jî hişyariyek ji nişkê ve şaş mayîn bi kelecan ketin #* {{jêder|ku|jêgirtin=Xeta trênê nêzîkî wî bû. Gelekî neçû giha ser xetê. Li vir bi xwe hisiya ku şev lê geriyaye û rêya xwe şaş kiriye. '''Veciniqî''' û hema pê re jî ji hindam de xwe li ser zik avêt erdê.|Serok Altaxûs, [[w:Laleş Qaso|Laleş Qaso]], Çapa 2., 2009, weşanxana Komal}} #* {{jêder|ku|url=ISBN 975-273-098-1|jêgirtin=Kevok vediciniqin.}} ==== Bi alfabeyên din ==== * {{ku-ar|ڤه‌جنقین}} ==== Formên alternatîv ==== {{kol3|ku|cure=Herwiha |veceniqan |veceniqhan |veceniqhîn |veceniqihan |veceniqihîn |veceniqiyan |veceniqîn |veceniqîyan |veceniqyan |veciniqan |veciniqhan |veciniqhîn |veciniqihan |veciniqihîn |veciniqiyan |veciniqîyan |veciniqyan }} ==== Jê ==== {{kol3|ku|cure=Jê |veciniqiyayî |veciniqî |veciniqok }} ==== Têkildar ==== * {{g|ku|veciniqandin}} ==== Etîmolojî ==== Ji {{pêş|ku|ve-|ciniqîn}}. ==== Bi zaravayên din ==== * {{Z|ckb}}: {{W-|ckb|داخورپان}}, {{W-|ckb|ڕاچەنین}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: [[wach]] [[werden]], {{W+|de|auffahren}}, {{W+|de|erwachen}}, {{W+|de|Entsetzen|m}}, {{W+|de|abschrecken}}, {{W+|de|aufschrecken}}, {{W+|de|schauern}}, {{W-|de|Panik haben}}, {{W-|de|Zittern|guman=erê}}, {{W-|de|Zusammenfahren|guman=erê}}, {{W+|de|schaudern|guman=erê}}, {{W+|de|zusammenfahren|guman=erê}}, {{W+|de|zusammenzucken|guman=erê}} * {{Z|fa}}: {{W+|fa|یکه خوردن}} * {{Z|fi}}: {{W+|fi|havahtua}} * {{Z|fr}}: se [[réveiller]] * {{Z|en}}: to {{W-|en|be alarmed}}, to {{W-|en|be startled}}, {{W+|en|awake}}, [[wake]] [[up]] [[to]], {{W+|en|awaken}}, become [[conscious]], {{W+|en|recoil}}, {{W+|en|blench|guman=erê}}, {{W+|en|boggle|guman=erê}}, {{W+|en|flinch|guman=erê}}, {{W+|en|boggling|guman=erê}}, {{W+|en|wince|guman=erê}}, {{W+|en|wincing|guman=erê}} * {{Z|it}}: {{W+|it|divenire}}, {{W+|it|tornare}}, {{W+|it|svegliarsi}} * {{Z|ru}}: {{W+|ru|очнуться}}, {{W+|ru|очухаться}} * {{Z|es}}: {{W+|es|despertarse}} * {{Z|sv}}: [[vakna]] [[upp]] * {{Z|tr}}: {{W+|tr|irkilmek}}, {{W+|tr|ürkmek}}, {{W+|tr|afallamak}}, {{W-|tr|korkup şaşırmak}}, {{W-|tr|şaşıp kalmak}}, {{W+|tr|benildemek}}, {{W+|tr|huylanmak}}, {{W+|tr|sıçramak}}, {{W+|tr|tevahhuş etmek}}, {{W+|tr|taharrüş etmek|guman=erê}}, {{W+|tr|belinlemek|guman=erê}} {{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|belinleme}}, {{W+|tr|sıçrama}}, {{W+|tr|tevahhuş}}, {{W+|tr|irkilme}}, {{W+|tr|ürkme}} {{werger-bin}} jpsbtg0sacgzusjh39t5hu3aefcdegp 6334075 6334074 2026-08-16T06:52:44Z ~2026-44707-21 15258 6334075 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Lêker === {{ku-tewîn-lk|veciniqîn|form=negerguhêz|niha=ciniq|borî=ciniqî|borî2=ciniqiya|pêşgir=ve}} # [[terqilîn]], [[varqilîn]], [[hilceniqîn]], <br>[[ji nişkê ve]] [[hay]] ji tiştekê/î bûn, <br>[[ji nişkê ve]] [[hişyar]] bûn, ji nişkê ve tirsîn lê tirsek mezin, bi surprîz yan jî hişyariyek ji nişkê ve şaş mayîn bi kelecan ketin #* {{jêder|ku|jêgirtin=Xeta trênê nêzîkî wî bû. Gelekî neçû giha ser xetê. Li vir bi xwe hisiya ku şev lê geriyaye û rêya xwe şaş kiriye. '''Veciniqî''' û hema pê re jî ji hindam de xwe li ser zik avêt erdê.|Serok Altaxûs, [[w:Laleş Qaso|Laleş Qaso]], Çapa 2., 2009, weşanxana Komal}} ==== Bi alfabeyên din ==== * {{ku-ar|ڤه‌جنقین}} ==== Formên alternatîv ==== {{kol3|ku|cure=Herwiha |veceniqan |veceniqhan |veceniqhîn |veceniqihan |veceniqihîn |veceniqiyan |veceniqîn |veceniqîyan |veceniqyan |veciniqan |veciniqhan |veciniqhîn |veciniqihan |veciniqihîn |veciniqiyan |veciniqîyan |veciniqyan }} ==== Jê ==== {{kol3|ku|cure=Jê |veciniqiyayî |veciniqî |veciniqok }} ==== Têkildar ==== * {{g|ku|veciniqandin}} ==== Etîmolojî ==== Ji {{pêş|ku|ve-|ciniqîn}}. ==== Bi zaravayên din ==== * {{Z|ckb}}: {{W-|ckb|داخورپان}}, {{W-|ckb|ڕاچەنین}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: [[wach]] [[werden]], {{W+|de|auffahren}}, {{W+|de|erwachen}}, {{W+|de|Entsetzen|m}}, {{W+|de|abschrecken}}, {{W+|de|aufschrecken}}, {{W+|de|schauern}}, {{W-|de|Panik haben}}, {{W-|de|Zittern|guman=erê}}, {{W-|de|Zusammenfahren|guman=erê}}, {{W+|de|schaudern|guman=erê}}, {{W+|de|zusammenfahren|guman=erê}}, {{W+|de|zusammenzucken|guman=erê}} * {{Z|fa}}: {{W+|fa|یکه خوردن}} * {{Z|fi}}: {{W+|fi|havahtua}} * {{Z|fr}}: se [[réveiller]] * {{Z|en}}: to {{W-|en|be alarmed}}, to {{W-|en|be startled}}, {{W+|en|awake}}, [[wake]] [[up]] [[to]], {{W+|en|awaken}}, become [[conscious]], {{W+|en|recoil}}, {{W+|en|blench|guman=erê}}, {{W+|en|boggle|guman=erê}}, {{W+|en|flinch|guman=erê}}, {{W+|en|boggling|guman=erê}}, {{W+|en|wince|guman=erê}}, {{W+|en|wincing|guman=erê}} * {{Z|it}}: {{W+|it|divenire}}, {{W+|it|tornare}}, {{W+|it|svegliarsi}} * {{Z|ru}}: {{W+|ru|очнуться}}, {{W+|ru|очухаться}} * {{Z|es}}: {{W+|es|despertarse}} * {{Z|sv}}: [[vakna]] [[upp]] * {{Z|tr}}: {{W+|tr|irkilmek}}, {{W+|tr|ürkmek}}, {{W+|tr|afallamak}}, {{W-|tr|korkup şaşırmak}}, {{W-|tr|şaşıp kalmak}}, {{W+|tr|benildemek}}, {{W+|tr|huylanmak}}, {{W+|tr|sıçramak}}, {{W+|tr|tevahhuş etmek}}, {{W+|tr|taharrüş etmek|guman=erê}}, {{W+|tr|belinlemek|guman=erê}} {{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|belinleme}}, {{W+|tr|sıçrama}}, {{W+|tr|tevahhuş}}, {{W+|tr|irkilme}}, {{W+|tr|ürkme}} {{werger-bin}} ggh4lnlzx7zpvbul6hhodqn0dia3h8n 6334076 6334075 2026-08-16T06:56:02Z ~2026-44707-21 15258 +nimûneya bikaranînê bi amûra « [[Mediawiki:Gadget-wikt.add-examples|Nimûne zêde bike]] » (v1.7). 6334076 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Lêker === {{ku-tewîn-lk|veciniqîn|form=negerguhêz|niha=ciniq|borî=ciniqî|borî2=ciniqiya|pêşgir=ve}} # [[terqilîn]], [[varqilîn]], [[hilceniqîn]], <br>[[ji nişkê ve]] [[hay]] ji tiştekê/î bûn, <br>[[ji nişkê ve]] [[hişyar]] bûn, ji nişkê ve tirsîn lê tirsek mezin, bi surprîz yan jî hişyariyek ji nişkê ve şaş mayîn bi kelecan ketin #* {{jêder|ku|jêgirtin=Xeta trênê nêzîkî wî bû. Gelekî neçû giha ser xetê. Li vir bi xwe hisiya ku şev lê geriyaye û rêya xwe şaş kiriye. '''Veciniqî''' û hema pê re jî ji hindam de xwe li ser zik avêt erdê.|Serok Altaxûs, [[w:Laleş Qaso|Laleş Qaso]], Çapa 2., 2009, weşanxana Komal}} #* {{jêder|ku|2=Mehmed Uzun. Siya Evînê. Ithaki: Istanbul, 2005.|jêgirtin=Kevok vediciniqin.}} ==== Bi alfabeyên din ==== * {{ku-ar|ڤه‌جنقین}} ==== Formên alternatîv ==== {{kol3|ku|cure=Herwiha |veceniqan |veceniqhan |veceniqhîn |veceniqihan |veceniqihîn |veceniqiyan |veceniqîn |veceniqîyan |veceniqyan |veciniqan |veciniqhan |veciniqhîn |veciniqihan |veciniqihîn |veciniqiyan |veciniqîyan |veciniqyan }} ==== Jê ==== {{kol3|ku|cure=Jê |veciniqiyayî |veciniqî |veciniqok }} ==== Têkildar ==== * {{g|ku|veciniqandin}} ==== Etîmolojî ==== Ji {{pêş|ku|ve-|ciniqîn}}. ==== Bi zaravayên din ==== * {{Z|ckb}}: {{W-|ckb|داخورپان}}, {{W-|ckb|ڕاچەنین}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: [[wach]] [[werden]], {{W+|de|auffahren}}, {{W+|de|erwachen}}, {{W+|de|Entsetzen|m}}, {{W+|de|abschrecken}}, {{W+|de|aufschrecken}}, {{W+|de|schauern}}, {{W-|de|Panik haben}}, {{W-|de|Zittern|guman=erê}}, {{W-|de|Zusammenfahren|guman=erê}}, {{W+|de|schaudern|guman=erê}}, {{W+|de|zusammenfahren|guman=erê}}, {{W+|de|zusammenzucken|guman=erê}} * {{Z|fa}}: {{W+|fa|یکه خوردن}} * {{Z|fi}}: {{W+|fi|havahtua}} * {{Z|fr}}: se [[réveiller]] * {{Z|en}}: to {{W-|en|be alarmed}}, to {{W-|en|be startled}}, {{W+|en|awake}}, [[wake]] [[up]] [[to]], {{W+|en|awaken}}, become [[conscious]], {{W+|en|recoil}}, {{W+|en|blench|guman=erê}}, {{W+|en|boggle|guman=erê}}, {{W+|en|flinch|guman=erê}}, {{W+|en|boggling|guman=erê}}, {{W+|en|wince|guman=erê}}, {{W+|en|wincing|guman=erê}} * {{Z|it}}: {{W+|it|divenire}}, {{W+|it|tornare}}, {{W+|it|svegliarsi}} * {{Z|ru}}: {{W+|ru|очнуться}}, {{W+|ru|очухаться}} * {{Z|es}}: {{W+|es|despertarse}} * {{Z|sv}}: [[vakna]] [[upp]] * {{Z|tr}}: {{W+|tr|irkilmek}}, {{W+|tr|ürkmek}}, {{W+|tr|afallamak}}, {{W-|tr|korkup şaşırmak}}, {{W-|tr|şaşıp kalmak}}, {{W+|tr|benildemek}}, {{W+|tr|huylanmak}}, {{W+|tr|sıçramak}}, {{W+|tr|tevahhuş etmek}}, {{W+|tr|taharrüş etmek|guman=erê}}, {{W+|tr|belinlemek|guman=erê}} {{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|belinleme}}, {{W+|tr|sıçrama}}, {{W+|tr|tevahhuş}}, {{W+|tr|irkilme}}, {{W+|tr|ürkme}} {{werger-bin}} me16r1md99dgq3jx4q0ym73ato6vrrt nezanî 0 18063 6334014 6313371 2026-08-16T01:15:40Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6334014 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[cehalet]], [[cahilî]], [[cahilbûn]], [[nezanbûn]], [[xeşîmî]], [[naşîtî]] #* {{bêmînak|ku}} # {{kontrol|rêz=erê|[[cehl]], [[xişîmî]], [[torîtî]], [[naîvîtî]], [[ecemîtî]]}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|نه‌زانی}} ==== Formên alternatîv ==== {{kol3|ku|cure=Herwiha |nezanîtî |nezantî }} ==== Jê ==== {{kol3|ku|cure=Jê |nezanî kirin<pos:lêker> |nezanîkirin<pos:navdêr> |nezanîkirî<pos:rengdêr> }} ==== Etîmolojî ==== Ji {{paş|ku|nezan|-î}} ==== Bi zaravayên din ==== * {{Z|ckb}}: {{W-|ckb|nazanî}} ==== Ji wêjeya klasîk ==== * {{jêder|ku|{{Jêgirtin/Ehmedê Xanî/Mem û Zîn}}|jêgirtin=Ew şîr li bin serê xwe danî</br>Ewreng-i veşar kes-i '''nezanî'''</br>Mîrê weko dil bi kerbê sotî}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Ignoranz|f}}, {{W+|de|Einfalt|f}}, {{W+|de|Nichtwissen}}, {{W+|de|Unkenntnis}}, {{W+|de|Unwissenheit|f}}, {{W+|de|Unerfahrenheit|f|guman=erê}} * {{Z|zh}}: {{W-|zh|无知|tr=wú zhī}} * {{Z|ar}}: {{W-|ar|عي|guman=erê}}, {{W-|ar|عیي|guman=erê}} * {{Z|hy}}: {{W+|hy|անտեղյակություն}}, {{W+|hy|մոլորություն}} * {{Z|fa}}: {{W-|fa|جهل|tr=cehel}}, [[نادانی]] (nadanî), [[بی‌سوادی]] (bîsewadî = [[bêsewadî]]), {{W+|fa|حماقت}}, {{W+|fa|نادانی}}, {{W+|fa|نادانی}}, {{W-|fa|بی‌سوادی}} * {{Z|fi}}: {{W+|fi|tietämättömyys}}, {{W+|fi|sivistymättömyys}}, {{W-|fi|kouluttamattomuus}} * {{Z|fr}}: {{W+|fr|ignorance|f}} * {{Z|en}}: {{W-|en|ignorace}}, {{W+|en|ignorance}}, {{W+|en|rusticity}}, {{W+|en|impersonal}}, {{W+|en|nescience|guman=erê}}, {{W+|en|nown|guman=erê}}, {{W+|en|bad manners|guman=erê}} * {{Z|it}}: {{W+|it|ignoranza|f}} * {{Z|hu}}: {{W+|hu|tudatlanság}} * {{Z|no}}: {{W+|no|uvitenhet}} * {{Z|pt}}: {{W+|pt|ignorância|f}} * {{Z|es}}: {{W+|es|ignorancia|f}} * {{Z|tr}}: {{W+|tr|cehalet}}, {{W+|tr|bilgisizlik}}, {{W+|tr|bilisizlik}}, {{W+|tr|cahillik}}, {{W+|tr|cehil}}, {{W+|tr|kakavanlık}}, {{W+|tr|kofluk}}, {{W+|tr|nadanlık}}, {{W+|tr|vukufsuzluk}}, {{W+|tr|anlamazlık}} * {{Z|el}}: {{W+|el|άγνοια}}, {{W+|el|αμάθεια}}, {{W+|el|αμορφωσιά}} {{werger-bin}} 7ur13gsbomo4bdhew5jjd42h2hzfr1x 6334028 6334014 2026-08-16T01:41:12Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6334028 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[cehalet]], [[cahilî]], [[cahilbûn]], [[nezanbûn]], [[xeşîmî]], [[naşîtî]] #* {{bêmînak|ku}} # {{kontrol|rêz=erê|[[cehl]], [[xişîmî]], [[torîtî]], [[naîvîtî]], [[ecemîtî]]}} ==== Ji wêjeya klasîk ==== * {{jêder|ku|{{Jêgirtin/Ehmedê Xanî/Mem û Zîn}}|jêgirtin=Ew şîr li bin serê xwe danî</br>Ewreng-i veşar kes-i '''nezanî'''</br>Mîrê weko dil bi kerbê sotî}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|نه‌زانی}} ==== Formên alternatîv ==== {{kol3|ku|cure=Herwiha |nezanîtî |nezantî }} ==== Jê ==== {{kol3|ku|cure=Jê |nezanî kirin<pos:lêker> |nezanîkirin<pos:navdêr> |nezanîkirî<pos:rengdêr> }} ==== Etîmolojî ==== Ji {{paş|ku|nezan|-î}} ==== Bi zaravayên din ==== * {{Z|ckb}}: {{W-|ckb|nazanî}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Ignoranz|f}}, {{W+|de|Einfalt|f}}, {{W+|de|Nichtwissen}}, {{W+|de|Unkenntnis}}, {{W+|de|Unwissenheit|f}}, {{W+|de|Unerfahrenheit|f|guman=erê}} * {{Z|zh}}: {{W-|zh|无知|tr=wú zhī}} * {{Z|ar}}: {{W-|ar|عي|guman=erê}}, {{W-|ar|عیي|guman=erê}} * {{Z|hy}}: {{W+|hy|անտեղյակություն}}, {{W+|hy|մոլորություն}} * {{Z|fa}}: {{W-|fa|جهل|tr=cehel}}, [[نادانی]] (nadanî), [[بی‌سوادی]] (bîsewadî = [[bêsewadî]]), {{W+|fa|حماقت}}, {{W+|fa|نادانی}}, {{W+|fa|نادانی}}, {{W-|fa|بی‌سوادی}} * {{Z|fi}}: {{W+|fi|tietämättömyys}}, {{W+|fi|sivistymättömyys}}, {{W-|fi|kouluttamattomuus}} * {{Z|fr}}: {{W+|fr|ignorance|f}} * {{Z|en}}: {{W-|en|ignorace}}, {{W+|en|ignorance}}, {{W+|en|rusticity}}, {{W+|en|impersonal}}, {{W+|en|nescience|guman=erê}}, {{W+|en|nown|guman=erê}}, {{W+|en|bad manners|guman=erê}} * {{Z|it}}: {{W+|it|ignoranza|f}} * {{Z|hu}}: {{W+|hu|tudatlanság}} * {{Z|no}}: {{W+|no|uvitenhet}} * {{Z|pt}}: {{W+|pt|ignorância|f}} * {{Z|es}}: {{W+|es|ignorancia|f}} * {{Z|tr}}: {{W+|tr|cehalet}}, {{W+|tr|bilgisizlik}}, {{W+|tr|bilisizlik}}, {{W+|tr|cahillik}}, {{W+|tr|cehil}}, {{W+|tr|kakavanlık}}, {{W+|tr|kofluk}}, {{W+|tr|nadanlık}}, {{W+|tr|vukufsuzluk}}, {{W+|tr|anlamazlık}} * {{Z|el}}: {{W+|el|άγνοια}}, {{W+|el|αμάθεια}}, {{W+|el|αμορφωσιά}} {{werger-bin}} 610yxunaohmf15z37oby9triuaqiwwc fort 0 18851 6333942 6326232 2026-08-15T23:21:10Z Wikihez 7344 /* Mane */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333942 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[gef]], [[hereşe]], [[tehdîd]], [[lêxurrîn]], [[lêheytandin]] #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Jê ==== {{kol3|ku|cure=Jê |fort kirin<pos:lêker> |fortkirin<pos:navdêr> |fortdan<pos:navdêr> |fortkirî<pos:rengdêr> |fortik |fortî }} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Bide ber ==== * {{g|ku|firt}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Angeberei}} {{mê}}, {{W|de|Aufschneiden}}, {{W|de|Lüge}} {{mê}} * {{Z|fa}}: {{W|fa|بلندی}}, {{W|fa|درجه بالا}}, {{W|fa|تهدید}}, {{W|fa|خشن پایه}} * {{Z|fi}}: {{W|fi|uhkaus}} * {{Z|en}}: {{W|en|threat}}, {{W|en|rodomontade}}, {{W|en|windy}}, {{W|en|lug|guman=erê}}, {{W|en|swaggering|guman=erê}}, {{W|en|lope|guman=erê}}, {{W|en|lordosis|guman=erê}}, {{W|en|pomp|guman=erê}}, {{W|en|prancing|guman=erê}}, {{W|en|strutting|guman=erê}}, {{W|en|haughtiness|guman=erê}}, {{W|en|magnificence|guman=erê}} * {{Z|tr}}: {{W|tr|atmasyon}}, {{W|tr|blöf}}, {{W|tr|dikine tıraş}}, {{W|tr|yumruk}}, {{W|tr|palavra}}, {{W|tr|martaval}}, {{W|tr|tafra}}, {{W|tr|dikine traş|guman=erê}} {{werger-bin}} == {{ziman|de}} == === Bilêvkirin === * {{deng|de|De-fort.ogg}} === Navdêr === {{navdêr|de}} # [[çûyî]], [[combûyî]], [[gombûyî]] #* {{bênimûne|de}} == {{ziman|fr}} == === Bilêvkirin === * {{deng|fr|LL-Q150 (fra)-Poslovitch-fort.wav|Deng|dever=Cornimont, Fransa}} * {{deng|fr|LL-Q150 (fra)-WikiLucas00-fort.wav|Deng|dever=Lyon, Fransa}} * {{deng|fr|LL-Q150 (fra)-Lepticed7-fort.wav|Deng|dever=Aude, Fransa}} * {{deng|fr|LL-Q150 (fra)-DSwissK-fort.wav|Deng|dever=Valais, Swîsre}} * {{deng|fr|LL-Q150 (fra)-LoquaxFR-fort.wav|Deng|dever=Vosges, Fransa}} === Mane === {{cure?|fr}} # [[xurt]], [[bihêz]], [[qewî]], [[biqewet]] #* {{bênimûne|fr}} == {{ziman|nl}} == === Navdêr === {{navdêr|nl|z=nt}} # {{f|nl|avahî}} {{g|ku|keleh}} #* {{bênimûne|nl}} === Çavkanî === {{rûpela wergerê|nl|keleh}} == {{ziman|en}} == === Bilêvkirin === * {{deng|en|en-us-fort.ogg|dever=DYA}} * {{deng|en|LL-Q1860 (eng)-Grendelkhan-fort.wav|Deng|dever=Connecticut, DYA}} === Navdêr === {{navdêr|en}} # [[kel(h)e]], [[kela]], [[himbêz]] <ref>Ferhenga Kurdî-Îngîlîzî ya Salah Sadallah</ref> #* {{bênimûne|en}} === Çavkanî === {{çavkanî}} segs3qu3h3tfq5b45b5l3yca3xqa0ld cerd 0 18942 6333921 6304172 2026-08-15T23:03:02Z Wikihez 7344 /* Binêre herwiha */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333921 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{IPA|ku|/d͡ʒɛɾd/}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[nobet]], [[çavdêrî]], [[sereguhî]], [[parastin]], [[matîjêkirin]] #* {{jêder|ku|{{Jêgirtin/Ehmedê Xanî/Mem û Zîn}}|jêgirtin=Bajar û kelat û xanî berdan</br>Teşbîhê bi nijdeyan û '''cerd'''an</br>Sef sef dimeşîne kûh û deştan}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * {{g|ku|cerde}} ==== Bide ber ==== * {{g|ku|cird}} ==== Binêre herwiha ==== {{kol3|ku |berd |derd |merd |zerd }} ==== Jê ==== {{kol3|ku|cure=Jê |cerd girtin<pos:lêker> |cerd kirin<pos:lêker> |cerd dan<pos:lêker> |cerdgirtin<pos:navdêr> |cerdkirin<pos:navdêr> |cerddan<pos:navdêr> |cerdgirtî<pos:rengdêr> |cerdkirî<pos:rengdêr> |cerdevan |cerdevanî |cerdevanîtî }} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Verteidigung|m}} * {{Z|fa}}: {{W+|fa|راهزن}}, {{W+|fa|یاغی}} * {{Z|en}}: {{W+|en|raid}}, {{W+|en|mob}}, {{W+|en|thug}}, {{W+|en|yobbo}}, {{W+|en|highwayman}}, {{W+|en|gangster}}, {{W+|en|brigand}} * {{Z|tr}}: {{W+|tr|baskın}}, {{W+|tr|korsan}} {{werger-bin}} == {{ziman|sga}} == === Navdêr === {{navdêr|sga}} # {{mijar|sga|pîşe}} {{g|ku|pîşewer}}, {{g|ku|destkar}} #* {{bênimûne|sga}} === Çavkanî === {{rûpela wergerê|sga|pîşewer}} ci4xop7uf63hh6gqaypidrpcwngyeqw 6333981 6333921 2026-08-15T23:41:50Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333981 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{IPA|ku|/d͡ʒɛɾd/}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[nobet]], [[çavdêrî]], [[sereguhî]], [[parastin]], [[matîjêkirin]] #* {{jêder|ku|{{Jêgirtin/Ehmedê Xanî/Mem û Zîn}}|jêgirtin=Bajar û kelat û xanî berdan</br>Teşbîhê bi nijdeyan û '''cerd'''an</br>Sef sef dimeşîne kûh û deştan}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * {{g|ku|cerde}} ==== Jê ==== {{kol3|ku|cure=Jê |cerd girtin<pos:lêker> |cerd kirin<pos:lêker> |cerd dan<pos:lêker> |cerdgirtin<pos:navdêr> |cerdkirin<pos:navdêr> |cerddan<pos:navdêr> |cerdgirtî<pos:rengdêr> |cerdkirî<pos:rengdêr> |cerdevan |cerdevanî |cerdevanîtî }} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Bide ber ==== * {{g|ku|cird}} ==== Herwiha binêre ==== {{kol3|ku |berd |derd |merd |zerd }} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Verteidigung|m}} * {{Z|fa}}: {{W+|fa|راهزن}}, {{W+|fa|یاغی}} * {{Z|en}}: {{W+|en|raid}}, {{W+|en|mob}}, {{W+|en|thug}}, {{W+|en|yobbo}}, {{W+|en|highwayman}}, {{W+|en|gangster}}, {{W+|en|brigand}} * {{Z|tr}}: {{W+|tr|baskın}}, {{W+|tr|korsan}} {{werger-bin}} == {{ziman|sga}} == === Navdêr === {{navdêr|sga}} # {{mijar|sga|pîşe}} {{g|ku|pîşewer}}, {{g|ku|destkar}} #* {{bênimûne|sga}} === Çavkanî === {{rûpela wergerê|sga|pîşewer}} so9vidgy9ylnqvjaryk96g0dza5y7gu şahid 0 20289 6333985 6322653 2026-08-16T00:37:38Z Zerwanda 12183 6333985 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=mn}} # [[govan]], [[gewa]], [[dîdevan]], <br>kesa/ê ku dîtiye dema tiştek [[qewimîn|qewimiye]] yan hatiye [[kirin]] û [[karîn|dikare]] [[paşî]] [[bas]]a wê bike #* {{bêmînak|ku}} ==== Ji wêjeya klasîk ==== * {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin=Nûr ji piştê hate nîva cebhetê</br>Hin dibêjin hate tilya '''şahid'''ê}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê û nêr}} ==== Bi alfabeyên din ==== * {{ku-ar|شاهد}} ==== Formên alternatîv ==== * {{g|ku|şahîd}} ==== Hevmane ==== {{kol3|ku |gewa |govan }} ==== Jê ==== {{kol3|ku|cure=Jê |şahid bûn<pos:lêker> |şahid kirin<pos:lêker> |şahidbûn<pos:navdêr> |şahidkirin<pos:navdêr> |şahidbûyî<pos:rengdêr> |şahidkirî<pos:rengdêr> |şahidî |şahidîtî |şahidtî }} === Nişeyên karanînê === Di Kurmancî da pirr caran ''-ahi-'' dibine ''-aha-'' îcar li nav qisedana gel ''şahid'' pitiriya caran wek ''şahad'' tê xwendin; bide ber {{q|ku|cahil}} > ''cahal'', {{q|ku|micahid}} > ''micahad'', u {{hv|ckb|شایەت}}. ==== Têkildar ==== {{kol3|ku|cure=Têkildar |şehade |şehadet }} ==== Etîmolojî ==== Ji {{ji|ar|ku|شاهد|tr=şahid}}, [[hevreh]]a aramî [[ܣܗܕܐ]] (sehda: 1. şahid 2. [[şehîd]]), têkilî [[şehîd]], [[şehade]], [[şehadet]]. Bo têkiliya "şahid" û "şehîd" herwiha bide ber yûnaniya kevn [[μάρτυς]] (martus: 1. şahid 2. şehîd) ku serekaniya hevwateya peyva "şehîd" ya bi bi zimanên ewropî ye: îngilîzî û fransî [[martyr]], almanî [[Märtyrer]], spanî [[mártir]]. ==== Bide ber ==== * {{g|ku|şehîd}} ==== Werger ==== {{werger-ser}} * {{Z|af}}: {{W-|af|getuie}} * {{Z|de}}: {{W+|de|Zeuge|n}}, {{W+|de|Zeugin|m}} * {{Z|az}}: {{W+|az|şahid}}, {{W-|az|tanıq}} * {{Z|ba}}: {{W-|ba|шаһит}} * {{Z|be}}: {{W-|be|све́дка|n|m}} * {{Z|bn}}: {{W-|bn|সাক্ষী}} * {{Z|bg}}: {{W+|bg|свиде́тел|n}}, {{W-|bg|свиде́телка|m}}, {{W+|bg|очеви́дец|n}}, {{W-|bg|све́док|n}} * {{Z|cs}}: {{W+|cs|svědek|n}}, {{W-|cs|svědkyně|m}} * {{Z|chr}}: {{W-|chr|ᎠᎦᏔᎯ}} * {{Z|zh}}: *: {{Z|cmn}}: {{W+|cmn|證人|tr=zhèngrén}}, {{W+|cmn|見證人|tr=jiànzhèngrén}}, {{W+|cmn|目擊者|tr=mùjīzhě}} * {{Z|da}}: {{W+|da|vidne|nt}} * {{Z|ar}}: {{W+|ar|شَاهِد}}, {{W-|ar|شَاهِدَة|m}}, {{W+|ar|شَهِيد}}, {{W-|ar|شَهِيدَة|m}} *: {{Z|arz}}: {{W-|arz|شاهد|n|tr=šāhid}} * {{Z|hy}}: {{W+|hy|վկա}}, {{W+|hy|ականատես}} * {{Z|eo}}: {{W-|eo|atestanto}} * {{Z|ee}}: {{W-|ee|ɖasedila}} * {{Z|fa}}: {{W+|fa|شاهد|tr=šâhed}}, {{W+|fa|گواه|tr=govâh}} * {{Z|fi}}: {{W+|fi|todistaja}} * {{Z|fr}}: {{W+|fr|témoin|n}} * {{Z|fur}}: {{W-|fur|testimone}} * {{Z|fy}}: {{W-|fy|tsjûge|g}} * {{Z|gd}}: {{W-|gd|neach-fianais|n}} * {{Z|ka}}: {{W-|ka|მოწმე}}, {{W-|ka|თვითმხილველი}} * {{Z|hi}}: {{W+|hi|गवाह|n}}, {{W+|hi|साक्षी|n}} * {{Z|nl}}: {{W+|nl|getuige|n}} * {{Z|he}}: {{W+|he|עֵד|n|tr=ed}} * {{Z|ang}}: {{W-|ang|ġewita|n}} * {{Z|en}}: {{W+|en|witness}} * {{Z|ga}}: {{W-|ga|fianaise|m}}, {{W-|ga|finné|n}} * {{Z|it}}: {{W+|it|testimone|n}} * {{Z|is}}: {{W-|is|vottur|n}} * {{Z|ja}}: {{W+|ja|目撃者|tr=もくげきしゃ, mokugekisha}} * {{Z|ca}}: {{W+|ca|testimoni|n}} * {{Z|ko}}: {{W+|ko|목격자}} * {{Z|la}}: {{W-|la|testis}} * {{Z|lo}}: {{W-|lo|ພະຍານ}}, {{W-|lo|ສັກຂີ}} * {{Z|mk}}: {{W-|mk|сведок|n}} * {{Z|mi}}: {{W-|mi|kaititiro}} * {{Z|mr}}: {{W-|mr|साक्षीदार}} * {{Z|hu}}: {{W+|hu|szemtanú}}, {{W+|hu|fültanú}} * {{Z|mn}}: *: Kirîlî: {{W+|mn|гэрч}} * {{Z|nrf}}: {{W-|nrf|têmoin|n}} * {{Z|non}}: {{W-|non|váttr|n}} * {{Z|no}}: *: {{Z|nb}}: {{W+|nb|vitne|nt}} *: {{Z|nn}}: {{W-|nn|vitne|nt}} * {{Z|ug}}: {{W-|ug|گۇۋاھچى}} * {{Z|uz}}: {{W+|uz|guvoh}}, {{W+|uz|shohid}} * {{Z|ps}}: {{W+|ps|شاهد|n|tr=šāhéd}}, {{W-|ps|ګواه|n|tr=gawãh}} * {{Z|pdt}}: {{W-|pdt|Zeij|m}} * {{Z|pl}}: {{W+|pl|świadek|n}} * {{Z|pt}}: {{W+|pt|testemunha|m}} * {{Z|ro}}: {{W+|ro|martor|n}}, {{W+|ro|martoră|m}} * {{Z|ru}}: {{W+|ru|свиде́тель|n}}, {{W+|ru|свиде́тельница|m}}, {{W+|ru|очеви́дец|n}} * {{Z|sc}}: {{W-|sc|distimonzu|n}}, {{W-|sc|testimóngiu|n}}, {{W-|sc|tistimognu|n}} * {{Z|ceb}}: {{W-|ceb|saksi}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|свѐдок|n}}, {{W-|sh|свјѐдок|n}}, {{W-|sh|сведо̀киња|m}}, {{W-|sh|свједо̀киња|m}} *: Latînî: {{W+|sh|svèdok|n}}, {{W+|sh|svjèdok|n}}, {{W-|sh|svedòkinja|m}}, {{W+|sh|svjedòkinja|m}} * {{Z|orv}}: {{W-|orv|съвѣдѣтель|n}} * {{Z|sk}}: {{W-|sk|svedok|n}}, {{W-|sk|svedkyňa|m}} * {{Z|es}}: {{W+|es|testigo|n}} * {{Z|sw}}: {{W+|sw|shahidi}} * {{Z|sv}}: {{W+|sv|vittne|nt}} * {{Z|tg}}: {{W-|tg|шоҳид}}, {{W-|tg|гувоҳ}} * {{Z|th}}: {{W+|th|สักขี}}, {{W+|th|พยาน}}, {{W-|th|ผู้เห็นเหตุการณ์}} * {{Z|te}}: {{W+|te|సాక్షి}} * {{Z|tt}}: {{W+|tt|шаһит}} * {{Z|tr}}: {{W+|tr|şahit}}, {{W+|tr|tanık}} * {{Z|tk}}: {{W-|tk|şaýat}} * {{Z|txb}}: {{W-|txb|reme}} * {{Z|ur}}: {{W-|ur|گواہ|n|tr=gavāh}}, {{W-|ur|شاہد|n|tr=śāhid}} * {{Z|uk}}: {{W-|uk|сві́док|n}}, {{W-|uk|очеви́дець|n}} * {{Z|vec}}: {{W-|vec|testimònio|n}} * {{Z|vi}}: {{W+|vi|nhân chứng}} * {{Z|cy}}: {{W+|cy|tyst|n}} * {{Z|km}}: {{W+|km|សាក្សី}}, {{W-|km|កសិណសាក្សី}} * {{Z|yi}}: {{W-|yi|עד|n|tr=eyd}} * {{Z|el}}: {{W+|el|μάρτυρας|n}} *: Kevn: {{W-|grc|μάρτυς|n}} {{werger-bin}} :{{werger çavkanî|en|witness|beş=Ev qismê Wergerê|oldid=75883196}} == {{ziman|az}} == === Navdêr === {{navdêr|az}} # {{g|ku|şahid}} #* {{bêmînak|az}} === Çavkanî === {{rûpela wergerê|az|şahid}} oovobadvi7vt2dxnhfwyt0h5qixhqua 6333986 6333985 2026-08-16T00:38:44Z Wikihez 7344 ([[m:Special:MyLanguage/User:Jon Harald Søby/diffedit|diffedit]]) 6333986 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=mn}} # [[govan]], [[gewa]], [[dîdevan]], <br>kesa/ê ku dîtiye dema tiştek [[qewimîn|qewimiye]] yan hatiye [[kirin]] û [[karîn|dikare]] [[paşî]] [[bas]]a wê bike #* {{bêmînak|ku}} ==== Ji wêjeya klasîk ==== * {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin=Nûr ji piştê hate nîva cebhetê</br>Hin dibêjin hate tilya '''şahid'''ê}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê û nêr}} ==== Bi alfabeyên din ==== * {{ku-ar|شاهد}} ==== Formên alternatîv ==== * {{g|ku|şahîd}} ==== Hevmane ==== {{kol3|ku |gewa |govan }} ==== Jê ==== {{kol3|ku|cure=Jê |şahid bûn<pos:lêker> |şahid kirin<pos:lêker> |şahidbûn<pos:navdêr> |şahidkirin<pos:navdêr> |şahidbûyî<pos:rengdêr> |şahidkirî<pos:rengdêr> |şahidî |şahidîtî |şahidtî }} ==== Nişeyên karanînê ==== Di Kurmancî da pirr caran ''-ahi-'' dibine ''-aha-'' îcar li nav qisedana gel ''şahid'' pitiriya caran wek ''şahad'' tê xwendin; bide ber {{q|ku|cahil}} > ''cahal'', {{q|ku|micahid}} > ''micahad'', u {{hv|ckb|شایەت}}. ==== Têkildar ==== {{kol3|ku|cure=Têkildar |şehade |şehadet }} ==== Etîmolojî ==== Ji {{ji|ar|ku|شاهد|tr=şahid}}, [[hevreh]]a aramî [[ܣܗܕܐ]] (sehda: 1. şahid 2. [[şehîd]]), têkilî [[şehîd]], [[şehade]], [[şehadet]]. Bo têkiliya "şahid" û "şehîd" herwiha bide ber yûnaniya kevn [[μάρτυς]] (martus: 1. şahid 2. şehîd) ku serekaniya hevwateya peyva "şehîd" ya bi bi zimanên ewropî ye: îngilîzî û fransî [[martyr]], almanî [[Märtyrer]], spanî [[mártir]]. ==== Bide ber ==== * {{g|ku|şehîd}} ==== Werger ==== {{werger-ser}} * {{Z|af}}: {{W-|af|getuie}} * {{Z|de}}: {{W+|de|Zeuge|n}}, {{W+|de|Zeugin|m}} * {{Z|az}}: {{W+|az|şahid}}, {{W-|az|tanıq}} * {{Z|ba}}: {{W-|ba|шаһит}} * {{Z|be}}: {{W-|be|све́дка|n|m}} * {{Z|bn}}: {{W-|bn|সাক্ষী}} * {{Z|bg}}: {{W+|bg|свиде́тел|n}}, {{W-|bg|свиде́телка|m}}, {{W+|bg|очеви́дец|n}}, {{W-|bg|све́док|n}} * {{Z|cs}}: {{W+|cs|svědek|n}}, {{W-|cs|svědkyně|m}} * {{Z|chr}}: {{W-|chr|ᎠᎦᏔᎯ}} * {{Z|zh}}: *: {{Z|cmn}}: {{W+|cmn|證人|tr=zhèngrén}}, {{W+|cmn|見證人|tr=jiànzhèngrén}}, {{W+|cmn|目擊者|tr=mùjīzhě}} * {{Z|da}}: {{W+|da|vidne|nt}} * {{Z|ar}}: {{W+|ar|شَاهِد}}, {{W-|ar|شَاهِدَة|m}}, {{W+|ar|شَهِيد}}, {{W-|ar|شَهِيدَة|m}} *: {{Z|arz}}: {{W-|arz|شاهد|n|tr=šāhid}} * {{Z|hy}}: {{W+|hy|վկա}}, {{W+|hy|ականատես}} * {{Z|eo}}: {{W-|eo|atestanto}} * {{Z|ee}}: {{W-|ee|ɖasedila}} * {{Z|fa}}: {{W+|fa|شاهد|tr=šâhed}}, {{W+|fa|گواه|tr=govâh}} * {{Z|fi}}: {{W+|fi|todistaja}} * {{Z|fr}}: {{W+|fr|témoin|n}} * {{Z|fur}}: {{W-|fur|testimone}} * {{Z|fy}}: {{W-|fy|tsjûge|g}} * {{Z|gd}}: {{W-|gd|neach-fianais|n}} * {{Z|ka}}: {{W-|ka|მოწმე}}, {{W-|ka|თვითმხილველი}} * {{Z|hi}}: {{W+|hi|गवाह|n}}, {{W+|hi|साक्षी|n}} * {{Z|nl}}: {{W+|nl|getuige|n}} * {{Z|he}}: {{W+|he|עֵד|n|tr=ed}} * {{Z|ang}}: {{W-|ang|ġewita|n}} * {{Z|en}}: {{W+|en|witness}} * {{Z|ga}}: {{W-|ga|fianaise|m}}, {{W-|ga|finné|n}} * {{Z|it}}: {{W+|it|testimone|n}} * {{Z|is}}: {{W-|is|vottur|n}} * {{Z|ja}}: {{W+|ja|目撃者|tr=もくげきしゃ, mokugekisha}} * {{Z|ca}}: {{W+|ca|testimoni|n}} * {{Z|ko}}: {{W+|ko|목격자}} * {{Z|la}}: {{W-|la|testis}} * {{Z|lo}}: {{W-|lo|ພະຍານ}}, {{W-|lo|ສັກຂີ}} * {{Z|mk}}: {{W-|mk|сведок|n}} * {{Z|mi}}: {{W-|mi|kaititiro}} * {{Z|mr}}: {{W-|mr|साक्षीदार}} * {{Z|hu}}: {{W+|hu|szemtanú}}, {{W+|hu|fültanú}} * {{Z|mn}}: *: Kirîlî: {{W+|mn|гэрч}} * {{Z|nrf}}: {{W-|nrf|têmoin|n}} * {{Z|non}}: {{W-|non|váttr|n}} * {{Z|no}}: *: {{Z|nb}}: {{W+|nb|vitne|nt}} *: {{Z|nn}}: {{W-|nn|vitne|nt}} * {{Z|ug}}: {{W-|ug|گۇۋاھچى}} * {{Z|uz}}: {{W+|uz|guvoh}}, {{W+|uz|shohid}} * {{Z|ps}}: {{W+|ps|شاهد|n|tr=šāhéd}}, {{W-|ps|ګواه|n|tr=gawãh}} * {{Z|pdt}}: {{W-|pdt|Zeij|m}} * {{Z|pl}}: {{W+|pl|świadek|n}} * {{Z|pt}}: {{W+|pt|testemunha|m}} * {{Z|ro}}: {{W+|ro|martor|n}}, {{W+|ro|martoră|m}} * {{Z|ru}}: {{W+|ru|свиде́тель|n}}, {{W+|ru|свиде́тельница|m}}, {{W+|ru|очеви́дец|n}} * {{Z|sc}}: {{W-|sc|distimonzu|n}}, {{W-|sc|testimóngiu|n}}, {{W-|sc|tistimognu|n}} * {{Z|ceb}}: {{W-|ceb|saksi}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|свѐдок|n}}, {{W-|sh|свјѐдок|n}}, {{W-|sh|сведо̀киња|m}}, {{W-|sh|свједо̀киња|m}} *: Latînî: {{W+|sh|svèdok|n}}, {{W+|sh|svjèdok|n}}, {{W-|sh|svedòkinja|m}}, {{W+|sh|svjedòkinja|m}} * {{Z|orv}}: {{W-|orv|съвѣдѣтель|n}} * {{Z|sk}}: {{W-|sk|svedok|n}}, {{W-|sk|svedkyňa|m}} * {{Z|es}}: {{W+|es|testigo|n}} * {{Z|sw}}: {{W+|sw|shahidi}} * {{Z|sv}}: {{W+|sv|vittne|nt}} * {{Z|tg}}: {{W-|tg|шоҳид}}, {{W-|tg|гувоҳ}} * {{Z|th}}: {{W+|th|สักขี}}, {{W+|th|พยาน}}, {{W-|th|ผู้เห็นเหตุการณ์}} * {{Z|te}}: {{W+|te|సాక్షి}} * {{Z|tt}}: {{W+|tt|шаһит}} * {{Z|tr}}: {{W+|tr|şahit}}, {{W+|tr|tanık}} * {{Z|tk}}: {{W-|tk|şaýat}} * {{Z|txb}}: {{W-|txb|reme}} * {{Z|ur}}: {{W-|ur|گواہ|n|tr=gavāh}}, {{W-|ur|شاہد|n|tr=śāhid}} * {{Z|uk}}: {{W-|uk|сві́док|n}}, {{W-|uk|очеви́дець|n}} * {{Z|vec}}: {{W-|vec|testimònio|n}} * {{Z|vi}}: {{W+|vi|nhân chứng}} * {{Z|cy}}: {{W+|cy|tyst|n}} * {{Z|km}}: {{W+|km|សាក្សី}}, {{W-|km|កសិណសាក្សី}} * {{Z|yi}}: {{W-|yi|עד|n|tr=eyd}} * {{Z|el}}: {{W+|el|μάρτυρας|n}} *: Kevn: {{W-|grc|μάρτυς|n}} {{werger-bin}} :{{werger çavkanî|en|witness|beş=Ev qismê Wergerê|oldid=75883196}} == {{ziman|az}} == === Navdêr === {{navdêr|az}} # {{g|ku|şahid}} #* {{bêmînak|az}} === Çavkanî === {{rûpela wergerê|az|şahid}} j7kcf6y34bngmtm8g94y0su8zaiktum 6333987 6333986 2026-08-16T00:41:07Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333987 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=mn}} # [[govan]], [[gewa]], [[dîdevan]], <br>kesa/ê ku dîtiye dema tiştek [[qewimîn|qewimiye]] yan hatiye [[kirin]] û [[karîn|dikare]] [[paşî]] [[bas]]a wê bike #* {{bêmînak|ku}} ==== Ji wêjeya klasîk ==== * {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin=Nûr ji piştê hate nîva cebhetê</br>Hin dibêjin hate tilya '''şahid'''ê}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê û nêr}} ==== Bi alfabeyên din ==== * {{ku-ar|شاهد}} ==== Formên alternatîv ==== * {{g|ku|şahîd}} ==== Hevmane ==== {{kol3|ku |gewa |govan }} ==== Jê ==== {{kol3|ku|cure=Jê |şahid bûn<pos:lêker> |şahid kirin<pos:lêker> |şahidbûn<pos:navdêr> |şahidkirin<pos:navdêr> |şahidbûyî<pos:rengdêr> |şahidkirî<pos:rengdêr> |şahidî |şahidîtî |şahidtî }} ==== Têkildar ==== {{kol3|ku|cure=Têkildar |şehade |şehadet }} ==== Etîmolojî ==== Ji {{ji|ar|ku|شاهد|tr=şahid}}, [[hevreh]]a aramî [[ܣܗܕܐ]] (sehda: 1. şahid 2. [[şehîd]]), têkilî [[şehîd]], [[şehade]], [[şehadet]]. Bo têkiliya "şahid" û "şehîd" herwiha bide ber yûnaniya kevn [[μάρτυς]] (martus: 1. şahid 2. şehîd) ku serekaniya hevwateya peyva "şehîd" ya bi bi zimanên ewropî ye: îngilîzî û fransî [[martyr]], almanî [[Märtyrer]], spanî [[mártir]]. ==== Bide ber ==== * {{g|ku|şehîd}} ==== Nişeyên karanînê ==== Di Kurmancî da pirr caran ''-ahi-'' dibine ''-aha-'' îcar li nav qisedana gel ''şahid'' pitiriya caran wek ''şahad'' tê xwendin; bide ber {{q|ku|cahil}} > ''cahal'', {{q|ku|micahid}} > ''micahad'', u {{hv|ckb|شایەت}}. ==== Werger ==== {{werger-ser}} * {{Z|af}}: {{W-|af|getuie}} * {{Z|de}}: {{W+|de|Zeuge|n}}, {{W+|de|Zeugin|m}} * {{Z|az}}: {{W+|az|şahid}}, {{W-|az|tanıq}} * {{Z|ba}}: {{W-|ba|шаһит}} * {{Z|be}}: {{W-|be|све́дка|n|m}} * {{Z|bn}}: {{W-|bn|সাক্ষী}} * {{Z|bg}}: {{W+|bg|свиде́тел|n}}, {{W-|bg|свиде́телка|m}}, {{W+|bg|очеви́дец|n}}, {{W-|bg|све́док|n}} * {{Z|cs}}: {{W+|cs|svědek|n}}, {{W-|cs|svědkyně|m}} * {{Z|chr}}: {{W-|chr|ᎠᎦᏔᎯ}} * {{Z|zh}}: *: {{Z|cmn}}: {{W+|cmn|證人|tr=zhèngrén}}, {{W+|cmn|見證人|tr=jiànzhèngrén}}, {{W+|cmn|目擊者|tr=mùjīzhě}} * {{Z|da}}: {{W+|da|vidne|nt}} * {{Z|ar}}: {{W+|ar|شَاهِد}}, {{W-|ar|شَاهِدَة|m}}, {{W+|ar|شَهِيد}}, {{W-|ar|شَهِيدَة|m}} *: {{Z|arz}}: {{W-|arz|شاهد|n|tr=šāhid}} * {{Z|hy}}: {{W+|hy|վկա}}, {{W+|hy|ականատես}} * {{Z|eo}}: {{W-|eo|atestanto}} * {{Z|ee}}: {{W-|ee|ɖasedila}} * {{Z|fa}}: {{W+|fa|شاهد|tr=šâhed}}, {{W+|fa|گواه|tr=govâh}} * {{Z|fi}}: {{W+|fi|todistaja}} * {{Z|fr}}: {{W+|fr|témoin|n}} * {{Z|fur}}: {{W-|fur|testimone}} * {{Z|fy}}: {{W-|fy|tsjûge|g}} * {{Z|gd}}: {{W-|gd|neach-fianais|n}} * {{Z|ka}}: {{W-|ka|მოწმე}}, {{W-|ka|თვითმხილველი}} * {{Z|hi}}: {{W+|hi|गवाह|n}}, {{W+|hi|साक्षी|n}} * {{Z|nl}}: {{W+|nl|getuige|n}} * {{Z|he}}: {{W+|he|עֵד|n|tr=ed}} * {{Z|ang}}: {{W-|ang|ġewita|n}} * {{Z|en}}: {{W+|en|witness}} * {{Z|ga}}: {{W-|ga|fianaise|m}}, {{W-|ga|finné|n}} * {{Z|it}}: {{W+|it|testimone|n}} * {{Z|is}}: {{W-|is|vottur|n}} * {{Z|ja}}: {{W+|ja|目撃者|tr=もくげきしゃ, mokugekisha}} * {{Z|ca}}: {{W+|ca|testimoni|n}} * {{Z|ko}}: {{W+|ko|목격자}} * {{Z|la}}: {{W-|la|testis}} * {{Z|lo}}: {{W-|lo|ພະຍານ}}, {{W-|lo|ສັກຂີ}} * {{Z|mk}}: {{W-|mk|сведок|n}} * {{Z|mi}}: {{W-|mi|kaititiro}} * {{Z|mr}}: {{W-|mr|साक्षीदार}} * {{Z|hu}}: {{W+|hu|szemtanú}}, {{W+|hu|fültanú}} * {{Z|mn}}: *: Kirîlî: {{W+|mn|гэрч}} * {{Z|nrf}}: {{W-|nrf|têmoin|n}} * {{Z|non}}: {{W-|non|váttr|n}} * {{Z|no}}: *: {{Z|nb}}: {{W+|nb|vitne|nt}} *: {{Z|nn}}: {{W-|nn|vitne|nt}} * {{Z|ug}}: {{W-|ug|گۇۋاھچى}} * {{Z|uz}}: {{W+|uz|guvoh}}, {{W+|uz|shohid}} * {{Z|ps}}: {{W+|ps|شاهد|n|tr=šāhéd}}, {{W-|ps|ګواه|n|tr=gawãh}} * {{Z|pdt}}: {{W-|pdt|Zeij|m}} * {{Z|pl}}: {{W+|pl|świadek|n}} * {{Z|pt}}: {{W+|pt|testemunha|m}} * {{Z|ro}}: {{W+|ro|martor|n}}, {{W+|ro|martoră|m}} * {{Z|ru}}: {{W+|ru|свиде́тель|n}}, {{W+|ru|свиде́тельница|m}}, {{W+|ru|очеви́дец|n}} * {{Z|sc}}: {{W-|sc|distimonzu|n}}, {{W-|sc|testimóngiu|n}}, {{W-|sc|tistimognu|n}} * {{Z|ceb}}: {{W-|ceb|saksi}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|свѐдок|n}}, {{W-|sh|свјѐдок|n}}, {{W-|sh|сведо̀киња|m}}, {{W-|sh|свједо̀киња|m}} *: Latînî: {{W+|sh|svèdok|n}}, {{W+|sh|svjèdok|n}}, {{W-|sh|svedòkinja|m}}, {{W+|sh|svjedòkinja|m}} * {{Z|orv}}: {{W-|orv|съвѣдѣтель|n}} * {{Z|sk}}: {{W-|sk|svedok|n}}, {{W-|sk|svedkyňa|m}} * {{Z|es}}: {{W+|es|testigo|n}} * {{Z|sw}}: {{W+|sw|shahidi}} * {{Z|sv}}: {{W+|sv|vittne|nt}} * {{Z|tg}}: {{W-|tg|шоҳид}}, {{W-|tg|гувоҳ}} * {{Z|th}}: {{W+|th|สักขี}}, {{W+|th|พยาน}}, {{W-|th|ผู้เห็นเหตุการณ์}} * {{Z|te}}: {{W+|te|సాక్షి}} * {{Z|tt}}: {{W+|tt|шаһит}} * {{Z|tr}}: {{W+|tr|şahit}}, {{W+|tr|tanık}} * {{Z|tk}}: {{W-|tk|şaýat}} * {{Z|txb}}: {{W-|txb|reme}} * {{Z|ur}}: {{W-|ur|گواہ|n|tr=gavāh}}, {{W-|ur|شاہد|n|tr=śāhid}} * {{Z|uk}}: {{W-|uk|сві́док|n}}, {{W-|uk|очеви́дець|n}} * {{Z|vec}}: {{W-|vec|testimònio|n}} * {{Z|vi}}: {{W+|vi|nhân chứng}} * {{Z|cy}}: {{W+|cy|tyst|n}} * {{Z|km}}: {{W+|km|សាក្សី}}, {{W-|km|កសិណសាក្សី}} * {{Z|yi}}: {{W-|yi|עד|n|tr=eyd}} * {{Z|el}}: {{W+|el|μάρτυρας|n}} *: Kevn: {{W-|grc|μάρτυς|n}} {{werger-bin}} :{{werger çavkanî|en|witness|beş=Ev qismê Wergerê|oldid=75883196}} == {{ziman|az}} == === Navdêr === {{navdêr|az}} # {{g|ku|şahid}} #* {{bêmînak|az}} === Çavkanî === {{rûpela wergerê|az|şahid}} c8u9h69sxhmnphwgb2qdle4ewn34yz2 nîşaste 0 22128 6334016 6313703 2026-08-16T01:17:08Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334016 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[karbohîdrat]]ek [[pirhêl]] e û bi taybetî di nav [[tov]]î, [[petat]]an, [[genim]]î, [[genimok]] û [[birinc]]î de heye <br>(bo [[xwarin]]ê pir [[giring]] e lê herwiha bo [[çir]]bûna [[kaxez]]ê û [[cil]]an jî têt [[bikaranîn]]). Formûla molekûlî C<sub>6</sub>H<sub>10</sub>O<sub>5</sub>)<sub>n</sub> e. #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê|guherto=hemû}} ==== Bi alfabeyên din ==== * kurdî-erebî: [[نشاسته]] ====== ==== Formên alternatîv ==== * [[nîşa]] (2) * [[nîşast]] * [[nîşasta]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|sq}}: {{W+|sq|niseshte}}, {{W+|sq|kollaris}}, {{W+|sq|koll}} * {{Z|de}}: [[stärke|Stärke]] (Zucker) * {{Z|bg}}: [[нишестен]] (nîşesten) * {{Z|cs}}: {{W-|cs|škrob}} * {{Z|zh}}: {{W+|zh|澱粉}}, {{W+|zh|淀粉}} * {{Z|da}}: {{W-|da|stivelse}} * {{Z|id}}: {{W+|id|kanji}} * {{Z|ar}}: [[نشاء]] (nişai) * {{Z|eo}}: {{W-|eo|apreturo}} * {{Z|fa}}: [[نشاسته]] (nîşaste) * {{Z|fi}}: {{W+|fi|tärkkelys}} * {{Z|fr}}: {{W+|fr|amidon}} * {{Z|nl}}: {{W-|nl|etmeel}} * {{Z|en}}: {{W+|en|starch}} * {{Z|it}}: {{W+|it|amido}} * {{Z|ja}}: {{W-|ja|デンプン}} * {{Z|ko}}: {{W+|ko|전분}} * {{Z|ms}}: {{W+|ms|kanji}} * {{Z|yua}}: {{W-|yua|cha'ak}} * {{Z|hu}}: {{W+|hu|keményítő}} * {{Z|pl}}: {{W+|pl|skrobia}} * {{Z|pt}}: {{W+|pt|amido}} * {{Z|ru}}: [[крахмал]] (kraxmal) * {{Z|es}}: {{W+|es|almidón}} * {{Z|tr}}: {{W+|tr|nişasta}} * {{Z|el}}: {{W+|el|άμυλο}} {{werger-bin}} sje9z50n4p815xdimwkq4xunjhn929t 6334017 6334016 2026-08-16T01:17:22Z Wikihez 7344 /* == */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334017 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[karbohîdrat]]ek [[pirhêl]] e û bi taybetî di nav [[tov]]î, [[petat]]an, [[genim]]î, [[genimok]] û [[birinc]]î de heye <br>(bo [[xwarin]]ê pir [[giring]] e lê herwiha bo [[çir]]bûna [[kaxez]]ê û [[cil]]an jî têt [[bikaranîn]]). Formûla molekûlî C<sub>6</sub>H<sub>10</sub>O<sub>5</sub>)<sub>n</sub> e. #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê|guherto=hemû}} ==== Bi alfabeyên din ==== * kurdî-erebî: [[نشاسته]] ==== Formên alternatîv ==== * [[nîşa]] (2) * [[nîşast]] * [[nîşasta]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|sq}}: {{W+|sq|niseshte}}, {{W+|sq|kollaris}}, {{W+|sq|koll}} * {{Z|de}}: [[stärke|Stärke]] (Zucker) * {{Z|bg}}: [[нишестен]] (nîşesten) * {{Z|cs}}: {{W-|cs|škrob}} * {{Z|zh}}: {{W+|zh|澱粉}}, {{W+|zh|淀粉}} * {{Z|da}}: {{W-|da|stivelse}} * {{Z|id}}: {{W+|id|kanji}} * {{Z|ar}}: [[نشاء]] (nişai) * {{Z|eo}}: {{W-|eo|apreturo}} * {{Z|fa}}: [[نشاسته]] (nîşaste) * {{Z|fi}}: {{W+|fi|tärkkelys}} * {{Z|fr}}: {{W+|fr|amidon}} * {{Z|nl}}: {{W-|nl|etmeel}} * {{Z|en}}: {{W+|en|starch}} * {{Z|it}}: {{W+|it|amido}} * {{Z|ja}}: {{W-|ja|デンプン}} * {{Z|ko}}: {{W+|ko|전분}} * {{Z|ms}}: {{W+|ms|kanji}} * {{Z|yua}}: {{W-|yua|cha'ak}} * {{Z|hu}}: {{W+|hu|keményítő}} * {{Z|pl}}: {{W+|pl|skrobia}} * {{Z|pt}}: {{W+|pt|amido}} * {{Z|ru}}: [[крахмал]] (kraxmal) * {{Z|es}}: {{W+|es|almidón}} * {{Z|tr}}: {{W+|tr|nişasta}} * {{Z|el}}: {{W+|el|άμυλο}} {{werger-bin}} akvc9n0t4qjj9tts8iprojdlrdnkvau 6334025 6334017 2026-08-16T01:31:29Z Wikihez 7344 /* Bi alfabeyên din */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334025 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[karbohîdrat]]ek [[pirhêl]] e û bi taybetî di nav [[tov]]î, [[petat]]an, [[genim]]î, [[genimok]] û [[birinc]]î de heye <br>(bo [[xwarin]]ê pir [[giring]] e lê herwiha bo [[çir]]bûna [[kaxez]]ê û [[cil]]an jî têt [[bikaranîn]]). Formûla molekûlî C<sub>6</sub>H<sub>10</sub>O<sub>5</sub>)<sub>n</sub> e. #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê|guherto=hemû}} ==== Bi alfabeyên din ==== * {{ku-ar|نشاسته}} ==== Formên alternatîv ==== * [[nîşa]] (2) * [[nîşast]] * [[nîşasta]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|sq}}: {{W+|sq|niseshte}}, {{W+|sq|kollaris}}, {{W+|sq|koll}} * {{Z|de}}: [[stärke|Stärke]] (Zucker) * {{Z|bg}}: [[нишестен]] (nîşesten) * {{Z|cs}}: {{W-|cs|škrob}} * {{Z|zh}}: {{W+|zh|澱粉}}, {{W+|zh|淀粉}} * {{Z|da}}: {{W-|da|stivelse}} * {{Z|id}}: {{W+|id|kanji}} * {{Z|ar}}: [[نشاء]] (nişai) * {{Z|eo}}: {{W-|eo|apreturo}} * {{Z|fa}}: [[نشاسته]] (nîşaste) * {{Z|fi}}: {{W+|fi|tärkkelys}} * {{Z|fr}}: {{W+|fr|amidon}} * {{Z|nl}}: {{W-|nl|etmeel}} * {{Z|en}}: {{W+|en|starch}} * {{Z|it}}: {{W+|it|amido}} * {{Z|ja}}: {{W-|ja|デンプン}} * {{Z|ko}}: {{W+|ko|전분}} * {{Z|ms}}: {{W+|ms|kanji}} * {{Z|yua}}: {{W-|yua|cha'ak}} * {{Z|hu}}: {{W+|hu|keményítő}} * {{Z|pl}}: {{W+|pl|skrobia}} * {{Z|pt}}: {{W+|pt|amido}} * {{Z|ru}}: [[крахмал]] (kraxmal) * {{Z|es}}: {{W+|es|almidón}} * {{Z|tr}}: {{W+|tr|nişasta}} * {{Z|el}}: {{W+|el|άμυλο}} {{werger-bin}} t08ied2cyi365c0biki613psr7rp2te kannadayî 0 22919 6333963 6309569 2026-08-15T23:34:49Z Wikihez 7344 /* Alfabeya zimanê kannadayî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333963 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[ziman]]ek e li [[eyalet]]a [[Karnataka]]yê ya [[Hindistan]]ê têt [[peyivîn]] #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * [[kanarayî]] * [[kannarayî]] ==== Bide ber ==== * [[kanadayî]] * [[kenedayî]] ===Binêre herwiha === {{veşêre-ser|Alfabeya zimanê kanadayî}} * '''[[bideng|Bideng]]''': <div style="font-size: 150%;"> [[ಅ]] [[ಆ]] [[ಇ]] [[ಈ]] [[ಉ]] [[ಊ]] [[ಋ]] [[ಌ]] [[ಎ]] [[ಏ]] [[ಐ]] [[ಒ]] [[ಓ]] [[ಔ]] </div> * '''[[bêdeng|Bêdeng]]''': <div style="font-size: 150%;"> [[ಕ]] [[ಖ]] [[ಗ]] [[ಘ]] [[ಙ]] [[ಚ]] [[ಛ]] [[ಜ]] [[ಝ]] [[ಞ]] [[ಟ]] [[ಠ]] [[ಡ]] [[ಢ]] [[ಣ]] [[ತ]] [[ಥ]] [[ದ]] [[ಧ]] [[ನ]] [[ಪ]] [[ಫ]] [[ಬ]] [[ಭ]] [[ಮ]] [[ಯ]] [[ರ]] [[ಱ]] [[ಲ]] [[ಳ]] [[ವ]] [[ಶ]] [[ಷ]] [[ಸ]] [[ಹ]] </div> * '''[[hejmar]]''': <div style="font-size: 150%;"> [[೦]] [[೧]] [[೨]] [[೩]] [[೪]] [[೫]] [[೬]] [[೭]] [[೮]] [[೯]] </div> {{veşêre-bin}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|zh}}: {{W+|zh|坎那达语}} * {{Z|fi}}: {{W+|fi|kannada}} * {{Z|fr}}: {{W|fr|kannara|m}} * {{Z|hi}}: {{W+|hi|कन्नड़}} * {{Z|nl}}: {{W+|nl|Kannada}} * {{Z|en}}: {{W+|en|Kannada}} * {{Z|ja}}: {{W+|ja|カンナダ語}} * {{Z|kn}}: {{W+|kn|ಕನ್ನಡ}} * {{Z|wa}}: {{W+|wa|Kannada}} {{werger-bin}} ghvo7fui1yo0w9w40ay4xvzxn09vnzp 6333964 6333963 2026-08-15T23:34:59Z Wikihez 7344 /* Binêre herwiha */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333964 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[ziman]]ek e li [[eyalet]]a [[Karnataka]]yê ya [[Hindistan]]ê têt [[peyivîn]] #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * [[kanarayî]] * [[kannarayî]] ==== Bide ber ==== * [[kanadayî]] * [[kenedayî]] ====Binêre herwiha ==== {{veşêre-ser|Alfabeya zimanê kanadayî}} * '''[[bideng|Bideng]]''': <div style="font-size: 150%;"> [[ಅ]] [[ಆ]] [[ಇ]] [[ಈ]] [[ಉ]] [[ಊ]] [[ಋ]] [[ಌ]] [[ಎ]] [[ಏ]] [[ಐ]] [[ಒ]] [[ಓ]] [[ಔ]] </div> * '''[[bêdeng|Bêdeng]]''': <div style="font-size: 150%;"> [[ಕ]] [[ಖ]] [[ಗ]] [[ಘ]] [[ಙ]] [[ಚ]] [[ಛ]] [[ಜ]] [[ಝ]] [[ಞ]] [[ಟ]] [[ಠ]] [[ಡ]] [[ಢ]] [[ಣ]] [[ತ]] [[ಥ]] [[ದ]] [[ಧ]] [[ನ]] [[ಪ]] [[ಫ]] [[ಬ]] [[ಭ]] [[ಮ]] [[ಯ]] [[ರ]] [[ಱ]] [[ಲ]] [[ಳ]] [[ವ]] [[ಶ]] [[ಷ]] [[ಸ]] [[ಹ]] </div> * '''[[hejmar]]''': <div style="font-size: 150%;"> [[೦]] [[೧]] [[೨]] [[೩]] [[೪]] [[೫]] [[೬]] [[೭]] [[೮]] [[೯]] </div> {{veşêre-bin}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|zh}}: {{W+|zh|坎那达语}} * {{Z|fi}}: {{W+|fi|kannada}} * {{Z|fr}}: {{W|fr|kannara|m}} * {{Z|hi}}: {{W+|hi|कन्नड़}} * {{Z|nl}}: {{W+|nl|Kannada}} * {{Z|en}}: {{W+|en|Kannada}} * {{Z|ja}}: {{W+|ja|カンナダ語}} * {{Z|kn}}: {{W+|kn|ಕನ್ನಡ}} * {{Z|wa}}: {{W+|wa|Kannada}} {{werger-bin}} f4f562qsefri94co6o4ejiafbxhkc36 6333966 6333964 2026-08-15T23:41:05Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333966 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[ziman]]ek e li [[eyalet]]a [[Karnataka]]yê ya [[Hindistan]]ê têt [[peyivîn]] #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * [[kanarayî]] * [[kannarayî]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Bide ber ==== * [[kanadayî]] * [[kenedayî]] ==== Herwiha binêre ==== {{veşêre-ser|Alfabeya zimanê kanadayî}} * '''[[bideng|Bideng]]''': <div style="font-size: 150%;"> [[ಅ]] [[ಆ]] [[ಇ]] [[ಈ]] [[ಉ]] [[ಊ]] [[ಋ]] [[ಌ]] [[ಎ]] [[ಏ]] [[ಐ]] [[ಒ]] [[ಓ]] [[ಔ]] </div> * '''[[bêdeng|Bêdeng]]''': <div style="font-size: 150%;"> [[ಕ]] [[ಖ]] [[ಗ]] [[ಘ]] [[ಙ]] [[ಚ]] [[ಛ]] [[ಜ]] [[ಝ]] [[ಞ]] [[ಟ]] [[ಠ]] [[ಡ]] [[ಢ]] [[ಣ]] [[ತ]] [[ಥ]] [[ದ]] [[ಧ]] [[ನ]] [[ಪ]] [[ಫ]] [[ಬ]] [[ಭ]] [[ಮ]] [[ಯ]] [[ರ]] [[ಱ]] [[ಲ]] [[ಳ]] [[ವ]] [[ಶ]] [[ಷ]] [[ಸ]] [[ಹ]] </div> * '''[[hejmar]]''': <div style="font-size: 150%;"> [[೦]] [[೧]] [[೨]] [[೩]] [[೪]] [[೫]] [[೬]] [[೭]] [[೮]] [[೯]] </div> {{veşêre-bin}} ==== Werger ==== {{werger-ser}} * {{Z|zh}}: {{W+|zh|坎那达语}} * {{Z|fi}}: {{W+|fi|kannada}} * {{Z|fr}}: {{W|fr|kannara|m}} * {{Z|hi}}: {{W+|hi|कन्नड़}} * {{Z|nl}}: {{W+|nl|Kannada}} * {{Z|en}}: {{W+|en|Kannada}} * {{Z|ja}}: {{W+|ja|カンナダ語}} * {{Z|kn}}: {{W+|kn|ಕನ್ನಡ}} * {{Z|wa}}: {{W+|wa|Kannada}} {{werger-bin}} r9rbrjyiy6jprzjd8t85bbgfpn73m8h firar 0 24008 6333886 6326335 2026-08-15T19:24:48Z Wikihez 7344 /* Rengdêr */ [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6333886 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[rev]], [[revîn]] (bi taybetî ji [[leşkerî|leşkeriyê]]) #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * {{g|ku|fîrar}} ==== Jê ==== {{kol3|ku|cure=Jê |firarî |firar kirin<pos:lêker> |firarkirin<pos:navdêr> |firarkirî<pos:rengdêr> }} ==== Etîmolojî ==== Ji {{deyn|ar|ku|فِرار}}. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Fahnenflucht}} {{mê}}, {{W|de|Flucht}} {{mê}}, {{W|de|Flüchtling}} {{n}}, {{W|de|Fortlaufen}}, {{W|de|Desertion|guman=erê}} {{mê}}, {{W|de|Desertation|f|guman=erê}} * {{Z|fa}}: {{W|fa|گریز}}, {{W|fa|فرار}} * {{Z|en}}: {{W|en|recreant}}, {{W|en|desertion|guman=erê}} * {{Z|tr}}: {{W|tr|firar}}, {{W|tr|firarî}}, {{W|tr|kaçak}} {{werger-bin}} === Rengdêr === {{rengdêr|ku}} # Ya/yê ku [[revîn|direve]] yan [[revîn|reviye]]. #: {{hevmane|ku|revok}} #* {{bêmînak|ku}} ==== Werger ==== {{werger-ser}} {{werger-bin}} == {{ziman|tr}} == === Navdêr === {{navdêr|tr}} # [[rev]], firar #: {{mk|tr|Buna '''firar''' denilmez, kurtuluş denir.|rêz=1|Ji vê re rev nayê gotin, xelasî tê gotin.}} # [[mişextî]], firar #* {{bêmînak|tr}} 4ijxuo01ltko0s4rizrlasgv28uq9da 6333887 6333886 2026-08-15T19:25:50Z Wikihez 7344 /* {{ziman|ku}} */ format, [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6333887 wikitext text/x-wiki == {{ziman|ku}} == === Formên alternatîv === * {{g|ku|fîrar}} === Bilêvkirin === * {{ku-kîte}} === Etîmolojî === Ji {{deyn|ar|ku|فِرار}}. === Navdêr === {{navdêr|ku|z=m}} # [[rev]], [[revîn]] (bi taybetî ji [[leşkerî|leşkeriyê]]) #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Fahnenflucht}} {{mê}}, {{W|de|Flucht}} {{mê}}, {{W|de|Flüchtling}} {{n}}, {{W|de|Fortlaufen}}, {{W|de|Desertion|guman=erê}} {{mê}}, {{W|de|Desertation|f|guman=erê}} * {{Z|fa}}: {{W|fa|گریز}}, {{W|fa|فرار}} * {{Z|en}}: {{W|en|recreant}}, {{W|en|desertion|guman=erê}} * {{Z|tr}}: {{W|tr|firar}}, {{W|tr|firarî}}, {{W|tr|kaçak}} {{werger-bin}} === Rengdêr === {{rengdêr|ku}} # Ya/yê ku [[revîn|direve]] yan [[revîn|reviye]]. #: {{hevmane|ku|revok}} #* {{bêmînak|ku}} ==== Werger ==== {{werger-ser}} {{werger-bin}} === Jê === {{kol3|ku|cure=Jê |firarî |firar kirin<pos:lêker> |firarkirin<pos:navdêr> |firarkirî<pos:rengdêr> }} == {{ziman|tr}} == === Navdêr === {{navdêr|tr}} # [[rev]], firar #: {{mk|tr|Buna '''firar''' denilmez, kurtuluş denir.|rêz=1|Ji vê re rev nayê gotin, xelasî tê gotin.}} # [[mişextî]], firar #* {{bêmînak|tr}} 8umqbgl2wpp3i5isewdtx2dl441c90o 6333888 6333887 2026-08-15T19:26:04Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333888 wikitext text/x-wiki == {{ziman|ku}} == === Formên alternatîv === * {{g|ku|fîrar}} === Etîmolojî === Ji {{deyn|ar|ku|فِرار}}. === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[rev]], [[revîn]] (bi taybetî ji [[leşkerî|leşkeriyê]]) #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Fahnenflucht}} {{mê}}, {{W|de|Flucht}} {{mê}}, {{W|de|Flüchtling}} {{n}}, {{W|de|Fortlaufen}}, {{W|de|Desertion|guman=erê}} {{mê}}, {{W|de|Desertation|f|guman=erê}} * {{Z|fa}}: {{W|fa|گریز}}, {{W|fa|فرار}} * {{Z|en}}: {{W|en|recreant}}, {{W|en|desertion|guman=erê}} * {{Z|tr}}: {{W|tr|firar}}, {{W|tr|firarî}}, {{W|tr|kaçak}} {{werger-bin}} === Rengdêr === {{rengdêr|ku}} # Ya/yê ku [[revîn|direve]] yan [[revîn|reviye]]. #: {{hevmane|ku|revok}} #* {{bêmînak|ku}} ==== Werger ==== {{werger-ser}} {{werger-bin}} === Jê === {{kol3|ku|cure=Jê |firarî |firar kirin<pos:lêker> |firarkirin<pos:navdêr> |firarkirî<pos:rengdêr> }} == {{ziman|tr}} == === Navdêr === {{navdêr|tr}} # [[rev]], firar #: {{mk|tr|Buna '''firar''' denilmez, kurtuluş denir.|rêz=1|Ji vê re rev nayê gotin, xelasî tê gotin.}} # [[mişextî]], firar #* {{bêmînak|tr}} 2rr8e887flm4q22tacbpqvi8ub2p5cj 6333889 6333888 2026-08-15T19:26:45Z Wikihez 7344 /* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333889 wikitext text/x-wiki == {{ziman|ku}} == === Formên alternatîv === * {{g|ku|fîrar}} === Etîmolojî === Ji {{deyn|ar|ku|فِرار}}. === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[rev]], [[revîn]] (bi taybetî ji [[leşkerî|leşkeriyê]]) #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Fahnenflucht}} {{mê}}, {{W|de|Flucht}} {{mê}}, {{W|de|Flüchtling}} {{n}}, {{W|de|Fortlaufen}}, {{W|de|Desertion|guman=erê}} {{mê}}, {{W|de|Desertation|f|guman=erê}} * {{Z|fa}}: {{W|fa|گریز}}, {{W|fa|فرار}} * {{Z|en}}: {{W|en|recreant}}, {{W|en|desertion|guman=erê}} * {{Z|tr}}: {{W|tr|firar}}, {{W|tr|firarî}}, {{W|tr|kaçak}} {{werger-bin}} === Rengdêr === {{rengdêr|ku}} # Ya/yê ku [[revîn|direve]] yan [[revîn|reviye]]. #: {{hevmane|ku|revok}} #* {{bêmînak|ku}} ==== Werger ==== {{werger-ser}} {{werger-bin}} === Jê === {{kol3|ku|cure=Jê |firarî |firar kirin<pos:lêker> |firarkirin<pos:navdêr> |firarkirî<pos:rengdêr> }} == {{ziman|tr}} == === Navdêr === {{navdêr|tr}} # [[rev]], {{g|ku|firar}} #: {{mk|tr|Buna '''firar''' denilmez, kurtuluş denir.|rêz=1|Ji vê re rev nayê gotin, xelasî tê gotin.}} # [[mişextî]], firar #* {{bêmînak|tr}} 8mrd3y2ak0eh6wrbfjs0ni4x2npjs3b hêm 0 24087 6333954 6326336 2026-08-15T23:28:57Z Wikihez 7344 /* Binêre herwiha */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333954 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[nem]], [[ritûbat]], [[şilî]] <br>(bi taybetî ya [[dîwar]]an di [[hindir]]ê [[avahî|avahiyan]] ve) #* {{bênimûne|ku}} # {{kontrol|rêz=erê|[[şilî]], [[ritubat]], [[rewek]], [[rewa]]}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bide ber ==== * [[hem]] * [[him]] * [[hîm]] ==== Binêre herwiha ==== * [[hêman]] ==== Jê ==== * [[bêhêm]] * [[bêhêmî]] * [[bihêm]] * [[hêmdar]] * [[hêmdarî]] * [[hêmdêr]] * [[hêmdêrî]] * [[hêmî]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Feuchtigkeit}} {{mê}} * {{Z|ast}}: {{W|ast|humedanza}} * {{Z|bg}}: {{W|bg|влажност}} * {{Z|cs}}: {{W|cs|vlhkost}} * {{Z|zh}}: {{W|zh|濕度}}, {{W|zh|湿度}} * {{Z|ar}}: {{W|ar|رطوبة}} * {{Z|fa}}: {{W|fa|نمناک}} * {{Z|fi}}: {{W|fi|kosteus}} * {{Z|fr}}: {{W|fr|humidité}} * {{Z|nl}}: {{W|nl|luchtvochtigheid}} * {{Z|en}}: {{W|en|humidity}}, {{W|en|dampness}}, {{W|en|dewiness}}, {{W|en|insignia|guman=erê}} * {{Z|ja}}: {{W|ja|湿気}} * {{Z|lt}}: {{W|lt|mitrums}} * {{Z|mk}}: {{W|mk|влага}} * {{Z|ms}}: {{W|ms|kelembapan}} * {{Z|nv}}: {{W|nv|níłchʼi ditłééʼ}} * {{Z|pl}}: {{W|pl|wilgotność}} * {{Z|pt}}: {{W|pt|umidade}}, {{W|pt|humidade}} * {{Z|ro}}: {{W|ro|umezeală}} * {{Z|ru}}: {{W|ru|влажность}} * {{Z|sd}}: {{W|sd|اٻس}} * {{Z|es}}: {{W|es|humedad}} * {{Z|sv}}: {{W|sv|luftfuktighet}} * {{Z|tr}}: {{W|tr|rutubet}}, {{W|tr|nem}} {{werger-bin}} 2egz1tqf0grc8u7ur8inpqx559l2ksw 6333970 6333954 2026-08-15T23:41:17Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333970 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[nem]], [[ritûbat]], [[şilî]] <br>(bi taybetî ya [[dîwar]]an di [[hindir]]ê [[avahî|avahiyan]] ve) #* {{bênimûne|ku}} # {{kontrol|rêz=erê|[[şilî]], [[ritubat]], [[rewek]], [[rewa]]}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Jê ==== * [[bêhêm]] * [[bêhêmî]] * [[bihêm]] * [[hêmdar]] * [[hêmdarî]] * [[hêmdêr]] * [[hêmdêrî]] * [[hêmî]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Bide ber ==== * [[hem]] * [[him]] * [[hîm]] ==== Herwiha binêre ==== * [[hêman]] ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Feuchtigkeit}} {{mê}} * {{Z|ast}}: {{W|ast|humedanza}} * {{Z|bg}}: {{W|bg|влажност}} * {{Z|cs}}: {{W|cs|vlhkost}} * {{Z|zh}}: {{W|zh|濕度}}, {{W|zh|湿度}} * {{Z|ar}}: {{W|ar|رطوبة}} * {{Z|fa}}: {{W|fa|نمناک}} * {{Z|fi}}: {{W|fi|kosteus}} * {{Z|fr}}: {{W|fr|humidité}} * {{Z|nl}}: {{W|nl|luchtvochtigheid}} * {{Z|en}}: {{W|en|humidity}}, {{W|en|dampness}}, {{W|en|dewiness}}, {{W|en|insignia|guman=erê}} * {{Z|ja}}: {{W|ja|湿気}} * {{Z|lt}}: {{W|lt|mitrums}} * {{Z|mk}}: {{W|mk|влага}} * {{Z|ms}}: {{W|ms|kelembapan}} * {{Z|nv}}: {{W|nv|níłchʼi ditłééʼ}} * {{Z|pl}}: {{W|pl|wilgotność}} * {{Z|pt}}: {{W|pt|umidade}}, {{W|pt|humidade}} * {{Z|ro}}: {{W|ro|umezeală}} * {{Z|ru}}: {{W|ru|влажность}} * {{Z|sd}}: {{W|sd|اٻس}} * {{Z|es}}: {{W|es|humedad}} * {{Z|sv}}: {{W|sv|luftfuktighet}} * {{Z|tr}}: {{W|tr|rutubet}}, {{W|tr|nem}} {{werger-bin}} 602s45aeebni1ss1z7rwry05p53lsqx erjeng 0 29515 6333820 6306162 2026-08-15T14:41:14Z ~2026-31052-98 14994 /* Etîmolojî */ 6333820 wikitext text/x-wiki {{bnr-h|Erjeng}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # {{mijar|ku|hest}} [[hest|Hest]]a [[nexweş]] ya dikeve [[dil]]ê mirovî [[dema]] [[bawer kirin|bawer dike]] ku dê tiştek [[xirab]] [[qewimîn|biqewime]]. #: {{hevmane|ku|saw|kabûs|xof|sam|sehm|hijmet|hêb|hêw|qurf|dehşet}} #* {{jêder|ku|{{Jêgirtin/Melayê Cizîrî/Dîwana Melayê Cizirî}}|jêgirtin=Tu rojê neqşikê bavê</br>Ko da '''Erjeng''' ji wê navê</br>Li ber rojê nebit perde}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|ئەرژەنگ}} ==== Jê ==== {{kol3|ku|cure=Jê |erjeng bûn<q:lêker> |erjeng kirin<q:lêker> |erjengbûn<q:navdêr> |erjengkirin<q:navdêr> |erjengbûyî<q:rengdêr> |erjengkirî<q:rengdêr> |erjengî }} ==== Etîmolojî ==== {{hevreha Farsî ارژنگ û Kudiya kervin: navê pirtûka Manî pêxembere ku bi nîgaran navdar bû|ku}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|abscheulich}}, {{W+|de|Grauen|n}}, {{W+|de|grauenhaft}}, {{W+|de|beängstigend|guman=erê}} * {{Z|fa}}: {{W+|fa|ترسناک}} * {{Z|fi}}: {{W+|fi|kauhu}}, {{W+|fi|kammo}} * {{Z|en}}: {{W+|en|horror}}, {{W+|en|fear}}, {{W+|en|terror}}, {{W+|en|dread}}, {{W+|en|dreaded}}, {{W+|en|redoubted}}, {{W-|en|applalling}}, {{W+|en|terrible}}, {{W+|en|direful}}, {{W+|en|dreadful}}, {{W+|en|macabre}}, {{W+|en|bloodcurdling|guman=erê}}, {{W+|en|nasty|guman=erê}}, {{W+|en|odious|guman=erê}} * {{Z|tr}}: {{W+|tr|dehşet}}, {{W+|tr|korkunç}}, {{W+|tr|dehşetli}}, {{W+|tr|vahim}} {{werger-bin}} === Rengdêr === {{rengdêr|ku}} # [[hest|Hest]]a [[nexweş]] ya dikeve [[dil]]ê mirovî [[dema]] [[bawer kirin|bawer dike]] ku dê tiştek [[xirab]] [[qewimîn|biqewime]]. #* {{jêder|ku|jêgirtin=Bi metirsîyeke '''erjeng''', kitana xwe bi ser serê xwe dadike û di ber xwe de diponije hîv.|{{Jêgirtin/Îrfan Amîda/Şevek Şîzofren|r=5}}}} #* {{jêder-pirtûk|ku|jêgirtin=Divîya bû biçe, ji vê tarîtîya '''erjeng'''...|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=93|isbn=9786257724838}} #* {{jêder|ku|jêgirtin=Serê xwe ber bi jor ve kir, dengekî '''erjeng''' ji xwe derxist û dinya bi hatina xwe hesand.|{{Jêgirtin/Sadiq Ûskan/Gurê Manco}}}} ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W+|en|dreaded}}, {{W+|en|terrible}},{{W+|en|dreadful}}, {{W+|en|macabre}}, {{W+|en|bloodcurdling}} * {{Z|tr}}: {{W+|tr|dehşet}}, {{W+|tr|korkunç}}, {{W+|tr|dehşetli}}, {{W+|tr|vahim}} {{werger-bin}} okcyybf88ztczgykc582p99begfm77o 6333821 6333820 2026-08-15T14:41:45Z ~2026-31052-98 14994 /* Etîmolojî */ 6333821 wikitext text/x-wiki {{bnr-h|Erjeng}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # {{mijar|ku|hest}} [[hest|Hest]]a [[nexweş]] ya dikeve [[dil]]ê mirovî [[dema]] [[bawer kirin|bawer dike]] ku dê tiştek [[xirab]] [[qewimîn|biqewime]]. #: {{hevmane|ku|saw|kabûs|xof|sam|sehm|hijmet|hêb|hêw|qurf|dehşet}} #* {{jêder|ku|{{Jêgirtin/Melayê Cizîrî/Dîwana Melayê Cizirî}}|jêgirtin=Tu rojê neqşikê bavê</br>Ko da '''Erjeng''' ji wê navê</br>Li ber rojê nebit perde}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|ئەرژەنگ}} ==== Jê ==== {{kol3|ku|cure=Jê |erjeng bûn<q:lêker> |erjeng kirin<q:lêker> |erjengbûn<q:navdêr> |erjengkirin<q:navdêr> |erjengbûyî<q:rengdêr> |erjengkirî<q:rengdêr> |erjengî }} ==== Etîmolojî ==== {{hevreha Farsî ارژنگ û Kudiya kevin: navê pirtûka Manî pêxembere ku bi nîgaran navdar bû|ku}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|abscheulich}}, {{W+|de|Grauen|n}}, {{W+|de|grauenhaft}}, {{W+|de|beängstigend|guman=erê}} * {{Z|fa}}: {{W+|fa|ترسناک}} * {{Z|fi}}: {{W+|fi|kauhu}}, {{W+|fi|kammo}} * {{Z|en}}: {{W+|en|horror}}, {{W+|en|fear}}, {{W+|en|terror}}, {{W+|en|dread}}, {{W+|en|dreaded}}, {{W+|en|redoubted}}, {{W-|en|applalling}}, {{W+|en|terrible}}, {{W+|en|direful}}, {{W+|en|dreadful}}, {{W+|en|macabre}}, {{W+|en|bloodcurdling|guman=erê}}, {{W+|en|nasty|guman=erê}}, {{W+|en|odious|guman=erê}} * {{Z|tr}}: {{W+|tr|dehşet}}, {{W+|tr|korkunç}}, {{W+|tr|dehşetli}}, {{W+|tr|vahim}} {{werger-bin}} === Rengdêr === {{rengdêr|ku}} # [[hest|Hest]]a [[nexweş]] ya dikeve [[dil]]ê mirovî [[dema]] [[bawer kirin|bawer dike]] ku dê tiştek [[xirab]] [[qewimîn|biqewime]]. #* {{jêder|ku|jêgirtin=Bi metirsîyeke '''erjeng''', kitana xwe bi ser serê xwe dadike û di ber xwe de diponije hîv.|{{Jêgirtin/Îrfan Amîda/Şevek Şîzofren|r=5}}}} #* {{jêder-pirtûk|ku|jêgirtin=Divîya bû biçe, ji vê tarîtîya '''erjeng'''...|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=93|isbn=9786257724838}} #* {{jêder|ku|jêgirtin=Serê xwe ber bi jor ve kir, dengekî '''erjeng''' ji xwe derxist û dinya bi hatina xwe hesand.|{{Jêgirtin/Sadiq Ûskan/Gurê Manco}}}} ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W+|en|dreaded}}, {{W+|en|terrible}},{{W+|en|dreadful}}, {{W+|en|macabre}}, {{W+|en|bloodcurdling}} * {{Z|tr}}: {{W+|tr|dehşet}}, {{W+|tr|korkunç}}, {{W+|tr|dehşetli}}, {{W+|tr|vahim}} {{werger-bin}} ou9zn1wc91xca4abpvoczjh4kr828rf 6333847 6333821 2026-08-15T16:12:08Z Balyozbot 7867 Bot: Paqijiyên kozmetîk (Lînk paqij kir.) 6333847 wikitext text/x-wiki {{bnr-h|Erjeng}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # {{mijar|ku|hest}} [[hest|Hesta]] [[nexweş]] ya dikeve [[dil]]ê mirovî [[dema]] [[bawer kirin|bawer dike]] ku dê tiştek [[xirab]] [[qewimîn|biqewime]]. #: {{hevmane|ku|saw|kabûs|xof|sam|sehm|hijmet|hêb|hêw|qurf|dehşet}} #* {{jêder|ku|{{Jêgirtin/Melayê Cizîrî/Dîwana Melayê Cizirî}}|jêgirtin=Tu rojê neqşikê bavê</br>Ko da '''Erjeng''' ji wê navê</br>Li ber rojê nebit perde}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|ئەرژەنگ}} ==== Jê ==== {{kol3|ku|cure=Jê |erjeng bûn<q:lêker> |erjeng kirin<q:lêker> |erjengbûn<q:navdêr> |erjengkirin<q:navdêr> |erjengbûyî<q:rengdêr> |erjengkirî<q:rengdêr> |erjengî }} ==== Etîmolojî ==== {{hevreha Farsî ارژنگ û Kudiya kevin: navê pirtûka Manî pêxembere ku bi nîgaran navdar bû|ku}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|abscheulich}}, {{W+|de|Grauen|n}}, {{W+|de|grauenhaft}}, {{W+|de|beängstigend|guman=erê}} * {{Z|fa}}: {{W+|fa|ترسناک}} * {{Z|fi}}: {{W+|fi|kauhu}}, {{W+|fi|kammo}} * {{Z|en}}: {{W+|en|horror}}, {{W+|en|fear}}, {{W+|en|terror}}, {{W+|en|dread}}, {{W+|en|dreaded}}, {{W+|en|redoubted}}, {{W-|en|applalling}}, {{W+|en|terrible}}, {{W+|en|direful}}, {{W+|en|dreadful}}, {{W+|en|macabre}}, {{W+|en|bloodcurdling|guman=erê}}, {{W+|en|nasty|guman=erê}}, {{W+|en|odious|guman=erê}} * {{Z|tr}}: {{W+|tr|dehşet}}, {{W+|tr|korkunç}}, {{W+|tr|dehşetli}}, {{W+|tr|vahim}} {{werger-bin}} === Rengdêr === {{rengdêr|ku}} # [[hest|Hesta]] [[nexweş]] ya dikeve [[dil]]ê mirovî [[dema]] [[bawer kirin|bawer dike]] ku dê tiştek [[xirab]] [[qewimîn|biqewime]]. #* {{jêder|ku|jêgirtin=Bi metirsîyeke '''erjeng''', kitana xwe bi ser serê xwe dadike û di ber xwe de diponije hîv.|{{Jêgirtin/Îrfan Amîda/Şevek Şîzofren|r=5}}}} #* {{jêder-pirtûk|ku|jêgirtin=Divîya bû biçe, ji vê tarîtîya '''erjeng'''...|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=93|isbn=9786257724838}} #* {{jêder|ku|jêgirtin=Serê xwe ber bi jor ve kir, dengekî '''erjeng''' ji xwe derxist û dinya bi hatina xwe hesand.|{{Jêgirtin/Sadiq Ûskan/Gurê Manco}}}} ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W+|en|dreaded}}, {{W+|en|terrible}},{{W+|en|dreadful}}, {{W+|en|macabre}}, {{W+|en|bloodcurdling}} * {{Z|tr}}: {{W+|tr|dehşet}}, {{W+|tr|korkunç}}, {{W+|tr|dehşetli}}, {{W+|tr|vahim}} {{werger-bin}} 3i2gff03b9fkhx3z4gyvo69fuip2rk6 piçîn 0 38154 6334080 6314756 2026-08-16T07:42:12Z Keyomerd 8814 /* Lêker */ 6334080 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Lêker === {{lêker|ku|c=x-ngh}} # [[piç]] bûn, [[qurtivîn]], [[qetîn]], [[pirt]] bûn, hatin [[piçandin]], <br>[[ben]] yan [[werîs]] yan tiştek din yê [[zirav]] bûn du yan [[pirtir]] [[parçe]] #:''Benê zirav zû '''dipiçe'''.'' #* {{jêder|ku|{{Jêgirtin/Feqiyê Teyran}}|jêgirtin=Teftêş kirin ji nutfetê</br>Çi tişt '''piçe''' nafericin</br>însan ji tînêd xaricin}} # [[alîn]], [[hemêz kirin]] #* {{Memozîn 2007|jêgirtin=Dem lêk '''piçiyan''' û dem cuda bûn</br>Geh têk hejiyan û geh di ba bûn|r=137}} ==== Tewandin ==== ''Lêker'': : -piç- ==== Formên alternatîv ==== * [[piçan]] * [[piçhan]] * [[piçihan]] * [[piçihîn]] * [[piçiyan]] * [[piçyan]] ==== Jê ==== * [[piçiyayî]] * [[piçî]] * [[piçok]] ==== Têkildar ==== * [[piçandin]] ==== Etîmolojî ==== Ji {{qertaf|ku|piç|-în}}. ==== Werger ==== {{werger-ser}} {{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}} {{werger-bin}} 3mq2ek3ejfg2j299uykph6lwgev4xb1 hevxemî 0 38480 6333952 6308459 2026-08-15T23:28:00Z Wikihez 7344 /* {{ziman|ku}} */ [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6333952 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[xemgîn]]bûna li gel kesek din, <br>[[hevpar]]bûna li gel [[xem]]ên kesa/ê ku [[bela]]yek hatiye serî #* {{jêder|ku|jêgirtin=Serokê Kurdistanê êrîşa terorîstî ya ko duhî li Mexmûrê li himberî baregehê PDK-ê hatî kirin û di encamê de 32 kes hatîn kuştin û 115 kes birîndar bûyîn şermezar kir û hevxemiya xwe bo kesûkarên kuştî û birîndaran diyar kir, sersaxî ji bo kesûkarên kuştiyan xwest û hêvî kir ko birîndar bi rojekê zûtir sax û selamet bin.|Kurdistantv.net, 7/2007}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * {{g|ku|hemxemî}} * {{g|ku|hemxemîtî}} * {{g|ku|hemxemtî}} * {{g|ku|hevxemîtî}} * {{g|ku|hevxemtî}} ==== Etîmolojî ==== Ji {{paş|ku|hevxem|-î}} ==== Bi zaravayên din ==== * {{Z|ckb}}: {{W-|ckb|hawxemî}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Beileid|m}}, {{W|de|Mitleid|m|guman=erê}}, {{W|de|Einfühlungsvermögen|m|guman=erê}} {{werger-bin}} mjjdn8ybwt8agc10oa38z1pnoea5ede pêkanîn 0 40079 6334048 6326560 2026-08-16T01:58:05Z Wikihez 7344 6334048 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m|lk=pêk anîn}} # [[bicihanîn]], [[kirin]], [[encamdan]], [[îcra]] #* {{bêmînak|ku}} # [[lihevanîn]], [[sulh]] pê dan kirin #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * [[pêkhanîn]] * [[pêkhênan]] * [[pêkhînan]] * [[pêkînan]] ==== Etîmolojî ==== Ji {{qertaf|ku|pêk|anîn}}. ==== Werger ==== {{werger-ser|bicihanîn}} * {{Z|de}}: {{W+|de|einrichten}}, {{W+|de|Ausführung}} {{mê}}, {{W+|de|Ausübung}} {{mê}}, {{W+|de|Durchführung}} {{mê}}, {{W+|de|Vollzug}} {{n}}, {{W+|de|Anfertigung}} {{mê}}, {{W+|de|Produktion}} {{mê}}, {{W+|de|Verarbeitung}} {{mê}}, {{W+|de|Verwirklichung}} {{mê}}, {{W+|de|anstellen}}, {{W+|de|betreiben}}, {{W+|de|bewältigen}}, {{W+|de|bilden}}, {{W+|de|erzeugen}}, {{W+|de|formieren}}, {{W+|de|gebären}}, {{W+|de|herstellen}}, {{W+|de|hervorbringen}}, {{W+|de|produzieren}}, {{W+|de|realisieren}}, {{W+|de|verwirklichen}}, {{W-|de|zustande bringen}}, {{W+|de|zustande kommen}} * {{Z|ar}}: {{W-|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|fa}}: {{W+|fa|اجراکردن}}, {{W-|fa|تحقق بخشیدن}}, {{W+|fa|انجام دادن}} * {{Z|fi}}: {{W+|fi|toteutus}} * {{Z|en}}: {{W+|en|execution}}, {{W+|en|performance}}, {{W+|en|rendering}}, {{W+|en|rendition}}, {{W+|en|carrying out}}, {{W+|en|enforcement}}, {{W+|en|accomplishment}}, {{W+|en|exercise}}, {{W+|en|fulfillment}}, {{W+|en|construction}}, {{W+|en|composition}}, {{W+|en|achievement|guman=erê}}, {{W+|en|combination|guman=erê}}, {{W+|en|combining|guman=erê}}, {{W+|en|composing|guman=erê}}, {{W+|en|formation|guman=erê}}, {{W+|en|put together|guman=erê}}, {{W+|en|reconciling|guman=erê}}, {{W+|en|synthesizing|guman=erê}} * {{Z|tr}}: {{W+|tr|yapma}}, {{W-|tr|yerine getirme}}, bir işi [[yürütme]], {{W+|tr|icra}}, {{W+|tr|becerme}}, {{W+|tr|bileşme}}, {{W+|tr|ifa}}, {{W+|tr|oluşturma}}, {{W+|tr|oluşturmak}}, {{W+|tr|sağlamak}}, {{W+|tr|icraat}}, {{W+|tr|yaratma}}, {{W+|tr|temin|guman=erê}}, {{W+|tr|gerçekleştirmek|guman=erê}}, {{W+|tr|gerçekleştirme|guman=erê}} {{werger-bin}} === Navdêr === {{navdêr|ku|c=m|lk=pê kanîn}} # [[hêz|Hêz]] û [[taqet|taqeta]] [[xwe|xwe]] [[têrî|têrî]] [[tiştekî|tiştekî]] [[kirin|kirin]]. bi wê/wî kanîn ==== Etîmolojî ==== Ji {{qertaf|ku|pê|kanîn}}. ==== Werger ==== {{werger-ser}} {{werger-bin}} 8cw10zqpnu5vbqoxpffrksezifran4e 6334070 6334048 2026-08-16T03:12:12Z Balyozbot 7867 Bot: Paqijiyên kozmetîk (Lînk paqij kir.) 6334070 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m|lk=pêk anîn}} # [[bicihanîn]], [[kirin]], [[encamdan]], [[îcra]] #* {{bêmînak|ku}} # [[lihevanîn]], [[sulh]] pê dan kirin #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * [[pêkhanîn]] * [[pêkhênan]] * [[pêkhînan]] * [[pêkînan]] ==== Etîmolojî ==== Ji {{qertaf|ku|pêk|anîn}}. ==== Werger ==== {{werger-ser|bicihanîn}} * {{Z|de}}: {{W+|de|einrichten}}, {{W+|de|Ausführung}} {{mê}}, {{W+|de|Ausübung}} {{mê}}, {{W+|de|Durchführung}} {{mê}}, {{W+|de|Vollzug}} {{n}}, {{W+|de|Anfertigung}} {{mê}}, {{W+|de|Produktion}} {{mê}}, {{W+|de|Verarbeitung}} {{mê}}, {{W+|de|Verwirklichung}} {{mê}}, {{W+|de|anstellen}}, {{W+|de|betreiben}}, {{W+|de|bewältigen}}, {{W+|de|bilden}}, {{W+|de|erzeugen}}, {{W+|de|formieren}}, {{W+|de|gebären}}, {{W+|de|herstellen}}, {{W+|de|hervorbringen}}, {{W+|de|produzieren}}, {{W+|de|realisieren}}, {{W+|de|verwirklichen}}, {{W-|de|zustande bringen}}, {{W+|de|zustande kommen}} * {{Z|ar}}: {{W-|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|fa}}: {{W+|fa|اجراکردن}}, {{W-|fa|تحقق بخشیدن}}, {{W+|fa|انجام دادن}} * {{Z|fi}}: {{W+|fi|toteutus}} * {{Z|en}}: {{W+|en|execution}}, {{W+|en|performance}}, {{W+|en|rendering}}, {{W+|en|rendition}}, {{W+|en|carrying out}}, {{W+|en|enforcement}}, {{W+|en|accomplishment}}, {{W+|en|exercise}}, {{W+|en|fulfillment}}, {{W+|en|construction}}, {{W+|en|composition}}, {{W+|en|achievement|guman=erê}}, {{W+|en|combination|guman=erê}}, {{W+|en|combining|guman=erê}}, {{W+|en|composing|guman=erê}}, {{W+|en|formation|guman=erê}}, {{W+|en|put together|guman=erê}}, {{W+|en|reconciling|guman=erê}}, {{W+|en|synthesizing|guman=erê}} * {{Z|tr}}: {{W+|tr|yapma}}, {{W-|tr|yerine getirme}}, bir işi [[yürütme]], {{W+|tr|icra}}, {{W+|tr|becerme}}, {{W+|tr|bileşme}}, {{W+|tr|ifa}}, {{W+|tr|oluşturma}}, {{W+|tr|oluşturmak}}, {{W+|tr|sağlamak}}, {{W+|tr|icraat}}, {{W+|tr|yaratma}}, {{W+|tr|temin|guman=erê}}, {{W+|tr|gerçekleştirmek|guman=erê}}, {{W+|tr|gerçekleştirme|guman=erê}} {{werger-bin}} === Navdêr === {{navdêr|ku|c=m|lk=pê kanîn}} # [[hêz|Hêz]] û [[taqet]]a [[xwe]] [[têrî]] [[tiştekî]] [[kirin]]. bi wê/wî kanîn ==== Etîmolojî ==== Ji {{qertaf|ku|pê|kanîn}}. ==== Werger ==== {{werger-ser}} {{werger-bin}} sj36a65lglxhbm3ys74ijen11potws4 katakanayî 0 40137 6333990 6309695 2026-08-16T00:57:22Z Wikihez 7344 /* Kîteyên katakanayî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333990 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[cûn]]ek [[kîtenivîs]]ê ye ku [[ziman]]ê [[japonî]] pê tê [[nivîsîn]] #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== Ji {{paş|ku|katakana|-yî}} ==== Bide ber ==== * [[hîraganayî]] ==== Binêre herwiha ==== {{veşêre-ser|Kîteyên katakanayî}} {| border="0" cellspacing="2px" cellpadding="2px" width="100%" |-bgcolor="#BECFEB" valign=top align="center" |ア&nbsp;'''''a''''' |イ&nbsp;'''''i''''' |ウ&nbsp;'''''u''''' |エ&nbsp;'''''e''''' |オ&nbsp;'''''o''''' |bgcolor="#D4D4D4"|('''''ya''''') |bgcolor="#D4D4D4"|('''''yu''''') |bgcolor="#D4D4D4"|('''''yo''''') |-bgcolor="#E7F5DE" valign=top align="center" |カ&nbsp;'''''ka''''' |キ&nbsp;'''''ki''''' |ク&nbsp;'''''ku''''' |ケ&nbsp;'''''ke''''' |コ&nbsp;'''''ko''''' |bgcolor="#F3F5DE"|キャ&nbsp;'''''kya''''' |bgcolor="#F3F5DE"|キュ&nbsp;'''''kyu''''' |bgcolor="#F3F5DE"|キョ&nbsp;'''''kyo''''' |-bgcolor="#E7F5DE" valign=top align="center" |サ&nbsp;'''''sa''''' |シ&nbsp;'''''shi''''' |ス&nbsp;'''''su''''' |セ&nbsp;'''''se''''' |ソ&nbsp;'''''so''''' |bgcolor="#F3F5DE"|シャ&nbsp;'''''sha''''' |bgcolor="#F3F5DE"|シュ&nbsp;'''''shu''''' |bgcolor="#F3F5DE"|ショ&nbsp;'''''sho''''' |-bgcolor="#E7F5DE" valign=top align="center" |タ&nbsp;'''''ta''''' |チ&nbsp;'''''chi''''' |ツ&nbsp;'''''tsu''''' |テ&nbsp;'''''te''''' |ト&nbsp;'''''to''''' |bgcolor="#F3F5DE"|チャ&nbsp;'''''cha''''' |bgcolor="#F3F5DE"|チュ&nbsp;'''''chu''''' |bgcolor="#F3F5DE"|チョ&nbsp;'''''cho''''' |-bgcolor="#E7F5DE" valign=top align="center" |ナ&nbsp;'''''na''''' |ニ&nbsp;'''''ni''''' |ヌ&nbsp;'''''nu''''' |ネ&nbsp;'''''ne''''' |ノ&nbsp;'''''no''''' |bgcolor="#F3F5DE"|ニャ&nbsp;'''''nya''''' |bgcolor="#F3F5DE"|ニュ&nbsp;'''''nyu''''' |bgcolor="#F3F5DE"|ニョ&nbsp;'''''nyo''''' |-bgcolor="#E7F5DE" valign=top align="center" |ハ&nbsp;'''''ha''''' |ヒ&nbsp;'''''hi''''' |フ&nbsp;'''''fu''''' |ヘ&nbsp;'''''he''''' |ホ&nbsp;'''''ho''''' |bgcolor="#F3F5DE"|ヒャ&nbsp;'''''hya''''' |bgcolor="#F3F5DE"|ヒュ&nbsp;'''''hyu''''' |bgcolor="#F3F5DE"|ヒョ&nbsp;'''''hyo''''' |-bgcolor="#E7F5DE" valign=top align="center" |マ&nbsp;'''''ma''''' |ミ&nbsp;'''''mi''''' |ム&nbsp;'''''mu''''' |メ&nbsp;'''''me''''' |モ&nbsp;'''''mo''''' |bgcolor="#F3F5DE"|ミャ&nbsp;'''''mya''''' |bgcolor="#F3F5DE"|ミュ&nbsp;'''''myu''''' |bgcolor="#F3F5DE"|ミョ&nbsp;'''''myo''''' |-bgcolor="#E7F5DE" valign=top align="center" |ヤ&nbsp;'''''ya''''' |bgcolor="#E9E9E9"| |ユ&nbsp;'''''yu''''' |bgcolor="#E9E9E9"| |ヨ&nbsp;'''''yo''''' |bgcolor="#E9E9E9" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |ラ&nbsp;'''''ra''''' |リ&nbsp;'''''ri''''' |ル&nbsp;'''''ru''''' |レ&nbsp;'''''re''''' |ロ&nbsp;'''''ro''''' |bgcolor="#F3F5DE"|リャ&nbsp;'''''rya''''' |bgcolor="#F3F5DE"|リュ&nbsp;'''''ryu''''' |bgcolor="#F3F5DE"|リョ&nbsp;'''''ryo''''' |-bgcolor="#E7F5DE" valign=top align="center" |ワ&nbsp;'''''wa''''' |<span style="color:red;">ヰ&nbsp;'''''wi'''''</span> |bgcolor="#E9E9E9"| |<span style="color:red;">ヱ&nbsp;'''''we'''''</span> |ヲ&nbsp;'''''wo''''' |bgcolor="#E9E9E9" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9" colspan="4"| |ン&nbsp;'''''n''''' |bgcolor="#E9E9E9" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |ガ&nbsp;'''''ga''''' |ギ&nbsp;'''''gi''''' |グ&nbsp;'''''gu''''' |ゲ&nbsp;'''''ge''''' |ゴ&nbsp;'''''go''''' |bgcolor="#F3F5DE"|ギャ&nbsp;'''''gya''''' |bgcolor="#F3F5DE"|ギュ&nbsp;'''''gyu''''' |bgcolor="#F3F5DE"|ギョ&nbsp;'''''gyo''''' |-bgcolor="#E7F5DE" valign=top align="center" |ザ&nbsp;'''''za''''' |ジ&nbsp;'''''ji''''' |ズ&nbsp;'''''zu''''' |ゼ&nbsp;'''''ze''''' |ゾ&nbsp;'''''zo''''' |bgcolor="#F3F5DE"|ジャ&nbsp;'''''ja''''' |bgcolor="#F3F5DE"|ジュ&nbsp;'''''ju''''' |bgcolor="#F3F5DE"|ジョ&nbsp;'''''jo''''' |-bgcolor="#E7F5DE" valign=top align="center" |ダ&nbsp;'''''da''''' |ヂ&nbsp;('''''ji''''') |ヅ&nbsp;('''''zu''''') |デ&nbsp;'''''de''''' |ド&nbsp;'''''do''''' |bgcolor="#F3F5DE"|ヂャ&nbsp;('''''ja''''') |bgcolor="#F3F5DE"|ヂュ&nbsp;('''''ju''''') |bgcolor="#F3F5DE"|ヂョ&nbsp;('''''jo''''') |-bgcolor="#E7F5DE" valign=top align="center" |バ&nbsp;'''''ba''''' |ビ&nbsp;'''''bi''''' |ブ&nbsp;'''''bu''''' |ベ&nbsp;'''''be''''' |ボ&nbsp;'''''bo''''' |bgcolor="#F3F5DE"|ビャ&nbsp;'''''bya''''' |bgcolor="#F3F5DE"|ビュ&nbsp;'''''byu''''' |bgcolor="#F3F5DE"|ビョ&nbsp;'''''byo''''' |-bgcolor="#E7F5DE" valign=top align="center" |パ&nbsp;'''''pa''''' |ピ&nbsp;'''''pi''''' |プ&nbsp;'''''pu''''' |ペ&nbsp;'''''pe''''' |ポ&nbsp;'''''po''''' |bgcolor="#F3F5DE"|ピャ&nbsp;'''''pya''''' |bgcolor="#F3F5DE"|ピュ&nbsp;'''''pyu''''' |bgcolor="#F3F5DE"|ピョ&nbsp;'''''pyo''''' |- |bgcolor="#FFFFFF" colspan="8"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9" colspan="3"| |イェ&nbsp;'''''ye''''' |bgcolor="#E9E9E9"| |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9"| |ウィ&nbsp;'''''wi''''' |bgcolor="#E9E9E9"| |ウェ&nbsp;'''''we''''' |ウォ&nbsp;'''''wo''''' |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |<span style="color:red;">ヷ&nbsp;'''''va'''''</span> |<span style="color:red;">ヸ&nbsp;'''''vi'''''</span> |bgcolor="#E9E9E9"| |<span style="color:red;">ヹ&nbsp;'''''ve'''''</span> |<span style="color:red;">ヺ&nbsp;'''''vo'''''</span> |-bgcolor="#E7F5DE" valign=top align="center" |ヴァ&nbsp;'''''va''''' |ヴィ&nbsp;'''''vi''''' |ヴ&nbsp;'''''vu''''' |ヴェ&nbsp;'''''ve''''' |ヴォ&nbsp;'''''vo''''' |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9" colspan="3"| |シェ&nbsp;'''''she''''' |bgcolor="#E9E9E9"| |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9" colspan="3"| |ジェ&nbsp;'''''je''''' |bgcolor="#E9E9E9"| |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9" colspan="3"| |チェ&nbsp;'''''che''''' |bgcolor="#E9E9E9"| |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9"| |ティ&nbsp;'''''ti''''' |トゥ&nbsp;'''''tu''''' |bgcolor="#E9E9E9" colspan="2"| |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9" colspan="2"| |テュ&nbsp;'''''tyu''''' |bgcolor="#E9E9E9" colspan="2"| |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9"| |ディ&nbsp;'''''di''''' |ドゥ&nbsp;'''''du''''' |bgcolor="#E9E9E9" colspan="2"| |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9" colspan="2"| |デュ&nbsp;'''''dyu''''' |bgcolor="#E9E9E9" colspan="2"| |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |ツァ&nbsp;'''''tsa''''' |ツィ&nbsp;'''''tsi''''' |bgcolor="#E9E9E9"| |ツェ&nbsp;'''''tse''''' |ツォ&nbsp;'''''tso''''' |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |ファ&nbsp;'''''fa''''' |フィ&nbsp;'''''fi''''' |bgcolor="#E9E9E9"| |フェ&nbsp;'''''fe''''' |フォ&nbsp;'''''fo''''' |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9" colspan="2"| |フュ&nbsp;'''''fyu''''' |bgcolor="#E9E9E9" colspan="2"| |bgcolor="#FFFFFF" colspan="3"| |} {{veşêre-bin}} ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W|en|Katakana}} {{werger-bin}} qox7gv1xva7wdpb16jems10bahul5os 6334037 6333990 2026-08-16T01:41:39Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6334037 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[cûn]]ek [[kîtenivîs]]ê ye ku [[ziman]]ê [[japonî]] pê tê [[nivîsîn]] #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== Ji {{paş|ku|katakana|-yî}} ==== Bide ber ==== * [[hîraganayî]] ==== Herwiha binêre ==== {{veşêre-ser|Kîteyên katakanayî}} {| border="0" cellspacing="2px" cellpadding="2px" width="100%" |-bgcolor="#BECFEB" valign=top align="center" |ア&nbsp;'''''a''''' |イ&nbsp;'''''i''''' |ウ&nbsp;'''''u''''' |エ&nbsp;'''''e''''' |オ&nbsp;'''''o''''' |bgcolor="#D4D4D4"|('''''ya''''') |bgcolor="#D4D4D4"|('''''yu''''') |bgcolor="#D4D4D4"|('''''yo''''') |-bgcolor="#E7F5DE" valign=top align="center" |カ&nbsp;'''''ka''''' |キ&nbsp;'''''ki''''' |ク&nbsp;'''''ku''''' |ケ&nbsp;'''''ke''''' |コ&nbsp;'''''ko''''' |bgcolor="#F3F5DE"|キャ&nbsp;'''''kya''''' |bgcolor="#F3F5DE"|キュ&nbsp;'''''kyu''''' |bgcolor="#F3F5DE"|キョ&nbsp;'''''kyo''''' |-bgcolor="#E7F5DE" valign=top align="center" |サ&nbsp;'''''sa''''' |シ&nbsp;'''''shi''''' |ス&nbsp;'''''su''''' |セ&nbsp;'''''se''''' |ソ&nbsp;'''''so''''' |bgcolor="#F3F5DE"|シャ&nbsp;'''''sha''''' |bgcolor="#F3F5DE"|シュ&nbsp;'''''shu''''' |bgcolor="#F3F5DE"|ショ&nbsp;'''''sho''''' |-bgcolor="#E7F5DE" valign=top align="center" |タ&nbsp;'''''ta''''' |チ&nbsp;'''''chi''''' |ツ&nbsp;'''''tsu''''' |テ&nbsp;'''''te''''' |ト&nbsp;'''''to''''' |bgcolor="#F3F5DE"|チャ&nbsp;'''''cha''''' |bgcolor="#F3F5DE"|チュ&nbsp;'''''chu''''' |bgcolor="#F3F5DE"|チョ&nbsp;'''''cho''''' |-bgcolor="#E7F5DE" valign=top align="center" |ナ&nbsp;'''''na''''' |ニ&nbsp;'''''ni''''' |ヌ&nbsp;'''''nu''''' |ネ&nbsp;'''''ne''''' |ノ&nbsp;'''''no''''' |bgcolor="#F3F5DE"|ニャ&nbsp;'''''nya''''' |bgcolor="#F3F5DE"|ニュ&nbsp;'''''nyu''''' |bgcolor="#F3F5DE"|ニョ&nbsp;'''''nyo''''' |-bgcolor="#E7F5DE" valign=top align="center" |ハ&nbsp;'''''ha''''' |ヒ&nbsp;'''''hi''''' |フ&nbsp;'''''fu''''' |ヘ&nbsp;'''''he''''' |ホ&nbsp;'''''ho''''' |bgcolor="#F3F5DE"|ヒャ&nbsp;'''''hya''''' |bgcolor="#F3F5DE"|ヒュ&nbsp;'''''hyu''''' |bgcolor="#F3F5DE"|ヒョ&nbsp;'''''hyo''''' |-bgcolor="#E7F5DE" valign=top align="center" |マ&nbsp;'''''ma''''' |ミ&nbsp;'''''mi''''' |ム&nbsp;'''''mu''''' |メ&nbsp;'''''me''''' |モ&nbsp;'''''mo''''' |bgcolor="#F3F5DE"|ミャ&nbsp;'''''mya''''' |bgcolor="#F3F5DE"|ミュ&nbsp;'''''myu''''' |bgcolor="#F3F5DE"|ミョ&nbsp;'''''myo''''' |-bgcolor="#E7F5DE" valign=top align="center" |ヤ&nbsp;'''''ya''''' |bgcolor="#E9E9E9"| |ユ&nbsp;'''''yu''''' |bgcolor="#E9E9E9"| |ヨ&nbsp;'''''yo''''' |bgcolor="#E9E9E9" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |ラ&nbsp;'''''ra''''' |リ&nbsp;'''''ri''''' |ル&nbsp;'''''ru''''' |レ&nbsp;'''''re''''' |ロ&nbsp;'''''ro''''' |bgcolor="#F3F5DE"|リャ&nbsp;'''''rya''''' |bgcolor="#F3F5DE"|リュ&nbsp;'''''ryu''''' |bgcolor="#F3F5DE"|リョ&nbsp;'''''ryo''''' |-bgcolor="#E7F5DE" valign=top align="center" |ワ&nbsp;'''''wa''''' |<span style="color:red;">ヰ&nbsp;'''''wi'''''</span> |bgcolor="#E9E9E9"| |<span style="color:red;">ヱ&nbsp;'''''we'''''</span> |ヲ&nbsp;'''''wo''''' |bgcolor="#E9E9E9" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9" colspan="4"| |ン&nbsp;'''''n''''' |bgcolor="#E9E9E9" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |ガ&nbsp;'''''ga''''' |ギ&nbsp;'''''gi''''' |グ&nbsp;'''''gu''''' |ゲ&nbsp;'''''ge''''' |ゴ&nbsp;'''''go''''' |bgcolor="#F3F5DE"|ギャ&nbsp;'''''gya''''' |bgcolor="#F3F5DE"|ギュ&nbsp;'''''gyu''''' |bgcolor="#F3F5DE"|ギョ&nbsp;'''''gyo''''' |-bgcolor="#E7F5DE" valign=top align="center" |ザ&nbsp;'''''za''''' |ジ&nbsp;'''''ji''''' |ズ&nbsp;'''''zu''''' |ゼ&nbsp;'''''ze''''' |ゾ&nbsp;'''''zo''''' |bgcolor="#F3F5DE"|ジャ&nbsp;'''''ja''''' |bgcolor="#F3F5DE"|ジュ&nbsp;'''''ju''''' |bgcolor="#F3F5DE"|ジョ&nbsp;'''''jo''''' |-bgcolor="#E7F5DE" valign=top align="center" |ダ&nbsp;'''''da''''' |ヂ&nbsp;('''''ji''''') |ヅ&nbsp;('''''zu''''') |デ&nbsp;'''''de''''' |ド&nbsp;'''''do''''' |bgcolor="#F3F5DE"|ヂャ&nbsp;('''''ja''''') |bgcolor="#F3F5DE"|ヂュ&nbsp;('''''ju''''') |bgcolor="#F3F5DE"|ヂョ&nbsp;('''''jo''''') |-bgcolor="#E7F5DE" valign=top align="center" |バ&nbsp;'''''ba''''' |ビ&nbsp;'''''bi''''' |ブ&nbsp;'''''bu''''' |ベ&nbsp;'''''be''''' |ボ&nbsp;'''''bo''''' |bgcolor="#F3F5DE"|ビャ&nbsp;'''''bya''''' |bgcolor="#F3F5DE"|ビュ&nbsp;'''''byu''''' |bgcolor="#F3F5DE"|ビョ&nbsp;'''''byo''''' |-bgcolor="#E7F5DE" valign=top align="center" |パ&nbsp;'''''pa''''' |ピ&nbsp;'''''pi''''' |プ&nbsp;'''''pu''''' |ペ&nbsp;'''''pe''''' |ポ&nbsp;'''''po''''' |bgcolor="#F3F5DE"|ピャ&nbsp;'''''pya''''' |bgcolor="#F3F5DE"|ピュ&nbsp;'''''pyu''''' |bgcolor="#F3F5DE"|ピョ&nbsp;'''''pyo''''' |- |bgcolor="#FFFFFF" colspan="8"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9" colspan="3"| |イェ&nbsp;'''''ye''''' |bgcolor="#E9E9E9"| |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9"| |ウィ&nbsp;'''''wi''''' |bgcolor="#E9E9E9"| |ウェ&nbsp;'''''we''''' |ウォ&nbsp;'''''wo''''' |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |<span style="color:red;">ヷ&nbsp;'''''va'''''</span> |<span style="color:red;">ヸ&nbsp;'''''vi'''''</span> |bgcolor="#E9E9E9"| |<span style="color:red;">ヹ&nbsp;'''''ve'''''</span> |<span style="color:red;">ヺ&nbsp;'''''vo'''''</span> |-bgcolor="#E7F5DE" valign=top align="center" |ヴァ&nbsp;'''''va''''' |ヴィ&nbsp;'''''vi''''' |ヴ&nbsp;'''''vu''''' |ヴェ&nbsp;'''''ve''''' |ヴォ&nbsp;'''''vo''''' |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9" colspan="3"| |シェ&nbsp;'''''she''''' |bgcolor="#E9E9E9"| |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9" colspan="3"| |ジェ&nbsp;'''''je''''' |bgcolor="#E9E9E9"| |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9" colspan="3"| |チェ&nbsp;'''''che''''' |bgcolor="#E9E9E9"| |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9"| |ティ&nbsp;'''''ti''''' |トゥ&nbsp;'''''tu''''' |bgcolor="#E9E9E9" colspan="2"| |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9" colspan="2"| |テュ&nbsp;'''''tyu''''' |bgcolor="#E9E9E9" colspan="2"| |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9"| |ディ&nbsp;'''''di''''' |ドゥ&nbsp;'''''du''''' |bgcolor="#E9E9E9" colspan="2"| |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9" colspan="2"| |デュ&nbsp;'''''dyu''''' |bgcolor="#E9E9E9" colspan="2"| |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |ツァ&nbsp;'''''tsa''''' |ツィ&nbsp;'''''tsi''''' |bgcolor="#E9E9E9"| |ツェ&nbsp;'''''tse''''' |ツォ&nbsp;'''''tso''''' |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |ファ&nbsp;'''''fa''''' |フィ&nbsp;'''''fi''''' |bgcolor="#E9E9E9"| |フェ&nbsp;'''''fe''''' |フォ&nbsp;'''''fo''''' |bgcolor="#FFFFFF" colspan="3"| |-bgcolor="#E7F5DE" valign=top align="center" |bgcolor="#E9E9E9" colspan="2"| |フュ&nbsp;'''''fyu''''' |bgcolor="#E9E9E9" colspan="2"| |bgcolor="#FFFFFF" colspan="3"| |} {{veşêre-bin}} ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W|en|Katakana}} {{werger-bin}} cjouu4kvymx2cbbnfqv4kg1k12hqa2w kîndar 0 41453 6334083 6134760 2026-08-16T08:05:09Z Keyomerd 8814 /* Rengdêr */ 6334083 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|kîndar}} {{rengdêr|ku}} # [[bikîn]], [[kînewer]], [[har]], [[hêrs]], [[hêç]], [[qehirî]], [[qehirandî]], [[enirî]], [[enirandî]], [[kerbdar]], [[girrek]] #* {{bêmînak|ku}} # {{kontrol|rêz=erê|[[bikerb]]}} ==== Bi alfabeyên din ==== * {{ku-ar|كیندار}} ==== Dijmane ==== * {{g|ku|bêkîn}} ==== Jê ==== * {{g|ku|kîndarî}} ==== Etîmolojî ==== Ji {{paş|ku|kîn|-dar}}. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|gehässig}}, {{W|de|rachsüchtig}} * {{Z|ar}}: {{W|ar|الحقود}}, {{W|ar|الشنآن}}, {{W|ar|الضاغن}}, {{W|ar|القالي|guman=erê}}, {{W|ar|حاقد|guman=erê}}, {{W|ar|مضطغن|guman=erê}} * {{Z|fa}}: {{W|fa|کینه توز}}, {{W|fa|انتقام گیرنده}}, {{W|fa|کینه توز}} * {{Z|en}}: {{W|en|ferocious}}, {{W|en|furious}}, {{W|en|detester}}, {{W|en|malevolent}}, {{W|en|blasted|guman=erê}}, {{W|en|despiteous|guman=erê}}, {{W|en|fulsome|guman=erê}}, {{W|en|malicious|guman=erê}}, {{W|en|noxious|guman=erê}}, {{W|en|spiteful|guman=erê}}, {{W|en|spleenful|guman=erê}}, {{W|en|spleenish|guman=erê}}, {{W|en|stigmatic|guman=erê}}, {{W|en|ungracious|guman=erê}}, {{W|en|vindictive|guman=erê}}, {{W|en|hateful|guman=erê}}, {{W|en|ill-wisher|guman=erê}}, {{W|en|loathsome|guman=erê}}, {{W|en|maleficent|guman=erê}}, {{W|en|unlovely|guman=erê}}, {{W|en|unpalatable|guman=erê}}, {{W|en|unsavoury|guman=erê}} * {{Z|tr}}: {{W|tr|azgın}}, {{W|tr|azılı}}, {{W|tr|garazlı}}, {{W|tr|hınçlı}}, {{W|tr|kinci}}, {{W|tr|kindar}}, {{W|tr|kinli}} {{werger-bin}} clctatp0dser56k9ey7ox0j0cjvl5v9 menber 0 45844 6334003 6311932 2026-08-16T01:06:27Z Wikihez 7344 /* Pirrjimar */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334003 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # li [[mizgeft]]an [[cih]]ê [[bilind]] yê ku [[mela]] jê [[weiz]] dide #* {{jêder-pirtûk|ku|jêgirtin=Dînek afirand ji [[înkar]]ê<br> Bi [[secde]] û [[mihrab]] û [[menber]]<br> [[red|Redda]] Xweda û pêxemberan kir<br> Reddê kir [[xweda|xwede]], xwe kir pêxember|nivîskar=Rojen Barnas|sernav=Milkê Evînê|cîh=Stockholm|weşanxane=Nûdem|sal=1995|rûpel=18|isbn=91 88592-146}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|مەنبەر}} ==== Hevmane ==== * [[mînber]] ==== Bide ber ==== * [[mihrab]] ==== Têkildar ==== * [[menabir]] ==== Etîmolojî ==== Ji {{ji|ar|ku|منبر}}. ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W|ar|منبر}} * {{Z|en}}: {{W|en|platform}} * {{Z|tr}}: {{W+|tr|menber}} {{werger-bin}} 57obt1hkuamxeb5fqt8be44t3xj1uak 6334004 6334003 2026-08-16T01:07:02Z Wikihez 7344 6334004 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # li [[mizgeft]]an [[cih]]ê [[bilind]] yê ku [[mela]] jê [[weiz]] dide #* {{jêder-pirtûk|ku|jêgirtin=Dînek afirand ji înkarê<br> Bi secde û mihrab û menber<br> Redda Xweda û pêxemberan kir<br> Reddê kir xwede, xwe kir pêxember|nivîskar=Rojen Barnas|sernav=Milkê Evînê|cîh=Stockholm|weşanxane=Nûdem|sal=1995|rûpel=18|isbn=91 88592-146}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|مەنبەر}} ==== Hevmane ==== * [[mînber]] ==== Bide ber ==== * [[mihrab]] ==== Têkildar ==== * [[menabir]] ==== Etîmolojî ==== Ji {{ji|ar|ku|منبر}}. ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W|ar|منبر}} * {{Z|en}}: {{W|en|platform}} * {{Z|tr}}: {{W+|tr|menber}} {{werger-bin}} f1bpn36ffjot6ac8nf9c5xc959lb90f 6334033 6334004 2026-08-16T01:41:27Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6334033 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # li [[mizgeft]]an [[cih]]ê [[bilind]] yê ku [[mela]] jê [[weiz]] dide #* {{jêder-pirtûk|ku|jêgirtin=Dînek afirand ji înkarê<br> Bi secde û mihrab û menber<br> Redda Xweda û pêxemberan kir<br> Reddê kir xwede, xwe kir pêxember|nivîskar=Rojen Barnas|sernav=Milkê Evînê|cîh=Stockholm|weşanxane=Nûdem|sal=1995|rûpel=18|isbn=91 88592-146}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|مەنبەر}} ==== Hevmane ==== * [[mînber]] ==== Têkildar ==== * [[menabir]] ==== Etîmolojî ==== Ji {{ji|ar|ku|منبر}}. ==== Bide ber ==== * [[mihrab]] ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W|ar|منبر}} * {{Z|en}}: {{W|en|platform}} * {{Z|tr}}: {{W+|tr|menber}} {{werger-bin}} cztd91h4sa3pgih5nigjgm452k9bjej diyod 0 47556 6333937 6305474 2026-08-15T23:14:58Z Wikihez 7344 /* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333937 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[têl]]ek [[karebayî]] ye ku [[enerjî]] tê re ji tiştekî [[herikîn|diherrike]] yek din #* {{jêder|ku|jêgirtin=Ridvan ji xwe re dike armanc ku pîlek peyda bike bi enrjîya hereketê bixebite û ji bo vê yekê jî '''diyot''' û têlên sifir bikaranîye. Wî gelek têl(500 lef) bikaranîye ku dema werin hejandin enerjîyek derê holê. Ev enerjîya ji hejandinê dertê bi wasiteya diyotan pîlê şarj dike û her cara ku pîl vala dibe bi hejandinê careka din tije dibe.|Netkurd.com, 12/3007}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * [[diyot]] ==== Têkildar ==== * [[triyod]] * [[pentod]] === Rastnivîsî === Forma rast ya nivîsîna vê peyvê bi kurdî ''diyod'' e, ne ''diyot''. Bi tirkî ''diyot'' e ji ber ku di wî zimanî de herfa ''d'' bi gelemperî nayê dawiya peyvê. ==== Etîmolojî ==== Bi rêya fransî yan îngilîzî [[diode]] ji yûnaniya kevn ''odos'' ([[rê]], [[rêk]]). ==== Jê ==== * [[diyodî]] ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|diode}} * {{Z|bg}}: {{W|bg|диод}} * {{Z|cs}}: {{W|cs|dioda}} * {{Z|zh}}: {{W|zh|二極體}} * {{Z|da}}: {{W|da|diode}} * {{Z|id}}: {{W|id|dioda}} * {{Z|ar}}: {{W|ar|صمام ثنائي}} * {{Z|eo}}: {{W|eo|diodo}} * {{Z|et}}: {{W|et|pooljuhtdiood}} * {{Z|fi}}: {{W|fi|diodi}} * {{Z|fr}}: {{W|fr|diode}} * {{Z|nl}}: {{W|nl|diode}} * {{Z|he}}: {{W|he|דיודה}} * {{Z|io}}: {{W|io|diodo}} * {{Z|en}}: {{W|en|diode}} * {{Z|it}}: {{W|it|diodo}} * {{Z|ja}}: {{W|ja|ダイオード}} * {{Z|ca}}: {{W|ca|díode}} * {{Z|ko}}: {{W|ko|다이오드}} * {{Z|la}}: {{W|la|diodus}} * {{Z|lt}}: {{W|lt|puslaidininkis diodas}} * {{Z|ms}}: {{W|ms|diod}} * {{Z|hu}}: {{W|hu|dióda}} * {{Z|nds}}: {{W|nds|diode}} * {{Z|nn}}: {{W|nn|diode}} * {{Z|no}}: {{W|no|diode}} * {{Z|pl}}: {{W|pl|dioda}} * {{Z|pt}}: {{W|pt|díodo}} (semicondutor) * {{Z|ro}}: {{W|ro|diodă}} * {{Z|ru}}: {{W|ru|диод}} * {{Z|sh}}: {{W|sh|dioda}} * {{Z|sh}}: {{W|sh|диода}} * {{Z|sl}}: {{W|sl|dioda}} * {{Z|es}}: {{W|es|diodo}} * {{Z|sv}}: {{W|sv|diod}} * {{Z|ta}}: {{W|ta|இருமுனையம்}} * {{Z|th}}: {{W|th|ไดโอด}} * {{Z|tr}}: {{W|tr|diyot}} * {{Z|uk}}: {{W|uk|діод}} {{werger-bin}} el27g7qraxz0b8kje8ehm9i08rtuydv 6333938 6333937 2026-08-15T23:15:17Z Wikihez 7344 /* Rastnivîsî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333938 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[têl]]ek [[karebayî]] ye ku [[enerjî]] tê re ji tiştekî [[herikîn|diherrike]] yek din #* {{jêder|ku|jêgirtin=Ridvan ji xwe re dike armanc ku pîlek peyda bike bi enrjîya hereketê bixebite û ji bo vê yekê jî '''diyot''' û têlên sifir bikaranîye. Wî gelek têl(500 lef) bikaranîye ku dema werin hejandin enerjîyek derê holê. Ev enerjîya ji hejandinê dertê bi wasiteya diyotan pîlê şarj dike û her cara ku pîl vala dibe bi hejandinê careka din tije dibe.|Netkurd.com, 12/3007}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * [[diyot]] ==== Têkildar ==== * [[triyod]] * [[pentod]] ==== Bikaranîn ==== Forma rast ya nivîsîna vê peyvê bi kurdî ''diyod'' e, ne ''diyot''. Bi tirkî ''diyot'' e ji ber ku di wî zimanî de herfa ''d'' bi gelemperî nayê dawiya peyvê. ==== Etîmolojî ==== Bi rêya fransî yan îngilîzî [[diode]] ji yûnaniya kevn ''odos'' ([[rê]], [[rêk]]). ==== Jê ==== * [[diyodî]] ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|diode}} * {{Z|bg}}: {{W|bg|диод}} * {{Z|cs}}: {{W|cs|dioda}} * {{Z|zh}}: {{W|zh|二極體}} * {{Z|da}}: {{W|da|diode}} * {{Z|id}}: {{W|id|dioda}} * {{Z|ar}}: {{W|ar|صمام ثنائي}} * {{Z|eo}}: {{W|eo|diodo}} * {{Z|et}}: {{W|et|pooljuhtdiood}} * {{Z|fi}}: {{W|fi|diodi}} * {{Z|fr}}: {{W|fr|diode}} * {{Z|nl}}: {{W|nl|diode}} * {{Z|he}}: {{W|he|דיודה}} * {{Z|io}}: {{W|io|diodo}} * {{Z|en}}: {{W|en|diode}} * {{Z|it}}: {{W|it|diodo}} * {{Z|ja}}: {{W|ja|ダイオード}} * {{Z|ca}}: {{W|ca|díode}} * {{Z|ko}}: {{W|ko|다이오드}} * {{Z|la}}: {{W|la|diodus}} * {{Z|lt}}: {{W|lt|puslaidininkis diodas}} * {{Z|ms}}: {{W|ms|diod}} * {{Z|hu}}: {{W|hu|dióda}} * {{Z|nds}}: {{W|nds|diode}} * {{Z|nn}}: {{W|nn|diode}} * {{Z|no}}: {{W|no|diode}} * {{Z|pl}}: {{W|pl|dioda}} * {{Z|pt}}: {{W|pt|díodo}} (semicondutor) * {{Z|ro}}: {{W|ro|diodă}} * {{Z|ru}}: {{W|ru|диод}} * {{Z|sh}}: {{W|sh|dioda}} * {{Z|sh}}: {{W|sh|диода}} * {{Z|sl}}: {{W|sl|dioda}} * {{Z|es}}: {{W|es|diodo}} * {{Z|sv}}: {{W|sv|diod}} * {{Z|ta}}: {{W|ta|இருமுனையம்}} * {{Z|th}}: {{W|th|ไดโอด}} * {{Z|tr}}: {{W|tr|diyot}} * {{Z|uk}}: {{W|uk|діод}} {{werger-bin}} 4qhm5g4l5ljk0fc4i8635sfdklpw2d5 6333977 6333938 2026-08-15T23:41:38Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333977 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[têl]]ek [[karebayî]] ye ku [[enerjî]] tê re ji tiştekî [[herikîn|diherrike]] yek din #* {{jêder|ku|jêgirtin=Ridvan ji xwe re dike armanc ku pîlek peyda bike bi enrjîya hereketê bixebite û ji bo vê yekê jî '''diyot''' û têlên sifir bikaranîye. Wî gelek têl(500 lef) bikaranîye ku dema werin hejandin enerjîyek derê holê. Ev enerjîya ji hejandinê dertê bi wasiteya diyotan pîlê şarj dike û her cara ku pîl vala dibe bi hejandinê careka din tije dibe.|Netkurd.com, 12/3007}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Notên bikaranînê ==== Forma rast ya nivîsîna vê peyvê bi kurdî ''diyod'' e, ne ''diyot''. Bi tirkî ''diyot'' e ji ber ku di wî zimanî de herfa ''d'' bi gelemperî nayê dawiya peyvê. ==== Formên alternatîv ==== * [[diyot]] ==== Jê ==== * [[diyodî]] ==== Têkildar ==== * [[triyod]] * [[pentod]] ==== Etîmolojî ==== Bi rêya fransî yan îngilîzî [[diode]] ji yûnaniya kevn ''odos'' ([[rê]], [[rêk]]). ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|diode}} * {{Z|bg}}: {{W|bg|диод}} * {{Z|cs}}: {{W|cs|dioda}} * {{Z|zh}}: {{W|zh|二極體}} * {{Z|da}}: {{W|da|diode}} * {{Z|id}}: {{W|id|dioda}} * {{Z|ar}}: {{W|ar|صمام ثنائي}} * {{Z|eo}}: {{W|eo|diodo}} * {{Z|et}}: {{W|et|pooljuhtdiood}} * {{Z|fi}}: {{W|fi|diodi}} * {{Z|fr}}: {{W|fr|diode}} * {{Z|nl}}: {{W|nl|diode}} * {{Z|he}}: {{W|he|דיודה}} * {{Z|io}}: {{W|io|diodo}} * {{Z|en}}: {{W|en|diode}} * {{Z|it}}: {{W|it|diodo}} * {{Z|ja}}: {{W|ja|ダイオード}} * {{Z|ca}}: {{W|ca|díode}} * {{Z|ko}}: {{W|ko|다이오드}} * {{Z|la}}: {{W|la|diodus}} * {{Z|lt}}: {{W|lt|puslaidininkis diodas}} * {{Z|ms}}: {{W|ms|diod}} * {{Z|hu}}: {{W|hu|dióda}} * {{Z|nds}}: {{W|nds|diode}} * {{Z|nn}}: {{W|nn|diode}} * {{Z|no}}: {{W|no|diode}} * {{Z|pl}}: {{W|pl|dioda}} * {{Z|pt}}: {{W|pt|díodo}} (semicondutor) * {{Z|ro}}: {{W|ro|diodă}} * {{Z|ru}}: {{W|ru|диод}} * {{Z|sh}}: {{W|sh|dioda}} * {{Z|sh}}: {{W|sh|диода}} * {{Z|sl}}: {{W|sl|dioda}} * {{Z|es}}: {{W|es|diodo}} * {{Z|sv}}: {{W|sv|diod}} * {{Z|ta}}: {{W|ta|இருமுனையம்}} * {{Z|th}}: {{W|th|ไดโอด}} * {{Z|tr}}: {{W|tr|diyot}} * {{Z|uk}}: {{W|uk|діод}} {{werger-bin}} 1n85m1wgdg0tki1muq1viib31ar3i0o veniştin 0 48237 6334073 6288961 2026-08-16T06:45:30Z ~2026-44707-21 15258 +nimûneya bikaranînê bi amûra « [[Mediawiki:Gadget-wikt.add-examples|Nimûne zêde bike]] » (v1.7). 6334073 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{kîte|ku|ve|niş|tin}} === Lêker === {{lêker|ku|c=x-ngh}} # Bi ser derekê ve vegirtin û li ser danîn, [[li ser rûniştin]]. #* {{jêder|ku|jêgirtin=Min dizanibû ku ew dê bi kêfxweşî were nik min '''venişe''' û ava xwe vexwe, qûta xwe bixwe.|{{Jêgirtin/Mehmed Uzun/Mirina Kalekî Rind/1987}}}} #* {{jêder-kitêb|ku|nivîskar=Mehmed Uzun|sernav=Siya Evînê|weşanxane=İthaki|cih=İstanbul|sala-weşandinê=2005|isbn=975-273-098-1|jêgirtin=Bellê, ew jin bû ku wan ê silav lê bikirina û li ser milên wê '''veniştina'''.}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|landen|guman=erê}}, {{W+|de|setzen|guman=erê}}, {{W-|de|sich niederlassen|guman=erê}}, {{W+|de|Abscheidung|guman=erê}}, {{W-|de|Ausfällung|guman=erê}}, {{W+|de|Sitz|guman=erê}} * {{Z|fa}}: {{W+|fa|فرود آمدن|guman=erê}}, {{W+|fa|قرار گرفتن|guman=erê}} * {{Z|en}}: {{W+|en|berth|guman=erê}}, {{W+|en|coming down|guman=erê}} * {{Z|tr}}: {{W+|tr|konmak|guman=erê}}, {{W-|tr|menzil tutmak|guman=erê}}, {{W+|tr|tüneklemek|guman=erê}}, {{W+|tr|tünemek|guman=erê}}, {{W+|tr|konma|guman=erê}}, {{W+|tr|konuş|guman=erê}}, {{W+|tr|tünekleme|guman=erê}}, {{W+|tr|tüneme|guman=erê}} {{werger-bin}} nx4zy1wnvpfvseeylni1uhtm4jjatun mêvanname 0 48482 6334008 6312780 2026-08-16T01:10:30Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6334008 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[defter]]a ku [[mêvan]] yan [[bikarîner]] [[nav]] û / yan [[nerîn]]ên xwe lê [[nivîsîn|dinivîsin]] #* {{bêmînak|ku}} # {{f|ku|internet}} [[rûpel]]ê ku [[mêvan]] [[nerîn]]ên xwe lê [[nivîsîn|dinivîsin]] #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê|guherto=hemû}} ==== Formên alternatîv ==== * {{g|ku|mêhvanname}} * {{g|ku|mihvanname}} * {{g|ku|mîvanname}} ==== Etîmolojî ==== Ji {{qertaf|ku|mêvan|-name}}. ==== Bi zaravayên din ==== * {{Z|ckb}}: {{W-|ckb|mîwanname}} ==== Werger ==== {{werger-ser}} * {{Z|fi}}: {{W+|fi|vieraskirja}} * {{Z|fr}}: {{W+|fr|livre d'or}} * {{Z|en}}: {{W+|en|guest book}}, {{W+|en|guestbook}} * {{Z|el}}: {{W+|el|βιβλίο επισκεπτών}} {{werger-bin}} hu7i1qbji5h5vq46gibtjja9g5s23z5 Gotûbêja bikarhêner:Rojhilat 3 48815 6333945 6013302 2026-08-15T23:23:28Z Wikihez 7344 [[Bikarhêner:Wikihez/skrîpt/js/şablon-lêke.js|T]]: Agahdarkirin: [[goganîbûnî]] 6333945 wikitext text/x-wiki Hêja Rojhilat, gelek spas bo alîkariya te. Peyvên ku cenabê te li ferhengê zêde dike, pirr bikêrhatî ne. Herçi peyvên "têgih" û "têgeh" in, bi baweriya min herdu jî rast in. Tercihkirina yekê ji herduyan teqrîben karek keyfî ye. Lê ji neçarî me yek bijartiye. Eger hin sedemên zimannasî hebin ku "têgeh"ê ji "têgih"ê rasttir biselmînin, em dê "têgeh"ê bikin peyva serekî. Ez ne dijî guherandinê me. --[[Bikarhêner:Ferhengvan|Ferhengvan]] 20:52, 5 reşemî 2008 (UTC) zor sipas ji bo xebatê te --[[Bikarhêner:Ciwan|Ciwan]] 06:38, 13 pûşper 2008 (UTC) ==Peyvên xwestî== Rojhilatê hêja! Pirr spas bo xebata te li ser Wîkîferhengê. Niha min lîsteyek peyvên xwestî amade kiriye ku divê em di ferhengê de ji her peyvekê ji wan re rûpelekê çêkin. Eger hin peyv hebin ku tu jî dixwazî li ferhengê bên zêdekirin, dikarî li ser wê rûpelê zêde bikî. Lîste ev e: '''[[Wîkîferheng:Xwestin/kurdî|Xwestin]]''' Herdem di xweşî û şadiyan de be! --[[Bikarhêner:Ferhengvan|Ferhengvan]] 07:45, 17 tebax 2009 (UTC) == interwikilinks == selav heval ew interwilik ê ku bi peyva ve girêdidî, nînin.[[Bikarhêner:George Animal|George Animal²²]] 22:02, 1 sermawez 2010 (UTC) ==Heman format== Hevalê hêja, gelek spas bo alîkariya te. Lê rica dikim ku tu jî mîna me hemiyan eynî formata/dirûvê/şiklê rûpelan ava bikî: Li destpêkê navê ZIMAN, paşî WATE, paşî HERWIHA (eger çend awayên heman peyvê hebin), paşî JI (peyv ji çi peyvan çêbûye), paşî JÊ (peyvên ku ji wê peyvê peyda bûne), paşî WERGERR bi zimanên din. Diyarkirina awayê "JIHEVKETANDIN"a peyvan di ferhengê de ne pêwîst e ji ber ku di kurmancî de kitandina gelek hêsan û rêgezî ye (li gor qaydeyên diyar e). Herwiha mixabin tu IPA şaş bi kar tînî. Silavên ji dilê min --[[Bikarhêner:Ferhengvan|Ferhengvan]] 12:49, 4 sermawez 2010 (UTC) ==Spasî== Gelek spas bo sererastkirina wateya [[çukur]]ê. --[[Bikarhêner:Ferhengvan|Ferhengvan]] <small>([[User talk:Ferhengvan|Nîqaş]])</small> 05:53, 3 tebax 2011 (UTC) == Şablonên nû == :Silav Rojhilat, :gelek spas ji bo beşdariya te; min [http://ku.wiktionary.org/wiki/%C5%9Eablon:%C5%9EablonaDir%C3%BBv%C3%AA_Biw%C3%AAj ] şablonek ji biwêjê afirinad û min niha şablonek ji bo gotina pêşiyan afirand, lê belê gotar '''gotina pêşiyan''' niha nehtiye girêdan, tu dikarî wê gotarê biafirînî?--Silav[[Bikarhêner:George Animal|ζΞ∀Ω]] <small>([[User talk:George Animal|Nîqaş]])</small> 16:07, 30 kewçêr 2011 (UTC) ---- :Silav Rojhilat :min niha peyamek ji e-nameya te re shand, tu dikarî bersivê bidî?-spas --[[Bikarhêner:George Animal|George Animal]] ([[Gotûbêja bikarhêner:George Animal|gotûbêj]]) 18:11, 17 pûşper 2013 (UTC) :Tu dikarî li e-nameya xwe binêrî, ezê peyamekê ji te re bişînim.Silav--[[Bikarhêner:George Animal|George Animal]] ([[Gotûbêja bikarhêner:George Animal|gotûbêj]]) 08:25, 23 pûşper 2013 (UTC) == Global account == Hi Rojhilat! As a [[:m:Stewards|Steward]] I'm involved in the upcoming [[:m:Help:Unified login|unification]] of all accounts organized by the Wikimedia Foundation (see [[:m:Single User Login finalisation announcement]]). By looking at [[Special:CentralAuth/Rojhilat|your account]], I realized that you don't have a global account yet. In order to secure your name, I recommend you to create such account on your own by submitting your password on [[Special:MergeAccount]] and unifying your local accounts. If you have any problems with doing that or further questions, please don't hesitate to contact me on my [[User talk:DerHexer|talk page]]. Cheers, [[Bikarhêner:DerHexer|DerHexer]] ([[Gotûbêja bikarhêner:DerHexer|gotûbêj]]) 22:02, 16 rêbendan 2015 (UTC) == GFDL == Hi! I noticed that you have uploaded a file with the license GFDL [[:Wêne:şepeluk.JPG]]. However the license GFDL have disclaimers (Ji bo devjêberdana mafên xwedîtiyê [[:en:w:Wikipedia:general disclaimer|li vir]] binêre.) Disclaimers should not be used per [[:w:en:Wikipedia:GFDL standardization]]. So I would like to hear if you would remove the disclaimers? --[[Bikarhêner:MGA73|MGA73]] ([[Gotûbêja bikarhêner:MGA73|gotûbêj]]) 17:09, 24 tîrmeh 2024 (UTC) == [[goganîbûnî]] == Merheba @[[Bikarhêner:Rojhilat|Rojhilat]], di madeya [[goganîbûnî]] de çavkanî hewce ye. 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) ontqlpwjlns5k7prtovrlz5t3jf53ve dey 0 48958 6333935 6305190 2026-08-15T23:13:18Z Wikihez 7344 /* Binere */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333935 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # Ew [[giya]]yê hişk yan şîn yan jî pûşê li ser hev hatiye dayîn û dewisandin. Komika pûş û [[giyha]] #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ====Herwiha binêre ==== * [[deya pûş]] * [[lod]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|ot yığını}} {{werger-bin}} 272db2xhy9vq583jp02wrfzv7dxhoea 6333978 6333935 2026-08-15T23:41:41Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333978 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # Ew [[giya]]yê hişk yan şîn yan jî pûşê li ser hev hatiye dayîn û dewisandin. Komika pûş û [[giyha]] #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ====Herwiha binêre ==== * [[deya pûş]] * [[lod]] ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|ot yığını}} {{werger-bin}} notjlk5ntz3d6b5psbf3jke4mrcndrg kirtîn 0 48973 6333988 6310231 2026-08-16T00:53:08Z Wikihez 7344 /* Binere */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333988 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # Dengê "kirt" #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} === Herwiha binêre === * [[kirt]] * [[kirtînî]] * [[kirtînî jê anîn]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|tıkırdama}}, {{W+|tr|kütürdemek}}, {{W|tr|çıtırdama|guman=erê}}, {{W|tr|kakırdama|guman=erê}}, {{W|tr|kütürdeme|guman=erê}}, {{W|tr|çıtırdamak|guman=erê}}, {{W|tr|kakırdamak|guman=erê}} {{werger-bin}} hywmszx986izsjjcrzjzewjiotbcash 6334063 6333988 2026-08-16T02:17:17Z Wikihez 7344 /* Herwiha binêre */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334063 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # Dengê "kirt" #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Herwiha binêre ==== * [[kirt]] * [[kirtînî]] * [[kirtînî jê anîn]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|tıkırdama}}, {{W+|tr|kütürdemek}}, {{W|tr|çıtırdama|guman=erê}}, {{W|tr|kakırdama|guman=erê}}, {{W|tr|kütürdeme|guman=erê}}, {{W|tr|çıtırdamak|guman=erê}}, {{W|tr|kakırdamak|guman=erê}} {{werger-bin}} djelff8shiczmtlt5kad1c3x5zdgnzl 6334064 6334063 2026-08-16T02:41:07Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6334064 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # Dengê "kirt" #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Herwiha binêre ==== * [[kirt]] * [[kirtînî]] * [[kirtînî jê anîn]] ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|tıkırdama}}, {{W+|tr|kütürdemek}}, {{W|tr|çıtırdama|guman=erê}}, {{W|tr|kakırdama|guman=erê}}, {{W|tr|kütürdeme|guman=erê}}, {{W|tr|çıtırdamak|guman=erê}}, {{W|tr|kakırdamak|guman=erê}} {{werger-bin}} jmo1g1mos7rucom8fstwwm0tjw8878f kirtînî 0 48974 6333991 6310233 2026-08-16T00:58:11Z Wikihez 7344 /* Binere */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333991 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # navê dengê "kirtîn" #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Binêre herwiha ==== * [[kirt]] * [[kirtîn]] * [[kirtînî jê anîn]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|tıkırtı}} {{werger-bin}} g9a06vothpnj9gkae32l6h3so1auoj9 6334036 6333991 2026-08-16T01:41:36Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6334036 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # navê dengê "kirtîn" #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Herwiha binêre ==== * [[kirt]] * [[kirtîn]] * [[kirtînî jê anîn]] ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|tıkırtı}} {{werger-bin}} b1fg0u4z635xgc3u7ypz6uga343r8gh nexwendewarî 0 49923 6334012 6313332 2026-08-16T01:14:19Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6334012 wikitext text/x-wiki == {{ziman|ku}} == === Navdêr === {{navdêr|ku|z=m}} # Ne[[zanîn]] [[xwendin|bixwîne]] û [[nivîsîn|binivîse]]. #: {{hevmane|ku|bêsewadî|cahilî|cehalet|nezanî}} #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * {{g|ku|nexwandewarî}} * {{g|ku|nexandewarî}} ==== Etîmolojî ==== Ji {{paş|ku|nexwendewar|-î}}. ==== Bi zaravayên din ==== * {{Z|ckb}}: {{W-|ckb|nexwêndewarî}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Analphabetismus|m}} * {{Z|cs}}: {{W-|cs|negramotnost|f}} * {{Z|fi}}: {{W+|fi|lukutaidottomuus}} * {{Z|en}}: {{W+|en|illiteracy}}, {{W+|en|analphabetism}} * {{Z|es}}: {{W+|es|analfabetismo|m}} * {{Z|sv}}: {{W+|sv|analfabetism|c}} {{werger-bin}} h5m1166g59vki9e0d4s3f9sank62wvn pandemî 0 49982 6334022 6313913 2026-08-16T01:20:39Z Wikihez 7344 /* Binêre herwiha */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334022 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[êş]]a [[berbelav]] ya ku li gelek [[der]]an [[peyda]] bûye #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Têkildar ==== * [[epîdemî]] ==== Binêre herwiha ==== * [[endemî]] ==== Etîmolojî ==== Ji yewnaniya kevn [[pan-]] + [[δῆμος]] ==== Jê ==== * [[pandemîk]] * [[pandemînas]] * [[pandemînasî]] * [[pandemyolog]] * [[pandemyolojî]] ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Pandemie|f}} * {{Z|fi}}: {{W+|fi|pandemia}} * {{Z|fr}}: {{W+|fr|pandémie|f}} * {{Z|en}}: [[pandemic]] (disease) * {{Z|no}}: {{W-|no|pandemi}} * {{Z|sv}}: {{W+|sv|pandemi}} * {{Z|tr}}: {{W+|tr|epidemi}} {{werger-bin}} nez3slihqlbdczkec1m1d7zzs5k1qvs 6334027 6334022 2026-08-16T01:41:09Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6334027 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[êş]]a [[berbelav]] ya ku li gelek [[der]]an [[peyda]] bûye #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Jê ==== * [[pandemîk]] * [[pandemînas]] * [[pandemînasî]] * [[pandemyolog]] * [[pandemyolojî]] ==== Têkildar ==== * [[epîdemî]] ==== Etîmolojî ==== Ji yewnaniya kevn [[pan-]] + [[δῆμος]] ==== Herwiha binêre ==== * [[endemî]] ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Pandemie|f}} * {{Z|fi}}: {{W+|fi|pandemia}} * {{Z|fr}}: {{W+|fr|pandémie|f}} * {{Z|en}}: [[pandemic]] (disease) * {{Z|no}}: {{W-|no|pandemi}} * {{Z|sv}}: {{W+|sv|pandemi}} * {{Z|tr}}: {{W+|tr|epidemi}} {{werger-bin}} fn8u2byh8kyy8yvzj1df1polapi1ksa mêkut 0 50025 6334006 6312750 2026-08-16T01:08:46Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334006 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[çekûç]], amûrek serikreq e û bi taybetî bo kutana bizmaran têt bikaranîn #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== {{ji?}} === Bi alfabeyên din === * {{ku-ar|مێکوت}} ==== Werger ==== {{werger-ser}} * {{Z|af}}: {{W+|af|hamer}} * {{Z|sq}}: {{W+|sq|çekan}} * {{Z|de}}: {{W|de|Hammer|m}}, {{W+|de|Holzhammer}} * {{Z|eu}}: {{W+|eu|mailu}} * {{Z|br}}: {{W+|br|morzhol}} * {{Z|da}}: {{W+|da|hammer}} * {{Z|eo}}: {{W+|eo|martelo}} * {{Z|et}}: {{W+|et|haamer}} * {{Z|fa}}: {{W+|fa|پتک}}, {{W+|fa|پتک چوبی}} * {{Z|fi}}: {{W+|fi|vasara}} * {{Z|fr}}: {{W|fr|marteau|m}} * {{Z|gl}}: {{W+|gl|martelo}} * {{Z|nl}}: {{W|nl|hamer|m}} * {{Z|en}}: {{W+|en|hammer}}, {{W+|en|beetle}}, {{W|en|pounder|guman=erê}} * {{Z|ga}}: {{W+|ga|casúr}} * {{Z|it}}: {{W|it|martello|m}} * {{Z|is}}: {{W+|is|hamar}} * {{Z|ca}}: {{W+|ca|martell}} * {{Z|la}}: {{W+|la|martellus}} * {{Z|hu}}: {{W+|hu|kalapács}} * {{Z|no}}: {{W+|no|hammer}} * {{Z|pap}}: {{W+|pap|martin}} * {{Z|pl}}: {{W+|pl|młotek}} * {{Z|pt}}: {{W+|pt|martelo}} * {{Z|ro}}: {{W+|ro|ciocan}} * {{Z|ru}}: {{W+|ru|молот}} * {{Z|sh}}: {{W+|sh|čekić}} * {{Z|sk}}: {{W+|sk|búchat}} * {{Z|es}}: {{W|es|martillo|m}} * {{Z|sw}}: {{W+|sw|nyundo}} * {{Z|sv}}: {{W+|sv|hammare}} * {{Z|tr}}: {{W+|tr|çekiç}}, {{W+|tr|tokmak}} * {{Z|cy}}: {{W+|cy|morthwyl}} {{werger-bin}} 27yaypzixxkukn5lrbnba3zd9p4wzjr 6334007 6334006 2026-08-16T01:10:00Z Wikihez 7344 /* {{ziman|ku}} */ [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6334007 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[amûr|Amûrek]] [[serikreq|serikreq]] e û [[bi taybetî]] bo [[kutan|kutan]]a [[bizmar|bizmaran]] [[têt|têt]] [[bikaranîn|bikaranîn]]. #: {{hevmane|ku|çekûç}} #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== {{ji?}} ==== Bi alfabeyên din ==== * {{ku-ar|مێکوت}} ==== Werger ==== {{werger-ser}} * {{Z|af}}: {{W+|af|hamer}} * {{Z|sq}}: {{W+|sq|çekan}} * {{Z|de}}: {{W|de|Hammer|m}}, {{W+|de|Holzhammer}} * {{Z|eu}}: {{W+|eu|mailu}} * {{Z|br}}: {{W+|br|morzhol}} * {{Z|da}}: {{W+|da|hammer}} * {{Z|eo}}: {{W+|eo|martelo}} * {{Z|et}}: {{W+|et|haamer}} * {{Z|fa}}: {{W+|fa|پتک}}, {{W+|fa|پتک چوبی}} * {{Z|fi}}: {{W+|fi|vasara}} * {{Z|fr}}: {{W|fr|marteau|m}} * {{Z|gl}}: {{W+|gl|martelo}} * {{Z|nl}}: {{W|nl|hamer|m}} * {{Z|en}}: {{W+|en|hammer}}, {{W+|en|beetle}}, {{W|en|pounder|guman=erê}} * {{Z|ga}}: {{W+|ga|casúr}} * {{Z|it}}: {{W|it|martello|m}} * {{Z|is}}: {{W+|is|hamar}} * {{Z|ca}}: {{W+|ca|martell}} * {{Z|la}}: {{W+|la|martellus}} * {{Z|hu}}: {{W+|hu|kalapács}} * {{Z|no}}: {{W+|no|hammer}} * {{Z|pap}}: {{W+|pap|martin}} * {{Z|pl}}: {{W+|pl|młotek}} * {{Z|pt}}: {{W+|pt|martelo}} * {{Z|ro}}: {{W+|ro|ciocan}} * {{Z|ru}}: {{W+|ru|молот}} * {{Z|sh}}: {{W+|sh|čekić}} * {{Z|sk}}: {{W+|sk|búchat}} * {{Z|es}}: {{W|es|martillo|m}} * {{Z|sw}}: {{W+|sw|nyundo}} * {{Z|sv}}: {{W+|sv|hammare}} * {{Z|tr}}: {{W+|tr|çekiç}}, {{W+|tr|tokmak}} * {{Z|cy}}: {{W+|cy|morthwyl}} {{werger-bin}} 7tp2zgvuj1yfaqhvwuz51f7ajk7d15o 6334032 6334007 2026-08-16T01:41:24Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6334032 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[amûr|Amûrek]] [[serikreq|serikreq]] e û [[bi taybetî]] bo [[kutan|kutan]]a [[bizmar|bizmaran]] [[têt|têt]] [[bikaranîn|bikaranîn]]. #: {{hevmane|ku|çekûç}} #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|مێکوت}} ==== Etîmolojî ==== {{ji?}} ==== Werger ==== {{werger-ser}} * {{Z|af}}: {{W+|af|hamer}} * {{Z|sq}}: {{W+|sq|çekan}} * {{Z|de}}: {{W|de|Hammer|m}}, {{W+|de|Holzhammer}} * {{Z|eu}}: {{W+|eu|mailu}} * {{Z|br}}: {{W+|br|morzhol}} * {{Z|da}}: {{W+|da|hammer}} * {{Z|eo}}: {{W+|eo|martelo}} * {{Z|et}}: {{W+|et|haamer}} * {{Z|fa}}: {{W+|fa|پتک}}, {{W+|fa|پتک چوبی}} * {{Z|fi}}: {{W+|fi|vasara}} * {{Z|fr}}: {{W|fr|marteau|m}} * {{Z|gl}}: {{W+|gl|martelo}} * {{Z|nl}}: {{W|nl|hamer|m}} * {{Z|en}}: {{W+|en|hammer}}, {{W+|en|beetle}}, {{W|en|pounder|guman=erê}} * {{Z|ga}}: {{W+|ga|casúr}} * {{Z|it}}: {{W|it|martello|m}} * {{Z|is}}: {{W+|is|hamar}} * {{Z|ca}}: {{W+|ca|martell}} * {{Z|la}}: {{W+|la|martellus}} * {{Z|hu}}: {{W+|hu|kalapács}} * {{Z|no}}: {{W+|no|hammer}} * {{Z|pap}}: {{W+|pap|martin}} * {{Z|pl}}: {{W+|pl|młotek}} * {{Z|pt}}: {{W+|pt|martelo}} * {{Z|ro}}: {{W+|ro|ciocan}} * {{Z|ru}}: {{W+|ru|молот}} * {{Z|sh}}: {{W+|sh|čekić}} * {{Z|sk}}: {{W+|sk|búchat}} * {{Z|es}}: {{W|es|martillo|m}} * {{Z|sw}}: {{W+|sw|nyundo}} * {{Z|sv}}: {{W+|sv|hammare}} * {{Z|tr}}: {{W+|tr|çekiç}}, {{W+|tr|tokmak}} * {{Z|cy}}: {{W+|cy|morthwyl}} {{werger-bin}} 0algu9svbwef2cgx3ib2lp6o1lfg417 6334058 6334032 2026-08-16T02:12:07Z Balyozbot 7867 Bot: Paqijiyên kozmetîk (Lînk paqij kir, --Valahiyên nehewce.) 6334058 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[amûr|Amûrek]] [[serikreq]] e û [[bi taybetî]] bo [[kutan]]a [[bizmar]]an [[têt]] [[bikaranîn]]. #: {{hevmane|ku|çekûç}} #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|مێکوت}} ==== Etîmolojî ==== {{ji?}} ==== Werger ==== {{werger-ser}} * {{Z|af}}: {{W+|af|hamer}} * {{Z|sq}}: {{W+|sq|çekan}} * {{Z|de}}: {{W|de|Hammer|m}}, {{W+|de|Holzhammer}} * {{Z|eu}}: {{W+|eu|mailu}} * {{Z|br}}: {{W+|br|morzhol}} * {{Z|da}}: {{W+|da|hammer}} * {{Z|eo}}: {{W+|eo|martelo}} * {{Z|et}}: {{W+|et|haamer}} * {{Z|fa}}: {{W+|fa|پتک}}, {{W+|fa|پتک چوبی}} * {{Z|fi}}: {{W+|fi|vasara}} * {{Z|fr}}: {{W|fr|marteau|m}} * {{Z|gl}}: {{W+|gl|martelo}} * {{Z|nl}}: {{W|nl|hamer|m}} * {{Z|en}}: {{W+|en|hammer}}, {{W+|en|beetle}}, {{W|en|pounder|guman=erê}} * {{Z|ga}}: {{W+|ga|casúr}} * {{Z|it}}: {{W|it|martello|m}} * {{Z|is}}: {{W+|is|hamar}} * {{Z|ca}}: {{W+|ca|martell}} * {{Z|la}}: {{W+|la|martellus}} * {{Z|hu}}: {{W+|hu|kalapács}} * {{Z|no}}: {{W+|no|hammer}} * {{Z|pap}}: {{W+|pap|martin}} * {{Z|pl}}: {{W+|pl|młotek}} * {{Z|pt}}: {{W+|pt|martelo}} * {{Z|ro}}: {{W+|ro|ciocan}} * {{Z|ru}}: {{W+|ru|молот}} * {{Z|sh}}: {{W+|sh|čekić}} * {{Z|sk}}: {{W+|sk|búchat}} * {{Z|es}}: {{W|es|martillo|m}} * {{Z|sw}}: {{W+|sw|nyundo}} * {{Z|sv}}: {{W+|sv|hammare}} * {{Z|tr}}: {{W+|tr|çekiç}}, {{W+|tr|tokmak}} * {{Z|cy}}: {{W+|cy|morthwyl}} {{werger-bin}} ewogvpqtwwfn1aogvcfv6o8xr075loy mît 0 51259 6334009 6312862 2026-08-16T01:11:45Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334009 wikitext text/x-wiki {{bnr-h|mit|MÎT}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[efsane]], [[dastan]], [[mîtos]], [[çîrok]]a [[qehreman]]î #* {{bêmînak|ku}} # kesa/ê yan tiştê ku di [[rastî|rastiyê]] de [[nîne]] #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== Ji yewnaniya kevn [[μῦθος]] ([[gotin]], [[galegal]]) ==== Jê ==== * [[mîtîk]] * [[mîtolog]] * [[mîtolojî]] * [[mîtolojîk]] ==== Werger ==== {{werger-ser}} * {{Z|af}}: {{W+|af|mite}} * {{Z|de}}: {{W|de|Mythus|m}} * {{Z|eo}}: {{W+|eo|mito}} * {{Z|fo}}: {{W+|fo|frumsøgn}}, {{W+|fo|gudasøga}} * {{Z|fi}}: {{W+|fi|myytti}} * {{Z|fr}}: {{W+|fr|mythe}} * {{Z|fy}}: {{W+|fy|myte}} * {{Z|nl}}: {{W+|nl|mythe}} * {{Z|io}}: {{W+|io|mito}} * {{Z|en}}: {{W+|en|myth}}, {{W+|en|whist}} * {{Z|it}}: {{W+|it|mito}} * {{Z|pt}}: {{W+|pt|myto}} * {{Z|es}}: {{W+|es|mito}} * {{Z|sv}}: {{W+|sv|myt}} * {{Z|tr}}: {{W+|tr|mit}}, {{W+|tr|mitos}} {{werger-bin}} b6y937fueemjdircwf4d78o6wq0n0s2 6334031 6334009 2026-08-16T01:41:21Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6334031 wikitext text/x-wiki {{bnr-h|mit|MÎT}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[efsane]], [[dastan]], [[mîtos]], [[çîrok]]a [[qehreman]]î #* {{bêmînak|ku}} # kesa/ê yan tiştê ku di [[rastî|rastiyê]] de [[nîne]] #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Jê ==== * [[mîtîk]] * [[mîtolog]] * [[mîtolojî]] * [[mîtolojîk]] ==== Etîmolojî ==== Ji yewnaniya kevn [[μῦθος]] ([[gotin]], [[galegal]]) ==== Werger ==== {{werger-ser}} * {{Z|af}}: {{W+|af|mite}} * {{Z|de}}: {{W|de|Mythus|m}} * {{Z|eo}}: {{W+|eo|mito}} * {{Z|fo}}: {{W+|fo|frumsøgn}}, {{W+|fo|gudasøga}} * {{Z|fi}}: {{W+|fi|myytti}} * {{Z|fr}}: {{W+|fr|mythe}} * {{Z|fy}}: {{W+|fy|myte}} * {{Z|nl}}: {{W+|nl|mythe}} * {{Z|io}}: {{W+|io|mito}} * {{Z|en}}: {{W+|en|myth}}, {{W+|en|whist}} * {{Z|it}}: {{W+|it|mito}} * {{Z|pt}}: {{W+|pt|myto}} * {{Z|es}}: {{W+|es|mito}} * {{Z|sv}}: {{W+|sv|myt}} * {{Z|tr}}: {{W+|tr|mit}}, {{W+|tr|mitos}} {{werger-bin}} 4bf0lpv4x182atd8ghf3049dm9wisb1 hanek 0 52188 6333948 6326738 2026-08-15T23:25:16Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333948 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[zaferan]], [[gula hesretê]], [[sefran]], [[riwek]]ek [[biharat]]der e #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Ji wêjeyê ==== ''GULA HESRETÊ-HANEK- SEFRAN- ZEHFERAN... BAHARATA HERÎ BUHA.'' (Bavê Jîndar, Lotikxane.com, 7/2009) ====Navê zanistî==== * [[Crocus sativus]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|bg}}: {{W|bg|шафран|m}} * {{Z|zh}}: [[番紅花]] / [[番红花]] (fān hóng huā) * {{Z|ar}}: [[زعفران|زَعْفَرَان]] (ze'feran) * {{Z|fa}}: [[زعفران]] (ze'feran) * {{Z|fi}}: {{W+|fi|sahrami}} * {{Z|fr}}: {{W+|fr|safran}} * {{Z|hi}}: [[केसर]] (kesar) * {{Z|en}}: {{W+|en|saffron}} * {{Z|it}}: {{W|it|zafferano|m}} * {{Z|ja}}: [[サフラン]] (safuran) * {{Z|la}}: {{W+|la|safranum}} * {{Z|no}}: {{W+|no|safran}} * {{Z|pl}}: {{W|pl|szafran|m}}, {{W|pl|krokus|m}} * {{Z|pt}}: {{W|pt|açafrão|m}} * {{Z|ru}}: [[шафран]] (šafrán) * {{Z|sa}}: [[कुङ्कुम]] [[kuṅkum]] * {{Z|sh}}: {{W|sh|šafran#Bosnian|m}} * {{Z|sh}}: *: Kirîlî: [[шафран#Serbian|шафран]] {{mê}} *: Latînî: {{W|la|šafran#Serbian|m}} * {{Z|sl}}: {{W|sl|žafran|m}} * {{Z|es}}: {{W|es|azafrán|m}} * {{Z|sv}}: {{W+|sv|saffran}} * {{Z|th}}: [[หญ้าฝรั่น]] (Ya Faran) * {{Z|tr}}: {{W+|tr|safran}} * {{Z|ur}}: {{W|ur|کیسر|tr=kesar}} {{werger-bin}} == {{ziman|tr}} == === Navdêr === {{navdêr|tr}} # [[gotin]], [[axaftin]] #* {{bênimûne|tr}} jiu2ovkis43m35dq4yw7d2wfjbf2lj6 6333972 6333948 2026-08-15T23:41:23Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333972 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[zaferan]], [[gula hesretê]], [[sefran]], [[riwek]]ek [[biharat]]der e #* {{bênimûne|ku}} ==== Ji wêjeyê ==== ''GULA HESRETÊ-HANEK- SEFRAN- ZEHFERAN... BAHARATA HERÎ BUHA.'' (Bavê Jîndar, Lotikxane.com, 7/2009) ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ====Navê zanistî==== * [[Crocus sativus]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|bg}}: {{W|bg|шафран|m}} * {{Z|zh}}: [[番紅花]] / [[番红花]] (fān hóng huā) * {{Z|ar}}: [[زعفران|زَعْفَرَان]] (ze'feran) * {{Z|fa}}: [[زعفران]] (ze'feran) * {{Z|fi}}: {{W+|fi|sahrami}} * {{Z|fr}}: {{W+|fr|safran}} * {{Z|hi}}: [[केसर]] (kesar) * {{Z|en}}: {{W+|en|saffron}} * {{Z|it}}: {{W|it|zafferano|m}} * {{Z|ja}}: [[サフラン]] (safuran) * {{Z|la}}: {{W+|la|safranum}} * {{Z|no}}: {{W+|no|safran}} * {{Z|pl}}: {{W|pl|szafran|m}}, {{W|pl|krokus|m}} * {{Z|pt}}: {{W|pt|açafrão|m}} * {{Z|ru}}: [[шафран]] (šafrán) * {{Z|sa}}: [[कुङ्कुम]] [[kuṅkum]] * {{Z|sh}}: {{W|sh|šafran#Bosnian|m}} * {{Z|sh}}: *: Kirîlî: [[шафран#Serbian|шафран]] {{mê}} *: Latînî: {{W|la|šafran#Serbian|m}} * {{Z|sl}}: {{W|sl|žafran|m}} * {{Z|es}}: {{W|es|azafrán|m}} * {{Z|sv}}: {{W+|sv|saffran}} * {{Z|th}}: [[หญ้าฝรั่น]] (Ya Faran) * {{Z|tr}}: {{W+|tr|safran}} * {{Z|ur}}: {{W|ur|کیسر|tr=kesar}} {{werger-bin}} == {{ziman|tr}} == === Navdêr === {{navdêr|tr}} # [[gotin]], [[axaftin]] #* {{bênimûne|tr}} hxoqgbc8lekrpzvtbvi5mketx94z481 ferhenga zanistî 0 52949 6333939 6306553 2026-08-15T23:16:27Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333939 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[zanistname]], [[ensîklopedî]] #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|heve=îzafe}} ==== Ji wêjeyê ==== ''Piştî salên xwe yên keçaniyê dilê min nexwestiye wan celeb pirtûkan, ên ko tijî bûyerên keşifandî û mirovên tineyî ne, bixwînim û cudayî jî tine ye heke Hemingway, Joyce, Aho, Christie, Jansson an jî kîjan ji wan mîlyaran destên wêjehez ên cîhanê nivîsîbin - ez pêtir ji rastiyên bê[[nakok]] hez dikim, û ji bo ko dema xwe xweş derbas bikim, carna [[ferhenga zanistî|ferhengên zanistî]] dixwînim.'' (Pasi Jääskeläinen: ''Li ciyê zivirîna trênan'', wergerrandin: Husein Muhammed, weşandin: Kovara Mehname 1999, Nefel.com, 8/2009) ==== Etîmolojî ==== [[ferheng]] + [[-a]] + [[zanistî]] fcbg2il9aa1rx58dr0p312fgbx0n5c8 6333976 6333939 2026-08-15T23:41:35Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333976 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[zanistname]], [[ensîklopedî]] #* {{bêmînak|ku}} ==== Ji wêjeyê ==== ''Piştî salên xwe yên keçaniyê dilê min nexwestiye wan celeb pirtûkan, ên ko tijî bûyerên keşifandî û mirovên tineyî ne, bixwînim û cudayî jî tine ye heke Hemingway, Joyce, Aho, Christie, Jansson an jî kîjan ji wan mîlyaran destên wêjehez ên cîhanê nivîsîbin - ez pêtir ji rastiyên bê[[nakok]] hez dikim, û ji bo ko dema xwe xweş derbas bikim, carna [[ferhenga zanistî|ferhengên zanistî]] dixwînim.'' (Pasi Jääskeläinen: ''Li ciyê zivirîna trênan'', wergerrandin: Husein Muhammed, weşandin: Kovara Mehname 1999, Nefel.com, 8/2009) ==== Tewandin ==== {{ku-tewîn-nav/nû|heve=îzafe}} ==== Etîmolojî ==== [[ferheng]] + [[-a]] + [[zanistî]] k2fdrfvwrduxw8runaafuj78612zpbq neguhdarî 0 53271 6334010 6326755 2026-08-16T01:13:03Z Wikihez 7344 /* Bi alfabeya erebî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334010 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[bêemrî]], [[bêfermanî]], [[bêtaetî]], [[bêîtaetî]], [[serhildan]], <br>[[qebûl]]nekirina [[ferman]]an, [[red]]kirina [[emir]]an, <br>bi [[emir]]ê kesekî nekirin, li gor [[ferman]]a kesekî nekirin #* {{bêmînak|ku}} # [[guh dan|guh nedan]] tiştekî, tişt [[bo xwe kirin xem|bo xwe nekirin xem]], tiştek [[piştguh kirin]], tiştek [[paş guhê xwe ve avêtin]] #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * [[neguhdarîtî]] * [[neguhdartî]] ==== Dijmane ==== * [[guhdarî]] ==== Têkildar ==== * [[neguhdar]] ==== Bi alfabeyên din==== * {{ku-ar|نه‌گوهداری}} ==== Etîmolojî ==== [[ne-]] + [[guh]] + [[-dar]] + [[-î]] ==== Jê ==== * [[bêfermaniya medenî]] * [[bêfermaniya sivîl]] ==== Werger ==== '''qebûlnekirina fermanan''' {{werger-ser}} * {{Z|de}}: [[Ungehorsam]] * {{Z|cs}}: [[neposlušnost]] {{mê}} * {{Z|ar}}: {{W-|ar|تمرد}},{{W-|ar|عصيان}},{{W-|ar|جموح}}, {{W-|ar|تجاهل}}, {{W-|ar|غلاظة}}, {{W-|ar|فظاظة}}, {{W-|ar|مخالفة}}, {{W-|ar|إخلال}}, {{W-|ar|سهو}}, {{W-|ar|غفلة}}, {{W-|ar|عدم استماع}} * {{Z|eo}}: {{W-|eo|malobeo}} * {{Z|fa}}: [[نافرمانی]] (nafermanî) * {{Z|fi}}: [[tottelemattomuus]] * {{Z|fr}}: [[désobéissance]] * {{Z|nl}}: [[ongehoorzaamheid]], {{W+|nl|insubordinatie}}, {{W+|nl|inbreuk}} * {{Z|he}}: [[אי-ציות]] * {{Z|en}}: {{W+|en|disobedience}}, {{W+|en|flouting}}, {{W+|en|contumacy}}, {{W+|en|rebellion}}, {{W+|en|noncompliance}}, {{W+|en|contumaciousness}}, {{W+|en|insubordination}}, {{W+|en|indiscipline}}, {{W+|en|breach}}, {{W+|en|inattentiveness|guman=erê}} * {{Z|hu}}: [[engedetlenség]] * {{Z|pap}}: {{W-|pap|desobediensia}} * {{Z|pl}}: [[nieposłuszeństwo]] * {{Z|sv}}: {{W+|sv|olydnad}} * {{Z|tr}}: [[itaatsızlık]] * {{Z|el}}: {{W+|el|αδικία}} {{werger-bin}} 7mn4ej81ewj3cse6q8jd9oulohkjypf 6334011 6334010 2026-08-16T01:13:28Z Wikihez 7344 /* Werger */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334011 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[bêemrî]], [[bêfermanî]], [[bêtaetî]], [[bêîtaetî]], [[serhildan]], <br>[[qebûl]]nekirina [[ferman]]an, [[red]]kirina [[emir]]an, <br>bi [[emir]]ê kesekî nekirin, li gor [[ferman]]a kesekî nekirin #* {{bêmînak|ku}} # [[guh dan|guh nedan]] tiştekî, tişt [[bo xwe kirin xem|bo xwe nekirin xem]], tiştek [[piştguh kirin]], tiştek [[paş guhê xwe ve avêtin]] #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * [[neguhdarîtî]] * [[neguhdartî]] ==== Dijmane ==== * [[guhdarî]] ==== Têkildar ==== * [[neguhdar]] ==== Bi alfabeyên din==== * {{ku-ar|نه‌گوهداری}} ==== Etîmolojî ==== [[ne-]] + [[guh]] + [[-dar]] + [[-î]] ==== Jê ==== * [[bêfermaniya medenî]] * [[bêfermaniya sivîl]] ==== Werger ==== {{werger-ser|qebûlnekirina fermanan}} * {{Z|de}}: [[Ungehorsam]] * {{Z|cs}}: [[neposlušnost]] {{mê}} * {{Z|ar}}: {{W-|ar|تمرد}},{{W-|ar|عصيان}},{{W-|ar|جموح}}, {{W-|ar|تجاهل}}, {{W-|ar|غلاظة}}, {{W-|ar|فظاظة}}, {{W-|ar|مخالفة}}, {{W-|ar|إخلال}}, {{W-|ar|سهو}}, {{W-|ar|غفلة}}, {{W-|ar|عدم استماع}} * {{Z|eo}}: {{W-|eo|malobeo}} * {{Z|fa}}: [[نافرمانی]] (nafermanî) * {{Z|fi}}: [[tottelemattomuus]] * {{Z|fr}}: [[désobéissance]] * {{Z|nl}}: [[ongehoorzaamheid]], {{W+|nl|insubordinatie}}, {{W+|nl|inbreuk}} * {{Z|he}}: [[אי-ציות]] * {{Z|en}}: {{W+|en|disobedience}}, {{W+|en|flouting}}, {{W+|en|contumacy}}, {{W+|en|rebellion}}, {{W+|en|noncompliance}}, {{W+|en|contumaciousness}}, {{W+|en|insubordination}}, {{W+|en|indiscipline}}, {{W+|en|breach}}, {{W+|en|inattentiveness|guman=erê}} * {{Z|hu}}: [[engedetlenség]] * {{Z|pap}}: {{W-|pap|desobediensia}} * {{Z|pl}}: [[nieposłuszeństwo]] * {{Z|sv}}: {{W+|sv|olydnad}} * {{Z|tr}}: [[itaatsızlık]] * {{Z|el}}: {{W+|el|αδικία}} {{werger-bin}} 85m1jfe2u6klz55j8ds6xkn31j9zrg2 6334030 6334011 2026-08-16T01:41:18Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6334030 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[bêemrî]], [[bêfermanî]], [[bêtaetî]], [[bêîtaetî]], [[serhildan]], <br>[[qebûl]]nekirina [[ferman]]an, [[red]]kirina [[emir]]an, <br>bi [[emir]]ê kesekî nekirin, li gor [[ferman]]a kesekî nekirin #* {{bêmînak|ku}} # [[guh dan|guh nedan]] tiştekî, tişt [[bo xwe kirin xem|bo xwe nekirin xem]], tiştek [[piştguh kirin]], tiştek [[paş guhê xwe ve avêtin]] #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din==== * {{ku-ar|نه‌گوهداری}} ==== Formên alternatîv ==== * [[neguhdarîtî]] * [[neguhdartî]] ==== Dijmane ==== * [[guhdarî]] ==== Jê ==== * [[bêfermaniya medenî]] * [[bêfermaniya sivîl]] ==== Têkildar ==== * [[neguhdar]] ==== Etîmolojî ==== [[ne-]] + [[guh]] + [[-dar]] + [[-î]] ==== Werger ==== {{werger-ser|qebûlnekirina fermanan}} * {{Z|de}}: [[Ungehorsam]] * {{Z|cs}}: [[neposlušnost]] {{mê}} * {{Z|ar}}: {{W-|ar|تمرد}},{{W-|ar|عصيان}},{{W-|ar|جموح}}, {{W-|ar|تجاهل}}, {{W-|ar|غلاظة}}, {{W-|ar|فظاظة}}, {{W-|ar|مخالفة}}, {{W-|ar|إخلال}}, {{W-|ar|سهو}}, {{W-|ar|غفلة}}, {{W-|ar|عدم استماع}} * {{Z|eo}}: {{W-|eo|malobeo}} * {{Z|fa}}: [[نافرمانی]] (nafermanî) * {{Z|fi}}: [[tottelemattomuus]] * {{Z|fr}}: [[désobéissance]] * {{Z|nl}}: [[ongehoorzaamheid]], {{W+|nl|insubordinatie}}, {{W+|nl|inbreuk}} * {{Z|he}}: [[אי-ציות]] * {{Z|en}}: {{W+|en|disobedience}}, {{W+|en|flouting}}, {{W+|en|contumacy}}, {{W+|en|rebellion}}, {{W+|en|noncompliance}}, {{W+|en|contumaciousness}}, {{W+|en|insubordination}}, {{W+|en|indiscipline}}, {{W+|en|breach}}, {{W+|en|inattentiveness|guman=erê}} * {{Z|hu}}: [[engedetlenség]] * {{Z|pap}}: {{W-|pap|desobediensia}} * {{Z|pl}}: [[nieposłuszeństwo]] * {{Z|sv}}: {{W+|sv|olydnad}} * {{Z|tr}}: [[itaatsızlık]] * {{Z|el}}: {{W+|el|αδικία}} {{werger-bin}} qe7tze5vphqb1qisk541g2r9kxn4bev fiqurî 0 54326 6333940 6306693 2026-08-15T23:18:46Z Wikihez 7344 /* ji */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333940 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[rewş]] yan jî [[nîşan]]a [[nexêrî]]yê<br> '''fiqurî''' dibare bi ser me ve<br> van gotinan ji '''fiqurî''' dibêje #* {{bênimûne|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== Ji {{qf|ku|fiqur|-î}}. ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|uğursuzluk}} {{werger-bin}} bt1up5yc45xgweci9s8fay5rtmo9ra5 gilîname 0 55532 6333943 6307387 2026-08-15T23:22:12Z Wikihez 7344 /* Bi soranî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333943 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[name]]ya ku tê de [[gilî]] li kesekî yan titekî tê kirin <br>(bi taybetî [[name]]yên ku bo [[dadgeh]]an tên [[şandin]]) #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê|guherto=hemû}} ==== Formên alternatîv ==== * [[glîname]] ====Bi zaravayên din ==== *{{Z|ckb}}: [[gilêname]] ==== Ji wêjeyê ==== ''Piştî ku encama referandûmê bi "Erê" bi dawî bû û madeya makezakonê a 15 ku rê li ber mehkemekirina generalên ku darbeya 12-ê îlonê kiribûn digirt, kete, li gelek bajarên cuda hin saziyên sivîl di derheqê general û rêveberên darbeya 12-ê îlonê de gilîname dan mehkemeyan.'' (Netkurd.com, 9/2010) ==== Etîmolojî ==== Ji {{qertaf|ku|gilî|-name}}. ==== Jê ==== * [[gilînamedank]] * [[gilînamenivîs]] * [[gilînameyî]] ==== Werger ==== {{werger-ser}} * {{Z|de}}:, {{W|de|Anklageschrift|guman=erê}} * {{Z|fa}}: {{W+|fa|شکایت نامه}}, {{W+|fa|احضاریه}} * {{Z|fi}}: {{W+|fi|valituskirjelmä}} * {{Z|en}}: [[appeal]] (the document) * {{Z|tr}}: {{W+|tr|jurnal}}, {{W+|tr|şikayetname}} {{werger-bin}} 36tgl38hlziwe84kiz9v4ca78hu5ebm 6333974 6333943 2026-08-15T23:41:29Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333974 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[name]]ya ku tê de [[gilî]] li kesekî yan titekî tê kirin <br>(bi taybetî [[name]]yên ku bo [[dadgeh]]an tên [[şandin]]) #* {{bêmînak|ku}} ==== Ji wêjeyê ==== ''Piştî ku encama referandûmê bi "Erê" bi dawî bû û madeya makezakonê a 15 ku rê li ber mehkemekirina generalên ku darbeya 12-ê îlonê kiribûn digirt, kete, li gelek bajarên cuda hin saziyên sivîl di derheqê general û rêveberên darbeya 12-ê îlonê de gilîname dan mehkemeyan.'' (Netkurd.com, 9/2010) ==== Tewandin ==== {{ku-tewîn-nav/nû|mê|guherto=hemû}} ==== Formên alternatîv ==== * [[glîname]] ==== Jê ==== * [[gilînamedank]] * [[gilînamenivîs]] * [[gilînameyî]] ==== Etîmolojî ==== Ji {{qertaf|ku|gilî|-name}}. ====Bi zaravayên din ==== *{{Z|ckb}}: [[gilêname]] ==== Werger ==== {{werger-ser}} * {{Z|de}}:, {{W|de|Anklageschrift|guman=erê}} * {{Z|fa}}: {{W+|fa|شکایت نامه}}, {{W+|fa|احضاریه}} * {{Z|fi}}: {{W+|fi|valituskirjelmä}} * {{Z|en}}: [[appeal]] (the document) * {{Z|tr}}: {{W+|tr|jurnal}}, {{W+|tr|şikayetname}} {{werger-bin}} auunri0v3u4zbl0xshplk9me69usb0f hevserî 0 55675 6333950 6308450 2026-08-15T23:27:03Z Wikihez 7344 /* Bi soranî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333950 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[jinûmêrî]], [[zewac]], [[izdiwac]], [[malbat]], [[jinûmêrbûn]], <br>[[jiyan]]a [[jinûmêr]]an, <br>[[rewş]]a yan [[statû]]ya [[jin]]ekê û [[mêr]]ê wê #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * [[hevserîtî]] * [[hevsertî]] ====Bi zaravayên din === * {{Z|ckb}}: [[hawserî]], [[hawserêtî]] ==== Etîmolojî ==== Ji {{paş|ku|hevser|-î}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Ehe|f}}, {{W|de|Heirat|f}} * {{Z|cs}}: {{W|cs|sňatek|m}}, {{W|cs|manželství|n}} * {{Z|zh}}: [[婚姻]] (hūnyīn) * {{Z|da}}: {{W|da|ægteskab|n}}, {{W|da|giftermål|n}} * {{Z|ar}}: {{W|ar|زواج}} (zewac) * {{Z|hy}}: [[ամուսնություն]] (amusnut'yun) * {{Z|fa}}: {{W|fa|ازدواج}} (ezdevac) * {{Z|fi}}: {{W|fi|avioliitto}} * {{Z|fr}}: {{W|fr|mariage|m}} * {{Z|gd}}: {{W|gd|pòsadh|m}} * {{Z|nl}}: {{W|nl|huwelijk|f}} * {{Z|en}}: {{W|en|marriage}}, {{W|en|conjugality}}, {{W|en|connubial}}, {{W|en|connubialism|guman=erê}}, {{W|en|connubiality|guman=erê}} * {{Z|it}}: {{W|it|matrimonio|m}}, {{W|it|nozze}}, {{W|it|sposalizio}} * {{Z|ja}}: {{W|ja|結婚|tr=けっこん, kekkon}} * {{Z|ko}}: [[결혼]] (gyeolhon) * {{Z|la}}: {{W|la|matrimonium|n}} * {{Z|ml}}: {{W|ml|വിവാഹജീവിതം}} * {{Z|mt}}: {{W|mt|żwieġ|m}} * {{Z|hu}}: {{W|hu|házasság}} * {{Z|no}}: {{W|no|ekteskap|n}}, {{W|no|giftemål|n}} * {{Z|pl}}: {{W|pl|małżeństwo|n}} * {{Z|pt}}: {{W|pt|casamento|m}} * {{Z|ru}}: {{W|ru|брак|tr=brak|m}}, {{W|ru|замужество|tr=zamúžestvo|n}} * {{Z|es}}: {{W|es|matrimonio|m}} * {{Z|sw}}: {{W|sw|ndoa|xs=Swahili}} * {{Z|sv}}: {{W|sv|äktenskap|n}} * {{Z|tr}}: {{W|tr|evlilik}} {{werger-bin}} nchzua5r99rkdb0sowt3g6p3vxl4h8d 6333951 6333950 2026-08-15T23:27:12Z Wikihez 7344 /* =Bi zaravayên din */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333951 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[jinûmêrî]], [[zewac]], [[izdiwac]], [[malbat]], [[jinûmêrbûn]], <br>[[jiyan]]a [[jinûmêr]]an, <br>[[rewş]]a yan [[statû]]ya [[jin]]ekê û [[mêr]]ê wê #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * [[hevserîtî]] * [[hevsertî]] ====Bi zaravayên din ==== * {{Z|ckb}}: [[hawserî]], [[hawserêtî]] ==== Etîmolojî ==== Ji {{paş|ku|hevser|-î}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Ehe|f}}, {{W|de|Heirat|f}} * {{Z|cs}}: {{W|cs|sňatek|m}}, {{W|cs|manželství|n}} * {{Z|zh}}: [[婚姻]] (hūnyīn) * {{Z|da}}: {{W|da|ægteskab|n}}, {{W|da|giftermål|n}} * {{Z|ar}}: {{W|ar|زواج}} (zewac) * {{Z|hy}}: [[ամուսնություն]] (amusnut'yun) * {{Z|fa}}: {{W|fa|ازدواج}} (ezdevac) * {{Z|fi}}: {{W|fi|avioliitto}} * {{Z|fr}}: {{W|fr|mariage|m}} * {{Z|gd}}: {{W|gd|pòsadh|m}} * {{Z|nl}}: {{W|nl|huwelijk|f}} * {{Z|en}}: {{W|en|marriage}}, {{W|en|conjugality}}, {{W|en|connubial}}, {{W|en|connubialism|guman=erê}}, {{W|en|connubiality|guman=erê}} * {{Z|it}}: {{W|it|matrimonio|m}}, {{W|it|nozze}}, {{W|it|sposalizio}} * {{Z|ja}}: {{W|ja|結婚|tr=けっこん, kekkon}} * {{Z|ko}}: [[결혼]] (gyeolhon) * {{Z|la}}: {{W|la|matrimonium|n}} * {{Z|ml}}: {{W|ml|വിവാഹജീവിതം}} * {{Z|mt}}: {{W|mt|żwieġ|m}} * {{Z|hu}}: {{W|hu|házasság}} * {{Z|no}}: {{W|no|ekteskap|n}}, {{W|no|giftemål|n}} * {{Z|pl}}: {{W|pl|małżeństwo|n}} * {{Z|pt}}: {{W|pt|casamento|m}} * {{Z|ru}}: {{W|ru|брак|tr=brak|m}}, {{W|ru|замужество|tr=zamúžestvo|n}} * {{Z|es}}: {{W|es|matrimonio|m}} * {{Z|sw}}: {{W|sw|ndoa|xs=Swahili}} * {{Z|sv}}: {{W|sv|äktenskap|n}} * {{Z|tr}}: {{W|tr|evlilik}} {{werger-bin}} tc27s8co8pjytj2her664yhgwzxr3aq 6333971 6333951 2026-08-15T23:41:20Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333971 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[jinûmêrî]], [[zewac]], [[izdiwac]], [[malbat]], [[jinûmêrbûn]], <br>[[jiyan]]a [[jinûmêr]]an, <br>[[rewş]]a yan [[statû]]ya [[jin]]ekê û [[mêr]]ê wê #* {{bêmînak|ku}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * [[hevserîtî]] * [[hevsertî]] ==== Etîmolojî ==== Ji {{paş|ku|hevser|-î}} ====Bi zaravayên din ==== * {{Z|ckb}}: [[hawserî]], [[hawserêtî]] ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Ehe|f}}, {{W|de|Heirat|f}} * {{Z|cs}}: {{W|cs|sňatek|m}}, {{W|cs|manželství|n}} * {{Z|zh}}: [[婚姻]] (hūnyīn) * {{Z|da}}: {{W|da|ægteskab|n}}, {{W|da|giftermål|n}} * {{Z|ar}}: {{W|ar|زواج}} (zewac) * {{Z|hy}}: [[ամուսնություն]] (amusnut'yun) * {{Z|fa}}: {{W|fa|ازدواج}} (ezdevac) * {{Z|fi}}: {{W|fi|avioliitto}} * {{Z|fr}}: {{W|fr|mariage|m}} * {{Z|gd}}: {{W|gd|pòsadh|m}} * {{Z|nl}}: {{W|nl|huwelijk|f}} * {{Z|en}}: {{W|en|marriage}}, {{W|en|conjugality}}, {{W|en|connubial}}, {{W|en|connubialism|guman=erê}}, {{W|en|connubiality|guman=erê}} * {{Z|it}}: {{W|it|matrimonio|m}}, {{W|it|nozze}}, {{W|it|sposalizio}} * {{Z|ja}}: {{W|ja|結婚|tr=けっこん, kekkon}} * {{Z|ko}}: [[결혼]] (gyeolhon) * {{Z|la}}: {{W|la|matrimonium|n}} * {{Z|ml}}: {{W|ml|വിവാഹജീവിതം}} * {{Z|mt}}: {{W|mt|żwieġ|m}} * {{Z|hu}}: {{W|hu|házasság}} * {{Z|no}}: {{W|no|ekteskap|n}}, {{W|no|giftemål|n}} * {{Z|pl}}: {{W|pl|małżeństwo|n}} * {{Z|pt}}: {{W|pt|casamento|m}} * {{Z|ru}}: {{W|ru|брак|tr=brak|m}}, {{W|ru|замужество|tr=zamúžestvo|n}} * {{Z|es}}: {{W|es|matrimonio|m}} * {{Z|sw}}: {{W|sw|ndoa|xs=Swahili}} * {{Z|sv}}: {{W|sv|äktenskap|n}} * {{Z|tr}}: {{W|tr|evlilik}} {{werger-bin}} e5x128yeesm3e9ybbbmoi1ptjr231qb goganîbûnî 0 57353 6333946 6307560 2026-08-15T23:23:28Z Wikihez 7344 [[Bikarhêner:Wikihez/skrîpt/js/şablon-lêke.js|T]]: +{{bêçavkanî}} 6333946 wikitext text/x-wiki {{bêçavkanî}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # pêvajoya ku cîhan bêtir bi hev re dikeve nav têkiliyan; pêvajoya ber bi bêtir bi hevregirêdana cîhanê diçe; li gel hev nêzîk bûna millet û dewletên cîhanê di gelek biyavan de wek aborî, ramyarî û ragihandin ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} === Bideber === * [[herêmgêrî]] * [[herêmî bûn]] * [[herêmîbûnî]] * [[navçegêrî]] ==== Têkildar ==== * [[gog]] * [[goganî]] * [[goganîbûn]] ==== Jê ==== * [[goganîbunî parêz]] ==== Etîmolojî ==== Ji ''[[goganî]] + [[bûn]]''î ==== Werger ==== {{werger-ser}} * {{Z|en}}: to {{W+|en|globalisation}}, to {{W+|en|globalization}} * {{Z|tr}}: {{W+|tr|küreselleşme}} {{werger-bin}} === Çavkanî === {{çavkanî}} ouivs9sfnnlvezp8k7qcmjzxaxfc3t5 lêkolînên meydanî 0 60708 6333994 6311397 2026-08-16T01:01:09Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333994 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[lêkolîn]]ên [[zanistî]] yên ku bi [[xebatên meydanî]] tên kirin, <br>[[lêkolîn]]ên ku di nav [[sirişt]]ê de (ne li [[ezmûnxane]]yan) yan jî di nav [[gel]] de (ne tenê ji [[pirtûk]]an) tên kirin ==== Tewandin ==== {{ku-tewîn-nav/nû|heve=îzafe|nav=lêkolîna meydanî}} ==== Formên alternatîv ==== * [[lêkolînên qadî]] ==== Bi alfabeyên din ==== * {{ku-ar|لێکۆلینێن مه‌یدانی}} ==== Ji wêjeyê ==== * {{jêder|ku|jêgirtin=Nivîskarê vê gotarê [Nehro Zagros] xwediyê [[bawernameya doktorayê]] ye di warê etnomuzîkolojî li ser muzîka êzidiyên Ermenistanê. Ev bêtirî heft salan e ew [[lêkolînên meydanî]] li Ermenistan, Gurcistanê û Tirkiyê pêk tîne û niha li Zanîngeha York li Brîtanya lêkolînên xwe didomîne.|Rudaw.net, 5/2011}} ==== Etîmolojî ==== [[lêkolîn]] + [[-ên]] + [[meydanî]] ==== Werger ==== {{werger-ser}} * {{Z|fi}}: {{W+|fi|kenttätutkimus}} * {{Z|en}}: {{W+|en|field research}} {{werger-bin}} p9lfikg388bxwwchzd0tmiiok67xn97 6333995 6333994 2026-08-16T01:01:43Z Wikihez 7344 /* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333995 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|j=p}} # [[lêkolîn]]ên [[zanistî]] yên ku bi [[xebatên meydanî]] tên kirin, <br>[[lêkolîn]]ên ku di nav [[sirişt]]ê de (ne li [[ezmûnxane]]yan) yan jî di nav [[gel]] de (ne tenê ji [[pirtûk]]an) tên kirin ==== Tewandin ==== {{ku-tewîn-nav/nû|heve=îzafe|nav=lêkolîna meydanî}} ==== Formên alternatîv ==== * [[lêkolînên qadî]] ==== Bi alfabeyên din ==== * {{ku-ar|لێکۆلینێن مه‌یدانی}} ==== Ji wêjeyê ==== * {{jêder|ku|jêgirtin=Nivîskarê vê gotarê [Nehro Zagros] xwediyê [[bawernameya doktorayê]] ye di warê etnomuzîkolojî li ser muzîka êzidiyên Ermenistanê. Ev bêtirî heft salan e ew [[lêkolînên meydanî]] li Ermenistan, Gurcistanê û Tirkiyê pêk tîne û niha li Zanîngeha York li Brîtanya lêkolînên xwe didomîne.|Rudaw.net, 5/2011}} ==== Etîmolojî ==== [[lêkolîn]] + [[-ên]] + [[meydanî]] ==== Werger ==== {{werger-ser}} * {{Z|fi}}: {{W+|fi|kenttätutkimus}} * {{Z|en}}: {{W+|en|field research}} {{werger-bin}} 8wq6ca7cf56bm8ka4bywn6gev3e0af4 6333996 6333995 2026-08-16T01:02:14Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333996 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|j=p}} # [[lêkolîn]]ên [[zanistî]] yên ku bi [[xebatên meydanî]] tên kirin, <br>[[lêkolîn]]ên ku di nav [[sirişt]]ê de (ne li [[ezmûnxane]]yan) yan jî di nav [[gel]] de (ne tenê ji [[pirtûk]]an) tên kirin #* {{jêder|ku|jêgirtin=Nivîskarê vê gotarê [Nehro Zagros] xwediyê [[bawernameya doktorayê]] ye di warê etnomuzîkolojî li ser muzîka êzidiyên Ermenistanê. Ev bêtirî heft salan e ew [[lêkolînên meydanî]] li Ermenistan, Gurcistanê û Tirkiyê pêk tîne û niha li Zanîngeha York li Brîtanya lêkolînên xwe didomîne.|Rudaw.net, 5/2011}} ==== Tewandin ==== {{ku-tewîn-nav/nû|heve=îzafe|nav=lêkolîna meydanî}} ==== Formên alternatîv ==== * [[lêkolînên qadî]] ==== Bi alfabeyên din ==== * {{ku-ar|لێکۆلینێن مه‌یدانی}} ==== Etîmolojî ==== [[lêkolîn]] + [[-ên]] + [[meydanî]] ==== Werger ==== {{werger-ser}} * {{Z|fi}}: {{W+|fi|kenttätutkimus}} * {{Z|en}}: {{W+|en|field research}} {{werger-bin}} pdyrhi4ct7wfbt1xwyp8u3w51tr0q21 6334035 6333996 2026-08-16T01:41:33Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6334035 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|j=p}} # [[lêkolîn]]ên [[zanistî]] yên ku bi [[xebatên meydanî]] tên kirin, <br>[[lêkolîn]]ên ku di nav [[sirişt]]ê de (ne li [[ezmûnxane]]yan) yan jî di nav [[gel]] de (ne tenê ji [[pirtûk]]an) tên kirin #* {{jêder|ku|jêgirtin=Nivîskarê vê gotarê [Nehro Zagros] xwediyê [[bawernameya doktorayê]] ye di warê etnomuzîkolojî li ser muzîka êzidiyên Ermenistanê. Ev bêtirî heft salan e ew [[lêkolînên meydanî]] li Ermenistan, Gurcistanê û Tirkiyê pêk tîne û niha li Zanîngeha York li Brîtanya lêkolînên xwe didomîne.|Rudaw.net, 5/2011}} ==== Tewandin ==== {{ku-tewîn-nav/nû|heve=îzafe|nav=lêkolîna meydanî}} ==== Bi alfabeyên din ==== * {{ku-ar|لێکۆلینێن مه‌یدانی}} ==== Formên alternatîv ==== * [[lêkolînên qadî]] ==== Etîmolojî ==== [[lêkolîn]] + [[-ên]] + [[meydanî]] ==== Werger ==== {{werger-ser}} * {{Z|fi}}: {{W+|fi|kenttätutkimus}} * {{Z|en}}: {{W+|en|field research}} {{werger-bin}} b4siw7gp6phmgijyb7bfmww5igignth jornivîs 0 62743 6333959 6309391 2026-08-15T23:31:32Z Wikihez 7344 /* Binêre herwiha */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333959 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[herf]]ên yan [[hejmar]]ên ku li gel [[herf]] û [[hejmar]]ên din tên [[nivîsîn]] lê hinekî ji [[rêz]]a wan [[bilind]]tir û bi [[giştî]] [[hûr]]tir in #: ''Nivîsa normal <sup>jornivîs</sup>, <sub>jêrnivîs</sub>'' ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * {{g|ku|jornîşan}} ==== Dijmane ==== * {{g|ku|jêrnivîs}} * {{g|ku|jêrnîşan}} ==== Bide ber ==== * {{g|ku|sernivîs}} ==== Binêre herwiha ==== * {{g|ku|sernav}} * {{g|ku|bernav}} * {{g|ku|jornav}} ==== Jê ==== * {{g|ku|jornivîsî}} ==== Etîmolojî ==== Ji {{pêk|ku|jor|nivîs}}. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|hochstellung}}, {{W|de|Hochstellung|f}} * {{Z|ar}}: {{W|ar|مرتفع}} * {{Z|fa}}: {{W|fa|بالانویس}} (balanivîs) * {{Z|fi}}: {{W+|fi|yläindeksi}} * {{Z|fr}}: {{W+|fr|exposant}} * {{Z|en}}: {{W+|en|superscript}} * {{Z|sv}}: {{W+|sv|exponentläge}} * {{Z|tr}}: {{W+|tr|üst simge}}, {{W+|tr|üstsimge}} {{werger-bin}} eosg1jkbdywnm9dpmddo1exczf0yzu0 6333969 6333959 2026-08-15T23:41:14Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333969 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[herf]]ên yan [[hejmar]]ên ku li gel [[herf]] û [[hejmar]]ên din tên [[nivîsîn]] lê hinekî ji [[rêz]]a wan [[bilind]]tir û bi [[giştî]] [[hûr]]tir in #: ''Nivîsa normal <sup>jornivîs</sup>, <sub>jêrnivîs</sub>'' ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * {{g|ku|jornîşan}} ==== Dijmane ==== * {{g|ku|jêrnivîs}} * {{g|ku|jêrnîşan}} ==== Jê ==== * {{g|ku|jornivîsî}} ==== Etîmolojî ==== Ji {{pêk|ku|jor|nivîs}}. ==== Bide ber ==== * {{g|ku|sernivîs}} ==== Herwiha binêre ==== * {{g|ku|sernav}} * {{g|ku|bernav}} * {{g|ku|jornav}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|hochstellung}}, {{W|de|Hochstellung|f}} * {{Z|ar}}: {{W|ar|مرتفع}} * {{Z|fa}}: {{W|fa|بالانویس}} (balanivîs) * {{Z|fi}}: {{W+|fi|yläindeksi}} * {{Z|fr}}: {{W+|fr|exposant}} * {{Z|en}}: {{W+|en|superscript}} * {{Z|sv}}: {{W+|sv|exponentläge}} * {{Z|tr}}: {{W+|tr|üst simge}}, {{W+|tr|üstsimge}} {{werger-bin}} rqb617xbxvhq6tgrhk4bxmow2tza7m6 jêrnivîs 0 62744 6333961 6309441 2026-08-15T23:33:01Z Wikihez 7344 /* Binêre herwiha */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333961 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[herf]]ên yan [[hejmar]]ên ku li gel [[herf]] û [[hejmar]]ên din tên [[nivîsîn]] lê hinekî ji [[rêz]]a wan [[nizm]]tir û bi [[giştî]] [[hûr]]tir in #: ''Nivîsa normal <sub>jêrnivîs</sub>, <sup>jornivîs</sup>'' ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|ژێرنووس}} ==== Formên alternatîv ==== * {{g|ku|jêrnîşan}} ==== Dijmane ==== * {{g|ku|jornivîs}} * {{g|ku|jornîşan}} ==== Bide ber ==== * {{g|ku|binnivîs}} ==== Binêre herwiha ==== * {{g|ku|jêrnav}} * {{g|ku|bernav}} * {{g|ku|jornav}} ==== Jê ==== * {{g|ku|jêrnivîsî}} ==== Etîmolojî ==== Ji {{pêk|ku|jêr|nivîs}}. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Tiefstellung}} * {{Z|ar}}: {{W|ar|منخفض}} * {{Z|fa}}: {{W|fa|زیرنویس|tr=zîrnivîs}}, {{W+|fa|زیر نویس}}, {{W+|fa|پاورقی}} * {{Z|fi}}: {{W+|fi|alaindeksi}} * {{Z|fr}}: {{W+|fr|indice}} * {{Z|en}}: {{W+|en|subscript}}, {{W+|en|subtitles}}, {{W|en|subtitle|guman=erê}} * {{Z|sv}}: {{W+|sv|indexläge}} * {{Z|tr}}: {{W+|tr|alt simge}}, {{W+|tr|altsimge}}, {{W+|tr|altyazı}} {{werger-bin}} {{mijar|ku|zimannasî}} 9c19px8ah5c8dntch50dpgk33colzdw 6333968 6333961 2026-08-15T23:41:11Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333968 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[herf]]ên yan [[hejmar]]ên ku li gel [[herf]] û [[hejmar]]ên din tên [[nivîsîn]] lê hinekî ji [[rêz]]a wan [[nizm]]tir û bi [[giştî]] [[hûr]]tir in #: ''Nivîsa normal <sub>jêrnivîs</sub>, <sup>jornivîs</sup>'' ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|ژێرنووس}} ==== Formên alternatîv ==== * {{g|ku|jêrnîşan}} ==== Dijmane ==== * {{g|ku|jornivîs}} * {{g|ku|jornîşan}} ==== Jê ==== * {{g|ku|jêrnivîsî}} ==== Etîmolojî ==== Ji {{pêk|ku|jêr|nivîs}}. ==== Bide ber ==== * {{g|ku|binnivîs}} ==== Herwiha binêre ==== * {{g|ku|jêrnav}} * {{g|ku|bernav}} * {{g|ku|jornav}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Tiefstellung}} * {{Z|ar}}: {{W|ar|منخفض}} * {{Z|fa}}: {{W|fa|زیرنویس|tr=zîrnivîs}}, {{W+|fa|زیر نویس}}, {{W+|fa|پاورقی}} * {{Z|fi}}: {{W+|fi|alaindeksi}} * {{Z|fr}}: {{W+|fr|indice}} * {{Z|en}}: {{W+|en|subscript}}, {{W+|en|subtitles}}, {{W|en|subtitle|guman=erê}} * {{Z|sv}}: {{W+|sv|indexläge}} * {{Z|tr}}: {{W+|tr|alt simge}}, {{W+|tr|altsimge}}, {{W+|tr|altyazı}} {{werger-bin}} {{mijar|ku|zimannasî}} azd0uhypm86oti1nicnqsfcr854jho6 parîz 0 63221 6334041 6314045 2026-08-16T01:44:42Z Wikihez 7344 /* {{ziman|ku}} */ [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6334041 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[baxçe]], [[gulistan]] #* {{jêder|ku|jêgirtin=Ne gul û ne kulîlk man<br>Ne '''parîz''' û gulistan<br>Ne dengê xweş ne meqam<br>Pêve j’ah û [[intiqam]]|Kamuran Bedirxan, helbesta ''Birîn'', jêwergirtin Celadet.com, 4/2012}} # [[biheşt]] ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} === Têkildar === * {{g|ku|pirêz}} ==== Bide ber ==== * {{g|ku|parêz}} ==== Etîmolojî ==== Hevreha [[pirêz]] ([[baxçe]]), bide ber avestayî "peyrideêze" (baxçe, gulistan, bihişt) ji "peyri-" ([[dor]], [[dorber]], dorûber, dewrûdor) + "deêze" ([[dîwar]]) anku "cihê dîwarkirî, cihê ku dîwarek yan sûrek li dor hatiye avakirin daku wê biparêze) ku serekaniya peyva îngilîzî [[paradise]] (bihişt) û ya gelek zimanên din jî yên ewropî ye yên bi eynî maneyê ye. ndsuy6605u385nqvu9x20jb8jdx6syj mnemonics 0 92892 6334049 6261829 2026-08-16T02:01:23Z Wikihez 7344 6334049 wikitext text/x-wiki == {{ziman|en}} == === Bilêvkirin === * {{mj|KY}} {{IPA|en|/nəˈmɒn.ɪks/}} * {{mj|DYA}} {{IPA|en|/nəˈmɑn.ɪks/}} * {{deng|en|LL-Q1860 (eng)-Persent101-mnemonics.wav|Deng|dever=}} * {{deng|en|LL-Q1860 (eng)-Wodencafe-mnemonics.wav|Deng|dever=Teksas, DYA}} === Navdêr === {{wp|ziman=en}} {{navdêr|en|j=tp}} # [[lêkolîn|Lêkolîna]] [[teknîk|teknîkên]] [[ji bo]] [[bi hêsanî]] [[bîranîn|bîranîna]] her [[tişt|tiştî]]. ==== Formên alternatîv ==== * {{g|en|mnemonicks}} {{mj|kevnbûyî}} ==== Etîmolojî ==== Ji {{ji|grc|en|μνημονικά}}, pirjimara {{qal|grc|μνημονικόν}}, nêtara {{qal|grc|μνημονικός}}. npiawyq6v4bcl0nxe9gllyhx88bj1vi 6334050 6334049 2026-08-16T02:03:30Z Wikihez 7344 /* Bilêvkirin */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334050 wikitext text/x-wiki == {{ziman|en}} == === Bilêvkirin === * {{mj|QY}} {{IPA|en|/nəˈmɒn.ɪks/}} * {{mj|DYA}} {{IPA|en|/nəˈmɑn.ɪks/}} * {{deng|en|LL-Q1860 (eng)-Persent101-mnemonics.wav|Deng|dever=}} * {{deng|en|LL-Q1860 (eng)-Wodencafe-mnemonics.wav|Deng|dever=Teksas, DYA}} === Navdêr === {{wp|ziman=en}} {{navdêr|en|j=tp}} # [[lêkolîn|Lêkolîna]] [[teknîk|teknîkên]] [[ji bo]] [[bi hêsanî]] [[bîranîn|bîranîna]] her [[tişt|tiştî]]. ==== Formên alternatîv ==== * {{g|en|mnemonicks}} {{mj|kevnbûyî}} ==== Etîmolojî ==== Ji {{ji|grc|en|μνημονικά}}, pirjimara {{qal|grc|μνημονικόν}}, nêtara {{qal|grc|μνημονικός}}. axz17vii10ki5o4pnxsh10cwj9m5lp5 6334069 6334050 2026-08-16T03:12:09Z Balyozbot 7867 Bot: Paqijiyên kozmetîk (Lînk paqij kir.) 6334069 wikitext text/x-wiki == {{ziman|en}} == === Bilêvkirin === * {{mj|QY}} {{IPA|en|/nəˈmɒn.ɪks/}} * {{mj|DYA}} {{IPA|en|/nəˈmɑn.ɪks/}} * {{deng|en|LL-Q1860 (eng)-Persent101-mnemonics.wav|Deng|dever=}} * {{deng|en|LL-Q1860 (eng)-Wodencafe-mnemonics.wav|Deng|dever=Teksas, DYA}} === Navdêr === {{wp|ziman=en}} {{navdêr|en|j=tp}} # [[lêkolîn|Lêkolîna]] [[teknîk]]ên [[ji bo]] [[bi hêsanî]] [[bîranîn]]a her [[tişt]]î. ==== Formên alternatîv ==== * {{g|en|mnemonicks}} {{mj|kevnbûyî}} ==== Etîmolojî ==== Ji {{ji|grc|en|μνημονικά}}, pirjimara {{qal|grc|μνημονικόν}}, nêtara {{qal|grc|μνημονικός}}. 6dkrv8qbqd9k5bjto4pqokcmvwpej3x mijxele 0 116775 6334005 6326923 2026-08-16T01:07:44Z Wikihez 7344 /* Zazakî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334005 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # mij û [[moran]], mij û [[dûman]] ==== Tewandin ==== {{ku-tewîn-nav/nû|mê|guherto=hemû}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Nebel}} {{mê}}, {{W|de|Schwüle}} * {{Z|ar}}: {{W|ar|ضباب|guman=erê}} {{werger-bin}} == {{ziman|zza}} == === Navdêr === {{navdêr|zza|z=m}} # mij û [[moran]], mij û [[dûman]] <ref>http://www.scribd.com/doc/60905536/Vate-18</ref> ==== Formên alternatîv ==== * [[mizxele]] === Çavkanî === {{çavkanî}} n3m4tkbdm8qk70yf3gbbwhr4rpvk02m kekik 0 147881 6333866 4616163 2026-08-15T18:52:27Z Wikihez 7344 /* Tirkî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333866 wikitext text/x-wiki {{bnr-h|Kekik}} == {{ziman|tr}} == === Navdêr === {{navdêr|tr}} # [[catirî]], [[cehter]], [[zembûr]], [[awîşen]] ({{q|navz|Thymus vulgaris}}) qv15jwmeg6mqju6vn3ueeztd26hsmx0 kindar 0 148818 6334084 4632369 2026-08-16T08:05:26Z Keyomerd 8814 /* Rengdêr */ 6334084 wikitext text/x-wiki == {{ziman|tr}} == === Rengdêr === {{rengdêr|tr}} # [[kîndar]], [[mûdî]], [[kînewer]] # [[rikdar]], [[girdar]], [[kînoyî]], [[kînbaz]], [[rikok]], [[rikgir]], [[kînok]], [[kînewer]], [[kînedoz]], [[pangir]], [[rikoyî]], [[bikîn]] 478mw2v4jpr9m0sh2n4niogqrtrzsxp öngörülür 0 176146 6333787 5802122 2026-08-15T12:10:42Z Rewiye tine 7120 Rewiye tineî/ê navê [[öngörülebilir]] weke [[öngörülür]] guhart 5802122 wikitext text/x-wiki == {{ziman|tr}} == === Mane === {{cure?|tr}} # Tişta tê vezanîn Tişta tê texmin kirin gzi7libzd5wrasqzg6fb8z0ev2uh39v 6333789 6333787 2026-08-15T12:12:44Z Rewiye tine 7120 /* Mane */ 6333789 wikitext text/x-wiki == {{ziman|tr}} == == {{ziman|tr}} == === Rengdêr === {{rengdêr|tr}} # Tişta tê vezanîn, tişta tê texmin kirin jg3w67rhxaw21b9445qgdu0czwl1kfj 6333790 6333789 2026-08-15T12:12:56Z Rewiye tine 7120 6333790 wikitext text/x-wiki == {{ziman|tr}} == === Rengdêr === {{rengdêr|tr}} # Tişta tê vezanîn, tişta tê texmin kirin cvj6pgnzj1751x8kx144fft8y57t7ki 6333791 6333790 2026-08-15T12:14:58Z Rewiye tine 7120 /* Rengdêr */ 6333791 wikitext text/x-wiki == {{ziman|tr}} == === Rengdêr === {{rengdêr|tr}} # [[pêşbînîkirî]], Tişta tê vezanîn; tişta tê texmin kirin gfvfao0e0a3yhe700m1ikxdf7j8n11l 6333798 6333791 2026-08-15T12:35:26Z Rewiye tine 7120 /* Rengdêr */ 6333798 wikitext text/x-wiki == {{ziman|tr}} == === Rengdêr === {{rengdêr|tr}} # [[pêşbînbar]], tişta tê vezanîn; tişta tê texmin kirin evtciwidhpfugp6s279a3sort2kiuru öngörülemez 0 176147 6333797 5802123 2026-08-15T12:34:14Z Rewiye tine 7120 6333797 wikitext text/x-wiki == {{ziman|tr}} == === Rengdêr === {{rengdêr|tr}} # [[nepêşbînbar]], tişta nayê vezanîn; tişta nayê texmin kirin. 6qxm7dzg5q0dy8979az4nf4vaexco2i firyar 0 179295 6333815 6328242 2026-08-15T14:19:55Z Wikihez 7344 6333815 wikitext text/x-wiki == {{ziman|ku}} == === Navdêr === {{navdêr|ku|z=mn}} # {{K|ku|meslek|hewavanî}} {{e|ku|gelek|nadir|tenê di çend ferhengan de}} [[kes|Kesê]] ku [[balafir]]an [[ajotin|diajo]].<ref>{{Ferhenga Destî|r=123}}</ref> #: {{hevmane|ku|pîlot}} #* {{nimûne?|ku}} ==== Tewandin ==== {{ku-tewîn-nav|mê û nêr}} ==== Etîmolojî ==== Ji {{qf|ku|fir|-yar}}. ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|خلبان}}<ref>{{ferhenga kurdî-farsî}}</ref> * {{Z|tr}}: {{W+|tr|pilot}}<ref>{{Zana Farqînî|r=645}}</ref> {{werger-bin}} ==== Çavkanî ==== {{Çavkanî}} 6qpmikbkngz2m4rk7cp6rgg1sb42os9 6333885 6333815 2026-08-15T19:24:05Z Wikihez 7344 ([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +ku:navdêr:Kesê ku direve an jî bi dizî ji cihekî diçe cihekî din daku neyê girtin. 6333885 wikitext text/x-wiki == {{ziman|ku}} == === Navdêr 1 === {{navdêr|ku|z=mn}} # {{K|ku|meslek|hewavanî}} {{e|ku|gelek|nadir|tenê di çend ferhengan de}} [[kes|Kesê]] ku [[balafir]]an [[ajotin|diajo]].<ref>{{Ferhenga Destî|r=123}}</ref> #: {{hevmane|ku|pîlot}} #* {{nimûne?|ku}} ==== Tewandin ==== {{ku-tewîn-nav|mê û nêr}} ==== Etîmolojî ==== Ji {{qf|ku|fir|-yar}}. ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|خلبان}}<ref>{{ferhenga kurdî-farsî}}</ref> * {{Z|tr}}: {{W+|tr|pilot}}<ref>{{Zana Farqînî|r=645}}</ref> {{werger-bin}} ==== Çavkanî ==== {{Çavkanî}} === Navdêr 2 === {{navdêr|ku|c=mn}} # [[kes|Kesê]] ku [[revîn|direve]] [[an jî]] [[bi dizî]] ji [[cih|cihekî]] [[çûn|diçe]] cihekî [[din|din]] [[daku|daku]] [[hatin|neyê]] [[girtin|girtin]]. #* {{jêder-kitêb|ku|jêgirtin=... '''firyarê''' dewletê bi tabûr û eskerê nîzamê mi pirskirî ji van qîzan û bûkani mi dî xwedanekî xêra rabû ser darê pêyan e go Eyşê lê Eyşa Îbê, bînbaşya qîzan û bûkanê sibe bû Hemê Hacî lawê Gozê xwedanê martêliyê qaçax û '''firyarê''' dewletê îro...|sal=2022|nivîskar=Ömer Güneş & İbrahim Şahin|url=http://books.google.com.tr/books?id=ZXaAEAAAQBAJ&pg=PA206&dq=%22wan+firyaran%22+OR+%22firyar%C3%AA%22+OR+%22firyarin%22+OR+%22firyarek%C3%AA%22+OR+%22firyara%22+OR+%22w%C3%AA+firyar%C3%AA%22+OR+%22firyarino%22+OR+%22firyarine%22&hl=&cd=1&source=gbs_api|sernav=Dengbêj Şakiro|weşanxane=Nûbihar|ISBN=9786059413435|rûpel=206}} #* {{jêder-kovar|ku|jêgirtin=... '''firyarê''' mala şêx e. Bê lo, lo, lo, lo, lo, lo, lo, lo, lo, lo, lolî - lolyo, Wezê Qulpê, Axtaşê, li Gewgewê Îdirê diketim li orta dinê, Siyarê Qulpê, Axtaşê, Gewgewê Îdirê kişyane ser Şêx Zahar efendî bi hicûma...|sal=2023|nivîskar=Nûbihar|url=http://books.google.com.tr/books?id=Ry3BEAAAQBAJ&pg=PA41&dq=%22wan+firyaran%22+OR+%22firyar%C3%AA%22+OR+%22firyarin%22+OR+%22firyarek%C3%AA%22+OR+%22firyara%22+OR+%22w%C3%AA+firyar%C3%AA%22+OR+%22firyarino%22+OR+%22firyarine%22&hl=&cd=2&source=gbs_api|kovar=Nûbihar|hejmar=163|rûpel=41}} #*{{jêder-kitêb|ku|jêgirtin=Wekî sepaneke vekolanê, meş jêderka sirûşê ye bi raya şa’iran, xeyalperestan, yaxî û baxîyan û ektîvîstên ku dimeşin û hey digerin, bi raya '''firyarên''' ku bi peyatî baz dane, bi raya derbideran û civakên di mihesereyê de mayî; bi raya Soryalîstan û Sîçûeyşinistan, ji ber sepanên xwe yên saykocografyayê û dériveyan (xweberdanan); bi raya koma “Stalker: Observatoir Nomade”ê, ku di qelşên bajêr de bi kombendî dimeşe;|sal=2021|terciman=Kawa Nemir|sernav=Digel Bêmilkkirinê. Kitêbeke Çalakîyan}} #*{{jêder-kovar|ku|jêgirtin=lo lawo li vî welatê Serhedê<br>tu yê qisr û qusûrê li me nekî<br>de tu yê pêşîka '''firyarê''' me berdî<br>lo bira paşiya qaçaxê me hereeewûûû|r=49|sernav=Stranek li Ser Seyidxanê Kerr|nivîskar=Ev stran ji pirtûka Zeynelabidîn Zinar, Xwençe, cild 2, r.57- 59-an hatiye girtin.|kovar=Çira|sal=1996|hejmar=5}} ==== Tewandin ==== {{ku-tewîn-nav|mê û nêr}} ==== Etîmolojî ==== Ji {{qf|ku|fir|-yar}} mihtemelen bi riya {{lihevanîna dengî-maneyî|ar|ku|فِرار|t=firar|hûr=1}}. ==== Werger ==== {{werger-ser|kesê ku direve an jî bi dizî ji cihekî diçe cihekî din daku neyê girtin|1}} * {{Z|en}}: {{W|en|fugitive}} {{werger-bin}} 01n9dyxw49dsbcoxgazhg2voxfzz7n1 6333905 6333885 2026-08-15T21:12:09Z Balyozbot 7867 Bot: Paqijiyên kozmetîk (Lînk paqij kir, +Valahiya lîsteyan.) 6333905 wikitext text/x-wiki == {{ziman|ku}} == === Navdêr 1 === {{navdêr|ku|z=mn}} # {{K|ku|meslek|hewavanî}} {{e|ku|gelek|nadir|tenê di çend ferhengan de}} [[kes|Kesê]] ku [[balafir]]an [[ajotin|diajo]].<ref>{{Ferhenga Destî|r=123}}</ref> #: {{hevmane|ku|pîlot}} #* {{nimûne?|ku}} ==== Tewandin ==== {{ku-tewîn-nav|mê û nêr}} ==== Etîmolojî ==== Ji {{qf|ku|fir|-yar}}. ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|خلبان}}<ref>{{ferhenga kurdî-farsî}}</ref> * {{Z|tr}}: {{W+|tr|pilot}}<ref>{{Zana Farqînî|r=645}}</ref> {{werger-bin}} ==== Çavkanî ==== {{Çavkanî}} === Navdêr 2 === {{navdêr|ku|c=mn}} # [[kes|Kesê]] ku [[revîn|direve]] [[an jî]] [[bi dizî]] ji [[cih]]ekî [[çûn|diçe]] cihekî [[din]] [[daku]] [[hatin|neyê]] [[girtin]]. #* {{jêder-kitêb|ku|jêgirtin=... '''firyarê''' dewletê bi tabûr û eskerê nîzamê mi pirskirî ji van qîzan û bûkani mi dî xwedanekî xêra rabû ser darê pêyan e go Eyşê lê Eyşa Îbê, bînbaşya qîzan û bûkanê sibe bû Hemê Hacî lawê Gozê xwedanê martêliyê qaçax û '''firyarê''' dewletê îro...|sal=2022|nivîskar=Ömer Güneş & İbrahim Şahin|url=http://books.google.com.tr/books?id=ZXaAEAAAQBAJ&pg=PA206&dq=%22wan+firyaran%22+OR+%22firyar%C3%AA%22+OR+%22firyarin%22+OR+%22firyarek%C3%AA%22+OR+%22firyara%22+OR+%22w%C3%AA+firyar%C3%AA%22+OR+%22firyarino%22+OR+%22firyarine%22&hl=&cd=1&source=gbs_api|sernav=Dengbêj Şakiro|weşanxane=Nûbihar|ISBN=9786059413435|rûpel=206}} #* {{jêder-kovar|ku|jêgirtin=... '''firyarê''' mala şêx e. Bê lo, lo, lo, lo, lo, lo, lo, lo, lo, lo, lolî - lolyo, Wezê Qulpê, Axtaşê, li Gewgewê Îdirê diketim li orta dinê, Siyarê Qulpê, Axtaşê, Gewgewê Îdirê kişyane ser Şêx Zahar efendî bi hicûma...|sal=2023|nivîskar=Nûbihar|url=http://books.google.com.tr/books?id=Ry3BEAAAQBAJ&pg=PA41&dq=%22wan+firyaran%22+OR+%22firyar%C3%AA%22+OR+%22firyarin%22+OR+%22firyarek%C3%AA%22+OR+%22firyara%22+OR+%22w%C3%AA+firyar%C3%AA%22+OR+%22firyarino%22+OR+%22firyarine%22&hl=&cd=2&source=gbs_api|kovar=Nûbihar|hejmar=163|rûpel=41}} #* {{jêder-kitêb|ku|jêgirtin=Wekî sepaneke vekolanê, meş jêderka sirûşê ye bi raya şa’iran, xeyalperestan, yaxî û baxîyan û ektîvîstên ku dimeşin û hey digerin, bi raya '''firyarên''' ku bi peyatî baz dane, bi raya derbideran û civakên di mihesereyê de mayî; bi raya Soryalîstan û Sîçûeyşinistan, ji ber sepanên xwe yên saykocografyayê û dériveyan (xweberdanan); bi raya koma “Stalker: Observatoir Nomade”ê, ku di qelşên bajêr de bi kombendî dimeşe;|sal=2021|terciman=Kawa Nemir|sernav=Digel Bêmilkkirinê. Kitêbeke Çalakîyan}} #* {{jêder-kovar|ku|jêgirtin=lo lawo li vî welatê Serhedê<br>tu yê qisr û qusûrê li me nekî<br>de tu yê pêşîka '''firyarê''' me berdî<br>lo bira paşiya qaçaxê me hereeewûûû|r=49|sernav=Stranek li Ser Seyidxanê Kerr|nivîskar=Ev stran ji pirtûka Zeynelabidîn Zinar, Xwençe, cild 2, r.57- 59-an hatiye girtin.|kovar=Çira|sal=1996|hejmar=5}} ==== Tewandin ==== {{ku-tewîn-nav|mê û nêr}} ==== Etîmolojî ==== Ji {{qf|ku|fir|-yar}} mihtemelen bi riya {{lihevanîna dengî-maneyî|ar|ku|فِرار|t=firar|hûr=1}}. ==== Werger ==== {{werger-ser|kesê ku direve an jî bi dizî ji cihekî diçe cihekî din daku neyê girtin|1}} * {{Z|en}}: {{W|en|fugitive}} {{werger-bin}} dmqfzr4znnjr0vxybra5h67n4t31g34 dardekirin 0 262864 6333922 6304620 2026-08-15T23:03:55Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333922 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[li sêdarê dan]]<ref>{{Ferhenga Kamêran}}</ref> # Kuştina bi awayê ku zindiyekî ji stû ve bête daleqandin û ji ber şidîna benê li stû nekaribe bêhnê bide û bistîne ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== Ji ''[[dar]] + [[de]] + [[kirin]]''. ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|idam}}, {{W+|tr|asmak}}, {{W-|tr|darağacında asmak|guman=erê}} {{werger-bin}} === Çavkanî === {{çavkanî}} ivkdivpcu44cvwrm37pel5374u1pauc darfiroş 0 262867 6333923 6304625 2026-08-15T23:04:45Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333923 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=mn}} # kesê daran difiroşin<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê û nêr}} ==== Bi alfabeyên din ==== * {{ku-ar|دارفرۆش}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W-|ar|الحطاب|guman=erê}}, {{W-|ar|خشاب|guman=erê}} * {{Z|en}}: {{W+|en|lumberman}}, {{W+|en|timberman|guman=erê}}, {{W-|en|wood merchant|guman=erê}} {{werger-bin}} === Çavkanî === {{çavkanî}} c2ck2ep2j0vwd68mfwrvkob1mriojua daxme 0 262896 6333924 6304703 2026-08-15T23:05:32Z Wikihez 7344 /* Heriwha */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333924 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[pinî]], [[xal]], [[nuqte]], [[leke]], [[nîşan]], [[pirsik]] # [[mor]]<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê|guherto=hemû}} ==== Bi alfabeyên din ==== * {{ku-ar|داخمە}} ==== Herwiha ==== * [[dexme]] ==== Etîmolojî ==== Dibe ji {{ji|fa|ku}}. ==== Çavkanî ==== {{çavkanî}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Schandmal|guman=erê}} * {{Z|fa}}: {{W+|fa|دخمه|guman=erê}}, {{W+|fa|سوراخ|guman=erê}} * {{Z|en}}: {{W+|en|spot}}, (2) {{W+|en|seal}} * {{Z|tr}}: {{W+|tr|dama}}, {{W+|tr|damga|guman=erê}}, {{W+|tr|en|guman=erê}}, {{W+|tr|enine boyuna|guman=erê}} {{werger-bin}} gp7wmtkz91z759o004w0ioe9k4q7nw6 6333980 6333924 2026-08-15T23:41:47Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333980 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[pinî]], [[xal]], [[nuqte]], [[leke]], [[nîşan]], [[pirsik]] # [[mor]]<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê|guherto=hemû}} ==== Bi alfabeyên din ==== * {{ku-ar|داخمە}} ==== Formên alternatîv ==== * [[dexme]] ==== Etîmolojî ==== Dibe ji {{ji|fa|ku}}. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Schandmal|guman=erê}} * {{Z|fa}}: {{W+|fa|دخمه|guman=erê}}, {{W+|fa|سوراخ|guman=erê}} * {{Z|en}}: {{W+|en|spot}}, (2) {{W+|en|seal}} * {{Z|tr}}: {{W+|tr|dama}}, {{W+|tr|damga|guman=erê}}, {{W+|tr|en|guman=erê}}, {{W+|tr|enine boyuna|guman=erê}} {{werger-bin}} ==== Çavkanî ==== {{çavkanî}} svqa55q4j4oqfh4job37hmc45qu52rr deqkirin 0 262928 6333926 6304897 2026-08-15T23:08:13Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333926 wikitext text/x-wiki {{bnr-l|deq kirin}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[deqdan]]<ref>https://web.archive.org/web/20160305060132/https://rojbas5.files.wordpress.com/2012/05/ferhenga-kamc3aaran.pdf Ferhenga Kamêran</ref>. ==== Tewandin ==== {{ku-tewîn-nav|mê}} ==== Etîmolojî ==== Ji {{pêk|ku|deq|kirin}}. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Tätowierung|m}}, {{W|de|Versengen}} * {{Z|ar}}: {{W|ar|عمل وشم}} * {{Z|en}}: {{W|en|tattooing}} {{werger-bin}} === Çavkanî === {{çavkanî}} tb84ozs2tdx3dl2dokfcryu4lu5mtne derbestkirin 0 262935 6333927 6304922 2026-08-15T23:08:36Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333927 wikitext text/x-wiki {{bnr-l|derbest kirin}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # dema derê [[amane]]kî bi hêt girtin<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== Ji {{pêk|ku|derbest|kirin}}. ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W+|en|commitment}}, {{W+|en|obligating}}, {{W|en|vouchsafing|guman=erê}}, {{W|en|committing|guman=erê}} {{werger-bin}} === Çavkanî === {{çavkanî}} 7y0w9wy2fys0335wlzyfuck9jt7x3ar derdestkirin 0 262939 6333928 6304935 2026-08-15T23:09:09Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333928 wikitext text/x-wiki {{bnr-l|derdest kirin}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[desteserkirin|Desteserkirin]]<ref>https://web.archive.org/web/20160305060132/https://rojbas5.files.wordpress.com/2012/05/ferhenga-kamc3aaran.pdf Ferhenga Kamêran</ref>. ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== Ji {{pêk|ku|derdest|kirin}}. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Gefangennahme|m}} {{werger-bin}} === Çavkanî === {{çavkanî}} c3cfemjt8cg9lq004zhugn4qwdhnu6j destbilindkirin 0 262982 6333931 6305042 2026-08-15T23:11:42Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333931 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # xwe dane [[dest]]<ref>{{Ferhenga Kamêran}}</ref>, [[teslîm]]kirin, [[radest]]kirin # [[daxaz]]a [[beşdarî|beşdari]]yê kirin ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|دەستبلندکرن}} ==== Jê ==== * [[destbilindkirî]] ==== Etîmolojî ==== [[dest]] + [[bilind]] + [[kirin]] ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W|ar|استلم}}, {{W|ar|رفع اليد}} * {{Z|en}}: {{W|en|surrender}}, {{W|en|raising hands}} {{werger-bin}} === Çavkanî === {{çavkanî}} tnjo8vy1t7xme4nlgu0x11al4wqhii5 6333982 6333931 2026-08-16T00:12:07Z Balyozbot 7867 Bot: Paqijiyên kozmetîk (Lînk paqij kir.) 6333982 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # xwe dane [[dest]]<ref>{{Ferhenga Kamêran}}</ref>, [[teslîm]]kirin, [[radest]]kirin # [[daxaz]]a [[beşdarî|beşdariyê]] kirin ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|دەستبلندکرن}} ==== Jê ==== * [[destbilindkirî]] ==== Etîmolojî ==== [[dest]] + [[bilind]] + [[kirin]] ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W|ar|استلم}}, {{W|ar|رفع اليد}} * {{Z|en}}: {{W|en|surrender}}, {{W|en|raising hands}} {{werger-bin}} === Çavkanî === {{çavkanî}} ry507h3sojwu70pg0zgimh7deeb64ni devbeş 0 263032 6333933 6305122 2026-08-15T23:12:33Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333933 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=mn}} # mirovê hertim devê wî vekirî # [[pirbêj]] # yê tuca ji xwarinê û gotinan têr nabe # [[devkenî]]<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê û nêr}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|خسیس}}, {{W+|fa|احمق}} * {{Z|en}}: {{W+|en|widemouthed}}, {{W|en|wide-mouthed|guman=erê}}, {{W|en|gaper|guman=erê}}, {{W|en|chatterbox}}, a {{W|en|foul-mouthed}} person {{werger-bin}} === Çavkanî === {{çavkanî}} 8f108yaguf61p2f1bzvignic713ln86 deverûkirin 0 263041 6333934 6305132 2026-08-15T23:12:53Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333934 wikitext text/x-wiki {{bnr-l|deverû kirin}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[sernişîvkirin]], [[berevajîkirin]], [[serabinkirin]]<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== Ji {{pêk|ku|deverû|kirin}}. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Verkehrung|f}} * {{Z|ar}}: {{W|ar|قلب }} {{werger-bin}} === Çavkanî === {{çavkanî}} prb8z9mx7ta99olm2ofubkdvdokz1i3 dilxweşkirin 0 263191 6333936 6305359 2026-08-15T23:13:49Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333936 wikitext text/x-wiki {{bnr-l|dilxweş kirin}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[mirov]] bi [[gotin]]an [[dil]]ê [[yek]]î [[xweş]] ke, [[kêfxweşkirin]], [[asûdekirin]], [[jibîrvekirin]], '':te bi wê mizgînîyê dilê xwe kir''<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|دلخوەشکرن}} ==== Dijmane ==== * [[acizkirin]] ==== Jê ==== * [[dilxweşker]] ==== Etîmolojî ==== Ji {{pêk|ku|dilxweş|kirin}}. ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W|ar|التفكیه}} * {{Z|en}}: {{W|en|delightfulness}} * {{Z|tr}}: {{W|tr|sevindirme}}, {{W|tr|taltif}} {{werger-bin}} === Çavkanî === {{çavkanî}} ijnm3djkczb3zos526av5iepsgra0uy hevalkar 0 263705 6333949 6308351 2026-08-15T23:26:08Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333949 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=mn}} # hevalên karî, [[hevkar]], '':ez û wî hevalkarin''<ref>https://web.archive.org/web/20160305060132/https://rojbas5.files.wordpress.com/2012/05/ferhenga-kamc3aaran.pdf Ferhenga Kamêran</ref> (sic: pê diviye wî bibe ew) # (rêziman) [[adverb]], [[zerf]] ==== Tewandin ==== {{ku-tewîn-nav/nû|mê û nêr}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W+|ar|زميل}}, {{W+|ar|رفيق}}, {{W+|ar|صاحب}}, {{W+|ar|حال}}, {{W+|ar|ظرف}} * {{Z|en}}: {{W+|en|adverb}}, {{W+|en|colleague}}, {{W+|en|co-worker}}, {{W+|en|teammate|guman=erê}} * {{Z|sdh}}: {{W|sdh|kurdiya rojava}}, {{W|sdh|tueki}} * {{Z|tr}}: {{W+|tr|koldaş}}, {{W+|tr|partner}}, {{W+|tr|iş arkadaşı}} {{werger-bin}} === Çavkanî === {{çavkanî}} dx32wn69qdgvk4ycn50jnvo8vvdzr33 hevîrkirin 0 263711 6333953 6308468 2026-08-15T23:28:36Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333953 wikitext text/x-wiki {{bnr-l|hevîr kirin}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[têkilkirin]]a [[av]]ê û arî, [[tevlihev]]kirina av û [[ar]] û [[zeyt]]ê , [[çêkirin]] û [[berhevkirin]]a hevîrî ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|هەڤیرکرن}} ==== Formên alternatîv ==== * [[hêvîrkirin]] ==== Etîmolojî ==== Ji {{qertaf|ku|hevîr|kirin}}. ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W|ar|العجن|guman=erê}} * {{Z|en}}: {{W|en|knead}}, {{W|en|pureeing|guman=erê}}, {{W|en|spackling|guman=erê}} {{werger-bin}} 323qfr0miyatjkyuz84xzl0q3vs2v47 jajerûn 0 263792 6333957 6309272 2026-08-15T23:30:44Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333957 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # xwarineke ji jajî û rûn ên di nav êk da qelandî dihêt berhevkirin<ref>{{Ferhenga Kamêran}}</ref> #: ''Li ser qûnê kete '''jajerûn'''ê'' #: ''Li ser qûnê ket kodika '''jajerûn'''ê'' #: ''Li ser qûnê ket nava '''jajerûn'''ê'' #: ''Ji xwe re nikane pelûrê çêke, ji hevalê xwe re '''jajerûn'''ê çêdike'' ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|نوعی لبنیات}} {{werger-bin}} ==== Çavkanî ==== {{çavkanî}} gwuix50m6tvpv3qvbmsx8febnm9zz88 6333958 6333957 2026-08-15T23:31:05Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6333958 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # xwarineke ji jajî û rûn ên di nav êk da qelandî dihêt berhevkirin<ref>{{Ferhenga Kamêran}}</ref> #: {{nimûne|ku|Li ser qûnê kete '''jajerûn'''ê}} #: {{nimûne|ku|Li ser qûnê ket kodika '''jajerûn'''ê}} #: {{nimûne|ku|Li ser qûnê ket nava '''jajerûn'''ê}} #: {{nimûne|ku|Ji xwe re nikane pelûrê çêke, ji hevalê xwe re '''jajerûn'''ê çêdike}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|نوعی لبنیات}} {{werger-bin}} ==== Çavkanî ==== {{çavkanî}} fc9vk1nhj13x4201axlvmkqgr9weijs jêkvekirin 0 263832 6333960 6309427 2026-08-15T23:32:02Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333960 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[cudakirin]], ji [[hev]] [[dûr]] xistin<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|ژێكڤه‌كرن}} ==== Etîmolojî ==== * [[jêk]] + [[ve]] + [[kirin]] ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W|ar|التفریق|guman=erê}}, {{W|ar|فخذ بینهم|guman=erê}} * {{Z|en}}: to {{W|en|separate}}, {{W|en|separation}}, {{W|en|depolymerization|guman=erê}} {{werger-bin}} === Çavkanî === {{çavkanî}} 6pripm51oyjexrsk1gon3g2wal9r8yn kêfkirin 0 263987 6333992 6310882 2026-08-16T00:58:48Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333992 wikitext text/x-wiki {{bnr-l|kêf kirin}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # demên dilveker derbaz kirin, [[bi keyf ketin]]<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|کێفکرن}} ==== Etîmolojî ==== Ji {{pêk|ku|kêf|kirin}}. {{kontrolWergerr}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Genießen}} * {{Z|en}}: {{W|en|pleasure-seeking}}, {{W|en|jolly|guman=erê}}, {{W|en|jollying|guman=erê}}, {{W|en|junket|guman=erê}}, {{W|en|wiling|guman=erê}} * {{Z|tr}}: {{W|tr|eğlenme}}, {{W|tr|gönenme}}, {{W|tr|keyfetme}}, {{W|tr|seviniş}}, {{W|tr|sevinme}}, {{W|tr|sıcaklık}}, {{W|tr|şenelme}} {{werger-bin}} === Çavkanî === {{çavkanî}} pvtffjg8kii4lbti0g0iiunfdr6jxxb marekirin 0 264238 6333998 6311659 2026-08-16T01:03:22Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333998 wikitext text/x-wiki {{bnr-l|mare kirin}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[markirin]]<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|ماره‌كرن}} ==== Werger ==== {{werger-ser}} * {{Z|ar}}:{{W|ar|الزواج|guman=erê}} {{werger-bin}} === Çavkanî === {{çavkanî}} 5azwllzppoirxx0rhue001fhad5pqoy maytêkirin 0 264251 6334002 6311729 2026-08-16T01:05:47Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334002 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[dest]] di [[kar]]ên xelikî [[werdan]], [[bu]] wan mirova [[tê]] [[gotin]] yên mayê xwe di hemû karan diken<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Jê ==== * [[maytêker]] ==== Etîmolojî ==== [[may]] + -tê + [[kirin]] ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W|ar|عنى}}, {{W|ar|شأن}}, {{W|ar|تدخل}} * {{Z|en}}: to be a {{W+|en|busy-body}}, to {{W+|en|put your nose into someone's business}}, {{W|en|intervene}}, interfere * {{Z|tr}}: {{W|tr|müdahale}} {{werger-bin}} === Çavkanî === {{çavkanî}} fzijb9a7oec3fi7fn7zyl2ohsgcindt neçarkirin 0 264357 6334015 6313391 2026-08-16T01:16:14Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334015 wikitext text/x-wiki {{bnr-l|neçar kirin}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[mecbûr]] kirin, [[bêçare]], ya / yê ku ti [[çare]] anku [[hel]] nîne, neçarkirin<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|نه‌چاركرن}} ==== Etîmolojî ==== Ji {{pêk|ku|neçar|kirin}}. ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W|ar|الإلجاء|guman=erê}}, {{W|ar|الإلزام|guman=erê}} * {{Z|en}}: to be {{W|en|forced}}, {{W|en|forcing someone}}, {{W|en|obligatory}} {{werger-bin}} === Çavkanî === {{çavkanî}} octim056lwvt8toq0eg9jpfrws2zb2t nûber 0 264524 6334018 6313708 2026-08-16T01:17:55Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334018 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=mn}} # zarokê yekê, berê yekê, [[nexrî]]<ref>{{Ferhenga Kamêran}}</ref> # [[nûgihîştî]], [[nûçêbûyî]], [[berhem]]ek ku [[nû]] gihîştîbe, [[teze]] be ==== Tewandin ==== {{ku-tewîn-nav/nû|mê û nêr}} === Rengdêr === {{rengdêr|ku}} # zarokê yekê, berê yekê, [[nexrî]] ==== Etîmolojî ==== Ji {{qertaf|ku|nû|ber}}. ==== Werger ==== {{werger-ser|zarokê yekê (navdêr)}} * {{Z|en}}: {{W+|en|firstling}}, {{W+|en|first-born}}, {{W+|en|firstborn}} * {{Z|tr}}: {{W+|tr|turfanda}} {{werger-bin}} {{werger-ser|zarokê yekê (rengdêr)}} * {{Z|en}}: {{W+|en|first-born}} {{werger-bin}} {{werger-ser|berhema nû}} * {{Z|en}}: {{W-|en|fresh product}}, {{W+|en|firstfruit|guman=erê}} {{werger-bin}} === Çavkanî === {{çavkanî}} sujx0tmbj0drm8pai9tnra8vkwc25vl 6334019 6334018 2026-08-16T01:18:28Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334019 wikitext text/x-wiki == {{ziman|ku}} == ==== Etîmolojî ==== Ji {{qertaf|ku|nû|ber}}. === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=mn}} # zarokê yekê, berê yekê, [[nexrî]]<ref>{{Ferhenga Kamêran}}</ref> # [[nûgihîştî]], [[nûçêbûyî]], [[berhem]]ek ku [[nû]] gihîştîbe, [[teze]] be ==== Tewandin ==== {{ku-tewîn-nav/nû|mê û nêr}} === Rengdêr === {{rengdêr|ku}} # zarokê yekê, berê yekê, [[nexrî]] ==== Werger ==== {{werger-ser|zarokê yekê (navdêr)}} * {{Z|en}}: {{W+|en|firstling}}, {{W+|en|first-born}}, {{W+|en|firstborn}} * {{Z|tr}}: {{W+|tr|turfanda}} {{werger-bin}} {{werger-ser|zarokê yekê (rengdêr)}} * {{Z|en}}: {{W+|en|first-born}} {{werger-bin}} {{werger-ser|berhema nû}} * {{Z|en}}: {{W-|en|fresh product}}, {{W+|en|firstfruit|guman=erê}} {{werger-bin}} === Çavkanî === {{çavkanî}} 9ssycote0bdf293l7zp2stfdy8s33gy 6334020 6334019 2026-08-16T01:18:35Z Wikihez 7344 /* Etîmolojî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334020 wikitext text/x-wiki == {{ziman|ku}} == === Etîmolojî === Ji {{qertaf|ku|nû|ber}}. === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=mn}} # zarokê yekê, berê yekê, [[nexrî]]<ref>{{Ferhenga Kamêran}}</ref> # [[nûgihîştî]], [[nûçêbûyî]], [[berhem]]ek ku [[nû]] gihîştîbe, [[teze]] be ==== Tewandin ==== {{ku-tewîn-nav/nû|mê û nêr}} === Rengdêr === {{rengdêr|ku}} # zarokê yekê, berê yekê, [[nexrî]] ==== Werger ==== {{werger-ser|zarokê yekê (navdêr)}} * {{Z|en}}: {{W+|en|firstling}}, {{W+|en|first-born}}, {{W+|en|firstborn}} * {{Z|tr}}: {{W+|tr|turfanda}} {{werger-bin}} {{werger-ser|zarokê yekê (rengdêr)}} * {{Z|en}}: {{W+|en|first-born}} {{werger-bin}} {{werger-ser|berhema nû}} * {{Z|en}}: {{W-|en|fresh product}}, {{W+|en|firstfruit|guman=erê}} {{werger-bin}} === Çavkanî === {{çavkanî}} a2jzf3ye9l4e9bcsbgmxs5ntw5i6dh4 parçeparçekirin 0 264578 6334042 6314027 2026-08-16T01:45:00Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334042 wikitext text/x-wiki {{bnr-l|parçeparçe kirin}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[qedqedkirin]], [[pirtpirtkirin]], [[qedkirin]], [[hûrkirin]], [[kerkirin]], [[beşkirin]], [[parçkirin]], [[hincinîn]]<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|پارچەپارچەکرن}} ==== Etîmolojî ==== Ji {{pêk|ku|parçeparçe|kirin}}. ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W-|en|cutting into pieces}}, {{W+|en|partition}}, {{W+|en|fractionalizing|guman=erê}} * {{Z|tr}}: {{W+|tr|paralama}} {{werger-bin}} === Çavkanî === {{çavkanî}} d6q0ub96bq9l1buy7paqov24o3m3a2i peytkirin 0 264728 6334039 6314507 2026-08-16T01:43:13Z Wikihez 7344 ([[m:Special:MyLanguage/User:Jon Harald Søby/diffedit|diffedit]]) 6334039 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[serûberkirin]], [[rêkûpêkkirin]], [[qayîmkirin]]<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} === Çavkanî === {{çavkanî}} ==== Etîmolojî ==== Ji {{pêk|ku|peyt|kirin}}. ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W+|en|concentrating|guman=erê}} * {{Z|tr}}: {{W+|tr|sağlamlama}}, {{W+|tr|sağlamlaştırma}} {{werger-bin}} 8l2tvk0grt1mj2d6tpqfb5os9ibugwi 6334040 6334039 2026-08-16T01:43:31Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334040 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[serûberkirin]], [[rêkûpêkkirin]], [[qayîmkirin]]<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== Ji {{pêk|ku|peyt|kirin}}. ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W+|en|concentrating|guman=erê}} * {{Z|tr}}: {{W+|tr|sağlamlama}}, {{W+|tr|sağlamlaştırma}} {{werger-bin}} === Çavkanî === {{çavkanî}} d5d52qum9dq99oo51hkve7ym8mw3mnk pêşbînîkirin 0 264792 6334052 6315173 2026-08-16T02:08:45Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334052 wikitext text/x-wiki {{bnr-l|pêşbînî kirin}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[têbînîkirin]], [[hizir]] [[zanîn]]a [[pêşeroj]]ê û xwe jibo berhev kirin<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|پێشبینیكرن}} ==== Etîmolojî ==== Ji {{pêk|ku|pêşbînî|kirin}}. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Hochrechnung|f|guman=erê}} * {{Z|ar}}: {{W-|ar|التفرس|guman=erê}}, {{W-|ar|التكهن|guman=erê}}, {{W-|ar|التوسیم|guman=erê}}, {{W-|ar|التوقیع|guman=erê}} * {{Z|en}}: {{W+|en|expectation}}, {{W+|ar|prediction}}, {{W+|en|previsioning|guman=erê}}, {{W+|en|expect|guman=erê}} {{werger-bin}} === Çavkanî === {{çavkanî}} 157pan510drzsxg7u4idayvapm0ajjr pîtepêkirin 0 264942 6334054 6315316 2026-08-16T02:10:22Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334054 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # ne [[ihmal]][[kirin]]a kesek/tiştekî, [[bayexpêdan]], [[giringîpêdan]]<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== * [[pîte]] + [[pê]] + [[kirin]] === Dijmane === * [[pûtepênekirin]] ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W-|en|giving attention}}, {{W-|en|cast a glance}} {{werger-bin}} === Çavkanî === {{çavkanî}} 9wq4kaqhk3ub44fcsmhwacaahid8wlb 6334055 6334054 2026-08-16T02:10:32Z Wikihez 7344 /* Dijmane */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334055 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # ne [[ihmal]][[kirin]]a kesek/tiştekî, [[bayexpêdan]], [[giringîpêdan]]<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== * [[pîte]] + [[pê]] + [[kirin]] ==== Dijmane ==== * [[pûtepênekirin]] ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W-|en|giving attention}}, {{W-|en|cast a glance}} {{werger-bin}} === Çavkanî === {{çavkanî}} 0nvnlp74p3gvoh19egr7nhcqzo47zcj 6334066 6334055 2026-08-16T02:41:13Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6334066 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # ne [[ihmal]][[kirin]]a kesek/tiştekî, [[bayexpêdan]], [[giringîpêdan]]<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Dijmane ==== * [[pûtepênekirin]] ==== Etîmolojî ==== * [[pîte]] + [[pê]] + [[kirin]] ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W-|en|giving attention}}, {{W-|en|cast a glance}} {{werger-bin}} === Çavkanî === {{çavkanî}} 2u1pp9jgtxuln8r1t50mzkgosfojiro qaçaxçî 0 264957 6333919 6141162 2026-08-15T22:50:17Z Wikihez 7344 /* Etîmolojî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333919 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{rengdêr|ku}} # kesa/ê ku [[kar]]ên [[qaçax]] dike, <br>bi taybetî kesa/ê ku [[kelûpel]]an yan [[mirov]]an bi [[qaçaxî]] ji [[welat]]ekî [[birin|dibe]] [[welat]]ekî din ==== Etîmolojî ==== Ji {{ji|ota|ku|قاچاقچي|tr=qaçaqçi}} yan ji {{ji|tr|ku|kaçakçı}}.{{anlz|ku|qaçax|-çî}}. ==== Werger ==== {{werger-ser}} * {{Z|sq}}: {{W+|sq|kontrabandist|n}} * {{Z|de}}: {{W+|de|Schmuggler|n}}, {{W+|de|Schmugglerin|m}} * {{Z|az}}: {{W-|az|qaçaq}}, {{W-|az|qaçaqçı}} * {{Z|be}}: {{W-|be|кантрабанды́ст|n}}, {{W-|be|кантрабанды́стка|m}} * {{Z|bg}}: {{W-|bg|контрабанди́ст|n}}, {{W-|bg|контрабанди́стка|m}} * {{Z|cs}}: {{W+|cs|pašerák|n}}, {{W-|cs|pašeračka|m}}, {{W-|cs|podloudník|n}}, {{W-|cs|podloudnice|m}} * {{Z|zh}}: *: {{Z|cmn}}: {{W-|cmn|走私者|tr=zǒusīzhě}}, {{W-|cmn|走私販|tr=zǒusīfàn}}, {{W-|cmn|走私犯|tr=zǒusīfàn}} * {{Z|da}}: {{W-|da|smugler|g}} * {{Z|id}}: {{W+|id|penyelundup}} * {{Z|ar}}: {{W-|ar|مُهَرِّب|n}} * {{Z|hy}}: {{W+|hy|մաքսանենգ}} * {{Z|et}}: {{W-|et|salakaubavedaja}} * {{Z|fa}}: {{W+|fa|قاچاقچی|tr=qâčâqči}} * {{Z|fi}}: {{W+|fi|salakuljettaja}} * {{Z|fr}}: {{W+|fr|contrebandier|n}}, {{W+|fr|contrebandière|m}} * {{Z|ka}}: {{W-|ka|კონტრაბანდისტი}} * {{Z|hi}}: {{W+|hi|तस्कर|n}}, {{W-|hi|स्मग्लर|n}}, {{W-|hi|महसूलमार|n}} * {{Z|nl}}: {{W+|nl|smokkelaar|n}} * {{Z|he}}: {{W-|he|מַברִיחַ|n}} * {{Z|en}}: {{W+|en|smuggler}} * {{Z|it}}: {{W+|it|contrabbandiere|n}} * {{Z|is}}: {{W-|is|smyglari|n}} * {{Z|ja}}: {{W-|ja|密輸業者|tr=みつゆぎょうしゃ, mitsuyu gyōsha}} * {{Z|ca}}: {{W+|ca|contrabandista}}, {{W+|ca|passador|n}} * {{Z|ky}}: {{W-|ky|контрабандист}}, {{W-|ky|контрабандачы}}, {{W+|ky|аткезчи}} * {{Z|ko}}: {{W+|ko|밀수범}}, {{W+|ko|밀수업자}} * {{Z|lv}}: {{W-|lv|kontrabandists|n}} * {{Z|lt}}: {{W-|lt|kontrabandininkas|n}} * {{Z|mk}}: {{W-|mk|криумчар|n}}, {{W-|mk|шверцер|n}} * {{Z|ms}}: {{W-|ms|penyeludup}} * {{Z|mi}}: {{W-|mi|kaikuhu tāhae}}, {{W-|mi|kaikawe tāhae}} * {{Z|hu}}: {{W+|hu|csempész}} * {{Z|nrf}}: {{W-|nrf|fraudeux|n}} * {{Z|no}}: *: {{Z|nb}}: {{W+|nb|smugler|n}} *: {{Z|nn}}: {{W-|nn|smuglar|n}} * {{Z|ug}}: {{W-|ug|ئەتكەسچى}} * {{Z|uz}}: {{W+|uz|kontrabandist}}, {{W-|uz|kontrabandachi}} * {{Z|ps}}: {{W-|ps|قاچاقچي|n|tr=qāčāqči}}, {{W-|ps|قاچاقبر|n|tr=qāčāqbar}} * {{Z|pl}}: {{W+|pl|przemytnik|n}}, {{W+|pl|przemytniczka|m}}, {{W+|pl|szmugler|n}}, {{W+|pl|szmuglerka|m}}, {{W+|pl|kontrabandzista|n}}, {{W-|pl|kontrabandzistka|m}} * {{Z|pt}}: {{W-|pt|contrabandista|n|m}} * {{Z|kk}}: {{W-|kk|контрабандашы}} * {{Z|ro}}: {{W+|ro|contrabandist|n}} * {{Z|ru}}: {{W+|ru|контрабанди́ст|n}}, {{W+|ru|контрабанди́стка|m}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|крѝјумча̄р|n}} *: Latînî: {{W+|sh|krìjumčār|n}} * {{Z|sk}}: {{W-|sk|pašerák|n}}, {{W-|sk|pašeračka|m}} * {{Z|sl}}: {{W-|sl|tihotapec|n}}, {{W-|sl|tihotapka|m}} * {{Z|es}}: {{W-|es|contrabandista|n}} * {{Z|sv}}: {{W+|sv|smugglare|g}} * {{Z|tg}}: {{W-|tg|қочоқчӣ}} * {{Z|tl}}: {{W-|tl|mamumuslit}} * {{Z|th}}: {{W-|th|ผู้ลักลอบ}} * {{Z|tr}}: {{W+|tr|kaçakçı}} * {{Z|tk}}: {{W-|tk|kontrabandaçy}} * {{Z|uk}}: {{W-|uk|контрабанди́ст|n}}, {{W-|uk|контрабанди́стка|m}} * {{Z|vi}}: {{W-|vi|[[người]] [[buôn lậu]]}} * {{Z|el}}: {{W+|el|λαθρέμπορος|n}} {{werger-bin}} :{{werger çavkanî|en|smuggler|beş=Ev qismê Wergerê|oldid=76164275}} === Çavkanî === {{çavkanî}} hmk6en8kw2opv6qo491mrc5zmri0xur qurtalkirin 0 265095 6334061 6316063 2026-08-16T02:16:26Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334061 wikitext text/x-wiki {{bnr-l|qurtal kirin}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[rizgarkirin]], [[xilas kirin]], [[azadkirin]], ji [[dest]]an [[anîn]] der<ref>{{Ferhenga Kamêran}}</ref> ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|قورتالكرن}} ==== Jê ==== * [[qurtalker]] ==== Etîmolojî ==== Ji {{pêk|ku|qurtal|kirin}}. ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W-|ar|الإستخلاص|guman=erê}} * {{Z|en}}: {{W+|en|release}}, {{W+|en|liberation}}, {{W+|en|rescue}}, {{W+|en|salvation}}, {{W+|en|rescuing|guman=erê}} {{werger-bin}} === Çavkanî === {{çavkanî}} j1iapqsnlpxj3hjimf946mite2spzkx şîrhe 0 265966 6334081 6288140 2026-08-16T07:51:43Z Keyomerd 8814 /* Navdêr */ 6334081 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[çeper]], [[dîwar]], [[kelek]]<ref>{{Ferhenga Kamêran}}</ref> #: '''''Şîrheke''' mezin û qayim hebû, me nekarî em derbas bin.'' ==== Bi alfabeyên din ==== * {{ku-ar|شیرهە}} ==== Formên alternatîv ==== * [[şwîrhe]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W-|en|outer walls}} of a city, {{W+|en|wall|guman=erê}} {{werger-bin}} ==== Çavkanî ==== {{çavkanî}} cni7dnqy2xhsnb0nmhtmh83tnj3x74t otokrasî 0 282156 6334021 6313843 2026-08-16T01:20:07Z Wikihez 7344 /* Têkildar */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334021 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[şêwe]]yek ji [[rêveberî]] û [[hukim]] ku [[hêz]] hemû di [[dest]]ê [[yek]] kesekî de ye ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Têkildar ==== * [[otokrat]] * [[otokratîk]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W+|en|autocracy}} * {{Z|tr}}: {{W+|tr|otokrasi|guman=erê}} {{werger-bin}} ijjfakek1ojxga3s95vigfe4og3ridg kalekol 0 322635 6333962 6309528 2026-08-15T23:33:41Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333962 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # (''li [[Tirkiye|Tirkiyê]]'') [[qereqol]]ên li ser [[sinor]]an yên zexmtir û mihkemtir ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * [[qeleqol]] ==== Têkilî ==== * [[qereqol]] ==== Ji wêjeyê ==== * {{jêder|ku|jêgirtin=Li Wanê kalekol hatin protestokirin|ku.firatnews.com 4/2014}} ==== Etîmolojî ==== Ji {{ji|tr|ku|-}} ''kalekol'' ji [[kale]] ([[keleh]], [[kelhe]], [[qele]]) li ber modêla [[karakol]] ([[qereqol]]) ==== Werger ==== {{werger-ser}} * {{Z|tr}}: kalekol, yüksek güvenlikli sınır karakolu {{werger-bin}} 5l5wwxqtk6eak4wjj8hvesok349wjbp 6333967 6333962 2026-08-15T23:41:08Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333967 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # (''li [[Tirkiye|Tirkiyê]]'') [[qereqol]]ên li ser [[sinor]]an yên zexmtir û mihkemtir ==== Ji wêjeyê ==== * {{jêder|ku|jêgirtin=Li Wanê kalekol hatin protestokirin|ku.firatnews.com 4/2014}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * [[qeleqol]] ==== Têkildar ==== * [[qereqol]] ==== Etîmolojî ==== Ji {{ji|tr|ku|-}} ''kalekol'' ji [[kale]] ([[keleh]], [[kelhe]], [[qele]]) li ber modêla [[karakol]] ([[qereqol]]) ==== Werger ==== {{werger-ser}} * {{Z|tr}}: kalekol, yüksek güvenlikli sınır karakolu {{werger-bin}} t3p1k49pc9zsuv9f7owgqbt74mwmkci desperasyon 0 322642 6333929 6305027 2026-08-15T23:10:10Z Wikihez 7344 /* Kurmancî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333929 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[bêhêvîtî]], [[bêçaretî]] #* {{jêder|ku|jêgirtin=Dema ko mirov li reftarên PKK-ê û KCK-ê temaşa dike haletekê '''desperesyonê''' (bêçaretiyê) di gotin û kirinên wan de diyar dibe.|Nefel.com 4/2014}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Têkildar ==== * [[desperat]] ==== Etîmolojî ==== Ji {{ji|fr|ku|desperation}} ji {{ji|la}} [[desperatio|dēspērātiō]] ji [[desperatus]] ([[bêhêvî]], [[bêçare]], [[desperat]]) ji [[despero|dēspērō]] ([[bêhêvî]] bûn, [[hêvî|hêviya]] xwe [[ji dest dan]]) ji [[de-]] ([[ne-]], [[bê-]]) + [[spero|spērō]] ([[hêvî]] kirin) ji [[spes]] ([[hêvî]]) ==== Werger ==== * {{en}}: [[desperation]] o4aj4jkj8kz4ny6x5cerclzs5ln4vel 6333930 6333929 2026-08-15T23:10:46Z Wikihez 7344 /* Werger */ 6333930 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[bêhêvîtî]], [[bêçaretî]] #* {{jêder|ku|jêgirtin=Dema ko mirov li reftarên PKK-ê û KCK-ê temaşa dike haletekê '''desperesyonê''' (bêçaretiyê) di gotin û kirinên wan de diyar dibe.|Nefel.com 4/2014}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Têkildar ==== * [[desperat]] ==== Etîmolojî ==== Ji {{ji|fr|ku|desperation}} ji {{ji|la}} [[desperatio|dēspērātiō]] ji [[desperatus]] ([[bêhêvî]], [[bêçare]], [[desperat]]) ji [[despero|dēspērō]] ([[bêhêvî]] bûn, [[hêvî|hêviya]] xwe [[ji dest dan]]) ji [[de-]] ([[ne-]], [[bê-]]) + [[spero|spērō]] ([[hêvî]] kirin) ji [[spes]] ([[hêvî]]) ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W|en|desperation}} {{werger-bin}} 8qio8mxkyeef7atfo4oudztdf9hgxct qotik 0 379832 6334060 6315975 2026-08-16T02:12:40Z Wikihez 7344 /* Jêrenot û çavkanî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334060 wikitext text/x-wiki {{bnr-h|qotîk}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr 1 === {{navdêr|ku|z=m}} # {{f|ku|bijîşkî}} [[nexweşî|Nexweşiyek]] e ku dibe [[sedem]]a [[mirin]]a gelek kesan.<ref>{{Chyet2020|cild=M-Z}}</ref> #: {{hevmaneyên peyvê|ku|şob|weba|pejî}} #* {{jêder-malper |ku|jêgirtin=Sala 2020 ji tevayiya dinyayê ra bû sala '''qotikê''', epîdemiya Coronayê însan di malên wan da kirin girtî. |nivîskar={{w|Zinarê Xamo}}|sernav=Çînî rehet nasekinin|url=https://zinarexamo.blogspot.com/2021/01/cini-rehet-nasekinin.html|malper=zinarexamo.blogspot.com|sal=2021 }} #* {{jêder |ku|{{Jêgirtin/Mahmûd Lewendî/Compûtera ber dilê min/2002|r=13}}|jêgirtin=Di malbata me de, hetta di nav eşîra me de -yên ko bi destê hukmatê hatine kuştin û yên ko bi '''qotikê''' mirine ne tê de- kes bi ciwanî nemirîye. }} #* {{jêder-pirtûk |ku|jêgirtin=Belkî tu bivî para xurî-sorika!<br>Belkî tu rûvîya qertemezê kevî!<br>Lê '''qotikê''' lê girtî!<br>Firnê tera bê! |nivîskar={{w|Ordîxanê Celîl}}|sernav=Zargotina Kurda 2|cih=Moskva|sal=1978|rûpel=451 }} #* {{jêder-pirtûk |ku|jêgirtin=Kêf, kêfa serleşker bû<br>'''Qotik''' ketibû nav me<br>Bersivvanek jî pêyda nedibû<br>Gundîyên din jî ser zik li erdê mabûn<br>Çi danenîyan serê zarokan |nivîskar={{w|Evîn Çîçek}}|sernav=Awaza Serpêhatîyan 3|weşanxane=Weşanên Pêrî|sal=2004|rûpel=43|isbn=975-8245-95-7 }} # {{f|ku|bijîşkî}} [[nexweşî|Nexweşiyeke]] [[zarok]]an e ku dibe [[sedem]]a [[kuxik]]ê.<ref name = "FDestî">{{Ferhenga Destî|r=325}}</ref><ref name = "Farqînî" >{{Zana Farqînî|r=1530}}</ref><ref>{{pirtûk|nivîskar=Mikail Bülbül|nivîskar2=Dr. İsrafil Bülbül|sernav=Kürtçe Anamnez Anamneza bi Kurmancî|weşanxane=DİYARBAKIR TABİP ODASI YAYINLARI|sal=2009|rûpel=52}}</ref> #: {{hevmaneyên peyvê|ku|xeneqûtik|xenoq|bexikî}} #* {{jêgirtin?|ku}} # {{f|ku|heywannasî|bijîşkî}} [[nexweşî|Nexweşiyeke]] heywanan e ku dibe [[sedem]]a [[mirin]]a wan (bi taybetî [[pez]]).<ref>{{ferhenga Bozarslan|cild=L-R|r=779}}</ref><ref name = "MGazî">{{mustafa gazî|r=109}}</ref><ref>{{kovara kurmancî|hejmar=48|sernav=Navên hin nexweşiyên heywanan|nivîskar=Lezgînê ÇALÎ û Rûken BAGDU-KESKÎN}}</ref> #* {{jêder|ku|jêgirtin=Di nav kolanên tengik de, li ber deriyên xaniyên wêranbûyî, li ser reya revê, jin, mêr, zarok wek pezê ku '''qotik''' lêxe, an mirîşkên bi êşê bikevin hatibûn ramidandin, zikê wan tilêrî bûbûn.|{{Jêgirtin/Fawaz Husên/Siwarên Êşê/1994|r=57}}}} #* {{jêder-kovar |ku|jêgirtin=(...)hate bîra wî ku şevê dî ew li oda Apê Cenbelî ji ser hişê xwe çûbû, li wê odê wek berxekî ku '''qotikê''' lê dabe ji linga ketibû kef û kincê di dev û bêvila wî re avêtibû. |kovar=Pênûsa nû|sernav=Cenbelî|nivîskar=Luqman Silêman|hejmar=59|sal=2017|rûpel=ku}} #* {{jêder|ku|{{Jêgirtin/Hesenê Metê/Labîrenta Cinan/1994|r=47}}|jêgirtin=Xêr û guneh li hustuyê şêniyên gundê me, rast û derew para wan be... lê li gor ko tê gotinê, dibêjin gelek devên xwar li vir rast bûne, '''qotik''' li vir ji nava colên pezan reviyane, gelek dayikên histewir, xwe havêtine bextê vî Mekanê Mala Dînan. }} # {{f|ku|mecazî}} [[kul|Kul]], [[derd]], [[qehr]], [[bela]].<ref name ="FDestî"/><ref name = "Farqînî"/> #* {{jêder-malper |ku|jêgirtin=Bibînim xewnekî baş, ji bo bextê Hemê û Zeynê ye<br>Derkevin ji nav qal û '''qotikê''', qeda û belaya vê dinê ye<br>Çavên xwe ji xewê rakim bê qisawatê ye |nivîskar=Dîyar Budak|sernav=Evîna Hemê Şivan û Zeynê 5|url=http://www.rupelanu.com/evina-heme-sivan-u-zeyne-5-6608h.htm|malper=rupelanu.com|sal=2019 }} #* {{jêder-pirtûk |ku|jêgirtin=xwedê bi sere me da xera bike<br>Lê li şerê, li qewgê<br>li '''qotikê''', li qotînê<br>Li vê zilmê, li vê zilametê |amadekar=Wendelmoet Hamelink|sernav=The Sung Home|url=https://scholarlypublications.universiteitleiden.nl/access/item%3A2944872/download|weşanxane=Leiden University|sal=2014|rûpel=205 }} #* {{jêder|ku|jêgirtin=Ez çêtir dibînim ku bi awayê xwe bijîm: Bêyî ku karên weke karên keran bikim, bêyî ku di qehir û '''qotika''' jiyaneke gemarî de biqepijim, bêyî ku bihêlim yekî genî û çilmisî li ser min bibe xwedîgotin.|{{Jêgirtin/Hesenê Metê/Epîlog|r=118}}}} #* {{jêder-kovar |ku|jêgirtin=Çavê xwe teqlo beqlo dike<br>Bi qehr û '''qotik''' devê xwe vedike<br>Got; tu çawa ava min dikî şêlî<br>Di tapiya min de ye çem û gelî |kovar=Nûbihar|sernav=Berx û gur|nivîskar=Seyda Ronahî|hejmar=57|rûpel=119 }} # {{maneid|ku|cigareya xilasbûyî}} [[cigare|Cigareya]] ku hatiye kişandin.<ref name ="FDestî"/><ref name = "MGazî"/> #: {{hevmaneyên peyvê|ku|boçik|id1=cigareya xilasbûyî|qopik|id2=cigareya xilasbûyî|qutik|id3=cigareya xilasbûyî}} #* {{jêder-malper |ku|jêgirtin=Serê '''qotika''' cixarê di nava xwelîdankê de dipelaxt. |nivîskar=Rifat Arya/ Mesîla Dil|sernav=Berf û Xwîn|url=https://diyarname.com/article.php?Idx=207|malper=diyarname.com|sal=2008 }} #* {{jêder-malper |ku|jêgirtin='''Qotikê''' cixarê wan tilol dibûn dihatin ber lingê me disenîn. Me jî, ji wan '''qotika''', yên ku heta poçikê nehatibûne kişandin, dizîka ve hildida, dibir derva dikişand. |sernav=Qotikên Cixarê|url=https://www.seregolaintabe.com/qotiken-cixare/|malper=seregolaintabe.com }} #* {{jêder-kovar |ku|jêgirtin='''Qotika''' cixara xwe avêt erdê, her du destên xwe bir ber guhên xwe û dest bi kilamekê kir. |kovar=Tîroj|sernav=Bîr û nivîs|url=http://arsivakurd.org/images/arsiva_kurd/kovar/tiroj/tiroj_62.pdf|nivîskar=Alaattîn Ayhan|hejmar=62|sal=2013|rûpel=20 }} # [[tepik]], [[mitik]], [[girik]], [[tilik]], [[kumbirk]], [[gimt]], [[gint]], [[keloşk]] ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== Ji {{paş|ku|qot|-ik}}. ==== Werger ==== {{werger-ser|Nexweşiya berbelav|1|id=nexweşiya berbelav}} * {{Z|de}}: {{W+|de|Plage|m}} * {{Z|az}}: {{W-|az|qırğın}} * {{Z|be}}: {{W-|be|мор|n}} * {{Z|bg}}: {{W+|bg|мор|n}} * {{Z|hy}}: {{W+|hy|ժանտախտ}}, {{W+|hy|ժանտամահ}} * {{Z|eo}}: {{W-|eo|pesto}} * {{Z|et}}: {{W-|et|rändtaud}} * {{Z|fo}}: {{W-|fo|pest|m}}, {{W-|fo|pestur|n}} * {{Z|fi}}: {{W+|fi|kulkutauti}} * {{Z|fr}}: {{W+|fr|peste|m}} * {{Z|gd}}: {{W-|gd|plàigh|m}} * {{Z|gl}}: {{W+|gl|praga|m}} * {{Z|ka}}: {{W-|ka|ჭირი}} * {{Z|nl}}: {{W+|nl|pest}}, {{W+|nl|plaag}} * {{Z|he}}: {{W+|he|מַגֵּפָה|m|tr=magefá}} * {{Z|ang}}: {{W-|ang|wōl|n}} * {{Z|en}}: {{W+|en|plague}} * {{Z|ga}}: {{W-|ga|plá|m}} * {{Z|is}}: {{W-|is|plága|m}} * {{Z|ja}}: {{W+|ja|疫病|tr=ekibyō}}, {{W-|ja|疫癘|tr=ekirei}}, {{W+|ja|伝染病|tr=densenbyō}}, {{W+|ja|感染症|tr=kansenshō}} * {{Z|ca}}: {{W+|ca|pesta|m}}, {{W+|ca|plaga|m}} * {{Z|la}}: {{W-|la|pestis|m}}, {{W-|la|luēs|m}}, {{W-|la|clades|m}} * {{Z|mk}}: {{W-|mk|помор|n}}, {{W-|mk|епидемија|m}} * {{Z|cmn}}: {{W+|cmn|瘟疫|tr=wēnyì|sc=Hani}}, {{W-|cmn|疫癘|tr=yìlì|sc=Hani}} * {{Z|mi}}: {{W-|mi|urutā}}, {{W-|mi|mate urutā}} * {{Z|hu}}: {{W+|hu|járvány}} * {{Z|mn}}: {{W+|mn|тахал}} * {{Z|nrf}}: {{W-|nrf|mouôthinne|m}} * {{Z|nb}}: {{W-|nb|pest|n|m}}, {{W-|nb|pestepidemi|n}} * {{Z|nn}}: {{W-|nn|pest|n|m}}, {{W-|nn|pestepidemi|n}} * {{Z|oc}}: {{W-|oc|pèsta|m}} * {{Z|pt}}: {{W+|pt|praga|m}}, {{W+|pt|peste|m}} * {{Z|ro}}: {{W+|ro|ciumă|m}}, {{W+|ro|pestă|m}} * {{Z|ru}}: {{W+|ru|мор|n}}, {{W+|ru|чума́|m}}, {{W+|ru|эпиде́мия|m}}, {{W+|ru|пове́трие|nt}} * {{Z|sh}}: {{W+|sh|epidemija}} * {{Z|es}}: {{W+|es|plaga|m}} * {{Z|tl}}: {{W+|tl|salot}} * {{Z|tr}}: {{W+|tr|veba}}, {{W+|tr|kırgın}} * {{Z|uk}}: {{W+|uk|мір|n}}, {{W-|uk|мертвя́чка|m}}, {{W-|uk|чума́|m}} * {{Z|cy}}: {{W-|cy|plag|n}} * {{Z|km}}: {{W+|km|ប៉េស្ត}}, {{W-|km|ពិសឆ្លង|tr=pɨh clɑɑŋ|sc=Khmr}}, {{W-|km|រោគពិស|tr=rook pɨh|sc=Khmr}} * {{Z|grc}}: {{W-|grc|λοιμός|n}} * {{Z|el}}: {{W+|el|πανδημία|m}}, {{W+|el|λοιμός|n}}, {{W+|el|επιδημία|m}} {{werger-bin}} {{werger-ser|Nexweşiya heywanan|2}} {{werger-bin}} {{werger-bnr-h|Nexweşiya zarokan|3|xeneqîtik}} * {{Z|de}}: {{W+|de|Keuchhusten}} * {{Z|fi}}: {{W+|fi|hinkuyskä}} * {{Z|fr}}: {{W+|fr|coqueluche}} * {{Z|en}}: {{W+|en|whooping cough}}, {{W+|en|pertussis}} * {{Z|tr}}: {{W+|tr|boğmaca}} {{werger-bin}} {{werger-ser|Kul, derd|4}} {{werger-bin}} {{werger-bnr-h|Cigareya ku hatiye kişandin|5|qopik|id=cigareya xilasbûyî}} * {{Z|de}}: {{W+|de|Stummel|n}}, {{W+|de|Zigarettenstummel|n}}, {{W+|de|Kippe|m}}, {{W-|de|Zigarettenkippe|m}} * {{Z|ar}}: {{W-|ar|عَقْب سِيجَارَة}} * {{Z|fi}}: {{W+|fi|natsa}}, {{W+|fi|tumppi}}, {{W+|fi|tupakantumppi}} * {{Z|fr}}: {{W+|fr|mégot|n}} * {{Z|en}}: {{W+|en|butt}} * {{Z|es}}: {{W+|es|colilla|m}}, {{W+|es|bacha|m}}, {{W+|es|calilla|m}}, {{W-|es|chenca|m}}, {{W+|es|chicote|n}}, {{W+|es|chinga|m}}, {{W+|es|chiva|m}}, {{W+|es|pava|m}}, {{W+|es|pucho|n}} * {{Z|tr}}: {{W+|tr|izmarit}} {{werger-bin}} {{werger-ser|?}} * {{Z|fa}}: {{W+|fa|برس}}, {{W+|fa|بوته}}, {{W-|fa|حرف خشن}} * {{Z|en}}: {{W+|en|knob}} * {{Z|tr}}: {{W+|tr|tepecik}}, {{W-|tr|çakar çakmaz}}, {{W+|tr|höyük}} {{werger-bin}} === Navdêr 2 === [[Wêne:Kurdish Women, Kandal 15.jpg|thumb|Jina kurd di serî de bi kofî û '''qotikê''' xwe yê zêrîn.]] {{navdêr|ku|z=n}} # {{f|ku|Serhedî|cilûberg}} [[xeml|Xemleke]] [[zêr|bizêr]] e ku jinên kurd li [[kofî|kofiya]] xwe datînin û heta [[cênîk]]ê tê [[daliqandin]].<ref>{{kovara kurmancî|hejmar=11|sernav=Cil û berg|nivîskar=Muzaffer BEGZADE}}</ref><ref name = "Farqînî"/> #: {{hevmaneyên peyvê|ku|bercênîk}} #* {{jêder-pirtûk|ku|jêgirtin=Cînara (cîran) Wetê. 48 salî, bejnkin, xurt, çûr, çavsût. Dêrê çît, êlekê mexmer û şalika kesek li xwedike. Kofiya bi '''qotik''', carna hêratê dide serê xwe.|nivîskar=Taharê Biro|sernav=Memê û Eyşê (Şano)|weşanxane=Enstituya Kurdî ya Brukselê|sal=1991|rûpel=6}} #* {{jêder|ku|{{Jêgirtin/Zeynelabidîn Zinar/Balafira Jînê|r=56}}|jêgirtin=Hebû tunebû. Dibêjin ji Xwedê mezintir kesek tun bû. Mezinê dijminan '''qotikê''' serê me bû. Mezinên me jî tev di girtîgeh û zîndanan de dîlbeste bûn.}} #* {{jêder-malper|ku|jêgirtin=Go bêje çiqa çi nîşanê lawê te hene<br>Mi go serî da fînoyê sor î tolizî ye, '''qotikeke'''<ref group="Not">Di stranê de wek "qotikê" tê bilêvkirin lê belê di danasîna vîdeoyê de wek "qotikeke" hatiye nivîsin.</ref> reşemecîdî ye,<br>Hespeke boze xalxalî ye |nivîskar=Xatoyê Sinco|sernav=Heydaro|url=https://www.youtube.com/watch?v=e0I6vAAcxQ8&t=88s }} ==== Tewandin ==== {{ku-tewîn-nav/nû|nêr}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Binêre herwiha ==== * {{g|ku|kofî}} * {{g|ku|fîno}} * {{g|ku|dêrî}} * {{g|ku|fîstan}} * {{g|ku|cilûberg}} ==== Werger ==== {{werger-ser}} * {{Z|fr}}: {{W+|fr|frange}}, {{W+|fr|houppe}}<ref>{{pirtûk|nivîskar=Auguste Alexandre Jaba|url=https://bnk.institutkurde.org/images/pdf/V4XCUZ5PFY.pdf|sernav=Dictionnaire Kurde-Français|weşanxane=Académie Impériale|cih=St. Pétersbourg|sal=1879|rûpel=317}}</ref> * {{Z|en}}: {{W+|en|tassel}} {{mane|sewn on top of the woman's headwear}} * {{Z|ru}}: {{W+|ru|кисточка}} {{mane|вшиваемая на феску сверху}}<ref>{{ferhenga kurdî-rûsî|r=484}}</ref> {{werger-bin}} {{bend}} === Navdêr 3 === {{navdêr|ku|z=n}} # {{guharto|ku|qutik|id=cilekî folklorî|w=cilekî folklorî}} #* {{jêder-kovar|ku|jêgirtin=Di hedîsên Pêxemberê me Muhammed (s.x.l) jî behsa Kurdan hatîye kirin. Mesela di hinek hedîsande tê gotin ku Hz. Pêxember qemîs/'''qotikê''' xwe daye sehabîyekî şuna wî qotikekî “Kurdî/enbîcanî” li vî sehabî girtîye. Van rîwayetên hanê halê Kurdan ê wê demê ê aborî jî nîşan dide. Lewra hîn wê demê, berî niha bi 1400-1500 salî, hinek qumaş bi navê “Qumaşê Kurd” hatine binavkirin.|kovar=Şarkiyat ICSS’17|sernav=Dı Çavkanîyên ‘Erebî De Kurd (Mînak Wek Tefsîrên Qur’ân’a Kerîm)|url=http://www.bingol.edu.tr/documents/%C5%9Farkiyat%20%C3%B6zet%20kitab%C4%B1.pdf|nivîskar=Mustafa Öncü|sal=2017|rûpel=198}} === Çavkanî === ;Jêrenot {{çavkanî|group=Not}} ;Çavkanî {{çavkanî}} elqrci658h4g6mwjgyv8ocr4k4mf254 6334065 6334060 2026-08-16T02:41:10Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6334065 wikitext text/x-wiki {{bnr-h|qotîk}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr 1 === {{navdêr|ku|z=m}} # {{f|ku|bijîşkî}} [[nexweşî|Nexweşiyek]] e ku dibe [[sedem]]a [[mirin]]a gelek kesan.<ref>{{Chyet2020|cild=M-Z}}</ref> #: {{hevmaneyên peyvê|ku|şob|weba|pejî}} #* {{jêder-malper |ku|jêgirtin=Sala 2020 ji tevayiya dinyayê ra bû sala '''qotikê''', epîdemiya Coronayê însan di malên wan da kirin girtî. |nivîskar={{w|Zinarê Xamo}}|sernav=Çînî rehet nasekinin|url=https://zinarexamo.blogspot.com/2021/01/cini-rehet-nasekinin.html|malper=zinarexamo.blogspot.com|sal=2021 }} #* {{jêder |ku|{{Jêgirtin/Mahmûd Lewendî/Compûtera ber dilê min/2002|r=13}}|jêgirtin=Di malbata me de, hetta di nav eşîra me de -yên ko bi destê hukmatê hatine kuştin û yên ko bi '''qotikê''' mirine ne tê de- kes bi ciwanî nemirîye. }} #* {{jêder-pirtûk |ku|jêgirtin=Belkî tu bivî para xurî-sorika!<br>Belkî tu rûvîya qertemezê kevî!<br>Lê '''qotikê''' lê girtî!<br>Firnê tera bê! |nivîskar={{w|Ordîxanê Celîl}}|sernav=Zargotina Kurda 2|cih=Moskva|sal=1978|rûpel=451 }} #* {{jêder-pirtûk |ku|jêgirtin=Kêf, kêfa serleşker bû<br>'''Qotik''' ketibû nav me<br>Bersivvanek jî pêyda nedibû<br>Gundîyên din jî ser zik li erdê mabûn<br>Çi danenîyan serê zarokan |nivîskar={{w|Evîn Çîçek}}|sernav=Awaza Serpêhatîyan 3|weşanxane=Weşanên Pêrî|sal=2004|rûpel=43|isbn=975-8245-95-7 }} # {{f|ku|bijîşkî}} [[nexweşî|Nexweşiyeke]] [[zarok]]an e ku dibe [[sedem]]a [[kuxik]]ê.<ref name = "FDestî">{{Ferhenga Destî|r=325}}</ref><ref name = "Farqînî" >{{Zana Farqînî|r=1530}}</ref><ref>{{pirtûk|nivîskar=Mikail Bülbül|nivîskar2=Dr. İsrafil Bülbül|sernav=Kürtçe Anamnez Anamneza bi Kurmancî|weşanxane=DİYARBAKIR TABİP ODASI YAYINLARI|sal=2009|rûpel=52}}</ref> #: {{hevmaneyên peyvê|ku|xeneqûtik|xenoq|bexikî}} #* {{jêgirtin?|ku}} # {{f|ku|heywannasî|bijîşkî}} [[nexweşî|Nexweşiyeke]] heywanan e ku dibe [[sedem]]a [[mirin]]a wan (bi taybetî [[pez]]).<ref>{{ferhenga Bozarslan|cild=L-R|r=779}}</ref><ref name = "MGazî">{{mustafa gazî|r=109}}</ref><ref>{{kovara kurmancî|hejmar=48|sernav=Navên hin nexweşiyên heywanan|nivîskar=Lezgînê ÇALÎ û Rûken BAGDU-KESKÎN}}</ref> #* {{jêder|ku|jêgirtin=Di nav kolanên tengik de, li ber deriyên xaniyên wêranbûyî, li ser reya revê, jin, mêr, zarok wek pezê ku '''qotik''' lêxe, an mirîşkên bi êşê bikevin hatibûn ramidandin, zikê wan tilêrî bûbûn.|{{Jêgirtin/Fawaz Husên/Siwarên Êşê/1994|r=57}}}} #* {{jêder-kovar |ku|jêgirtin=(...)hate bîra wî ku şevê dî ew li oda Apê Cenbelî ji ser hişê xwe çûbû, li wê odê wek berxekî ku '''qotikê''' lê dabe ji linga ketibû kef û kincê di dev û bêvila wî re avêtibû. |kovar=Pênûsa nû|sernav=Cenbelî|nivîskar=Luqman Silêman|hejmar=59|sal=2017|rûpel=ku}} #* {{jêder|ku|{{Jêgirtin/Hesenê Metê/Labîrenta Cinan/1994|r=47}}|jêgirtin=Xêr û guneh li hustuyê şêniyên gundê me, rast û derew para wan be... lê li gor ko tê gotinê, dibêjin gelek devên xwar li vir rast bûne, '''qotik''' li vir ji nava colên pezan reviyane, gelek dayikên histewir, xwe havêtine bextê vî Mekanê Mala Dînan. }} # {{f|ku|mecazî}} [[kul|Kul]], [[derd]], [[qehr]], [[bela]].<ref name ="FDestî"/><ref name = "Farqînî"/> #* {{jêder-malper |ku|jêgirtin=Bibînim xewnekî baş, ji bo bextê Hemê û Zeynê ye<br>Derkevin ji nav qal û '''qotikê''', qeda û belaya vê dinê ye<br>Çavên xwe ji xewê rakim bê qisawatê ye |nivîskar=Dîyar Budak|sernav=Evîna Hemê Şivan û Zeynê 5|url=http://www.rupelanu.com/evina-heme-sivan-u-zeyne-5-6608h.htm|malper=rupelanu.com|sal=2019 }} #* {{jêder-pirtûk |ku|jêgirtin=xwedê bi sere me da xera bike<br>Lê li şerê, li qewgê<br>li '''qotikê''', li qotînê<br>Li vê zilmê, li vê zilametê |amadekar=Wendelmoet Hamelink|sernav=The Sung Home|url=https://scholarlypublications.universiteitleiden.nl/access/item%3A2944872/download|weşanxane=Leiden University|sal=2014|rûpel=205 }} #* {{jêder|ku|jêgirtin=Ez çêtir dibînim ku bi awayê xwe bijîm: Bêyî ku karên weke karên keran bikim, bêyî ku di qehir û '''qotika''' jiyaneke gemarî de biqepijim, bêyî ku bihêlim yekî genî û çilmisî li ser min bibe xwedîgotin.|{{Jêgirtin/Hesenê Metê/Epîlog|r=118}}}} #* {{jêder-kovar |ku|jêgirtin=Çavê xwe teqlo beqlo dike<br>Bi qehr û '''qotik''' devê xwe vedike<br>Got; tu çawa ava min dikî şêlî<br>Di tapiya min de ye çem û gelî |kovar=Nûbihar|sernav=Berx û gur|nivîskar=Seyda Ronahî|hejmar=57|rûpel=119 }} # {{maneid|ku|cigareya xilasbûyî}} [[cigare|Cigareya]] ku hatiye kişandin.<ref name ="FDestî"/><ref name = "MGazî"/> #: {{hevmaneyên peyvê|ku|boçik|id1=cigareya xilasbûyî|qopik|id2=cigareya xilasbûyî|qutik|id3=cigareya xilasbûyî}} #* {{jêder-malper |ku|jêgirtin=Serê '''qotika''' cixarê di nava xwelîdankê de dipelaxt. |nivîskar=Rifat Arya/ Mesîla Dil|sernav=Berf û Xwîn|url=https://diyarname.com/article.php?Idx=207|malper=diyarname.com|sal=2008 }} #* {{jêder-malper |ku|jêgirtin='''Qotikê''' cixarê wan tilol dibûn dihatin ber lingê me disenîn. Me jî, ji wan '''qotika''', yên ku heta poçikê nehatibûne kişandin, dizîka ve hildida, dibir derva dikişand. |sernav=Qotikên Cixarê|url=https://www.seregolaintabe.com/qotiken-cixare/|malper=seregolaintabe.com }} #* {{jêder-kovar |ku|jêgirtin='''Qotika''' cixara xwe avêt erdê, her du destên xwe bir ber guhên xwe û dest bi kilamekê kir. |kovar=Tîroj|sernav=Bîr û nivîs|url=http://arsivakurd.org/images/arsiva_kurd/kovar/tiroj/tiroj_62.pdf|nivîskar=Alaattîn Ayhan|hejmar=62|sal=2013|rûpel=20 }} # [[tepik]], [[mitik]], [[girik]], [[tilik]], [[kumbirk]], [[gimt]], [[gint]], [[keloşk]] ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== Ji {{paş|ku|qot|-ik}}. ==== Werger ==== {{werger-ser|Nexweşiya berbelav|1|id=nexweşiya berbelav}} * {{Z|de}}: {{W+|de|Plage|m}} * {{Z|az}}: {{W-|az|qırğın}} * {{Z|be}}: {{W-|be|мор|n}} * {{Z|bg}}: {{W+|bg|мор|n}} * {{Z|hy}}: {{W+|hy|ժանտախտ}}, {{W+|hy|ժանտամահ}} * {{Z|eo}}: {{W-|eo|pesto}} * {{Z|et}}: {{W-|et|rändtaud}} * {{Z|fo}}: {{W-|fo|pest|m}}, {{W-|fo|pestur|n}} * {{Z|fi}}: {{W+|fi|kulkutauti}} * {{Z|fr}}: {{W+|fr|peste|m}} * {{Z|gd}}: {{W-|gd|plàigh|m}} * {{Z|gl}}: {{W+|gl|praga|m}} * {{Z|ka}}: {{W-|ka|ჭირი}} * {{Z|nl}}: {{W+|nl|pest}}, {{W+|nl|plaag}} * {{Z|he}}: {{W+|he|מַגֵּפָה|m|tr=magefá}} * {{Z|ang}}: {{W-|ang|wōl|n}} * {{Z|en}}: {{W+|en|plague}} * {{Z|ga}}: {{W-|ga|plá|m}} * {{Z|is}}: {{W-|is|plága|m}} * {{Z|ja}}: {{W+|ja|疫病|tr=ekibyō}}, {{W-|ja|疫癘|tr=ekirei}}, {{W+|ja|伝染病|tr=densenbyō}}, {{W+|ja|感染症|tr=kansenshō}} * {{Z|ca}}: {{W+|ca|pesta|m}}, {{W+|ca|plaga|m}} * {{Z|la}}: {{W-|la|pestis|m}}, {{W-|la|luēs|m}}, {{W-|la|clades|m}} * {{Z|mk}}: {{W-|mk|помор|n}}, {{W-|mk|епидемија|m}} * {{Z|cmn}}: {{W+|cmn|瘟疫|tr=wēnyì|sc=Hani}}, {{W-|cmn|疫癘|tr=yìlì|sc=Hani}} * {{Z|mi}}: {{W-|mi|urutā}}, {{W-|mi|mate urutā}} * {{Z|hu}}: {{W+|hu|járvány}} * {{Z|mn}}: {{W+|mn|тахал}} * {{Z|nrf}}: {{W-|nrf|mouôthinne|m}} * {{Z|nb}}: {{W-|nb|pest|n|m}}, {{W-|nb|pestepidemi|n}} * {{Z|nn}}: {{W-|nn|pest|n|m}}, {{W-|nn|pestepidemi|n}} * {{Z|oc}}: {{W-|oc|pèsta|m}} * {{Z|pt}}: {{W+|pt|praga|m}}, {{W+|pt|peste|m}} * {{Z|ro}}: {{W+|ro|ciumă|m}}, {{W+|ro|pestă|m}} * {{Z|ru}}: {{W+|ru|мор|n}}, {{W+|ru|чума́|m}}, {{W+|ru|эпиде́мия|m}}, {{W+|ru|пове́трие|nt}} * {{Z|sh}}: {{W+|sh|epidemija}} * {{Z|es}}: {{W+|es|plaga|m}} * {{Z|tl}}: {{W+|tl|salot}} * {{Z|tr}}: {{W+|tr|veba}}, {{W+|tr|kırgın}} * {{Z|uk}}: {{W+|uk|мір|n}}, {{W-|uk|мертвя́чка|m}}, {{W-|uk|чума́|m}} * {{Z|cy}}: {{W-|cy|plag|n}} * {{Z|km}}: {{W+|km|ប៉េស្ត}}, {{W-|km|ពិសឆ្លង|tr=pɨh clɑɑŋ|sc=Khmr}}, {{W-|km|រោគពិស|tr=rook pɨh|sc=Khmr}} * {{Z|grc}}: {{W-|grc|λοιμός|n}} * {{Z|el}}: {{W+|el|πανδημία|m}}, {{W+|el|λοιμός|n}}, {{W+|el|επιδημία|m}} {{werger-bin}} {{werger-ser|Nexweşiya heywanan|2}} {{werger-bin}} {{werger-bnr-h|Nexweşiya zarokan|3|xeneqîtik}} * {{Z|de}}: {{W+|de|Keuchhusten}} * {{Z|fi}}: {{W+|fi|hinkuyskä}} * {{Z|fr}}: {{W+|fr|coqueluche}} * {{Z|en}}: {{W+|en|whooping cough}}, {{W+|en|pertussis}} * {{Z|tr}}: {{W+|tr|boğmaca}} {{werger-bin}} {{werger-ser|Kul, derd|4}} {{werger-bin}} {{werger-bnr-h|Cigareya ku hatiye kişandin|5|qopik|id=cigareya xilasbûyî}} * {{Z|de}}: {{W+|de|Stummel|n}}, {{W+|de|Zigarettenstummel|n}}, {{W+|de|Kippe|m}}, {{W-|de|Zigarettenkippe|m}} * {{Z|ar}}: {{W-|ar|عَقْب سِيجَارَة}} * {{Z|fi}}: {{W+|fi|natsa}}, {{W+|fi|tumppi}}, {{W+|fi|tupakantumppi}} * {{Z|fr}}: {{W+|fr|mégot|n}} * {{Z|en}}: {{W+|en|butt}} * {{Z|es}}: {{W+|es|colilla|m}}, {{W+|es|bacha|m}}, {{W+|es|calilla|m}}, {{W-|es|chenca|m}}, {{W+|es|chicote|n}}, {{W+|es|chinga|m}}, {{W+|es|chiva|m}}, {{W+|es|pava|m}}, {{W+|es|pucho|n}} * {{Z|tr}}: {{W+|tr|izmarit}} {{werger-bin}} {{werger-ser|?}} * {{Z|fa}}: {{W+|fa|برس}}, {{W+|fa|بوته}}, {{W-|fa|حرف خشن}} * {{Z|en}}: {{W+|en|knob}} * {{Z|tr}}: {{W+|tr|tepecik}}, {{W-|tr|çakar çakmaz}}, {{W+|tr|höyük}} {{werger-bin}} === Navdêr 2 === [[Wêne:Kurdish Women, Kandal 15.jpg|thumb|Jina kurd di serî de bi kofî û '''qotikê''' xwe yê zêrîn.]] {{navdêr|ku|z=n}} # {{f|ku|Serhedî|cilûberg}} [[xeml|Xemleke]] [[zêr|bizêr]] e ku jinên kurd li [[kofî|kofiya]] xwe datînin û heta [[cênîk]]ê tê [[daliqandin]].<ref>{{kovara kurmancî|hejmar=11|sernav=Cil û berg|nivîskar=Muzaffer BEGZADE}}</ref><ref name = "Farqînî"/> #: {{hevmaneyên peyvê|ku|bercênîk}} #* {{jêder-pirtûk|ku|jêgirtin=Cînara (cîran) Wetê. 48 salî, bejnkin, xurt, çûr, çavsût. Dêrê çît, êlekê mexmer û şalika kesek li xwedike. Kofiya bi '''qotik''', carna hêratê dide serê xwe.|nivîskar=Taharê Biro|sernav=Memê û Eyşê (Şano)|weşanxane=Enstituya Kurdî ya Brukselê|sal=1991|rûpel=6}} #* {{jêder|ku|{{Jêgirtin/Zeynelabidîn Zinar/Balafira Jînê|r=56}}|jêgirtin=Hebû tunebû. Dibêjin ji Xwedê mezintir kesek tun bû. Mezinê dijminan '''qotikê''' serê me bû. Mezinên me jî tev di girtîgeh û zîndanan de dîlbeste bûn.}} #* {{jêder-malper|ku|jêgirtin=Go bêje çiqa çi nîşanê lawê te hene<br>Mi go serî da fînoyê sor î tolizî ye, '''qotikeke'''<ref group="Not">Di stranê de wek "qotikê" tê bilêvkirin lê belê di danasîna vîdeoyê de wek "qotikeke" hatiye nivîsin.</ref> reşemecîdî ye,<br>Hespeke boze xalxalî ye |nivîskar=Xatoyê Sinco|sernav=Heydaro|url=https://www.youtube.com/watch?v=e0I6vAAcxQ8&t=88s }} ==== Tewandin ==== {{ku-tewîn-nav/nû|nêr}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Herwiha binêre ==== * {{g|ku|kofî}} * {{g|ku|fîno}} * {{g|ku|dêrî}} * {{g|ku|fîstan}} * {{g|ku|cilûberg}} ==== Werger ==== {{werger-ser}} * {{Z|fr}}: {{W+|fr|frange}}, {{W+|fr|houppe}}<ref>{{pirtûk|nivîskar=Auguste Alexandre Jaba|url=https://bnk.institutkurde.org/images/pdf/V4XCUZ5PFY.pdf|sernav=Dictionnaire Kurde-Français|weşanxane=Académie Impériale|cih=St. Pétersbourg|sal=1879|rûpel=317}}</ref> * {{Z|en}}: {{W+|en|tassel}} {{mane|sewn on top of the woman's headwear}} * {{Z|ru}}: {{W+|ru|кисточка}} {{mane|вшиваемая на феску сверху}}<ref>{{ferhenga kurdî-rûsî|r=484}}</ref> {{werger-bin}} {{bend}} === Navdêr 3 === {{navdêr|ku|z=n}} # {{guharto|ku|qutik|id=cilekî folklorî|w=cilekî folklorî}} #* {{jêder-kovar|ku|jêgirtin=Di hedîsên Pêxemberê me Muhammed (s.x.l) jî behsa Kurdan hatîye kirin. Mesela di hinek hedîsande tê gotin ku Hz. Pêxember qemîs/'''qotikê''' xwe daye sehabîyekî şuna wî qotikekî “Kurdî/enbîcanî” li vî sehabî girtîye. Van rîwayetên hanê halê Kurdan ê wê demê ê aborî jî nîşan dide. Lewra hîn wê demê, berî niha bi 1400-1500 salî, hinek qumaş bi navê “Qumaşê Kurd” hatine binavkirin.|kovar=Şarkiyat ICSS’17|sernav=Dı Çavkanîyên ‘Erebî De Kurd (Mînak Wek Tefsîrên Qur’ân’a Kerîm)|url=http://www.bingol.edu.tr/documents/%C5%9Farkiyat%20%C3%B6zet%20kitab%C4%B1.pdf|nivîskar=Mustafa Öncü|sal=2017|rûpel=198}} === Çavkanî === ;Jêrenot {{çavkanî|group=Not}} ;Çavkanî {{çavkanî}} c970sf4inzldm8toktvirqpznhh97ya predictable 0 404577 6333794 4569053 2026-08-15T12:25:47Z Rewiye tine 7120 6333794 wikitext text/x-wiki == {{ziman|en}} == === Rengdêr === {{rengdêr|en}} # [[pêşbînbar]], yê [[miteweqî]], [[berbînbar]]<ref>Ferhenga Kurdî-Îngîlîzî ya Salah Sadallah</ref> === Çavkanî === {{çavkanî}} dlnw8yium2qe4qnwfypch2yt0cim5ev 6333795 6333794 2026-08-15T12:27:05Z Rewiye tine 7120 6333795 wikitext text/x-wiki == {{ziman|en}} == === Rengdêr === {{rengdêr|en}} # [[pêşbînbar]], yê [[miteweqî]], [[berbînbar]]<ref>Ferhenga Kurdî-Îngîlîzî ya Salah Sadallah</ref> ==== Dijmane ==== [[unpredictable]] === Çavkanî === {{çavkanî}} 2n2wqerzpuq3i464gmfh4sjwwjn6tg7 pêşbînbar 0 444537 6333793 6178851 2026-08-15T12:24:54Z Rewiye tine 7120 Werger: +tirkî : [[öngörülür]]; +îngilîzî : [[predictable]] (bi alîkarî) 6333793 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{rengdêr|ku}} # [[berbînbar]] ==== Etîmolojî ==== * Ji {{paş|ku|pêşbîn|-bar}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W-|de|vorhersagbar|guman=erê}} * {{Z|en}}: {{W+|en|prognosticable}}, {{W+|en|predictable}} * {{Z|tr}}: {{W-|tr|öngörülür}} {{werger-bin}} 067lzjopk9rst413pdvtq13cnjysbn8 lêderkirin 0 654067 6333993 6311370 2026-08-16T00:59:43Z Wikihez 7344 /* Hevmane */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333993 wikitext text/x-wiki {{bnr-l|lê der kirin}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[jêbirin]], jê[[kêm]]kirin, anînder ji [[nav]] ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Bi alfabeyên din ==== * {{ku-ar|لێدەرکرن}} ==== Hevmane ==== * [[jêbirin]] ==== Etîmolojî ==== Ji {{deyn|ckb|ku}}. ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W|en|minus}}, {{W|en|subtraction}} {{werger-bin}} egk80qht368m9dic9h7c0x5ynmak7fr Gliederfüßer 0 730474 6334043 4649166 2026-08-16T01:48:07Z Wikihez 7344 /* Navdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334043 wikitext text/x-wiki == {{ziman|de}} == === Navdêr === {{navdêr|de|z=n}} # [[binemal]]eka [[kurmik]]an 2y3kuebmpuysjcr5gbkokm9snn0uhfd Wîkîferheng:Daxwazên peyitandinê 4 843283 6333947 6333532 2026-08-15T23:23:27Z Wikihez 7344 [[Bikarhêner:Wikihez/skrîpt/js/şablon-lêke.js|T]]: Daxwaza peyitandinê: +[[goganîbûnî]] 6333947 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) == <s>[[firvan]]</s> == 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:43, 7 tebax 2026 (UTC) :Ji xeynî Sadallah (ku min xwestibû bû were yasaxkirin [https://ku.wiktionary.org/wiki/W%C3%AEk%C3%AEferheng:D%C3%AEwan/2025#Yasaxkirina_hin_ferhengan] lê me ev tişt nekiribû standardek) û ferhengeke Husein Muhammad ti bikaranîna vê kelîmeyê nîne. Ji ber ku ev made ji hêla @[[Bikarhêner:Ferhengvan|Ferhengvan]] ve hatiye çêkirin, nabe ku em Husein Muhammed ji bo vê madeyê wekî çavkanî bi kar bînin. Loma tenê yek çavkanî heye. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:11, 7 tebax 2026 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:49, 13 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) 67y50idu519fmibf9dbsfb7v9jic5w7 lêkqelibîn 0 844458 6333997 6311399 2026-08-16T01:02:43Z Wikihez 7344 /* Çavkanî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333997 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # demajo an rewşa [[ko bûn]]. #* {{jêder-pirtûk|ku|jêgirtin=Konteksta [[kontakta zimanan|kontakta zimanî]] ya di navbera kurdî û tirkiyê de asîmetrîk e. Texer di kontekstên wisa de, netîceyên diyardeya '''lêkqelibînê''' diqewimin di bunyeya gramera zimanê bindest de.|nivîskar={{w|Ergin Öpengin}}|sernav=Rewşa kurdî ya sosyolenguîstîk li Tirkiyeyê|weşanxane={{w|Weşanên Avesta|Avesta}}|sal=2011|çap=1|rûpel=88|isbn=978-605-5585-71-6}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * li yek [[qelibîn]] ==== Têkildar ==== * [[ko bûn]] ==== Werger ==== {{werger-ser}} * {{W|en|convergence}}, {{W|en|conjunction}} {{werger-bin}} 670d1wmhud6nii2iwh5vc5fmznvcd9a pîvaza nemrûdê 0 935372 6334056 6325345 2026-08-16T02:10:50Z Wikihez 7344 /* Navê zanistî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334056 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[pîvazek]]e [[endemîk]] ku bi tenê li derdora [[Nemrûd|Çiyayê Nemrûda]] [[Semsûr]]ê şên dihê ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Navê zanistî ==== * [[Allium nemrutdaghense]] ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W-|tr|Nemrut soğanı}} {{werger-bin}} kmlaqh8fewue5fbnqieq3nqrhqprcc3 6334057 6334056 2026-08-16T02:11:05Z Wikihez 7344 /* Tewandin */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334057 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[pîvazek]]e [[endemîk]] ku bi tenê li derdora [[Nemrûd|Çiyayê Nemrûda]] [[Semsûr]]ê şên dihê ==== Tewandin ==== {{ku-tewîn-nav/nû|heve=îzafe}} ==== Navê zanistî ==== * [[Allium nemrutdaghense]] ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W-|tr|Nemrut soğanı}} {{werger-bin}} sen3y4q422716t40v6f08ntf9cga55o masîcank 0 935403 6333999 6311700 2026-08-16T01:04:47Z Wikihez 7344 6333999 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[nav|Navê]] [[hinek|hinek]] [[cure|cure]] [[giya|giyayên]] [[kulîlk|kulîlk]] [[zer|zer]] ku bi wan [[masî|masî]] [[hatin|dihêne]] [[girtin|girtin]]. ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Jê ==== * [[masî]] ==== Navê zanistî ==== * [[Verbascum]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Bi zaravayên kurdî ==== {{werger-ser}} {{werger-bin}} ==== Werger ==== {{werger-ser}} {{werger-bin}} 04bbcz1d6rjn1yifrl39kmoza2i3cgl 6334000 6333999 2026-08-16T01:04:56Z Wikihez 7344 /* Bi zaravayên kurdî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334000 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[nav|Navê]] [[hinek|hinek]] [[cure|cure]] [[giya|giyayên]] [[kulîlk|kulîlk]] [[zer|zer]] ku bi wan [[masî|masî]] [[hatin|dihêne]] [[girtin|girtin]]. ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Jê ==== * [[masî]] ==== Navê zanistî ==== * [[Verbascum]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Bi zaravayên din ==== {{werger-ser}} {{werger-bin}} ==== Werger ==== {{werger-ser}} {{werger-bin}} fl45hykvg0a2vxkgvkfne6jn776hsgt 6334001 6334000 2026-08-16T01:05:17Z Wikihez 7344 /* {{ziman|ku}} */ [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6334001 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[nav|Navê]] [[hinek|hinek]] [[cure|cure]] [[giya|giyayên]] [[kulîlk|kulîlk]] [[zer|zer]] ku bi wan [[masî|masî]] [[hatin|dihêne]] [[girtin|girtin]]. ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Jê ==== * {{g|ku|masî}} ==== Navê zanistî ==== * {{q|ku|Verbascum}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Bi zaravayên din ==== {{werger-ser}} {{werger-bin}} ==== Werger ==== {{werger-ser}} {{werger-bin}} e2ibo80zp57ahq897zva6kbhk7nf0dt 6334034 6334001 2026-08-16T01:41:30Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6334034 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[nav|Navê]] [[hinek|hinek]] [[cure|cure]] [[giya|giyayên]] [[kulîlk|kulîlk]] [[zer|zer]] ku bi wan [[masî|masî]] [[hatin|dihêne]] [[girtin|girtin]]. ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Navê zanistî ==== * {{q|ku|Verbascum}} ==== Jê ==== * {{g|ku|masî}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Bi zaravayên din ==== {{werger-ser}} {{werger-bin}} ==== Werger ==== {{werger-ser}} {{werger-bin}} ng6q6n69ci82h102yh6ak4aff9al9x2 6334059 6334034 2026-08-16T02:12:10Z Balyozbot 7867 Bot: Paqijiyên kozmetîk (Lînk paqij kir.) 6334059 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[nav|Navê]] [[hinek]] [[cure]] [[giya]]yên [[kulîlk]] [[zer]] ku bi wan [[masî]] [[hatin|dihêne]] [[girtin]]. ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Navê zanistî ==== * {{q|ku|Verbascum}} ==== Jê ==== * {{g|ku|masî}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Bi zaravayên din ==== {{werger-ser}} {{werger-bin}} ==== Werger ==== {{werger-ser}} {{werger-bin}} 9bc378sta7szia0w0nyq61kcnsyej1g Kekik 0 956749 6333864 4901889 2026-08-15T18:46:20Z Wikihez 7344 /* Tirkî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333864 wikitext text/x-wiki {{bnr-h|Kekik}} == {{ziman|tr}} == === Serenav === {{serenav|tr}} # Navekî {{navkes|tr|keç}} e. gxf5t0h8qgn5257ravxexhunuwpx2x4 6333865 6333864 2026-08-15T18:46:28Z Wikihez 7344 6333865 wikitext text/x-wiki {{bnr-h|kekik}} == {{ziman|tr}} == === Serenav === {{serenav|tr}} # Navekî {{navkes|tr|keç}} e. f4ljyu3nf5jgedx5lqesgh3sfgqk3go hûrbîn 0 976931 6333955 6324526 2026-08-15T23:29:21Z Wikihez 7344 /* Binêre herwiha */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333955 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navder === [[Wêne:Compound Microscope (cropped).JPG|thumb|'''Hûrbînek''']] {{navdêr|ku|z=m}} # {{f|ku|gelek|nadir}} [[alet|Aletek]] e ku mirov pê tiştên pirr [[hûrik]] dibîne.<ref>{{JBlau 1991|r=153}}</ref><ref>{{Ferhenga Kamêran|r=336}}</ref><ref>{{ferhenga zaravên teknîkî|r=62}}</ref> #: {{hevmane|ku|mîkroskop}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== {{neo|ku}} ji {{paş|ku|hûr|-bîn}}. ==== Bêhtir bixwîne ==== * {{wpedî}} ==== Werger ==== {{werger-bnr|mîkroskop}} === Çavkanî === {{çavkanî}} k7b6dry0nhh25fqrkjhfejp2jfukkvt 6333956 6333955 2026-08-15T23:29:33Z Wikihez 7344 /* Navder */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333956 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === [[Wêne:Compound Microscope (cropped).JPG|thumb|'''Hûrbînek''']] {{navdêr|ku|z=m}} # {{f|ku|gelek|nadir}} [[alet|Aletek]] e ku mirov pê tiştên pirr [[hûrik]] dibîne.<ref>{{JBlau 1991|r=153}}</ref><ref>{{Ferhenga Kamêran|r=336}}</ref><ref>{{ferhenga zaravên teknîkî|r=62}}</ref> #: {{hevmane|ku|mîkroskop}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Etîmolojî ==== {{neo|ku}} ji {{paş|ku|hûr|-bîn}}. ==== Bêhtir bixwîne ==== * {{wpedî}} ==== Werger ==== {{werger-bnr|mîkroskop}} === Çavkanî === {{çavkanî}} s95ez4o3r2ff083gslnu7be07w81lt8 kelobîn 0 1119030 6333989 6309836 2026-08-16T00:55:42Z Wikihez 7344 /* {{ziman|ku}} */ [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6333989 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[heyecan]], [[kelecan]], [[heraret]], [[hêrs]], [[kelîn]], <br>[[piçek]]ê [[tirsîn]] yan bi[[mereq]] bûn ji ber ku nizane ka dê [[baş]] [[bi ser ketin|bi ser keve]] yan #* {{jêder-kitêb|ku|jêgirtin=Weke deqekê duda ewê serê xwe kire ber xwe û nikaribû xeber da, nizanibû çawa dest bi xeberdana xwe bike, lê paşê ewê serê xwe bilind kir û '''kelobîn''' dest bi xeberdana xwe kir.|sernav=Sîsê (novel)|nivîskar=Mîroyê Esed|weşanxane=Neşîreta Haypêtrat|cih=Yêrêvan|sal=1961.}} ==== Tewandin ==== {{ku-tewîn-nav/nû|mê}} ==== Formên alternatîv ==== * {{hw|ku|kel û bêhn|kelobêhn|kel û bîn}} ==== Werger ==== {{werger-ser}} * {{Z|af}}: {{W+|af|geesdrif}}, {{W+|af|besieling}} * {{Z|de}}: {{W|de|Aufregung|f}}, {{W|de|Begeisterung|f}}, {{W|de|Erregung|f}}, {{W|de|Spannung|f}} * {{Z|cs}}: {{W|cs|entuziazmus|m}} * {{Z|da}}: {{W+|da|begejstring}} * {{Z|ar}}: {{W+|ar|حَماس}}, {{W+|ar|إِثارة}} * {{Z|eo}}: {{W+|eo|entuziasmo}} * {{Z|fa}}: {{W+|fa|هیجان|tr=heyecan}} * {{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|excitement}}, {{W+|en|enthusiasm}}, {{W+|en|zest}} * {{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|ru}}: {{W+|ru|возбуждение}}, * {{Z|es}}: {{W+|es|entusiasmo}} * {{Z|sv}}: {{W+|sv|entusiasm}}, {{W+|sv|hänförelse}} * {{Z|tr}}: {{W+|tr|coşku}}, {{W+|tr|heyecan}} {{werger-bin}} ntkzokgtsl5855pzp8lbjzcw0k9udkm ككلیك 0 1128360 6333867 5424980 2026-08-15T19:01:27Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: Ji [[en:ككلیك|en.wikt]] 6333867 wikitext text/x-wiki == {{ziman|ota}} == === Navdêr === [[Wêne:Perdix perdix hispaniensis MHNT PHAS 1996 18.jpg|thumb|{{lang|ota|ككلیك}}]] {{navdêr|ota|tr=keklik}} # {{e|ota|teyr}} {{g|ku|kew}} ==== Formên alternatîv ==== * {{hw|ota|ككلك|tr1=keklik}} ==== Etîmolojî ==== Ji {{mîr|trk-pro|ota|*keklik||kew}}<ref>{{R:trk:Clauson|entry=keklik|page=710}}</ref> û mihtemelen têkildarî {{qal|trk-pro|*kēkir-||qulpik hatin}}. Hevreha {{hv|otk|tr=keklik}}, {{qal|otk|tr=kekelik}}, {{hv|az|kəklik}}, {{hv|kk|кекілік}} û {{hv|slr|kegelik}}. ==== Jê ==== {{kol3|ota |آق ككلیك<tr:ak keklik> |ایری ككلیك<tr:iri keklik> |بیوك ككلیك<tr:büyük keklik> |چانطه‌ده ككلیك<tr:çantada keklik> |چیل ككلیك<tr:çil keklik> |قزل ككلیك<tr:kızıl keklik> |ككلیك اوتی<tr:keklik otu> |ككلیك بالغی<tr:keklik balığı> |ككلیك پالازی<tr:keklik palazı> |ككلیك چیكدمی<tr:keklik çiğdemi> |ككلیك نوعی<tr:keklik nevʼi> }} ==== Dûnde ==== * {{dû|tr|keklik}} * {{dû|hy|քէքլիկ|deyn=1}} ==== Bêhtir bixwîne ==== * {{R:ota:Abikean:1888|page=839a}} * {{R:ota:BdM|ككلیك|vol=II|page=636}} * {{R:tr:OTK|keklik|vol=3|page=2526}} * {{R:ota:Hindoglu|ككلك|page=393a}} * {{R:ota:Kelekian|page=1032}} * {{R:ota:Meninski|C|column=1271|Perdix}} * {{R:ota:Meninski|L|column=3987|entry=ككلك}} * {{R:tr:Nishanyan|keklik}} * {{R:ota:Redhouse|ككلك|page=1558}} ====Çavkanî==== {{Çavkanî}} 5tk47udh3v5gncxluar3ha2ojmm04d5 6333894 6333867 2026-08-15T19:41:06Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: rêzkirina beşan 6333894 wikitext text/x-wiki == {{ziman|ota}} == === Navdêr === [[Wêne:Perdix perdix hispaniensis MHNT PHAS 1996 18.jpg|thumb|{{lang|ota|ككلیك}}]] {{navdêr|ota|tr=keklik}} # {{e|ota|teyr}} {{g|ku|kew}} ==== Formên alternatîv ==== * {{hw|ota|ككلك|tr1=keklik}} ==== Jê ==== {{kol3|ota |آق ككلیك<tr:ak keklik> |ایری ككلیك<tr:iri keklik> |بیوك ككلیك<tr:büyük keklik> |چانطه‌ده ككلیك<tr:çantada keklik> |چیل ككلیك<tr:çil keklik> |قزل ككلیك<tr:kızıl keklik> |ككلیك اوتی<tr:keklik otu> |ككلیك بالغی<tr:keklik balığı> |ككلیك پالازی<tr:keklik palazı> |ككلیك چیكدمی<tr:keklik çiğdemi> |ككلیك نوعی<tr:keklik nevʼi> }} ==== Etîmolojî ==== Ji {{mîr|trk-pro|ota|*keklik||kew}}<ref>{{R:trk:Clauson|entry=keklik|page=710}}</ref> û mihtemelen têkildarî {{qal|trk-pro|*kēkir-||qulpik hatin}}. Hevreha {{hv|otk|tr=keklik}}, {{qal|otk|tr=kekelik}}, {{hv|az|kəklik}}, {{hv|kk|кекілік}} û {{hv|slr|kegelik}}. ==== Dûnde ==== * {{dû|tr|keklik}} * {{dû|hy|քէքլիկ|deyn=1}} ==== Bêhtir bixwîne ==== * {{R:ota:Abikean:1888|page=839a}} * {{R:ota:BdM|ككلیك|vol=II|page=636}} * {{R:tr:OTK|keklik|vol=3|page=2526}} * {{R:ota:Hindoglu|ككلك|page=393a}} * {{R:ota:Kelekian|page=1032}} * {{R:ota:Meninski|C|column=1271|Perdix}} * {{R:ota:Meninski|L|column=3987|entry=ككلك}} * {{R:tr:Nishanyan|keklik}} * {{R:ota:Redhouse|ككلك|page=1558}} ====Çavkanî==== {{Çavkanî}} sunlrc8wm4502tlafzgua07l4p4zuiy Bikarhêner:Wikihez/skrîpt/js/delete.js 2 1357331 6334047 6328726 2026-08-16T01:54:44Z Wikihez 7344 6334047 javascript text/javascript // <nowiki> // Key: mass-delete-category // Label: Jêbirina bi kom // Info: Rûpelên di kategoriyê de an rûpelên girêdayî (Girêdanên li ser vir) bi komî jê dibe (Taybet ji bo adminan) (function() { // Navê fonksiyonê li vir wekî 'mass-delete-category' tê diyarkirin daku loader.js bikar bîne window.wikihez_scripts = window.wikihez_scripts || {}; window.wikihez_scripts['mass-delete-category'] = function() { // Mode diyar bike: 'category' an 'backlinks' function getMode() { if (mw.config.get('wgNamespaceNumber') === 14) { return 'category'; } if (mw.config.get('wgCanonicalSpecialPageName') === 'Whatlinkshere') { return 'backlinks'; } return null; } const mode = getMode(); if (!mode) { mw.notify('Ev amûr tenê di rûpelên kategoriyê de an di rûpelên "Girêdanên li ser vir" de dixebite.', { type: 'error' }); return; } // Rûpela armanc a bidest bixe (kategorî bixwe, an rûpela ku Taybet:Girêdanên_li_ser_vir lê dinêre) function getTargetTitle() { if (mode === 'category') { return mw.config.get('wgPageName'); } // backlinks mode let target = mw.config.get('wgRelevantPageName'); if (!target) { target = mw.util.getParamValue('target'); } return target; } const targetTitle = getTargetTitle(); if (!targetTitle) { mw.notify('Rûpela armanc nehat dîtin.', { type: 'error' }); return; } mw.loader.using(["mediawiki.api", "mediawiki.util", "jquery.ui"]).done(function() { const api = new mw.Api(); function getCategoryMembers(categoryName, callback) { api.get({ action: "query", list: "categorymembers", cmtitle: categoryName, cmlimit: "max", format: "json" }).done(function(data) { if (data.query && data.query.categorymembers) { const members = data.query.categorymembers.reduce((acc, member) => { // Hemû namespaces: 14 binkategorî ne, yên din rûpelên normal/yên din in const group = (member.ns === 14) ? '14' : 'others'; if (!acc[group]) acc[group] = []; acc[group].push(member.title); return acc; }, { 'others': [], '14': [] }); callback(members); } else { callback({ 'others': [], '14': [] }); } }).fail(() => callback({ 'others': [], '14': [] })); } function getBacklinkMembers(pageTitle, callback) { api.get({ action: "query", list: "backlinks", bltitle: pageTitle, bllimit: "max", format: "json" }).done(function(data) { if (data.query && data.query.backlinks) { const nsMap = {}; const members = data.query.backlinks.reduce((acc, member) => { // Rûpelên ku bixwe redirect in ber bi armancê ve, ji yên din cuda tomar bike const group = member.redirect !== undefined ? 'redirects' : 'others'; if (!acc[group]) acc[group] = []; acc[group].push(member.title); nsMap[member.title] = member.ns; return acc; }, { 'others': [], 'redirects': [] }); members.nsMap = nsMap; callback(members); } else { callback({ 'others': [], 'redirects': [], nsMap: {} }); } }).fail(() => callback({ 'others': [], 'redirects': [], nsMap: {} })); } function getMembers(callback) { if (mode === 'category') { getCategoryMembers(targetTitle, callback); } else { getBacklinkMembers(targetTitle, callback); } } // Sedemên jêbirinê yên pêş-danasînkirî. Yekem ji bo mode/target diyar e, // "bot" gişî ye, "custom" nivîsandina bi destan vedibe. function getReasonPresets() { const presets = []; if (mode === 'category') { presets.push({ key: 'default', label: 'Paqijkirina kategoriyê', value: "Paqijkirina kategoriya [[:Kategorî:Madeyên ku bên jêbirin\n|Madeyên ku bên jêbirin]]" }); } else { presets.push({ key: 'default', label: 'Bêçavkanî', value: `Formên [[${targetTitle}]] hatine jêbirin çunkî bêçavkanî ne` }); } presets.push({ key: 'bot', label: 'Xeletiya botê', value: 'Xeletiya botê' }); presets.push({ key: 'custom', label: 'Din (bi destan)', value: '' }); return presets; } function getDefaultReason() { return getReasonPresets()[0].value; } function getDialogTitle() { return mode === 'category' ? 'Jêbirina bi kom ji kategoriyê' : 'Jêbirina bi kom ji rûpelên girêdayî'; } function getSecondGroupConfig() { // { value: hilbijartina di members de, label: ya ku têtê nîşandan } return mode === 'category' ? { value: '14', label: 'Binkategorî' } : { value: 'redirects', label: 'Redirect' }; } function displayModal(members) { const secondGroup = getSecondGroupConfig(); const reasonPresets = getReasonPresets(); const reasonOptionsHtml = reasonPresets.map(p => `<option value="${p.key}">${mw.html.escape(p.label)}</option>` ).join(''); const modalHtml = ` <style> #md-container { /* Şêwaza ronahiyê ya standard */ --md-bg: #ffffff; --md-fg: #202122; --md-border: #a2a9b1; --md-input-bg: #ffffff; --md-list-bg: #f8f9fa; --md-item-border: #eaecf0; --md-item-hover: #fee7e6; --md-danger-bg: #d33333; --md-danger-fg: #ffffff; --md-btn-bg: #f8f9fa; --md-btn-fg: #202122; --md-progress-track: #eaecf0; font-family: sans-serif; padding: 10px; background: var(--md-bg); color: var(--md-fg); } /* Şêwaza tarî: dema tercîha pergalê tarî be (skin-theme-clientpref-os) */ @media (prefers-color-scheme: dark) { html.skin-theme-clientpref-os #md-container { --md-bg: #101418; --md-fg: #eaecf0; --md-border: #54595d; --md-input-bg: #27292d; --md-list-bg: #18181d; --md-item-border: #36383d; --md-item-hover: #3a2626; --md-danger-bg: #f54739; --md-danger-fg: #ffffff; --md-btn-bg: #2b2d31; --md-btn-fg: #eaecf0; --md-progress-track: #36383d; } } /* Şêwaza tarî: dema bikarhêner bi zelalî moda şevê hilbijartibe */ html.skin-theme-clientpref-night #md-container { --md-bg: #101418; --md-fg: #eaecf0; --md-border: #54595d; --md-input-bg: #27292d; --md-list-bg: #18181d; --md-item-border: #36383d; --md-item-hover: #3a2626; --md-danger-bg: #f54739; --md-danger-fg: #ffffff; --md-btn-bg: #2b2d31; --md-btn-fg: #eaecf0; --md-progress-track: #36383d; } /* Fallback: heke tu klasa skînê tune be lê pergal tarî be (nimûne, li derveyî wîkiyê) */ @media (prefers-color-scheme: dark) { html:not(.skin-theme-clientpref-day):not(.skin-theme-clientpref-night):not(.skin-theme-clientpref-os) #md-container { --md-bg: #101418; --md-fg: #eaecf0; --md-border: #54595d; --md-input-bg: #27292d; --md-list-bg: #18181d; --md-item-border: #36383d; --md-item-hover: #3a2626; --md-danger-bg: #f54739; --md-danger-fg: #ffffff; --md-btn-bg: #2b2d31; --md-btn-fg: #eaecf0; --md-progress-track: #36383d; } } .md-input-group { margin-bottom: 12px; } .md-input-group label { display: block; font-weight: bold; margin-bottom: 5px; color: var(--md-fg); } #md-reason, #md-pattern, #md-reason-preset { width: 100%; padding: 8px; box-sizing: border-box; border: 1px solid var(--md-border); background: var(--md-input-bg); color: var(--md-fg); } #md-reason-preset { margin-bottom: 6px; } #md-pattern { font-family: monospace; } #md-list { border: 1px solid var(--md-border); max-height: 200px; overflow-y: scroll; background: var(--md-list-bg); margin-bottom: 10px; } .md-item { padding: 5px 10px; border-bottom: 1px solid var(--md-item-border); cursor: pointer; font-size: 0.85em; display: flex; justify-content: space-between; color: var(--md-fg); } .md-item:hover { background-color: var(--md-item-hover); } .md-item.selected { background-color: var(--md-danger-bg) !important; color: var(--md-danger-fg); } #md-progress-container { display: none; margin-bottom: 15px; } #md-progress-bar { width: 100%; background: var(--md-progress-track); height: 12px; border-radius: 6px; overflow: hidden; } #md-progress-fill { width: 0%; height: 100%; background: var(--md-danger-bg); transition: width 0.2s; } #md-status-text { font-size: 0.85em; margin-top: 5px; text-align: center; color: var(--md-fg); } .md-buttons { display: flex; gap: 5px; } .md-btn { padding: 6px 12px; border: 1px solid var(--md-border); background: var(--md-btn-bg); color: var(--md-btn-fg); cursor: pointer; } .md-btn-danger { background: var(--md-danger-bg); color: var(--md-danger-fg); border-color: var(--md-danger-bg); font-weight: bold; margin-left: auto; } .md-btn:disabled { opacity: 0.5; cursor: default; } /* Şêwaza dîalogê ya jQuery UI (sernav, kêlek) */ .md-dialog.ui-dialog { background: var(--md-bg, #fff); border-color: var(--md-border, #a2a9b1); } .md-dialog .ui-dialog-titlebar { background: var(--md-list-bg, #f8f9fa); border-color: var(--md-border, #a2a9b1); color: var(--md-fg, #202122); } .md-dialog .ui-dialog-title { color: var(--md-fg, #202122); } .md-dialog .ui-dialog-content { background: var(--md-bg, #fff); color: var(--md-fg, #202122); } html.skin-theme-clientpref-night .md-dialog.ui-dialog, html.skin-theme-clientpref-night .md-dialog .ui-dialog-titlebar, html.skin-theme-clientpref-night .md-dialog .ui-dialog-content { background: #101418; color: #eaecf0; border-color: #54595d; } @media (prefers-color-scheme: dark) { html.skin-theme-clientpref-os .md-dialog.ui-dialog, html.skin-theme-clientpref-os .md-dialog .ui-dialog-titlebar, html.skin-theme-clientpref-os .md-dialog .ui-dialog-content { background: #101418; color: #eaecf0; border-color: #54595d; } } </style> <div id="md-container"> <div class="md-input-group"> <label>Sedemê jêbirinê:</label> <select id="md-reason-preset"> ${reasonOptionsHtml} </select> <input type="text" id="md-reason" placeholder="Sedemê binivîse..." value="${getDefaultReason()}"> </div> <div class="md-input-group"> <label>Fîltra Regex (vebijarkî):</label> <input type="text" id="md-pattern" placeholder="Nimûne: ^Bikarhêner:.*"> </div> <div class="md-input-group"> <input type="radio" id="pgRadio" name="md-type" value="others" checked> <label style="display:inline" for="pgRadio">Rûpel (Hemû)</label> &nbsp; <input type="radio" id="catRadio" name="md-type" value="${secondGroup.value}"> <label style="display:inline" for="catRadio">${secondGroup.label}</label> </div> ${mode === 'backlinks' ? ` <div class="md-input-group"> <input type="checkbox" id="md-ns0-filter"> <label style="display:inline" for="md-ns0-filter">Tenê made (ns:0)</label> </div> ` : ''} <div id="md-list"></div> <div id="md-progress-container"> <div id="md-progress-bar"><div id="md-progress-fill"></div></div> <div id="md-status-text">Amade ye...</div> </div> <div class="md-buttons"> <button class="md-btn" id="md-selectAll">Hemûyan hilbijêre</button> <button class="md-btn md-btn-danger" id="md-deleteButton">Jê bibe</button> </div> </div> `; const $dialog = $('<div>').html(modalHtml).dialog({ title: getDialogTitle(), width: 500, modal: true, dialogClass: 'md-dialog' }); function renderList() { const type = $('input[name="md-type"]:checked').val(); const items = members[type] || []; const $list = $('#md-list').empty(); const pattern = $('#md-pattern').val(); const ns0Only = $('#md-ns0-filter').is(':checked'); let regex; try { if(pattern) regex = new RegExp(pattern); } catch(e) {} items.forEach(item => { if (regex && !regex.test(item)) return; if (ns0Only && members.nsMap && members.nsMap[item] !== 0) return; const $el = $('<div>').addClass('md-item').text(item); $list.append($el); }); } $('#md-list').on('click', '.md-item', function() { $(this).toggleClass('selected'); }); $('#md-selectAll').on('click', function() { $('.md-item').addClass('selected'); }); $('#md-reason-preset').on('change', function() { const key = $(this).val(); const preset = reasonPresets.find(p => p.key === key); if (preset && key !== 'custom') { $('#md-reason').val(preset.value); } else { $('#md-reason').val('').focus(); } }); $('#md-pattern, input[name="md-type"], #md-ns0-filter').on('input change', renderList); $('#md-deleteButton').on('click', function() { const selected = $('.md-item.selected').map(function() { return $(this).text(); }).get(); const reason = $('#md-reason').val(); if (selected.length === 0) { alert("Ji kerema xwe rûpelan hilbijêre!"); return; } if (!confirm(`Tu dixwazî ${selected.length} rûpelan jê bibe? Ev kiryar paşve naye girtin!`)) return; $(this).prop('disabled', true); $('.md-btn').prop('disabled', true); $('#md-progress-container').show(); processDeletions(selected, reason, $dialog); }); renderList(); } async function processDeletions(titles, reason, $dialog) { const total = titles.length; const poolSize = 6; // concurrent requests, matching Twinkle's default batch size const queue = titles.slice(); let completed = 0; let deleted = 0; function updateProgress() { const progress = Math.round((completed / total) * 100); $('#md-progress-fill').css('width', progress + '%'); $('#md-status-text').text(`Tê jêbirin: ${completed} / ${total}`); } async function deleteOne(title) { try { await api.postWithToken("csrf", { action: "delete", title: title, reason: reason + " ([[Bikarhêner:Wikihez/skrîpt/js/delete.js|delete.js]])" }); deleted++; } catch (err) { console.error("Xeletî di jêbirina rûpela " + title + ":", err); } completed++; updateProgress(); } // Each worker pulls the next title off the shared queue until it's empty async function worker() { while (queue.length) { const title = queue.shift(); await deleteOne(title); } } const workers = Array.from({ length: Math.min(poolSize, total) }, worker); await Promise.all(workers); $('#md-status-text').text(`Temam bû! ${deleted} rûpel hatin jêbirin.`); setTimeout(() => { $dialog.dialog('close'); location.reload(); }, 1500); } // Destpêkirina pêvajoyê getMembers(displayModal); }); }; })(); // </nowiki> mnk0acklgafjlvkj970ici1al16bog2 Wîkîferheng:Xebat 4 1357857 6333822 6333777 2026-08-15T14:59:41Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ Bersiv 6333822 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Nimûneya... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) 1qcr0fi5lxmaqhmeukakpgpi8qvidpr 6333827 6333822 2026-08-15T15:05:35Z Wikihez 7344 /* MediaWiki:Gadget-start.js */ Bersiv 6333827 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Nimûneya... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) 357gfs4grw8q0phmas0vml5tx927k95 6333829 6333827 2026-08-15T15:08:32Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ min şaş nivîsandiye... 6333829 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) raoyd3yra9t7lve6wkfy190imut0ab5 6333833 6333829 2026-08-15T15:19:36Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ Bersiv 6333833 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kirye cime "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) reqi47u7si05ibmfzdcehw7nkomrbsm 6333834 6333833 2026-08-15T15:20:10Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ 6333834 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) 77568xf5826c6gzrxonio10fkh6stu0 6333835 6333834 2026-08-15T15:23:36Z Wikihez 7344 /* MediaWiki:Gadget-start.js */ Bersiv 6333835 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) qf1j67iim8t8n2w8hdtvdbym5sema1b 6333836 6333835 2026-08-15T15:25:35Z Wikihez 7344 /* MediaWiki:Gadget-start.js */ Bersiv 6333836 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) kwir4i1bchhh40gtweob58ykf0rufrl 6333837 6333836 2026-08-15T15:27:02Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ Bersiv 6333837 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) 1irl13jjwuwy5vaiefo0kq6lx6wdm8w 6333838 6333837 2026-08-15T15:32:33Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ Bersiv 6333838 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) liiy2alqojq0j57n9l5kanuseqm1lld 6333839 6333838 2026-08-15T15:35:51Z Wikihez 7344 /* MediaWiki:Gadget-start.js */ Bersiv 6333839 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) k7wa2ffgkojvipiofw4xx525hf417pz 6333840 6333839 2026-08-15T15:47:24Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ Bersiv 6333840 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) 6k9akjc4y6stb1r46gdozh38jla5lwc 6333841 6333840 2026-08-15T15:49:13Z Wikihez 7344 /* MediaWiki:Gadget-start.js */ Bersiv 6333841 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) ep8wkke6lnjyjeccpfhsmeuhg9sv69i 6333842 6333841 2026-08-15T15:51:12Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ Bersiv 6333842 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneya[[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) cxxn11k4svu1dij6mmx1xhj9l2of03d 6333843 6333842 2026-08-15T15:52:43Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ 6333843 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) 278kjn0j0blugj200brffxrh4h66to6 6333844 6333843 2026-08-15T15:53:54Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ 6333844 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) d5qz1aqam55cxh0uchpjno61fw49ydv 6333845 6333844 2026-08-15T15:58:46Z Wikihez 7344 /* MediaWiki:Gadget-start.js */ Bersiv 6333845 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) fy8k5wm7o1tpvsmb45ili0chqt9rgb7 6333846 6333845 2026-08-15T16:03:47Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ Bersiv 6333846 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) 8qnsxbrp4kscrgzd05qddybc6zn7pl9 6333848 6333846 2026-08-15T16:14:45Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ Bersiv 6333848 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) :::::::::::::::::::::::::Bi min tenê yek carê were nivîsandin ji ber ku tu bi şasî maneyên xwe jî jê dibirî (dema ku tu li ser maneyê ditikînî) :) Le cem "Beşe zêde bike" jî were nivîsandin [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:14, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) 411xgpu45x7841nhy0d628v705j65yh 6333849 6333848 2026-08-15T16:15:36Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ 6333849 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) :::::::::::::::::::::::::Bi min tenê yek carê were nivîsandin ji ber ku tu bi şasî maneyên xwe jî jê dibirî (dema ku tu li ser maneyê ditikînî) :) Li cem "Beşe zêde bike" jî were nivîsandin [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:14, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) nucq4u5zqy1pp65umxuc70m7s0khob3 6333850 6333849 2026-08-15T16:17:08Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ 6333850 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) :::::::::::::::::::::::::Bi min tenê yek carê were nivîsandin ji ber ku tu bi şasî maneyên xwe jî jê dibirî (dema ku tu li ser maneyê ditikînî) :) Li cem "Beş zêde bike" jî were nivîsandin [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:14, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) 22ibrcq38s33tgszata3r4cnaal7aet 6333851 6333850 2026-08-15T16:48:15Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ Bersiv 6333851 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) :::::::::::::::::::::::::Bi min tenê yek carê were nivîsandin ji ber ku tu bi şasî maneyên xwe jî jê dibirî (dema ku tu li ser maneyê ditikînî) :) Li cem "Beş zêde bike" jî were nivîsandin [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::Bi kurdmancî "Rehê dema bilanî (subj)" ne hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:48, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) o38afjevdy11tmc1at0795gny15q3yx 6333852 6333851 2026-08-15T17:14:42Z Wikihez 7344 /* MediaWiki:Gadget-start.js */ Bersiv 6333852 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) :::::::::::::::::::::::::Bi min tenê yek carê were nivîsandin ji ber ku tu bi şasî maneyên xwe jî jê dibirî (dema ku tu li ser maneyê ditikînî) :) Li cem "Beş zêde bike" jî were nivîsandin [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::Bi kurdmancî "Rehê dema bilanî (subj)" ne hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:48, 15 tebax 2026 (UTC) :::::::::::::::::::::::::::Lazim e pêşî em şablonan li gorî zimanan çêkin wekî en.wikt {{şx|en-lêker}} dûre li gorî parametreyên TemplateDatayê em qutiyan dikarin zêde an kêm bikin. Niha Malûmatên şablonên etîmolojî, bilêbkirin û guharto hhwd. ji templatedayê dîstinê wextê pê li butona (i) dikî, lê gelek ji wan ne xwedî TemplateData ne. Hîn karên din jî hene divê em bikin wekî sererastkirina şablonên jêgirtinê. Loma niha wisa bimîne. Em li gotûbêja amûrê beşa Daxwaz çêkin? tiştên ku tên bîra me em li wir binivîsin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:14, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) 5v8sx5ics6937fwfz6yn1y1vmkqhagy 6333862 6333852 2026-08-15T18:11:59Z Wikihez 7344 /* MediaWiki:Gadget-start.js */ Bersiv 6333862 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) :::::::::::::::::::::::::Bi min tenê yek carê were nivîsandin ji ber ku tu bi şasî maneyên xwe jî jê dibirî (dema ku tu li ser maneyê ditikînî) :) Li cem "Beş zêde bike" jî were nivîsandin [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::Bi kurdmancî "Rehê dema bilanî (subj)" ne hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:48, 15 tebax 2026 (UTC) :::::::::::::::::::::::::::Lazim e pêşî em şablonan li gorî zimanan çêkin wekî en.wikt {{şx|en-lêker}} dûre li gorî parametreyên TemplateDatayê em qutiyan dikarin zêde an kêm bikin. Niha Malûmatên şablonên etîmolojî, bilêbkirin û guharto hhwd. ji templatedayê dîstinê wextê pê li butona (i) dikî, lê gelek ji wan ne xwedî TemplateData ne. Hîn karên din jî hene divê em bikin wekî sererastkirina şablonên jêgirtinê. Loma niha wisa bimîne. Em li gotûbêja amûrê beşa Daxwaz çêkin? tiştên ku tên bîra me em li wir binivîsin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::::Min yên li jor çêkir feqat bi min resma jêbirinê baş nebû, tenê ya talî tê jêbirin ne tiştekî normal e? Min Beşên din jî xiste nav Eleqedar, Beşên din ne hewce ye. Bila zêde tab jî nebin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:11, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) 3y8gkjo421j7o37647t03m03fxwkhcy 6333863 6333862 2026-08-15T18:17:17Z Wikihez 7344 6333863 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) :::::::::::::::::::::::::Bi min tenê yek carê were nivîsandin ji ber ku tu bi şasî maneyên xwe jî jê dibirî (dema ku tu li ser maneyê ditikînî) :) Li cem "Beş zêde bike" jî were nivîsandin [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::Bi kurdmancî "Rehê dema bilanî (subj)" ne hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:48, 15 tebax 2026 (UTC) :::::::::::::::::::::::::::Lazim e pêşî em şablonan li gorî zimanan çêkin wekî en.wikt {{şx|en-lêker}} dûre li gorî parametreyên TemplateDatayê em qutiyan dikarin zêde an kêm bikin. Niha Malûmatên şablonên etîmolojî, bilêbkirin û guharto hhwd. ji templatedayê dîstinê wextê pê li butona (i) dikî, lê gelek ji wan ne xwedî TemplateData ne. Hîn karên din jî hene divê em bikin wekî sererastkirina şablonên jêgirtinê. Loma niha wisa bimîne. Em li gotûbêja amûrê beşa Daxwaz çêkin? tiştên ku tên bîra me em li wir binivîsin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::::Min yên ku te gotine çêkir feqat bi min resma jêbirinê baş nebû, tenê ya talî tê jêbirin ne tiştekî normal e? Min Beşên din jî xiste nav Eleqedar, Beşên din ne hewce ye. Bila zêde tab jî nebin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:11, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) 77qxi7n1gaggxhqtmgmzqke8odp2mkw 6333898 6333863 2026-08-15T20:18:55Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ 6333898 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) :::::::::::::::::::::::::Bi min tenê yek carê were nivîsandin ji ber ku tu bi şasî maneyên xwe jî jê dibirî (dema ku tu li ser maneyê ditikînî) :) Li cem "Beş zêde bike" jî were nivîsandin [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::Bi kurdmancî "Rehê dema bilanî (subj)" ne hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:48, 15 tebax 2026 (UTC) :::::::::::::::::::::::::::Lazim e pêşî em şablonan li gorî zimanan çêkin wekî en.wikt {{şx|en-lêker}} dûre li gorî parametreyên TemplateDatayê em qutiyan dikarin zêde an kêm bikin. Niha Malûmatên şablonên etîmolojî, bilêbkirin û guharto hhwd. ji templatedayê dîstinê wextê pê li butona (i) dikî, lê gelek ji wan ne xwedî TemplateData ne. Hîn karên din jî hene divê em bikin wekî sererastkirina şablonên jêgirtinê. Loma niha wisa bimîne. Em li gotûbêja amûrê beşa Daxwaz çêkin? tiştên ku tên bîra me em li wir binivîsin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::::Min yên ku te gotine çêkir feqat bi min resma jêbirinê baş nebû, tenê ya talî tê jêbirin ne tiştekî normal e? Min Beşên din jî xiste nav Eleqedar, Beşên din ne hewce ye. Bila zêde tab jî nebin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:11, 15 tebax 2026 (UTC) {{outdent|::::::::::::::::::::::::::::}} Îconeê (min rind fêm nekir) li gor daxwaza xwe bike... Herwiha çend bug hene: # Di nav maneyê de nivîs "zû" nayê nivîsandin. # Dema ku tu beşê dikî "Navdêr", paşê jî "Lêker": wekî "Navdêr" dimîne. Tu ê li ser "Bilêvkirin" bitikînî. -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 20:18, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) 97nanrzeycgmmrmppgu3gc6as50ka3m 6333899 6333898 2026-08-15T20:20:04Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ 6333899 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew planê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) :::::::::::::::::::::::::Bi min tenê yek carê were nivîsandin ji ber ku tu bi şasî maneyên xwe jî jê dibirî (dema ku tu li ser maneyê ditikînî) :) Li cem "Beş zêde bike" jî were nivîsandin [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::Bi kurdmancî "Rehê dema bilanî (subj)" ne hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:48, 15 tebax 2026 (UTC) :::::::::::::::::::::::::::Lazim e pêşî em şablonan li gorî zimanan çêkin wekî en.wikt {{şx|en-lêker}} dûre li gorî parametreyên TemplateDatayê em qutiyan dikarin zêde an kêm bikin. Niha Malûmatên şablonên etîmolojî, bilêbkirin û guharto hhwd. ji templatedayê dîstinê wextê pê li butona (i) dikî, lê gelek ji wan ne xwedî TemplateData ne. Hîn karên din jî hene divê em bikin wekî sererastkirina şablonên jêgirtinê. Loma niha wisa bimîne. Em li gotûbêja amûrê beşa Daxwaz çêkin? tiştên ku tên bîra me em li wir binivîsin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::::Min yên ku te gotine çêkir feqat bi min resma jêbirinê baş nebû, tenê ya talî tê jêbirin ne tiştekî normal e? Min Beşên din jî xiste nav Eleqedar, Beşên din ne hewce ye. Bila zêde tab jî nebin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:11, 15 tebax 2026 (UTC) {{outdent|::::::::::::::::::::::::::::}} Îkona jêbirinê (min rind fêm nekir) li gor daxwaza xwe bike... Herwiha çend bug hene: # Di nav maneyê de nivîs "zû" nayê nivîsandin. # Dema ku tu beşê dikî "Navdêr", paşê jî "Lêker": wekî "Navdêr" dimîne. Tu ê li ser "Bilêvkirin" bitikînî. -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 20:18, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) c1h8jb81ngkpvllfset80i4k1q45vus 6333900 6333899 2026-08-15T20:22:53Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ 6333900 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew şemayê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) :::::::::::::::::::::::::Bi min tenê yek carê were nivîsandin ji ber ku tu bi şasî maneyên xwe jî jê dibirî (dema ku tu li ser maneyê ditikînî) :) Li cem "Beş zêde bike" jî were nivîsandin [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::Bi kurdmancî "Rehê dema bilanî (subj)" ne hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:48, 15 tebax 2026 (UTC) :::::::::::::::::::::::::::Lazim e pêşî em şablonan li gorî zimanan çêkin wekî en.wikt {{şx|en-lêker}} dûre li gorî parametreyên TemplateDatayê em qutiyan dikarin zêde an kêm bikin. Niha Malûmatên şablonên etîmolojî, bilêbkirin û guharto hhwd. ji templatedayê dîstinê wextê pê li butona (i) dikî, lê gelek ji wan ne xwedî TemplateData ne. Hîn karên din jî hene divê em bikin wekî sererastkirina şablonên jêgirtinê. Loma niha wisa bimîne. Em li gotûbêja amûrê beşa Daxwaz çêkin? tiştên ku tên bîra me em li wir binivîsin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::::Min yên ku te gotine çêkir feqat bi min resma jêbirinê baş nebû, tenê ya talî tê jêbirin ne tiştekî normal e? Min Beşên din jî xiste nav Eleqedar, Beşên din ne hewce ye. Bila zêde tab jî nebin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:11, 15 tebax 2026 (UTC) {{outdent|::::::::::::::::::::::::::::}} Îkona jêbirinê (min rind fêm nekir) li gor daxwaza xwe bike... Herwiha çend bug hene: # Di nav maneyê de nivîs "zû" nayê nivîsandin. # Dema ku tu beşê dikî "Navdêr", paşê jî "Lêker": wekî "Navdêr" dimîne. Tu ê li ser "Bilêvkirin" bitikînî. -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 20:18, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) sj6fmhyhi2tsrc0h7ymic1fuhrvigke 6333901 6333900 2026-08-15T20:40:34Z Wikihez 7344 /* MediaWiki:Gadget-start.js */ Bersiv 6333901 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew şemayê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) :::::::::::::::::::::::::Bi min tenê yek carê were nivîsandin ji ber ku tu bi şasî maneyên xwe jî jê dibirî (dema ku tu li ser maneyê ditikînî) :) Li cem "Beş zêde bike" jî were nivîsandin [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::Bi kurdmancî "Rehê dema bilanî (subj)" ne hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:48, 15 tebax 2026 (UTC) :::::::::::::::::::::::::::Lazim e pêşî em şablonan li gorî zimanan çêkin wekî en.wikt {{şx|en-lêker}} dûre li gorî parametreyên TemplateDatayê em qutiyan dikarin zêde an kêm bikin. Niha Malûmatên şablonên etîmolojî, bilêbkirin û guharto hhwd. ji templatedayê dîstinê wextê pê li butona (i) dikî, lê gelek ji wan ne xwedî TemplateData ne. Hîn karên din jî hene divê em bikin wekî sererastkirina şablonên jêgirtinê. Loma niha wisa bimîne. Em li gotûbêja amûrê beşa Daxwaz çêkin? tiştên ku tên bîra me em li wir binivîsin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::::Min yên ku te gotine çêkir feqat bi min resma jêbirinê baş nebû, tenê ya talî tê jêbirin ne tiştekî normal e? Min Beşên din jî xiste nav Eleqedar, Beşên din ne hewce ye. Bila zêde tab jî nebin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:11, 15 tebax 2026 (UTC) {{outdent|::::::::::::::::::::::::::::}} Îkona jêbirinê (min rind fêm nekir) li gor daxwaza xwe bike... Herwiha çend bug hene: # Di nav maneyê de nivîs "zû" nayê nivîsandin. # Dema ku tu beşê dikî "Navdêr", paşê jî "Lêker": wekî "Navdêr" dimîne. Tu ê li ser "Bilêvkirin" bitikînî. -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 20:18, 15 tebax 2026 (UTC) :Min 1 fêm kir, ji ber ku Werger û Bi zaravayên din tên updatekirin dereng dimîne, belkî li şûna wextê nivîsînê, em bikin piştî nivîsînê ew ê zûtir be. :Ya 2an min nikaribû bibînim çawa ev problem derdikeve, li ku derê wekî Navdêr dimîne piştî guhartinê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:40, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) 8q5ea3qyb5y02eret1eeyiytzdoiu49 6333903 6333901 2026-08-15T20:53:41Z Wikihez 7344 /* MediaWiki:Gadget-start.js */ Bersiv 6333903 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew şemayê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) :::::::::::::::::::::::::Bi min tenê yek carê were nivîsandin ji ber ku tu bi şasî maneyên xwe jî jê dibirî (dema ku tu li ser maneyê ditikînî) :) Li cem "Beş zêde bike" jî were nivîsandin [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::Bi kurdmancî "Rehê dema bilanî (subj)" ne hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:48, 15 tebax 2026 (UTC) :::::::::::::::::::::::::::Lazim e pêşî em şablonan li gorî zimanan çêkin wekî en.wikt {{şx|en-lêker}} dûre li gorî parametreyên TemplateDatayê em qutiyan dikarin zêde an kêm bikin. Niha Malûmatên şablonên etîmolojî, bilêbkirin û guharto hhwd. ji templatedayê dîstinê wextê pê li butona (i) dikî, lê gelek ji wan ne xwedî TemplateData ne. Hîn karên din jî hene divê em bikin wekî sererastkirina şablonên jêgirtinê. Loma niha wisa bimîne. Em li gotûbêja amûrê beşa Daxwaz çêkin? tiştên ku tên bîra me em li wir binivîsin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::::Min yên ku te gotine çêkir feqat bi min resma jêbirinê baş nebû, tenê ya talî tê jêbirin ne tiştekî normal e? Min Beşên din jî xiste nav Eleqedar, Beşên din ne hewce ye. Bila zêde tab jî nebin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:11, 15 tebax 2026 (UTC) {{outdent|::::::::::::::::::::::::::::}} Îkona jêbirinê (min rind fêm nekir) li gor daxwaza xwe bike... Herwiha çend bug hene: # Di nav maneyê de nivîs "zû" nayê nivîsandin. # Dema ku tu beşê dikî "Navdêr", paşê jî "Lêker": wekî "Navdêr" dimîne. Tu ê li ser "Bilêvkirin" bitikînî. -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 20:18, 15 tebax 2026 (UTC) :Min 1 fêm kir, ji ber ku Werger û Bi zaravayên din tên updatekirin dereng dimîne, belkî li şûna wextê nivîsînê, em bikin piştî nivîsînê ew ê zûtir be. :Ya 2an min nikaribû bibînim çawa ev problem derdikeve, li ku derê wekî Navdêr dimîne piştî guhartinê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:40, 15 tebax 2026 (UTC) ::Min fêm kir lazim e li Bilêvkirinê pê lê bikî da ku biguhêre... Ez ê rast bikim [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:53, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) cs2p2qiqywqj7b7pzrj4y9ja8x2cnp6 6333909 6333903 2026-08-15T21:37:35Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ Bersiv 6333909 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew şemayê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) :::::::::::::::::::::::::Bi min tenê yek carê were nivîsandin ji ber ku tu bi şasî maneyên xwe jî jê dibirî (dema ku tu li ser maneyê ditikînî) :) Li cem "Beş zêde bike" jî were nivîsandin [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::Bi kurdmancî "Rehê dema bilanî (subj)" ne hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:48, 15 tebax 2026 (UTC) :::::::::::::::::::::::::::Lazim e pêşî em şablonan li gorî zimanan çêkin wekî en.wikt {{şx|en-lêker}} dûre li gorî parametreyên TemplateDatayê em qutiyan dikarin zêde an kêm bikin. Niha Malûmatên şablonên etîmolojî, bilêbkirin û guharto hhwd. ji templatedayê dîstinê wextê pê li butona (i) dikî, lê gelek ji wan ne xwedî TemplateData ne. Hîn karên din jî hene divê em bikin wekî sererastkirina şablonên jêgirtinê. Loma niha wisa bimîne. Em li gotûbêja amûrê beşa Daxwaz çêkin? tiştên ku tên bîra me em li wir binivîsin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::::Min yên ku te gotine çêkir feqat bi min resma jêbirinê baş nebû, tenê ya talî tê jêbirin ne tiştekî normal e? Min Beşên din jî xiste nav Eleqedar, Beşên din ne hewce ye. Bila zêde tab jî nebin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:11, 15 tebax 2026 (UTC) {{outdent|::::::::::::::::::::::::::::}} Îkona jêbirinê (min rind fêm nekir) li gor daxwaza xwe bike... Herwiha çend bug hene: # Di nav maneyê de nivîs "zû" nayê nivîsandin. # Dema ku tu beşê dikî "Navdêr", paşê jî "Lêker": wekî "Navdêr" dimîne. Tu ê li ser "Bilêvkirin" bitikînî. -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 20:18, 15 tebax 2026 (UTC) :Min 1 fêm kir, ji ber ku Werger û Bi zaravayên din tên updatekirin dereng dimîne, belkî li şûna wextê nivîsînê, em bikin piştî nivîsînê ew ê zûtir be. :Ya 2an min nikaribû bibînim çawa ev problem derdikeve, li ku derê wekî Navdêr dimîne piştî guhartinê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:40, 15 tebax 2026 (UTC) ::Min fêm kir lazim e li Bilêvkirinê pê lê bikî da ku biguhêre... Ez ê rast bikim [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:53, 15 tebax 2026 (UTC) :::Tiştekî din :) Formatên "Bilêvkirin" (kare) û "Beş1" (nîv-oval) ne wekhev in. Herwiha formatên "+ Beş zêde bike" û "+ Mane zêde bike" jî ne wekhev in. Tercihên te ne an jî bug e? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:37, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) 5urnjhms171wcayjwhzrgwxbzulqmsp 6333910 6333909 2026-08-15T21:40:30Z Wikihez 7344 /* MediaWiki:Gadget-start.js */ Bersiv 6333910 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew şemayê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) :::::::::::::::::::::::::Bi min tenê yek carê were nivîsandin ji ber ku tu bi şasî maneyên xwe jî jê dibirî (dema ku tu li ser maneyê ditikînî) :) Li cem "Beş zêde bike" jî were nivîsandin [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::Bi kurdmancî "Rehê dema bilanî (subj)" ne hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:48, 15 tebax 2026 (UTC) :::::::::::::::::::::::::::Lazim e pêşî em şablonan li gorî zimanan çêkin wekî en.wikt {{şx|en-lêker}} dûre li gorî parametreyên TemplateDatayê em qutiyan dikarin zêde an kêm bikin. Niha Malûmatên şablonên etîmolojî, bilêbkirin û guharto hhwd. ji templatedayê dîstinê wextê pê li butona (i) dikî, lê gelek ji wan ne xwedî TemplateData ne. Hîn karên din jî hene divê em bikin wekî sererastkirina şablonên jêgirtinê. Loma niha wisa bimîne. Em li gotûbêja amûrê beşa Daxwaz çêkin? tiştên ku tên bîra me em li wir binivîsin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::::Min yên ku te gotine çêkir feqat bi min resma jêbirinê baş nebû, tenê ya talî tê jêbirin ne tiştekî normal e? Min Beşên din jî xiste nav Eleqedar, Beşên din ne hewce ye. Bila zêde tab jî nebin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:11, 15 tebax 2026 (UTC) {{outdent|::::::::::::::::::::::::::::}} Îkona jêbirinê (min rind fêm nekir) li gor daxwaza xwe bike... Herwiha çend bug hene: # Di nav maneyê de nivîs "zû" nayê nivîsandin. # Dema ku tu beşê dikî "Navdêr", paşê jî "Lêker": wekî "Navdêr" dimîne. Tu ê li ser "Bilêvkirin" bitikînî. -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 20:18, 15 tebax 2026 (UTC) :Min 1 fêm kir, ji ber ku Werger û Bi zaravayên din tên updatekirin dereng dimîne, belkî li şûna wextê nivîsînê, em bikin piştî nivîsînê ew ê zûtir be. :Ya 2an min nikaribû bibînim çawa ev problem derdikeve, li ku derê wekî Navdêr dimîne piştî guhartinê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:40, 15 tebax 2026 (UTC) ::Min fêm kir lazim e li Bilêvkirinê pê lê bikî da ku biguhêre... Ez ê rast bikim [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:53, 15 tebax 2026 (UTC) :::Tiştekî din :) Formatên "Bilêvkirin" (kare) û "Beş1" (nîv-oval) ne wekhev in. Herwiha formatên "+ Beş zêde bike" û "+ Mane zêde bike" jî ne wekhev in. Tercihên te ne an jî bug e? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:37, 15 tebax 2026 (UTC) ::::Ev nîv-oval ji min re gelek ecêb tê. Yên din lazim in yek şekil bin wekî +Mane zêde bike. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:40, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) ebvpeuhcke3tnrd9t10aaazlo0ve7a2 6333911 6333910 2026-08-15T21:43:48Z Wikihez 7344 /* MediaWiki:Gadget-start.js */ Bersiv 6333911 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew şemayê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) :::::::::::::::::::::::::Bi min tenê yek carê were nivîsandin ji ber ku tu bi şasî maneyên xwe jî jê dibirî (dema ku tu li ser maneyê ditikînî) :) Li cem "Beş zêde bike" jî were nivîsandin [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::Bi kurdmancî "Rehê dema bilanî (subj)" ne hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:48, 15 tebax 2026 (UTC) :::::::::::::::::::::::::::Lazim e pêşî em şablonan li gorî zimanan çêkin wekî en.wikt {{şx|en-lêker}} dûre li gorî parametreyên TemplateDatayê em qutiyan dikarin zêde an kêm bikin. Niha Malûmatên şablonên etîmolojî, bilêbkirin û guharto hhwd. ji templatedayê dîstinê wextê pê li butona (i) dikî, lê gelek ji wan ne xwedî TemplateData ne. Hîn karên din jî hene divê em bikin wekî sererastkirina şablonên jêgirtinê. Loma niha wisa bimîne. Em li gotûbêja amûrê beşa Daxwaz çêkin? tiştên ku tên bîra me em li wir binivîsin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::::Min yên ku te gotine çêkir feqat bi min resma jêbirinê baş nebû, tenê ya talî tê jêbirin ne tiştekî normal e? Min Beşên din jî xiste nav Eleqedar, Beşên din ne hewce ye. Bila zêde tab jî nebin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:11, 15 tebax 2026 (UTC) {{outdent|::::::::::::::::::::::::::::}} Îkona jêbirinê (min rind fêm nekir) li gor daxwaza xwe bike... Herwiha çend bug hene: # Di nav maneyê de nivîs "zû" nayê nivîsandin. # Dema ku tu beşê dikî "Navdêr", paşê jî "Lêker": wekî "Navdêr" dimîne. Tu ê li ser "Bilêvkirin" bitikînî. -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 20:18, 15 tebax 2026 (UTC) :Min 1 fêm kir, ji ber ku Werger û Bi zaravayên din tên updatekirin dereng dimîne, belkî li şûna wextê nivîsînê, em bikin piştî nivîsînê ew ê zûtir be. :Ya 2an min nikaribû bibînim çawa ev problem derdikeve, li ku derê wekî Navdêr dimîne piştî guhartinê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:40, 15 tebax 2026 (UTC) ::Min fêm kir lazim e li Bilêvkirinê pê lê bikî da ku biguhêre... Ez ê rast bikim [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:53, 15 tebax 2026 (UTC) :::Tiştekî din :) Formatên "Bilêvkirin" (kare) û "Beş1" (nîv-oval) ne wekhev in. Herwiha formatên "+ Beş zêde bike" û "+ Mane zêde bike" jî ne wekhev in. Tercihên te ne an jî bug e? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:37, 15 tebax 2026 (UTC) ::::Ev nîv-oval ji min re gelek ecêb tê. Yên din lazim in yek şekil bin wekî +Mane zêde bike. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:40, 15 tebax 2026 (UTC) :::::Li şûna "Ev ne pênase ye — şablonek bi kar bîne" ez ê çi binivîsim? Ti tişt nayê bîra min ya ku dikare vê bikaranînê îzah bike. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:43, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) dlcyfdwf3suvd6qjss52l5ti7dyaxp8 6333916 6333911 2026-08-15T22:12:55Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ Bersiv 6333916 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew şemayê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) :::::::::::::::::::::::::Bi min tenê yek carê were nivîsandin ji ber ku tu bi şasî maneyên xwe jî jê dibirî (dema ku tu li ser maneyê ditikînî) :) Li cem "Beş zêde bike" jî were nivîsandin [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::Bi kurdmancî "Rehê dema bilanî (subj)" ne hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:48, 15 tebax 2026 (UTC) :::::::::::::::::::::::::::Lazim e pêşî em şablonan li gorî zimanan çêkin wekî en.wikt {{şx|en-lêker}} dûre li gorî parametreyên TemplateDatayê em qutiyan dikarin zêde an kêm bikin. Niha Malûmatên şablonên etîmolojî, bilêbkirin û guharto hhwd. ji templatedayê dîstinê wextê pê li butona (i) dikî, lê gelek ji wan ne xwedî TemplateData ne. Hîn karên din jî hene divê em bikin wekî sererastkirina şablonên jêgirtinê. Loma niha wisa bimîne. Em li gotûbêja amûrê beşa Daxwaz çêkin? tiştên ku tên bîra me em li wir binivîsin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::::Min yên ku te gotine çêkir feqat bi min resma jêbirinê baş nebû, tenê ya talî tê jêbirin ne tiştekî normal e? Min Beşên din jî xiste nav Eleqedar, Beşên din ne hewce ye. Bila zêde tab jî nebin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:11, 15 tebax 2026 (UTC) {{outdent|::::::::::::::::::::::::::::}} Îkona jêbirinê (min rind fêm nekir) li gor daxwaza xwe bike... Herwiha çend bug hene: # Di nav maneyê de nivîs "zû" nayê nivîsandin. # Dema ku tu beşê dikî "Navdêr", paşê jî "Lêker": wekî "Navdêr" dimîne. Tu ê li ser "Bilêvkirin" bitikînî. -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 20:18, 15 tebax 2026 (UTC) :Min 1 fêm kir, ji ber ku Werger û Bi zaravayên din tên updatekirin dereng dimîne, belkî li şûna wextê nivîsînê, em bikin piştî nivîsînê ew ê zûtir be. :Ya 2an min nikaribû bibînim çawa ev problem derdikeve, li ku derê wekî Navdêr dimîne piştî guhartinê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:40, 15 tebax 2026 (UTC) ::Min fêm kir lazim e li Bilêvkirinê pê lê bikî da ku biguhêre... Ez ê rast bikim [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:53, 15 tebax 2026 (UTC) :::Tiştekî din :) Formatên "Bilêvkirin" (kare) û "Beş1" (nîv-oval) ne wekhev in. Herwiha formatên "+ Beş zêde bike" û "+ Mane zêde bike" jî ne wekhev in. Tercihên te ne an jî bug e? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:37, 15 tebax 2026 (UTC) ::::Ev nîv-oval ji min re gelek ecêb tê. Yên din lazim in yek şekil bin wekî +Mane zêde bike. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:40, 15 tebax 2026 (UTC) :::::Li şûna "Ev ne pênase ye — şablonek bi kar bîne" ez ê çi binivîsim? Ti tişt nayê bîra min ya ku dikare vê bikaranînê îzah bike. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:43, 15 tebax 2026 (UTC) ::::::Maneyê bi şablonan çêke (hevmane, rastnivîs, ku-Latn, ...) :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) 94myg6hejj7yz2bedf3680nh83e7re0 6333917 6333916 2026-08-15T22:15:34Z Ghybu 1393 /* MediaWiki:Gadget-start.js */ hevmane şas tê fêm kirin 6333917 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) *:Merheba @[[Bikarhêner:Ghybu|Ghybu]] Te gotibû di vê modulê de xeletî hene, jkx tu dikarî li vir binivîsî çi kêmasî hene, daku wextê rojane dikim ez ji bîr nekim? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 21 tîrmeh 2026 (UTC) *::Silav. Nizanim ji bîra min çûye... Herwiha ji bo çêkirina formên navdêran zanînên cîns û tîpa dawî bes e: *::* (-ê, mê) => çemandî, bangkirin *::* (-ê, nêr) => îzafe *::* (-ê, mê û nêr) => îzafe (nêr), bangkirin (mê), çemandî (mê) *::* (-a) => îzafe (mê) *::* (-ekî) => îzafe û çemandî (nêr, nebinavkirî) *::* (-eke) = > îzafe (mê, nebinavkirî) *::* ... *:: <code>if find(mw.title.getCurrentTitle().subpageText, 'ekî$') then ... end</code> *::<code><nowiki>{{ku-tewîn-navForm|<navdêr>|<zayend>}</nowiki></code> *::Tablo û nivîs di yekcarî de tên çêkirin... *::Feqet problem lêzêdekirina mînakan e. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:34, 21 tîrmeh 2026 (UTC) *:::Lêzêdekirina kîjan nimûneyan? Ev koda js ji bo çi ye? Qisûrê nenêre min fêm nekir :/ [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:13, 21 tîrmeh 2026 (UTC) *::::Li vira ([[hevalê#Formeke navdêrê]]) di bin maneyên 1. û 2. mînak nayên tevlî kirin :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:18, 21 tîrmeh 2026 (UTC) *:::::Ev tercîh e, ne mecbûrî ye, em dikarin [https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&diff=prev&oldid=6276350 wisa] bikin. Wekî din? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:29, 21 tîrmeh 2026 (UTC) *::::::Min li jor tênê got ku tenê parametreyên "navdêr" û "zayend" hewce nee. Bi '''[//ku.wiktionary.org/w/index.php?title=heval%C3%AA&curid=969734&diff=6276353&oldid=6276350 vî]''' awayî jî tê çêkirin. Parametreyên din ne hewce ne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 21 tîrmeh 2026 (UTC) *:::::::Ji bo wê şabloneke din lazim e, bila ev şablon wekî îngilîzî bimîne em ji bo kurmancî yekî din çêkin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:42, 21 tîrmeh 2026 (UTC) *::::::::[https://ku.wiktionary.org/w/index.php?title=heval%C3%AA&oldid=6276885 wisa] çawa ye? Bi min nivîsîna nimûneyan zêde ne lazim e ji ber ku ti kes serê xwe pê naêşîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:46, 23 tîrmeh 2026 (UTC) *:::::::::@[[Bikarhêner:Ghybu|Ghybu]] Vê şablonê bi kar bînin an na? Navê şablonê kê çi be? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:07, 24 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Modul:ziman/code to canonical name]] == Belgekirina skrîptê û js divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:31, 22 tîrmeh 2026 (UTC) :* [[MediaWiki:UpdateLanguageNameAndCode.js]] :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:50, 22 tîrmeh 2026 (UTC) ::* [[Modul:ziman/print]] ::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:52, 22 tîrmeh 2026 (UTC) :::*[[Modul:ziman/şablon]] :::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:56, 22 tîrmeh 2026 (UTC) ::::* [[MediaWiki:Gadget-translation editor.js/ziman.json]] ::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:06, 22 tîrmeh 2026 (UTC) == [[Modul:quote]] == Piştî ev modul hate hazirkirin, lazim e navên jegirtinan werin rastkirin û li hemûyan {{param|jêgirtin}} were zêdekirin. Bnr. [[Gotûbêja şablonê:Jêgirtin/Ehmedê Xanî/Mem û Zîn]] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 5 tebax 2026 (UTC) ::Ev modul hema bêje hazir e. Hûn li ser van madeyan çi difikirin: # {{para|tarîx}} lazim e full date be eger na, lazim e {{para|sal}} were bikaranîn. Feqat "'''2021''' kanûna pêşîn 23" bi vî şiklî bi min ne problem e çnkî derdê en.wikt "attestation" e delîla herî pêşî jî sal e. #: {{demo|sep=wisa xuya dibe<br>|<nowiki>{{jêder-kitêb/ceribandin|en |tarîx=23 December 2021|nivîskar=Harry Hobbs; George Williams|sernav=Micronations and the Search for Sovereignty|url=https://www.cambridge.org/core/books/micronations-and-the-search-for-sovereignty/B0414A3A322695D9EE71E4CDDFDA06DE|weşanxane=Cambridge University Press|rûpel=155|isbn=978-1-009-15012-5|jêgirtin=jêgirtin.|t=-}}</nowiki>}} #{{para|amadekar}}/{{para|edîtor}}/{{para|terciman}} bi şiklê edîtoriya, amadekariya, tercimekirina #: {{demo|sep=dide<br>|<nowiki>{{jêder-kitêb/ceribandin|en |sernav=Medical Surgical Nursing|serî=Juta's Manual of Nursing|cildê-seriyê=volume 4|edîtor=Sophie Mataniele Mogotlane; Joyce Mokoena; Motshedisi Eunice Chauke; Anne Young|sal=2005|weşanxane=Juta Academic|isbn=978-0702171840|rûpel=!12-29|jêgirtin=jêgirtin|t=-}}</nowiki>}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:09, 10 tebax 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] û @[[Bikarhêner:Ghybu|Ghybu]] Hîn gelek tişt hene divê îzah bikin û fikrê we pirs bikim, feqat îzahkirin pir zor e, em dest bi bikaranînê bikin û dûre tiştên ku hûn naxwazin em dikarin biguherînîn, dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:11, 10 tebax 2026 (UTC) ::Dibe, piştî çêbû, em di praktîkê de bibînin ku çawa ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:05, 10 tebax 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) :Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], ez dibêjim karê Modul:quote zêde wext bistîne, bila em dest bi bikaranîna van amûran bikin dûre kêmasiyan em ê temam bikin înşela. Dikarî vana li cihên xwe yên rast kopî paste bikî? # [[Special:PermanentLink/6291574|Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] # Ya li jêr kopî bike qismê herî dawî ya AmûrênVeşartî li [[MediaWiki:Gadgets-definition]]: ## <code><nowiki>* citoid-helper[ResourceLoader|hidden|default|dependencies=mediawiki.util]|citoid-helper.js</nowiki></code> --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:58, 26 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) ::::Ev jî çêbû, min beşa çavkanî jî çêkir. Eger xeletî dernekeve û problema valahiya piştî etîketê ji bîr nekim, piştî rojanekirina amûrên linkify, û citoid em dikarin bar bikin. Ez ê ti tiştê nû îlawe nekim, zêde dirêj bû. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 21 tîrmeh 2026 (UTC) :::::Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Dikarî wana bar bikî? :::::* [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] :::::* [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] :::::* [[MediaWiki:Gadgets-definition]] wisa rojane bike: :::::* start[ResourceLoader|default|package|dependencies=mediawiki.util,ext.gadget.StorageUtils,ext.gadget.citoid-helper]|start.js|start.css|start.js/data.json :::::[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:39, 5 tebax 2026 (UTC) {{şirove}} Dewama ''[[Special:PermanentLink/6333688|Gotûbêja bikarhêner:Rewiye tine#WF:Nû]]'' bila gotûbêja wî em spam nekin. :D {{r|Ghybu}} dikarî [[Special:PermanentLink/6333689|vê htmlê]] binêrî claude rast fêm kiriye yan na? Daxîne û wek html qeyd bike. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:43, 14 tebax 2026 (UTC) :Min seh wîkîyên din jî kir, li wîkiya fransî tiştekî wekî daxwaza min çêkirine (tiştên ku ne hewce ne wekî "tab" çêkirine an jî hatine vêşartin): [//fr.wiktionary.org/w/index.php?title=fdsdfdsf&action=edit&redlink=1]. Formata me yê berî jî bi vê lojîkê hatibû çêkirin, wekî de.wiktionary ([//de.wiktionary.org/w/index.php?title=sdfdsfsdfs&action=edit&preload=Vorlage:Formatvorlage_(Substantiv_vereinfacht)]) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:01, 14 tebax 2026 (UTC) ::PS: Dîsa jî Claude min rind fêm kiriye :)) Feqet min got ku beşên Mane", "Bilêvkirin" û "Beşên din" cem hev (wekî "tab") ". Û dema ku tu terî di nav "Besên din" Hevmane, Jê, ... li wira werin dayîn. Wêne/Resim û Nimûne jî di nav beşa ("tab") "Mane" [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:17, 14 tebax 2026 (UTC) ::Erê ya fr.wikt min jî dîtibû jixwe fikrê tab min ji wan girtibû :D (feqat min li cem wan tenê tab-a maneyê dît yên din nedît çawa tê vekirin nizanim) Berê hemû beş piştî maneyê bibûn, dûre min sê Tab çêkir, Bingehîn+Lînkkirin+Bikaranîn. Niha lazim e Tabeke din çêkim. Ya ku claude çêkiriye bnr. [[Special:PermanentLink/6333698#L-7]] ne baş e bnr. [[Special:PermanentLink/6333703|qiyaskirinê li ser vê htmlê]] Êdî ez Claude abuse dikime ji ber ku Pro ye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:26, 14 tebax 2026 (UTC) :::Claude dibêje: :::Good clarification — that's a real simplification, not just a relabel. Updated STEP_GROUPS from 5 tabs down to 3: :::Mane — the definitions themselves, plus Wêne (image), now grouped in with it instead of sitting in a separate misc tab. Nimûne needed no change since it was already rendering inside each Mane sense block, not as its own step. :::Bilêvkirin — unchanged, still just pronunciation. :::Beşên din — everything else in one flat bucket: hevmane, jê, têkildar, herwiha binêre, formên alternatîv, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, tewandin, etîmolojî, zaravayên din, werger, and bnr-h — instead of being split across the old Bingehîn/Lînkkirin/Bikaranîn/Din tabs. :::No DOM-order changes were needed this time — the fix from the blank-tab bug looks up the tab bar's position dynamically now, so it didn't matter that I regrouped which steps go where. Same two files, saved to your Wiki folder — worth another pass through all three tabs once you've pasted this in, same as last time. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:34, 14 tebax 2026 (UTC) ::::Mînak: Ziman --------------------------------------------- Cureyê rêzimanî (Navdêr) Navdêr (hilbijêre) ┆ Cîns (hilbijêre) ┆ Jimar (hilbijêre) - lêker -mê -yekjimar - rengdêr -nêr -pirjimar - ... -... -... --------------------------------------------- Mane || Bilêvkirin || Beşên din hilbijêre: - mane - IPA - Hevmane - nimûne - kîte - Dijmane - wêne Dema ku tu "Cureyê rêzimanî" dikî "Lêker" : Cureyê rêzimanî (Lêker) Lêker (hilbijêre) ┆ Cure (hilbijêre) - navdêr -rehê niha - rengdêr -rehê borî - ... -... --------------------------------------------- ┆ : select/option ("tab" nîne, tê dîtin)<br> || : "tab" -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:45, 14 tebax 2026 (UTC) '''Sê-stûnî ("┆" = ne tab), li gorî Cureyê rêzimanî:''' {| class="wikitable" ! Cureyê rêzimanî !! Stûna 2 !! Stûna 3 !! Têbînî |- | Navdêr / Serenav | Cîns (hilbijêre ▾: mê / nêr / ... — tenê heke ziman zayendê rêzimanî hebe) | '''Jimar''' (?) — pirs li jêr | Qadên "Forma mê/nêr/pirjimar/yekjimar" niha jî li vir hene — ma ev di "Jimar"-ê de tên tevlihev kirin, an cuda dimînin? |- | Rengdêr | (heman m/n/p/y forman ku Navdêr distîne) | Sûperlatîv (sûp) / Komparatîv (komp) | Ne li ser her du nîgaran hatiye behs kirin — ma sê-stûnî li vir jî tê bikaranîn? |- | Lêker | '''Cure''' = Cureyê lêkerê (hilbijêre ▾: gerguhêz / negerguhêz / xwerû-... / pêkhatî-... / hevedudanî-... / biwêjî-... — 10 vebijêrk) | Di heman stûnê de: Rehê dema niha / Rehê dema borî / Rehê dema bilanî (her sê qadên nivîsandinê ne, ne hilbijêrk in) | Ma "Cure" her sê rehan di xwe de digire wek yek stûn, an her yek stûneke cuda ye? |- | Tîp (herf/sembol) | Girdêk (gir) / Hûrek (hûr) | — | Ne behs kiriye |- | Her cureyek, li gorî zimên | Transliterasyon (tr) / Transkrîpsiyon (ts) | — | Bi zimên ve girêdayî ye, ne bi cureyê rêzimanî ve |- | Her cureyek, tenê ziman=japonî | Hanja / Translit. hanja | — | Ne bi cureyê rêzimanî ve girêdayî ye |- | Her cureyek | '''Tercîhên pêşketî''' (kolapsî): form, formaalt, nekatcure, nekatcins, nekatçendterm, serlînkneke, nekatpalîndrom, neformtr | — | Vebijarkî, ji bo hemû cureyan |} '''Tabên jêrîn — Mane ‖ Bilêvkirin ‖ Beşên din ("||" = tab):''' {| class="wikitable" ! Mane !! Bilêvkirin !! Beşên din (hemû 18 hêman) |- | mane, nimûne, wêne | şablonên bilêvkirinê (mînak: IPA, kîte) | tewandin, etîmolojî, bi zaravayên din, werger, jê, têkildar, herwiha binêre, formên alternatîv, hevmane, dijmane, jornav, jêrnav, notên bikaranînê, bi alfabeyên din, dûnde, çavkanî, bêhtir bixwîne, bnr-h |} '''Pirsên vekirî:''' # "Jimar" (yekjimar/pirjimar) — qadeke ku nîşan dide têketî bi xwe yekjimar e an pirjimar e. Ev cuda ye ji "Forma yekjimar (y)"/"Forma pirjimar (p)" ya heyî (ku forma DÎN a kelîmeyê tomar dike). Herdu bimînin, an werin yek kirin? # Ma sê-stûnî tenê ji bo Navdêr/Lêker e, an ji bo Rengdêr/Tîp jî heman mantiq derbas dibe? # Di "Beşên din" de: dixwazî pêşî navnîşek/hilbijartinek nîşan bide (17 hêmanên din jî tê de), û qad tenê piştî hilbijartinê xuya bibin? :Tu dikarî start.js ji Tercîh/ Amûran rakî û bi test.js li Amûran herî taliyê ye biceribînî. Claude ya li jor hazir kir, Jimar ez dikarim îzah bikim. Feqat bi min di tab-a maneyê de lazim e Bi zaravayên din (heta wek werger her car bila li rûpelan were zêdekirin) û werger jî hebe.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:18, 14 tebax 2026 (UTC) :;Navdêr: Tenê "cîns" û "jimar" bes e. "Forma mê", "Forma nêr", ... nayê fêm kirin. Bi min wekî "Tercîhên pêşketî" bi navkî din veşartî çêke. :;Lêker: "Cureyê lêkerê" nayê fêm kirin, bi min pêşta "geguhez/negerguhêz" were hilbijartin, paşê jî form "hevdudanî/pêkatî/..." ji ber ku her kes vana nizanî... Dîsa jî tu dizanî. :Bi min beşên "Hevmane" û dijmane jî bike de nav beşa Mane ("tab") ji ber ku pirr tên xwestin. :Şûnda Wêne jî Nimûne/jêgirtin... :Herwiha hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:35, 14 tebax 2026 (UTC) ::Nimûne/jêgirtin, hevmane, Dijmane li binê her maneyê hene. ji ber ku wana bi maneyê ve girêdayî ne lazim e wisa bimîne feqat belkî şiklekî baştir bibînin. Hînbûna bikaranîna formeke nû bi qasî hînbûna koda wîkiyê zor e heqîqeten... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 14 tebax 2026 (UTC) :::Min şaş fêm meke feqet te amûrek ji bo Wikihez çêkiriye :) Tu dixwazî ku hemû tiştên ku te çêkiriye tevlî vê Gadgetê bikî û bikarhênerên din jî bi kar bînin... Tu jî dizanî ku kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > Dijmane ! Du Gadget çêke yek ji bo bikarhênerên ku hertim li vira ne, yekeke din jî ji bo bikarhênerên din (yên ku pirr nên vira). :::Herwiha kesên ku hertim li vira ne bi Gadgetê gotar çênekin, ''copy/paste'' dikin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 14 tebax 2026 (UTC) ::::Min xwest her tişt li ser rêza xwe be ji bo ku hîn bibin çi diçe kû derê feqat bi vî şiklî jî zêde dirêj û tevlihev dibe. Loma ez ê wekî tu dibêjî bikim her tiştê din bila collapsed pêşketî be. Ê ku dixwaze pê lê ke û binêre çi dikare were zêdekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 14 tebax 2026 (UTC) :::::Niha baştir tê fêm kirin {{=)}} [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:01, 14 tebax 2026 (UTC) ::::::Min ji Opus 5 û Design Tool îstifade kiriye hema bêje milyonek token çûn :D pêşî dîzayn kir dûre dest pê kir wekî dîna bişuxile. Pereyê xwe %100 heq dike welleh :D feqat moda tarî ji bîr kiriye :D [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:12, 14 tebax 2026 (UTC) :::::::Spas! Etîmolojî jî wekî "Bilêvkirin", di beşekê din de cem wê, were çêkirin (Mane|Etîmolojî|Bilêvkirin|Beşên din)? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:20, 14 tebax 2026 (UTC) ::::::::(Mane>Tewandin>Werger|Etîmolojî>Dûnde>|Bilêvkirin(formatek çawa?)>Resim|Eleqedar>Jê>Têkildar>Herwiha binêre|Beşên din)? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:29, 14 tebax 2026 (UTC) :::::::::Nizanim, biceribîne... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:43, 14 tebax 2026 (UTC) ::::::::::"Li şablonekê bigere" ser Maneyê hatiye nivîsandin, nizanim rind tê fêm kirin an na? Min paşê fêm kir :)) Naskirina Wîkîferhengê hewce ye... Li bin were nivîsandin û "notek" hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:02, 15 tebax 2026 (UTC) :::::::::::"Malûmatên pêşketî nîşan bide" jî bike ser "Hevman" ji ber ku pirr li jor e. Tu nizanî çi dike (nayê dîtin)... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:09, 15 tebax 2026 (UTC) ::::::::::::Dever/Devok jî were nivîsandin ? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:22, 15 tebax 2026 (UTC) :::::::::::::Tistekî din, dema ku tu maneyê dinivîsî bi otomatîk li jêr mane "2" tê nivîsandin, ew jî ne baş e (pirranî ne hewce ye). Bi min wekî "tab" cem "Mane 1" were vekirin (MAne1|Mane 2|Mane 3), bi otomatîk û an jî bi tikandina ser "Maneyeke din lê zêde bike" (cem beşa Maneyê). An jî bin beşa Wergerê bi nivîsa "maneyeke din lê zêde bike" were çêkirin. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:44, 15 tebax 2026 (UTC) ::::::::::::::Ji bo mane2, mane3, ... problemek heye: "Beşên din" ji bo kîjan maneyê ye :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:49, 15 tebax 2026 (UTC) :::::::::::::::Devok/dever ya rastî ji bo kurmancî herî muhîm e lê diçe qismê etîketê ew jî veşartî ye, Niha çawa çêbûye? Min butona +mane zêde bike îlawe kiriye. Beşên din ji bo hemû maneyan e, ji bo maneyên xisûsî lazim e yek qismê malûmatên zêdetir bi kar bîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:01, 15 tebax 2026 (UTC) ::::::::::::::::mane1, man2, ... cem beşa "Mane" çito ye, wekî: ::::::::::::::::<poem> :::::::::::::::: '''Mane''' || Etîmoljî || Eleqedar || Beşên din :::::::::::::::: ----------------------------------------------------------------- :::::::::::::::: Mane 1 || '''Mane 2''' || + Mane zêde bike [[Wêne:OOjs UI icon trash-destructive.svg|18px]] :::::::::::::::: <small>Maneya kelîmeyê binivîse. Mane otomatîk tê ...</small> ::::::::::::::::┌───────────────────────────────────┐ ::::::::::::::::│ Kelîmeyên ji bo... │ ::::::::::::::::└───────────────────────────────────┘ :::::::::::::::: ----------------------------------------------------------------- ::::::::::::::::</poem> ::::::::::::::::Belkî çêkirin zor e... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:59, 15 tebax 2026 (UTC) :::::::::::::::::Ev nimûne çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:05, 15 tebax 2026 (UTC) ::::::::::::::::::Te beşa "Bilêvkirin" kiriye cem "Beş1", erê. Li gor vê lojîkê "Etîmlojî" jî were cem beşa "Bilêvkirin", na? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:19, 15 tebax 2026 (UTC) ::::::::::::::::::Etîmolojî h4 e Bilêvkirin h3 loma min Bilêvkirin xiste cem "Beş1". Tu dibêjî îzaha qismê Maneyê "Maneya kelîmeyê binivîse. Mane otomatîk tê" li bin tabên Maneyê bin ne wisa? Pir ferq dike? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:23, 15 tebax 2026 (UTC) :::::::::::::::::::Checkbox ji bo Etîmolojiya "Beş2" zêde bikim? Eger truthy be bila Etîmolojî h3 be û here pêşiya crz (cureyê rêzimanî em jî hinek kurtkirin bi kar bînin êdî) ? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 15 tebax 2026 (UTC) :::::::::::::::::::Na min tiştekî witira negot, min tenê ji bo fêmkirinê ew şemayê çêkir... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:27, 15 tebax 2026 (UTC) ::::::::::::::::::::OK, niha rind bû :) "Maneyeke din zêde bike" çito ye? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 15 tebax 2026 (UTC) ::::::::::::::::::::Temam wê demê her tişt çêbû... Însan hîn dikare gelek tişt zêde bike, feqat usage limits hene :D Min session-a 5 saeatî temam kir. Dûre ez ê wisa bikim wextê pê li taba Mane-Etîmolojî dikî here jor, bi vî aawayî piştî dagirtina her tiştî li jêr însan dikare bi hêsanî maneyên din binivîse. Pişhingî jî ez ê paqiya zimanî bikim, piştî hinek ceribandinan em nû bikin. Eger fikrên nû were dûre dîsa dikarin îlawe bikin :) [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:35, 15 tebax 2026 (UTC) :::::::::::::::::::::Temam! Dema ku tu "Mane 2" an "Mane 3" bi şaşî nivîsand... çito tê/n jêbirin? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 15 tebax 2026 (UTC) ::::::::::::::::::::::Vala bikî bes e, beşên vala dernakevin li outputê. butonek çêkin? li kû derê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:49, 15 tebax 2026 (UTC) ::::::::::::::::::::::Cem "Maneyeke din zêde bike" '''jêbibe''' were nivîsandin an jî wêneyê [[Wêne:OOjs UI icon trash-destructive.svg|22px]]. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:51, 15 tebax 2026 (UTC) :::::::::::::::::::::::Mane 1 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] Mane 2 [[File:OOjs_UI_icon_trash-destructive.svg|16px]] +Maneyeke din zêde bike çawa dibe? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:58, 15 tebax 2026 (UTC) ::::::::::::::::::::::::Nizanim kîjan nîşan baş e: va jî heye: <code>✕</code> [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:03, 15 tebax 2026 (UTC) :::::::::::::::::::::::::Bi min tenê yek carê were nivîsandin ji ber ku tu bi şasî maneyên xwe jî jê dibirî (dema ku tu li ser maneyê ditikînî) :) Li cem "Beş zêde bike" jî were nivîsandin [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::Bi kurdmancî "Rehê dema bilanî (subj)" ne hewce ye. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:48, 15 tebax 2026 (UTC) :::::::::::::::::::::::::::Lazim e pêşî em şablonan li gorî zimanan çêkin wekî en.wikt {{şx|en-lêker}} dûre li gorî parametreyên TemplateDatayê em qutiyan dikarin zêde an kêm bikin. Niha Malûmatên şablonên etîmolojî, bilêbkirin û guharto hhwd. ji templatedayê dîstinê wextê pê li butona (i) dikî, lê gelek ji wan ne xwedî TemplateData ne. Hîn karên din jî hene divê em bikin wekî sererastkirina şablonên jêgirtinê. Loma niha wisa bimîne. Em li gotûbêja amûrê beşa Daxwaz çêkin? tiştên ku tên bîra me em li wir binivîsin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:14, 15 tebax 2026 (UTC) ::::::::::::::::::::::::::::Min yên ku te gotine çêkir feqat bi min resma jêbirinê baş nebû, tenê ya talî tê jêbirin ne tiştekî normal e? Min Beşên din jî xiste nav Eleqedar, Beşên din ne hewce ye. Bila zêde tab jî nebin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:11, 15 tebax 2026 (UTC) {{outdent|::::::::::::::::::::::::::::}} Îkona jêbirinê (min rind fêm nekir) li gor daxwaza xwe bike... Herwiha çend bug hene: # Di nav maneyê de nivîs "zû" nayê nivîsandin. # Dema ku tu beşê dikî "Navdêr", paşê jî "Lêker": wekî "Navdêr" dimîne. Tu ê li ser "Bilêvkirin" bitikînî. -- [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 20:18, 15 tebax 2026 (UTC) :Min 1 fêm kir, ji ber ku Werger û Bi zaravayên din tên updatekirin dereng dimîne, belkî li şûna wextê nivîsînê, em bikin piştî nivîsînê ew ê zûtir be. :Ya 2an min nikaribû bibînim çawa ev problem derdikeve, li ku derê wekî Navdêr dimîne piştî guhartinê? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:40, 15 tebax 2026 (UTC) ::Min fêm kir lazim e li Bilêvkirinê pê lê bikî da ku biguhêre... Ez ê rast bikim [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:53, 15 tebax 2026 (UTC) :::Tiştekî din :) Formatên "Bilêvkirin" (kare) û "Beş1" (nîv-oval) ne wekhev in. Herwiha formatên "+ Beş zêde bike" û "+ Mane zêde bike" jî ne wekhev in. Tercihên te ne an jî bug e? [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:37, 15 tebax 2026 (UTC) ::::Ev nîv-oval ji min re gelek ecêb tê. Yên din lazim in yek şekil bin wekî +Mane zêde bike. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:40, 15 tebax 2026 (UTC) :::::Li şûna "Ev ne pênase ye — şablonek bi kar bîne" ez ê çi binivîsim? Ti tişt nayê bîra min ya ku dikare vê bikaranînê îzah bike. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:43, 15 tebax 2026 (UTC) ::::::Maneyê bi şablonan çêke (rastnivîs, şas nivîs, aweyekî din, ku-Latn, ...) :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:12, 15 tebax 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) ::Tewandina fiîlan û xeletiya modulê lazim e were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:40, 21 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) :Min "wikt." qismên cache kirinê ya wîkiya fransî bi [[MediaWiki:Gadget-StorageUtils.js]] guhartiye. loma ji bîr nekin wê amûrê li [[MediaWiki:Gadgets-definition]] zêde bikin. û navê amûrê jî biguhêrînin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:15, 23 tîrmeh 2026 (UTC) ::Berê li ser WF:ceribandin dixebitî. niha naxebite. Divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:10, 7 tebax 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-linkify.js]] == * ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) * Amûreke din wekî [[User:Wikihez/Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{r|Bikarhêner}} Merheba bira, dikarî viya jî bar bikî?: * [[Special:PermanentLink/6291974|linkify]] --> [[Mediawiki:Gadget-linkify.js]] Spas--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:42, 29 tîrmeh 2026 (UTC) :Dûre [https://ku.wiktionary.org/wiki/MediaWiki:Gadget-start.js#L-283 li vir] wiktviLinkify bike kuLinkify xêra xwe [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:51, 29 tîrmeh 2026 (UTC) ::Min ji bîr kir lê zêde bikim niha nikare "Dİ" bike "di", xeletiyeke berbelav a di nivîsên kurdî de, herfên din ên wekî ll yan rr jî hewce ne werin zêdekirin. Dûre em zêde bikin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:42, 29 tîrmeh 2026 (UTC) :::Min nû ferq kir, sayfeyên ku hîn nehatine çêkirin wîkîlînk nake. Problemeke mezin e divê were rastkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:15, 30 tîrmeh 2026 (UTC) ::::Na, lînk dike, tiştekî din heye... [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:49, 31 tîrmeh 2026 (UTC) == Amûra manayê == Amûreke din ji bo nivîsina maneyê wekî Nimûne zêde bike lazim e [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6276876 js] [https://ku.wiktionary.org/w/index.php?title=%C5%9Eablon:ceribandin2&oldid=6265629 şablon] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6265642 css] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:12, 23 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-jeder.js]] == @[[Bikarhêner:Ghybu|Ghybu]] Çavkaniyên jêderê di moda pêşdîtinê de jêderê vedişêre, ew jî min gelek eciz dike wextê çavkanî zêde dikim. Min ji Claude pirsî û kodan nîşanî wê da, wisa cewab da: Yes — and this file actually explains the whole thing precisely, better than my earlier guess about extract-stripping. What's happening: the CSS rule <syntaxhighlight lang="css"> .jeder{ display:none; } </syntaxhighlight> hides every citation by default, *unconditionally*. The only thing that ever makes it visible again is the gadget's JS: it finds each `.jeder`, builds the short "`— (year, author, +)`" summary from the `.j-pewist` fields, and either reveals the short version or — for citations with no `.j-pewist` fields — explicitly sets `display:inline` on the original. So visibility of citations depends entirely on this JS running. In the normal article view (Image 1) it runs, so you see the collapsed "`(1918, E. Rehmî Ji Mala Hekariyan, Amadekar: M. E. Bozarslan, +)`" form. In whatever generated Image 2 — a hover-preview/extract/API render — gadget JS doesn't execute, so nothing ever removes the `display:none`, and the citation vanishes completely rather than degrading to "still visible, just not collapsed." <b>The fix:</b> flip the default so the *un-collapsed* state is the safe fallback, and let JS do the hiding only after it successfully builds the short version. That way, any context without JS shows the full citation instead of nothing. CSS — remove the blanket hide: <syntaxhighlight lang="css"> .jeder { /* intentionally no display:none here — see Gadget-... .js */ } </syntaxhighlight> JS — do the hiding from script, after the short form exists: {{veşêre-ser}} <syntaxhighlight lang="js"> // Ji bo şablonên [[Şablon:jêder]] hatiye nivîsandin. // Parametreyên ku di navbera "<span class="j-pewist">...</span>" an "{{j-pêwîst|...}}" de ne venaşêre. $(function() { function nivisaKurtTevliBike(sund, nivisKurt) { var zede = $('<a>+</a>') .addClass('click') .attr('href', '#') .attr('title', 'zêdetir') .css('font-weight', 'bold'); var kurt = $(' <a>↩</a>') .addClass('click-kurt') .attr('href', '#') .attr('title', 'veşêre') .css('font-weight', 'bold'); $('<span>' + nivisKurt + '</span>') .append(zede).append(')') .addClass('jeder-kurt') .css('font-size', '0.85em') .insertAfter(sund); sund.append(' ').append(kurt); // Only hide the full citation once the short summary actually exists. // If this script never runs (no-JS clients, hover-preview extracts, // action=render, etc.), the full citation stays visible instead of // silently disappearing. sund.css('display', 'none'); } function vesere() { $('.jeder').each(function() { var elmTab = $(this).find('.j-pewist').clone(); if (elmTab.length) { var elm = ''; for (var i = elmTab.length - 1; i >= 0; i--) { elm = elmTab.eq(i).html() + ', ' + elm; } var nivisKurt = ' — (' + elm; nivisaKurtTevliBike($(this), nivisKurt); } // else: no j-pewist fields to shorten — leave the full citation // as it already renders (visible), nothing to do. }); } vesere(); $(".click").click(function(e) { e.preventDefault(); $(this).parent('.jeder-kurt').css('display', 'none'); $(this).parent('.jeder-kurt').prev().css('display', 'inline'); }); $(".click-kurt").click(function(e) { e.preventDefault(); $(this).parent('.jeder').css('display', 'none'); $(this).parent('.jeder').next().css('display', 'inline'); }); }); </syntaxhighlight> Net effect: - JS-enabled readers (normal article view): identical experience to today — collapsed short form with `+`/`↩` toggle. - No-JS contexts (previews, extracts, screen readers before JS loads, print, etc.): full citation is shown instead of nothing — a real regression fix rather than a cosmetic one. One caveat worth being upfront about: this fixes it *if* the preview context renders the gadget's HTML/CSS but doesn't execute gadget JS (which is the far more common case, and what this code strongly suggests is happening). If Image 2 instead comes from a pipeline that strips the `.jeder`/`.jegirtin-text` elements out of the HTML entirely before this CSS/JS even gets a chance to apply, no on-wiki CSS/JS change can help — that'd need the extract-generation config changed instead. Given what this gadget file shows, though, I'd bet on the CSS-hide explanation. {{veşêre-bin}} Em dûre biceribînin eger xeletî tinebe, vî tiştî jî rast bikin. --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:00, 23 tîrmeh 2026 (UTC) :Ez APIya MediaWiki rind nizanim belkî Claude dizane:) Em nikarin bibêjin dema ku moda "''action=edit''" e fonksiyona <code>function vesere()</code> bi kar meyîne. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:57, 24 tîrmeh 2026 (UTC) ::Na, di moda "edît"-ê de <code>var elmTab = null</code>... [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:13, 24 tîrmeh 2026 (UTC) ?: <syntaxhighlight lang="js"> if ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ){ var elmTab = []; } else { var elmTab = $(this).find('.j-pewist').clone(); } </syntaxhighlight> --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:31, 24 tîrmeh 2026 (UTC) :Ez jî nizanim Claude çiqas ji mediawiki fêm dike lê heta niha ti tişt nîne ku min jê pirs kir û nikaribû çêke, bila wekî reklam nebe feqat Claude mikemmel e, dibêjim "li vir çima xeletiyeke wisa derdikeve" di dosyeya 2000 rêzî de diçe tiştê xelet tenê rast dike tiştekî din naguherîne. Chatgpt û aistudio qet wisa nakin, eynî dosyeyê deh cara dinivîsin, deh netîceyên cuda derdikevin :D :Em dikarin vê amûrê wextê edit û submitê neaktîv bikin wekî <syntaxhighlight lang="js">if (!(action === "edit" || action === "submit")) { :return;</syntaxhighlight> lê wê demê display:none wê çibe nizanim. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:23, 24 tîrmeh 2026 (UTC) ::display:none ne hewce ye ma jixwe di nav kodê [https://ku.wiktionary.org/w/index.php?title=MediaWiki:Gadget-jeder.js&oldid=6069025#L-49 L-49] de inline/none heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:53, 24 tîrmeh 2026 (UTC) :Min bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/vector-2022.js&diff=prev&oldid=6290816#L-28] ceriband feqat nexebitî. "display:none" di pêşdîtinê de dixebite feqat js naşixule. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:43, 25 tîrmeh 2026 (UTC) ::Kodên JSê pir hez nakim (pêşta hukurina APIya MWyê hewce bû) dîsa jî ez ê seh bikim :) [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:49, 27 tîrmeh 2026 (UTC) :::Ez niha bi vî şiklî [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/test.js&oldid=6290820] [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Wikihez/common.css&oldid=6290821#L-8] bi kar tînim ti problem nîne. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:09, 27 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-PagePreviews.js]] == Ez dibêjim em vê amûrê jî çêkin [[:en:MediaWiki:Gadget-PagePreviews.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:56, 3 tebax 2026 (UTC) = Moda tarî = == [[Şablon:wîkîpediya]] == Rengê tarî de xirab e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:36, 4 tebax 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :Min [[Bikarhêner:Wikihez/skrîpt/py/kuwiktkozmetik.py|paqijiyen kozmetîk]] hazir kir feqat hîn navên şablonan naguhêre. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:05, 4 tebax 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) j6zbgocbxhrxiztn61w8ipcl55v1ryk Wîkîferheng:Bot/Balyozbot/tercîh.json 4 1358288 6334051 6325644 2026-08-16T02:06:24Z Wikihez 7344 6334051 json application/json { "rezker": { "pos_sections": [ "Mane", "Navdêr", "Lêker", "Rengdêr", "Hoker", "Artîkel", "Baneşan", "Biwêj", "Cînav", "Daçek", "Dordaçek", "Girêdek", "Gotineke pêşiyan", "Hejmar", "Hevok", "Îfade", "Kurtenav", "Navgir", "Paşgir", "Paşdaçek", "Pêşdaçek", "Pêşgir", "Pirtik", "Romanîzasyon", "Reh", "Sembol", "Serenav", "Tîp" ], "SUBSECTIONS_ORDER": [ "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", "Bi zaravayên din", "Werger", "Qafiye", "Anagram", "Çavkanî" ], "rename": { "Tewîn": "Tewandin", "Bikaranîn": "Notên bikaranînê", "Nîşe": "Notên bikaranînê", "Nişe": "Notên bikaranînê", "Nişeyên karanînê": "Notên bikaranînê", "Nîşeyên karanînê": "Notên bikaranînê", "Nîşeyên bikaranînê": "Notên bikaranînê", "Agahî": "Notên bikaranînê", "Agahdarî": "Notên bikaranînê", "Agadarî": "Notên bikaranînê", "Têbînî": "Notên bikaranînê", "Binêre jî": "Herwiha binêre", "Binêre herwiha": "Herwiha binêre", "Binere herwiha": "Herwiha binêre", "Herwiha binere": "Herwiha binêre", "Têkilî": "Têkildar", "Têkilîdar": "Têkildar", "Têkildarî": "Têkildar", "Rehnasî": "Etîmolojî", "Bêjenasî": "Etîmolojî", "Peyvnasî": "Etîmolojî", "Êtîmolojî": "Etîmolojî", "Hevwate": "Hevmane", "Dijwate": "Dijmane", "Herwiha": "Formên alternatîv", "Herwisa": "Formên alternatîv", "Herweha": "Formên alternatîv", "Ji": "Etîmolojî", "Hîpernîm": "Jornav", "Hîponîm": "Jêrnav", "Nêzik": "Nêzîk", "Bi zaravayên kurdî": "Bi zaravayên din", "Bêhtir xwendin": "Bêhtir bixwîne", "Zêdetir bixwîne": "Bêhtir bixwîne", "Zêdetir Bixwînin": "Bêhtir bixwîne", "Zêdetir bixwînin": "Bêhtir bixwîne", "Zêdetir hîn bibe": "Bêhtir bixwîne", "Xwendina zêdetir": "Bêhtir bixwîne" } } } 4y4ppwmr3llyfqfjzt6040csgtijyp1 Bikarhêner:Balyozbot/kontrol/rêzkirina beşan 2 1358302 6333944 6329930 2026-08-15T23:22:38Z Wikihez 7344 /* Nenas beş */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333944 wikitext text/x-wiki == Nenas beş == * [[goganîbûnî]]: nenas beş "Bideber" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[guhlêbûn]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[hanek]]: nenas beş "Pirrjimar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[hanek]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[hevalkar]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[hevserî]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[hevxemî]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[hevîrkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[hêm]]: nenas beş "Binêre herwiha" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[hûrbîn]]: nenas beş "Navder" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[jajerûn]]: nenas beş "Pîrepend" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[jornivîs]]: nenas beş "Binêre herwiha" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[jêkvekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[jêrnivîs]]: nenas beş "Binêre herwiha" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kalekol]]: nenas beş "Têkilî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kannadayî]]: nenas beş "Alfabeya zimanê kannadayî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[katakanayî]]: nenas beş "[[kîte|Kîteyên]] katakanayî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kelobîn]]: nenas beş "Ji wêjeyê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kirtîn]]: nenas beş "Binere" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kirtînî]]: nenas beş "Binere" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kêfkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[lêderkirin]]: nenas beş "Hevmane" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[lêkolînên meydanî]]: nenas beş "Yekjimar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[lêkqelibîn]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[lûlav]]: nenas beş "Binêre herwiha" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[marekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[masîcank]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[maytêkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[menber]]: nenas beş "Pirrjimar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[mijxele]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[mêkut]]: nenas beş "Bi Elfabeyên Din" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[mêvanname]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[mît]]: nenas beş "Binêre herwiha" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[navokî]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[neguhdarî]]: nenas beş "Bi alfabeya erebî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nexwendewarî]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nexweş]]: nenas beş "Rengêr" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nezanî]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[neçarkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nîşaste]]: nenas beş "Formûla molekûlî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nûber]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nûçename]]: nenas beş "Herwiha binere" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[otokrasî]]: nenas beş "Têkildar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pandemî]]: nenas beş "Binêre herwiha" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[parçeparçekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[parîz]]: nenas beş "Têkil" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[peytkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pir]]: nenas beş "Diyarker" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pê]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêbîrhatinok]]: nenas beş "Minak" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêkanîn]]: nenas beş "2. Mane qowet lê bûn" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêlîstik]]: nenas beş "Cûnên pêlistikan" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêmovkî]]: nenas beş "Pirjimarî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêşbînîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pîrek]]: nenas beş "3. kesa ne keç" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pîtepêkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pîvaza nemrûdê]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[qotik]]: nenas beş "Jêrenot û çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[qurtalkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[raberîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[ranêzîk]]: nenas beş "Jê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[seat]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[serederîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[silavkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[sinetkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[tawankirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[têwerkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[waiz]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[wexerkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[windakirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xanekirin]]: nenas beş "Bi alfabeyên din" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xaçkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xelatkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xirvekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xiyar]]: nenas beş "Name" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xwecihkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[zirbarbûn]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[zirk]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[Îsmaîl]]: nenas beş "Formên alternatîv" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[Ûnis]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[çareserkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[şaşîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[şîrfiroş]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[li]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[Perman]]: nenas beş "Lêker (Sorani – Erdelanî)" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[پەرمان]]: nenas beş "Lêker (Sorani – Erdelanî)" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[gula hesretê]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[fižol]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[qerqeşûn]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[me]]: nenas beş "Formekê lêkerê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[şîrkî]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[qilqaldar]]: nenas beş "Jê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kanistan]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[bersorik]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nava hefteyê]]: nenas beş "Pirrjimar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[bi]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[wer]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) == Astengî di rêzkirinê de == * [[bariyer]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[bayist]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[bayist]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[biyang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[biyokîmya]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[biyoteknolojî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[botanîk]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[bêemrî]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[bêfermanî]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[bêjename]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[bêrîvan]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[bûk]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[cilxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[derbûn]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[derkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[dualîtî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[gir]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[gir]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[gizing]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[hegemonî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[heste]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[heywannasî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[hezîran]]: astengî di rêzkirinê de ji ber binbeşa "Binêre herwiha" (ne hate rêzkirin) * [[hiyeroglîf]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[jêkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[kanûna paşîn]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[kefalet]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[komparatîv]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[kronolojî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[melû]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[meriçîn]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[mexel]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[neqişandin]]: astengî di rêzkirinê de ji ber binbeşa "Bi alfabeyên din" (ne hate rêzkirin) * [[nivistinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[nîlûfer]]: astengî di rêzkirinê de ji ber binbeşa "Bi alfabeyên din" (ne hate rêzkirin) * [[nîsanok]]: astengî di rêzkirinê de ji ber binbeşa "Navê zanistî" (ne hate rêzkirin) * [[peryod]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[petrokîmya]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[peyîz]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[pifdank]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[pismam]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[pol]]: astengî di rêzkirinê de ji ber binbeşa "Binêre herwiha" (ne hate rêzkirin) * [[qap]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[qefa]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[qolanî]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[raber]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[raketinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[rapelîn]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[razang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[razanxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[revandin]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[rezber]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[rûniştinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[serborî]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[surprîz]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[sûperlatîv]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[tabloîd]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[texe]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[teyr]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[tirp]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[tîre]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[werkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[weşanxane]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[wuşe]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[xwarin]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[zang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[zirz]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[zoolojî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[zêrandin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[çiriya yekem]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[çîvçîv]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[şepilîn]]: astengî di rêzkirinê de ji ber binbeşa "Tewandin" (ne hate rêzkirin) * [[şor]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[şêl]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[şêwr]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[paş guhê xwe ve neavêtin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[paşguh nekirin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[piştguh nekirin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[şehde]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[nahiye]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[zoolog]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[heywannas]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[bêdengahî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[aya]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[bijîşk]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[rolyef]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[mefreq]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) == Şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî == * [[dest]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[pestandin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[vewêrtin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[xeriqandin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[şepilîn]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" l2ivm0sase3tyfzgdr3jeewwdfqo69g 6333965 6333944 2026-08-15T23:35:31Z Wikihez 7344 /* Nenas beş */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333965 wikitext text/x-wiki == Nenas beş == * [[katakanayî]]: nenas beş "[[kîte|Kîteyên]] katakanayî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kelobîn]]: nenas beş "Ji wêjeyê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kirtîn]]: nenas beş "Binere" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kirtînî]]: nenas beş "Binere" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kêfkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[lêderkirin]]: nenas beş "Hevmane" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[lêkolînên meydanî]]: nenas beş "Yekjimar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[lêkqelibîn]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[lûlav]]: nenas beş "Binêre herwiha" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[marekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[masîcank]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[maytêkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[menber]]: nenas beş "Pirrjimar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[mijxele]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[mêkut]]: nenas beş "Bi Elfabeyên Din" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[mêvanname]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[mît]]: nenas beş "Binêre herwiha" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[navokî]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[neguhdarî]]: nenas beş "Bi alfabeya erebî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nexwendewarî]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nexweş]]: nenas beş "Rengêr" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nezanî]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[neçarkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nîşaste]]: nenas beş "Formûla molekûlî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nûber]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nûçename]]: nenas beş "Herwiha binere" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[otokrasî]]: nenas beş "Têkildar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pandemî]]: nenas beş "Binêre herwiha" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[parçeparçekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[parîz]]: nenas beş "Têkil" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[peytkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pir]]: nenas beş "Diyarker" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pê]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêbîrhatinok]]: nenas beş "Minak" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêkanîn]]: nenas beş "2. Mane qowet lê bûn" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêlîstik]]: nenas beş "Cûnên pêlistikan" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêmovkî]]: nenas beş "Pirjimarî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêşbînîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pîrek]]: nenas beş "3. kesa ne keç" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pîtepêkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pîvaza nemrûdê]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[qotik]]: nenas beş "Jêrenot û çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[qurtalkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[raberîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[ranêzîk]]: nenas beş "Jê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[seat]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[serederîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[silavkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[sinetkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[tawankirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[têwerkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[waiz]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[wexerkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[windakirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xanekirin]]: nenas beş "Bi alfabeyên din" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xaçkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xelatkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xirvekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xiyar]]: nenas beş "Name" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xwecihkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[zirbarbûn]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[zirk]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[Îsmaîl]]: nenas beş "Formên alternatîv" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[Ûnis]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[çareserkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[şaşîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[şîrfiroş]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[li]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[Perman]]: nenas beş "Lêker (Sorani – Erdelanî)" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[پەرمان]]: nenas beş "Lêker (Sorani – Erdelanî)" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[gula hesretê]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[fižol]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[qerqeşûn]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[me]]: nenas beş "Formekê lêkerê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[şîrkî]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[qilqaldar]]: nenas beş "Jê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kanistan]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[bersorik]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nava hefteyê]]: nenas beş "Pirrjimar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[bi]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[wer]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) == Astengî di rêzkirinê de == * [[bariyer]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[bayist]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[bayist]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[biyang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[biyokîmya]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[biyoteknolojî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[botanîk]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[bêemrî]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[bêfermanî]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[bêjename]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[bêrîvan]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[bûk]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[cilxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[derbûn]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[derkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[dualîtî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[gir]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[gir]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[gizing]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[hegemonî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[heste]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[heywannasî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[hezîran]]: astengî di rêzkirinê de ji ber binbeşa "Binêre herwiha" (ne hate rêzkirin) * [[hiyeroglîf]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[jêkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[kanûna paşîn]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[kefalet]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[komparatîv]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[kronolojî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[melû]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[meriçîn]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[mexel]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[neqişandin]]: astengî di rêzkirinê de ji ber binbeşa "Bi alfabeyên din" (ne hate rêzkirin) * [[nivistinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[nîlûfer]]: astengî di rêzkirinê de ji ber binbeşa "Bi alfabeyên din" (ne hate rêzkirin) * [[nîsanok]]: astengî di rêzkirinê de ji ber binbeşa "Navê zanistî" (ne hate rêzkirin) * [[peryod]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[petrokîmya]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[peyîz]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[pifdank]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[pismam]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[pol]]: astengî di rêzkirinê de ji ber binbeşa "Binêre herwiha" (ne hate rêzkirin) * [[qap]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[qefa]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[qolanî]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[raber]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[raketinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[rapelîn]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[razang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[razanxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[revandin]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[rezber]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[rûniştinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[serborî]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[surprîz]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[sûperlatîv]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[tabloîd]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[texe]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[teyr]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[tirp]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[tîre]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[werkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[weşanxane]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[wuşe]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[xwarin]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[zang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[zirz]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[zoolojî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[zêrandin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[çiriya yekem]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[çîvçîv]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[şepilîn]]: astengî di rêzkirinê de ji ber binbeşa "Tewandin" (ne hate rêzkirin) * [[şor]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[şêl]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[şêwr]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[paş guhê xwe ve neavêtin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[paşguh nekirin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[piştguh nekirin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[şehde]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[nahiye]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[zoolog]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[heywannas]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[bêdengahî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[aya]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[bijîşk]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[rolyef]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[mefreq]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) == Şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî == * [[dest]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[pestandin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[vewêrtin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[xeriqandin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[şepilîn]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" ilwfx4rp3um177ex32n6c8afu88xoqd 6333973 6333965 2026-08-15T23:41:26Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: +1 xeta 6333973 wikitext text/x-wiki == Nenas beş == * [[katakanayî]]: nenas beş "[[kîte|Kîteyên]] katakanayî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kelobîn]]: nenas beş "Ji wêjeyê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kirtîn]]: nenas beş "Binere" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kirtînî]]: nenas beş "Binere" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kêfkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[lêderkirin]]: nenas beş "Hevmane" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[lêkolînên meydanî]]: nenas beş "Yekjimar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[lêkqelibîn]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[lûlav]]: nenas beş "Binêre herwiha" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[marekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[masîcank]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[maytêkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[menber]]: nenas beş "Pirrjimar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[mijxele]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[mêkut]]: nenas beş "Bi Elfabeyên Din" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[mêvanname]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[mît]]: nenas beş "Binêre herwiha" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[navokî]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[neguhdarî]]: nenas beş "Bi alfabeya erebî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nexwendewarî]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nexweş]]: nenas beş "Rengêr" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nezanî]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[neçarkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nîşaste]]: nenas beş "Formûla molekûlî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nûber]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nûçename]]: nenas beş "Herwiha binere" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[otokrasî]]: nenas beş "Têkildar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pandemî]]: nenas beş "Binêre herwiha" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[parçeparçekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[parîz]]: nenas beş "Têkil" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[peytkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pir]]: nenas beş "Diyarker" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pê]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêbîrhatinok]]: nenas beş "Minak" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêkanîn]]: nenas beş "2. Mane qowet lê bûn" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêlîstik]]: nenas beş "Cûnên pêlistikan" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêmovkî]]: nenas beş "Pirjimarî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêşbînîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pîrek]]: nenas beş "3. kesa ne keç" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pîtepêkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pîvaza nemrûdê]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[qotik]]: nenas beş "Jêrenot û çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[qurtalkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[raberîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[ranêzîk]]: nenas beş "Jê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[seat]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[serederîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[silavkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[sinetkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[tawankirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[têwerkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[waiz]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[wexerkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[windakirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xanekirin]]: nenas beş "Bi alfabeyên din" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xaçkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xelatkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xirvekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xiyar]]: nenas beş "Name" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xwecihkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[zirbarbûn]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[zirk]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[Îsmaîl]]: nenas beş "Formên alternatîv" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[Ûnis]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[çareserkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[şaşîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[şîrfiroş]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[li]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[Perman]]: nenas beş "Lêker (Sorani – Erdelanî)" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[پەرمان]]: nenas beş "Lêker (Sorani – Erdelanî)" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[gula hesretê]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[fižol]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[qerqeşûn]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[me]]: nenas beş "Formekê lêkerê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[şîrkî]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[qilqaldar]]: nenas beş "Jê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kanistan]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[bersorik]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nava hefteyê]]: nenas beş "Pirrjimar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[bi]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[wer]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[goganîbûnî]]: nenas beş "Bideber" (ne hate rêzkirin, ne pos_section e lê binbeş hene) == Astengî di rêzkirinê de == * [[bariyer]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[bayist]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[bayist]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[biyang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[biyokîmya]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[biyoteknolojî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[botanîk]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[bêemrî]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[bêfermanî]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[bêjename]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[bêrîvan]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[bûk]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[cilxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[derbûn]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[derkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[dualîtî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[gir]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[gir]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[gizing]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[hegemonî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[heste]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[heywannasî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[hezîran]]: astengî di rêzkirinê de ji ber binbeşa "Binêre herwiha" (ne hate rêzkirin) * [[hiyeroglîf]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[jêkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[kanûna paşîn]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[kefalet]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[komparatîv]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[kronolojî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[melû]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[meriçîn]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[mexel]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[neqişandin]]: astengî di rêzkirinê de ji ber binbeşa "Bi alfabeyên din" (ne hate rêzkirin) * [[nivistinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[nîlûfer]]: astengî di rêzkirinê de ji ber binbeşa "Bi alfabeyên din" (ne hate rêzkirin) * [[nîsanok]]: astengî di rêzkirinê de ji ber binbeşa "Navê zanistî" (ne hate rêzkirin) * [[peryod]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[petrokîmya]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[peyîz]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[pifdank]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[pismam]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[pol]]: astengî di rêzkirinê de ji ber binbeşa "Binêre herwiha" (ne hate rêzkirin) * [[qap]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[qefa]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[qolanî]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[raber]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[raketinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[rapelîn]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[razang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[razanxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[revandin]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[rezber]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[rûniştinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[serborî]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[surprîz]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[sûperlatîv]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[tabloîd]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[texe]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[teyr]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[tirp]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[tîre]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[werkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[weşanxane]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[wuşe]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[xwarin]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[zang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[zirz]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[zoolojî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[zêrandin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[çiriya yekem]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[çîvçîv]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[şepilîn]]: astengî di rêzkirinê de ji ber binbeşa "Tewandin" (ne hate rêzkirin) * [[şor]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[şêl]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[şêwr]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[paş guhê xwe ve neavêtin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[paşguh nekirin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[piştguh nekirin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[şehde]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[nahiye]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[zoolog]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[heywannas]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[bêdengahî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[aya]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[bijîşk]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[rolyef]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[mefreq]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) == Şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî == * [[dest]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[pestandin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[vewêrtin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[xeriqandin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[şepilîn]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" 8j55tyn8je4l229ai10dz7xxfnfzts1 6334023 6333973 2026-08-16T01:21:04Z Wikihez 7344 /* Nenas beş */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334023 wikitext text/x-wiki == Nenas beş == * [[parçeparçekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[parîz]]: nenas beş "Têkil" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[peytkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pir]]: nenas beş "Diyarker" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pê]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêbîrhatinok]]: nenas beş "Minak" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêkanîn]]: nenas beş "2. Mane qowet lê bûn" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêlîstik]]: nenas beş "Cûnên pêlistikan" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêmovkî]]: nenas beş "Pirjimarî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pêşbînîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pîrek]]: nenas beş "3. kesa ne keç" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pîtepêkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[pîvaza nemrûdê]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[qotik]]: nenas beş "Jêrenot û çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[qurtalkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[raberîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[ranêzîk]]: nenas beş "Jê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[seat]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[serederîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[silavkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[sinetkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[tawankirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[têwerkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[waiz]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[wexerkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[windakirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xanekirin]]: nenas beş "Bi alfabeyên din" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xaçkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xelatkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xirvekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xiyar]]: nenas beş "Name" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[xwecihkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[zirbarbûn]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[zirk]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[Îsmaîl]]: nenas beş "Formên alternatîv" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[Ûnis]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[çareserkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[şaşîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[şîrfiroş]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[li]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[Perman]]: nenas beş "Lêker (Sorani – Erdelanî)" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[پەرمان]]: nenas beş "Lêker (Sorani – Erdelanî)" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[gula hesretê]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[fižol]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[qerqeşûn]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[me]]: nenas beş "Formekê lêkerê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[şîrkî]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[qilqaldar]]: nenas beş "Jê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kanistan]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[bersorik]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[nava hefteyê]]: nenas beş "Pirrjimar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[bi]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[wer]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[goganîbûnî]]: nenas beş "Bideber" (ne hate rêzkirin, ne pos_section e lê binbeş hene) == Astengî di rêzkirinê de == * [[bariyer]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[bayist]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[bayist]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[biyang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[biyokîmya]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[biyoteknolojî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[botanîk]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[bêemrî]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[bêfermanî]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[bêjename]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[bêrîvan]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[bûk]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[cilxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[derbûn]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[derkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[dualîtî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[gir]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[gir]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[gizing]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[hegemonî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[heste]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[heywannasî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[hezîran]]: astengî di rêzkirinê de ji ber binbeşa "Binêre herwiha" (ne hate rêzkirin) * [[hiyeroglîf]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[jêkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[kanûna paşîn]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[kefalet]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[komparatîv]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[kronolojî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[melû]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[meriçîn]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[mexel]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[neqişandin]]: astengî di rêzkirinê de ji ber binbeşa "Bi alfabeyên din" (ne hate rêzkirin) * [[nivistinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[nîlûfer]]: astengî di rêzkirinê de ji ber binbeşa "Bi alfabeyên din" (ne hate rêzkirin) * [[nîsanok]]: astengî di rêzkirinê de ji ber binbeşa "Navê zanistî" (ne hate rêzkirin) * [[peryod]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[petrokîmya]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[peyîz]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[pifdank]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[pismam]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[pol]]: astengî di rêzkirinê de ji ber binbeşa "Binêre herwiha" (ne hate rêzkirin) * [[qap]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[qefa]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[qolanî]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[raber]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[raketinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[rapelîn]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[razang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[razanxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[revandin]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[rezber]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[rûniştinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[serborî]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[surprîz]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[sûperlatîv]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[tabloîd]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[texe]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[teyr]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[tirp]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[tîre]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[werkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[weşanxane]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[wuşe]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[xwarin]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[zang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[zirz]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[zoolojî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[zêrandin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[çiriya yekem]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[çîvçîv]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[şepilîn]]: astengî di rêzkirinê de ji ber binbeşa "Tewandin" (ne hate rêzkirin) * [[şor]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[şêl]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[şêwr]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[paş guhê xwe ve neavêtin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[paşguh nekirin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[piştguh nekirin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[şehde]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[nahiye]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[zoolog]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[heywannas]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[bêdengahî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[aya]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[bijîşk]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[rolyef]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[mefreq]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) == Şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî == * [[dest]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[pestandin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[vewêrtin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[xeriqandin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[şepilîn]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" cset8bigui20o4124e5g0g68jk84cgo 6334024 6334023 2026-08-16T01:21:23Z Wikihez 7344 /* Nenas beş */ 6334024 wikitext text/x-wiki == Nenas beş == # [[parçeparçekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[parîz]]: nenas beş "Têkil" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[peytkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pir]]: nenas beş "Diyarker" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pê]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pêbîrhatinok]]: nenas beş "Minak" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pêkanîn]]: nenas beş "2. Mane qowet lê bûn" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pêlîstik]]: nenas beş "Cûnên pêlistikan" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pêmovkî]]: nenas beş "Pirjimarî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pêşbînîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pîrek]]: nenas beş "3. kesa ne keç" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pîtepêkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pîvaza nemrûdê]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[qotik]]: nenas beş "Jêrenot û çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[qurtalkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[raberîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[ranêzîk]]: nenas beş "Jê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[seat]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[serederîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[silavkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[sinetkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[tawankirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[têwerkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[waiz]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[wexerkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[windakirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xanekirin]]: nenas beş "Bi alfabeyên din" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xaçkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xelatkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xirvekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xiyar]]: nenas beş "Name" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xwecihkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[zirbarbûn]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[zirk]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[Îsmaîl]]: nenas beş "Formên alternatîv" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[Ûnis]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[çareserkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[şaşîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[şîrfiroş]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[li]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[Perman]]: nenas beş "Lêker (Sorani – Erdelanî)" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[پەرمان]]: nenas beş "Lêker (Sorani – Erdelanî)" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[gula hesretê]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[fižol]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[qerqeşûn]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[me]]: nenas beş "Formekê lêkerê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[şîrkî]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[qilqaldar]]: nenas beş "Jê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[kanistan]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[bersorik]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[nava hefteyê]]: nenas beş "Pirrjimar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[bi]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[wer]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[goganîbûnî]]: nenas beş "Bideber" (ne hate rêzkirin, ne pos_section e lê binbeş hene) == Astengî di rêzkirinê de == * [[bariyer]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[bayist]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[bayist]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[biyang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[biyokîmya]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[biyoteknolojî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[botanîk]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[bêemrî]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[bêfermanî]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[bêjename]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[bêrîvan]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[bûk]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[cilxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[derbûn]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[derkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[dualîtî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[gir]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[gir]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[gizing]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[hegemonî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[heste]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[heywannasî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[hezîran]]: astengî di rêzkirinê de ji ber binbeşa "Binêre herwiha" (ne hate rêzkirin) * [[hiyeroglîf]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[jêkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[kanûna paşîn]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[kefalet]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[komparatîv]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[kronolojî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[melû]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[meriçîn]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[mexel]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[neqişandin]]: astengî di rêzkirinê de ji ber binbeşa "Bi alfabeyên din" (ne hate rêzkirin) * [[nivistinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[nîlûfer]]: astengî di rêzkirinê de ji ber binbeşa "Bi alfabeyên din" (ne hate rêzkirin) * [[nîsanok]]: astengî di rêzkirinê de ji ber binbeşa "Navê zanistî" (ne hate rêzkirin) * [[peryod]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[petrokîmya]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[peyîz]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[pifdank]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[pismam]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[pol]]: astengî di rêzkirinê de ji ber binbeşa "Binêre herwiha" (ne hate rêzkirin) * [[qap]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[qefa]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[qolanî]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[raber]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[raketinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[rapelîn]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[razang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[razanxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[revandin]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[rezber]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[rûniştinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[serborî]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[surprîz]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[sûperlatîv]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[tabloîd]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[texe]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[teyr]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[tirp]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[tîre]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[werkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[weşanxane]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[wuşe]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[xwarin]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[zang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[zirz]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[zoolojî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[zêrandin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[çiriya yekem]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[çîvçîv]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[şepilîn]]: astengî di rêzkirinê de ji ber binbeşa "Tewandin" (ne hate rêzkirin) * [[şor]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[şêl]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[şêwr]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[paş guhê xwe ve neavêtin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[paşguh nekirin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[piştguh nekirin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[şehde]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[nahiye]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[zoolog]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[heywannas]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[bêdengahî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[aya]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[bijîşk]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[rolyef]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[mefreq]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) == Şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî == * [[dest]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[pestandin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[vewêrtin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[xeriqandin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[şepilîn]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" ipu7xveoxy5k1kwnbnlgx8ae9bjd0q5 6334038 6334024 2026-08-16T01:41:42Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: +1 xeta 6334038 wikitext text/x-wiki == Nenas beş == # [[parçeparçekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[parîz]]: nenas beş "Têkil" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[peytkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pir]]: nenas beş "Diyarker" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pê]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pêbîrhatinok]]: nenas beş "Minak" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pêkanîn]]: nenas beş "2. Mane qowet lê bûn" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pêlîstik]]: nenas beş "Cûnên pêlistikan" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pêmovkî]]: nenas beş "Pirjimarî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pêşbînîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pîrek]]: nenas beş "3. kesa ne keç" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pîtepêkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[pîvaza nemrûdê]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[qotik]]: nenas beş "Jêrenot û çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[qurtalkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[raberîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[ranêzîk]]: nenas beş "Jê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[seat]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[serederîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[silavkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[sinetkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[tawankirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[têwerkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[waiz]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[wexerkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[windakirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xanekirin]]: nenas beş "Bi alfabeyên din" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xaçkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xelatkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xirvekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xiyar]]: nenas beş "Name" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xwecihkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[zirbarbûn]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[zirk]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[Îsmaîl]]: nenas beş "Formên alternatîv" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[Ûnis]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[çareserkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[şaşîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[şîrfiroş]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[li]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[Perman]]: nenas beş "Lêker (Sorani – Erdelanî)" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[پەرمان]]: nenas beş "Lêker (Sorani – Erdelanî)" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[gula hesretê]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[fižol]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[qerqeşûn]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[me]]: nenas beş "Formekê lêkerê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[şîrkî]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[qilqaldar]]: nenas beş "Jê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[kanistan]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[bersorik]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[nava hefteyê]]: nenas beş "Pirrjimar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[bi]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[wer]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[goganîbûnî]]: nenas beş "Bideber" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kirtîn]]: nenas beş "Herwiha binêre" (ne hate rêzkirin, ne pos_section e lê binbeş hene) == Astengî di rêzkirinê de == * [[bariyer]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[bayist]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[bayist]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[biyang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[biyokîmya]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[biyoteknolojî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[botanîk]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[bêemrî]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[bêfermanî]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[bêjename]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[bêrîvan]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[bûk]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[cilxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[derbûn]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[derkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[dualîtî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[gir]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[gir]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[gizing]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[hegemonî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[heste]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[heywannasî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[hezîran]]: astengî di rêzkirinê de ji ber binbeşa "Binêre herwiha" (ne hate rêzkirin) * [[hiyeroglîf]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[jêkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[kanûna paşîn]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[kefalet]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[komparatîv]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[kronolojî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[melû]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[meriçîn]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[mexel]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[neqişandin]]: astengî di rêzkirinê de ji ber binbeşa "Bi alfabeyên din" (ne hate rêzkirin) * [[nivistinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[nîlûfer]]: astengî di rêzkirinê de ji ber binbeşa "Bi alfabeyên din" (ne hate rêzkirin) * [[nîsanok]]: astengî di rêzkirinê de ji ber binbeşa "Navê zanistî" (ne hate rêzkirin) * [[peryod]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[petrokîmya]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[peyîz]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[pifdank]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[pismam]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[pol]]: astengî di rêzkirinê de ji ber binbeşa "Binêre herwiha" (ne hate rêzkirin) * [[qap]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[qefa]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[qolanî]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[raber]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[raketinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[rapelîn]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[razang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[razanxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[revandin]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[rezber]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[rûniştinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[serborî]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[surprîz]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[sûperlatîv]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[tabloîd]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[texe]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[teyr]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[tirp]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[tîre]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[werkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[weşanxane]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[wuşe]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[xwarin]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[zang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[zirz]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[zoolojî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[zêrandin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[çiriya yekem]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[çîvçîv]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[şepilîn]]: astengî di rêzkirinê de ji ber binbeşa "Tewandin" (ne hate rêzkirin) * [[şor]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[şêl]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[şêwr]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[paş guhê xwe ve neavêtin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[paşguh nekirin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[piştguh nekirin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[şehde]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[nahiye]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[zoolog]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[heywannas]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[bêdengahî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[aya]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[bijîşk]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[rolyef]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[mefreq]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) == Şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî == * [[dest]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[pestandin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[vewêrtin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[xeriqandin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[şepilîn]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" ir3hehuhotduou3rlv2mbbur4hzw1rn 6334062 6334038 2026-08-16T02:16:57Z Wikihez 7344 /* Nenas beş */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6334062 wikitext text/x-wiki == Nenas beş == # [[raberîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[ranêzîk]]: nenas beş "Jê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[seat]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[serederîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[silavkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[sinetkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[tawankirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[têwerkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[waiz]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[wexerkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[windakirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xanekirin]]: nenas beş "Bi alfabeyên din" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xaçkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xelatkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xirvekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xiyar]]: nenas beş "Name" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xwecihkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[zirbarbûn]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[zirk]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[Îsmaîl]]: nenas beş "Formên alternatîv" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[Ûnis]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[çareserkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[şaşîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[şîrfiroş]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[li]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[Perman]]: nenas beş "Lêker (Sorani – Erdelanî)" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[پەرمان]]: nenas beş "Lêker (Sorani – Erdelanî)" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[gula hesretê]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[fižol]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[qerqeşûn]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[me]]: nenas beş "Formekê lêkerê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[şîrkî]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[qilqaldar]]: nenas beş "Jê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[kanistan]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[bersorik]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[nava hefteyê]]: nenas beş "Pirrjimar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[bi]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[wer]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[goganîbûnî]]: nenas beş "Bideber" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kirtîn]]: nenas beş "Herwiha binêre" (ne hate rêzkirin, ne pos_section e lê binbeş hene) == Astengî di rêzkirinê de == * [[bariyer]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[bayist]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[bayist]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[biyang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[biyokîmya]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[biyoteknolojî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[botanîk]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[bêemrî]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[bêfermanî]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[bêjename]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[bêrîvan]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[bûk]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[cilxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[derbûn]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[derkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[dualîtî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[gir]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[gir]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[gizing]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[hegemonî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[heste]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[heywannasî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[hezîran]]: astengî di rêzkirinê de ji ber binbeşa "Binêre herwiha" (ne hate rêzkirin) * [[hiyeroglîf]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[jêkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[kanûna paşîn]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[kefalet]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[komparatîv]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[kronolojî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[melû]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[meriçîn]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[mexel]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[neqişandin]]: astengî di rêzkirinê de ji ber binbeşa "Bi alfabeyên din" (ne hate rêzkirin) * [[nivistinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[nîlûfer]]: astengî di rêzkirinê de ji ber binbeşa "Bi alfabeyên din" (ne hate rêzkirin) * [[nîsanok]]: astengî di rêzkirinê de ji ber binbeşa "Navê zanistî" (ne hate rêzkirin) * [[peryod]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[petrokîmya]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[peyîz]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[pifdank]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[pismam]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[pol]]: astengî di rêzkirinê de ji ber binbeşa "Binêre herwiha" (ne hate rêzkirin) * [[qap]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[qefa]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[qolanî]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[raber]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[raketinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[rapelîn]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[razang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[razanxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[revandin]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[rezber]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[rûniştinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[serborî]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[surprîz]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[sûperlatîv]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[tabloîd]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[texe]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[teyr]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[tirp]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[tîre]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[werkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[weşanxane]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[wuşe]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[xwarin]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[zang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[zirz]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[zoolojî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[zêrandin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[çiriya yekem]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[çîvçîv]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[şepilîn]]: astengî di rêzkirinê de ji ber binbeşa "Tewandin" (ne hate rêzkirin) * [[şor]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[şêl]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[şêwr]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[paş guhê xwe ve neavêtin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[paşguh nekirin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[piştguh nekirin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[şehde]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[nahiye]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[zoolog]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[heywannas]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[bêdengahî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[aya]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[bijîşk]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[rolyef]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[mefreq]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) == Şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî == * [[dest]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[pestandin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[vewêrtin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[xeriqandin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[şepilîn]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" qyjbuv86khy2qazdytozxxwkuht2lxz 6334068 6334062 2026-08-16T02:41:19Z Balyozbot 7867 [[Special:PermanentLink/6298023|Bot]]: +1 xeta 6334068 wikitext text/x-wiki == Nenas beş == # [[raberîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[ranêzîk]]: nenas beş "Jê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[seat]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[serederîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[silavkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[sinetkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[tawankirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[têwerkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[waiz]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[wexerkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[windakirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xanekirin]]: nenas beş "Bi alfabeyên din" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xaçkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xelatkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xirvekirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xiyar]]: nenas beş "Name" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[xwecihkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[zirbarbûn]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[zirk]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[Îsmaîl]]: nenas beş "Formên alternatîv" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[Ûnis]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[çareserkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[şaşîkirin]]: nenas beş "Çavkanî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[şîrfiroş]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[li]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[Perman]]: nenas beş "Lêker (Sorani – Erdelanî)" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[پەرمان]]: nenas beş "Lêker (Sorani – Erdelanî)" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[gula hesretê]]: nenas beş "Navê zanistî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[fižol]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[qerqeşûn]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[me]]: nenas beş "Formekê lêkerê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[şîrkî]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[qilqaldar]]: nenas beş "Jê" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[kanistan]]: nenas beş "Bi soranî" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[bersorik]]: nenas beş "Bilêvkirin" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[nava hefteyê]]: nenas beş "Pirrjimar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[bi]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[wer]]: nenas beş "Pêşdaçek" (ne hate rêzkirin, ne pos_section e lê binbeş hene) # [[goganîbûnî]]: nenas beş "Bideber" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[kirtîn]]: nenas beş "Herwiha binêre" (ne hate rêzkirin, ne pos_section e lê binbeş hene) * [[parîz]]: nenas beş "Têkildar" (ne hate rêzkirin, ne pos_section e lê binbeş hene) == Astengî di rêzkirinê de == * [[bariyer]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[bayist]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[bayist]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[biyang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[biyokîmya]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[biyoteknolojî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[botanîk]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[bêemrî]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[bêfermanî]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[bêjename]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[bêrîvan]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[bûk]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[cilxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[derbûn]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[derkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[dualîtî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[gir]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[gir]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[gizing]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[hegemonî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[heste]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[heywannasî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[hezîran]]: astengî di rêzkirinê de ji ber binbeşa "Binêre herwiha" (ne hate rêzkirin) * [[hiyeroglîf]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[jêkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[kanûna paşîn]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[kefalet]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[komparatîv]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[kronolojî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[melû]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[meriçîn]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[mexel]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[neqişandin]]: astengî di rêzkirinê de ji ber binbeşa "Bi alfabeyên din" (ne hate rêzkirin) * [[nivistinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[nîlûfer]]: astengî di rêzkirinê de ji ber binbeşa "Bi alfabeyên din" (ne hate rêzkirin) * [[nîsanok]]: astengî di rêzkirinê de ji ber binbeşa "Navê zanistî" (ne hate rêzkirin) * [[peryod]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[petrokîmya]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[peyîz]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[pifdank]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[pismam]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[pol]]: astengî di rêzkirinê de ji ber binbeşa "Binêre herwiha" (ne hate rêzkirin) * [[qap]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[qefa]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[qolanî]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[raber]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[raketinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[rapelîn]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[razang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[razanxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[revandin]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[rezber]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[rûniştinxane]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[serborî]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[surprîz]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[sûperlatîv]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[tabloîd]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[texe]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[teyr]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[tirp]]: astengî di rêzkirinê de ji ber binbeşa "Werger" (ne hate rêzkirin) * [[tîre]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[werkirin]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[weşanxane]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[wuşe]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[xwarin]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[zang]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[zirz]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[zoolojî]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[zêrandin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[çiriya yekem]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[çîvçîv]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[şepilîn]]: astengî di rêzkirinê de ji ber binbeşa "Tewandin" (ne hate rêzkirin) * [[şor]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[şêl]]: astengî di rêzkirinê de ji ber binbeşa "Bide ber" (ne hate rêzkirin) * [[şêwr]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[paş guhê xwe ve neavêtin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[paşguh nekirin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[piştguh nekirin]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[şehde]]: astengî di rêzkirinê de ji ber binbeşa "Jê" (ne hate rêzkirin) * [[nahiye]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[zoolog]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[heywannas]]: astengî di rêzkirinê de ji ber binbeşa "Têkildar" (ne hate rêzkirin) * [[bêdengahî]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[aya]]: astengî di rêzkirinê de ji ber binbeşa "Hevmane" (ne hate rêzkirin) * [[bijîşk]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) * [[rolyef]]: astengî di rêzkirinê de ji ber binbeşa "Etîmolojî" (ne hate rêzkirin) * [[mefreq]]: astengî di rêzkirinê de ji ber binbeşa "Formên alternatîv" (ne hate rêzkirin) == Şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî == * [[dest]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[pestandin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[vewêrtin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[xeriqandin]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" * [[şepilîn]]: şablona ku-tewîn-nav hat zêdekirin li binbeşa Tewandin ya heyî, ji kerema xwe kontrol bike, beş: "Navdêr" eh8y0ctw9lg2ji2nkf8ozetd6fhwven daheristin 0 1358352 6334077 6327732 2026-08-16T07:31:03Z Keyomerd 8814 /* Etîmolojî */ 6334077 wikitext text/x-wiki == {{ziman|ku}} == === Lêker === {{lêker|ku|c=p-ngh}} # [[dahelîn]], [[daleqîn]] #* {{jêder|ku|{{Jêgirtin/Ehmedê Xanî/Mem û Zîn}}|jêgirtin=Sorgul ji xwe da li ser rehistî</br>Sinbil bi xwe pêk ve '''daheristî'''}} ==== Etîmolojî ==== Ji {{pêş|ku|da|heristin}}. ==== Werger ==== {{werger-ser}} {{werger-bin}} 6eeoxvye9iwhvohfzsra4x0sr7z4zn5 Bikarhêner:Wikihez/Gadget-test.css 2 1358394 6333817 6333780 2026-08-15T14:29:26Z Wikihez 7344 6333817 css text/css /* =================================================================== #editform while the wizard is active =================================================================== */ /* Keeps #editform genuinely laid out instead of display:none*/ .wiktku-offscreen { position: absolute !important; left: -9999px !important; top: 0 !important; width: 100%; max-width: 100%; visibility: hidden; } /* =================================================================== Base scale =================================================================== */ #wiktku-start-form { font-size: 0.92em; line-height: 1.35; } #wiktku-start-form * { box-sizing: border-box; } .wiktku-addlang-notice { margin: 0 0 0.8em; padding: 0.6em 0.8em; background: var(--wikt-palette-paleblue); border: 1px solid var(--wikt-palette-lightgrey); border-radius: 4px; } /* =================================================================== Step cards a compact card with a left accent bar, so each step reads as a distinct unit =================================================================== */ .wiktku-start-step { padding: 0.7em 0.9em; margin-bottom: 0.6em; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-left: 4px solid var(--wikt-palette-blue-9, #3366cc); border-radius: 6px; background: var(--wikt-palette-white); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); transition: border-left-color 0.15s ease, box-shadow 0.15s ease; } .wiktku-start-step:hover { box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08); } .wiktku-start-step:focus-within { border-left-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); } /* Ghybu, 14 Tebax 2026: "Cureyê rêzimanî" and "Parametreyên cureyê rêzimanî" should read as one question, not two. Fuse the posparams card onto the bottom of the pos card (shared left accent bar, no border/gap between them) and drop its own big heading in favor of the smaller, pos-specific label start.js now sets via question_fmt ("Cins/zayend" / "Cureyê lêkerê" / "Taybetmendî"). posparams.visible only turns this div on once a pos is chosen, and it always renders immediately after #wiktku-start-pos in the DOM, so this pairing is safe. */ #wiktku-start-pos { border-radius: 6px 6px 0 0; margin-bottom: 0; border-bottom: none; } #wiktku-start-posparams { border-radius: 0 0 6px 6px; border-top: none; padding-top: 0.3em; } #wiktku-start-posparams .wiktku-start-step-name { display: none; } /* Scoped to #wiktku-start-form (not just .wiktku-start-step-name) and !important on font-size: this is a real <h3> tag (see start.js), so the wiki skin's own default heading styles can otherwise win over a plain class rule and render it unpredictably (varies by skin/ viewport — this was previously landing at a different effective size on desktop Vector vs. mobile Minerva purely by skin-default accident, not by design). The heading now leads the visual hierarchy through both size AND colour (tinted to match the card's accent bar), while .wiktku-start-step-question below is deliberately lighter-weight and muted so the two never compete for attention. */ #wiktku-start-form .wiktku-start-step-name { font-size: 1.1em !important; font-weight: 700; letter-spacing: 0.03em; margin: 0 0 0.3em; line-height: 1.2; color: var(--wikt-palette-blue-9, #3366cc); border: 0; padding: 0; } /* Rewiye tine, 14 Tebax 2026: "pûnto jî biçûk in, xwendina wan hinek zehmet e" — the question text and the many small per-field labels (Cinsiyet:, Rehê dema niha:, …) were sized noticeably smaller than the heading above them; bumped both a step so the whole card reads at a more consistent, comfortable size instead of the heading standing out and everything under it feeling like fine print. */ .wiktku-start-step-question { font-size: 1em; font-weight: 400; color: var(--wikt-palette-grey-9, #555); margin: 0 0 0.5em; line-height: 1.45; } .wiktku-start-step label { padding-right: 1.2em; font-size: 1em; } /* Rewiye tine, 14 Tebax 2026: short reassurance notes next to the fields that most confused a first-time user (Bilêvkirin's template dropdown, Mane's per-sense template dropdown) — muted so they read as a hint, not another question competing with .wiktku-start-step-question. */ .wiktku-step-hint { font-size: 0.88em; font-style: italic; color: var(--wikt-palette-grey-8, #72777d); margin: 0 0 0.5em; line-height: 1.4; } /* Same specificity as the rule just above, so it must come after to actually win: the name label isn't a field label needing right padding or the form's base label size, it's a heading. */ #wiktku-start-form .wiktku-start-step-name label { padding-right: 0; font-size: inherit !important; color: inherit; } input[type="text"].wiktku-start-step-field { width: 100%; padding: 5px 8px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 4px; transition: border-color 0.12s ease, box-shadow 0.12s ease; } input[type="text"].wiktku-start-step-field:focus { border-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9, #3366cc); outline: 0; } input[type="text"].wiktku-start-step-field.wiktku-start-narrow { width: 20em; } /* Only used by selects that opt out via .wiktku-plain-select; other selects get their width from the searchable picker instead (see input.wiktku-ac-input). */ select.wiktku-start-narrow, input.wiktku-dfn-tpl-title { width: 20em; max-width: 100%; box-sizing: border-box; } #wiktku-start-spinner { float: right; margin-left: 1em; } #wiktku-start-footer { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5em; padding: 0.6em 0.2em; position: sticky; bottom: 0; background: var(--wikt-palette-white); border-top: 1px solid var(--wikt-palette-grey-3, #e0e0e0); z-index: 5; } /* Quiet, non-competing text — sits next to the cache buttons so the person can tell at a glance whether their latest edits are backed up, without it fighting the buttons for attention. */ #wiktku-last-saved { font-size: 0.85em; color: var(--wikt-palette-grey-9, #767676); white-space: nowrap; } /* ── Tercîh (settings) icon button — sits in the footer next to the cache buttons. Uses the Codex "settings" (color-subtle) icon from Commons directly rather than an OOUI icon-pack module, so it renders the exact requested glyph without pulling in an extra dependency. */ .wiktku-prefs-btn { width: 2.2em; height: 2.2em; flex: 0 0 auto; padding: 0; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-radius: 2px; background-color: var(--wikt-palette-white); background-image: url(//upload.wikimedia.org/wikipedia/commons/e/e0/Codex_icon_settings_color-subtle.svg); background-repeat: no-repeat; background-position: center; background-size: 1.2em 1.2em; cursor: pointer; } .wiktku-prefs-btn:hover { background-color: var(--wikt-palette-grey-0, #f8f9fa); } .wiktku-prefs-btn:active { background-color: var(--wikt-palette-grey-1, #eaecf0); } /* Tercîh dialog body — OOUI's bare ProcessDialog body has no inset of its own, so text/fields otherwise sit flush against the window edges. */ .wiktku-prefs-dialog-body { padding: 1em 1.2em; } /* ── "Bişîne" click feedback ── */ @keyframes wiktku-btn-flash-pulse { 0% { box-shadow: 0 0 0 0 rgba(51, 102, 204, 0.55); } 70% { box-shadow: 0 0 0 9px rgba(51, 102, 204, 0); } 100% { box-shadow: 0 0 0 0 rgba(51, 102, 204, 0); } } #wiktku-unhide-editform.wiktku-btn-flash { animation: wiktku-btn-flash-pulse 0.5s ease-out; } /* Persistent state while the wikitext is being built/submitted, set alongside OOUI's own setDisabled(true) so it reads clearly even if the skin's default disabled style is subtle. */ #wiktku-unhide-editform.wiktku-btn-sending .oo-ui-buttonElement-button { background-color: var(--wikt-palette-grey-9, #767676) !important; border-color: var(--wikt-palette-grey-9, #767676) !important; cursor: progress; opacity: 1 !important; } /* Wikihez, 14 Tebax 2026 (item 7): looks exactly like OOUI's own disabled state, but ISN'T one — the button stays a real, clickable widget so its click handler can still run and explain why (see wiktkuNotify call next to wiktkuContentGateOk in start.js). A true setDisabled(true) here would swallow the click before that message could ever show. */ #wiktku-unhide-editform.wiktku-btn-soft-disabled .oo-ui-buttonElement-button { opacity: 0.5; cursor: not-allowed; } /* ── "Beşên din" picker (item 3) ── */ .wiktku-besendin-picker { margin: 0.6em 0 1em; } .wiktku-besendin-picker .wiktku-besendin-select { width: 100%; max-width: 24em; } #wiktku-start-form textarea.wiktku-start-step-field, #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield { resize: vertical !important; overflow: auto !important; box-sizing: border-box !important; vertical-align: top; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; transition: border-color 0.1s ease, box-shadow 0.1s ease; } /* Modern focus state to match the searchable-picker inputs. */ #wiktku-start-form textarea.wiktku-start-step-field:focus, #wiktku-start-form textarea.wiktku-start-narrow:focus, #wiktku-start-form textarea.wiktku-dfn-subfield:focus { border-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9, #3366cc); outline: 0; } /* Standard: every textarea in the form is full width by default */ #wiktku-start-form textarea:not(.wiktku-start-narrow) { width: 100%; max-width: 100%; box-sizing: border-box; } #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield.wiktku-start-narrow { width: 20em; max-width: 100%; min-width: 8em; height: calc(1.7em + 10px); min-height: calc(1.7em + 10px); padding-top: 4px !important; padding-bottom: 4px !important; line-height: 1.35 !important; resize: none !important; } /* Exception: "Sernav" / "Sernavê orjînal" citation-source fields (kitêb, kovar, malper, …) — long enough to be worth 2 rows and manual resizing. */ #wiktku-start-form textarea.wiktku-dfn-quote-src-input.wiktku-dfn-quote-src-input--title { height: calc(2 * 1.35em + 10px); min-height: calc(2 * 1.35em + 10px); } /* ── Manual drag-to-resize handle ── */ #wiktku-start-form textarea:not(.wiktku-start-narrow) { resize: none !important; } /* Inline modifier button (⊕) */ .wiktku-word-li { display: flex; align-items: flex-start; flex-wrap: wrap; gap: 0.3em; } .wiktku-mod-btn { flex: 0 0 auto; width: 1.6em; height: 1.6em; padding: 0; line-height: 1; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); color: var(--wikt-palette-blue-9, #3366cc); font-size: 1em; cursor: pointer; } .wiktku-mod-btn:hover { border-color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-paleblue, #eaf3ff); } .wiktku-mod-picker { display: flex; flex-wrap: wrap; gap: 0.25em; width: 100%; margin-top: 0.15em; padding: 0.35em; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; background: var(--wikt-palette-white); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); } .wiktku-mod-pill { padding: 2px 8px; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-radius: 12px; background: var(--wikt-palette-paleblue, #eaf3ff); font-size: 0.85em; white-space: nowrap; cursor: pointer; } .wiktku-mod-pill:hover { border-color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); } .wiktku-mod-pill:disabled, .wiktku-mod-pill.wiktku-mod-pill-used { border-color: var(--wikt-palette-grey-3, #e0e0e0); background: var(--wikt-palette-lightgrey); color: var(--wikt-palette-grey-3, #999); cursor: not-allowed; opacity: 0.6; } .wiktku-mod-pill:disabled:hover, .wiktku-mod-pill.wiktku-mod-pill-used:hover { border-color: var(--wikt-palette-grey-3, #e0e0e0); background: var(--wikt-palette-lightgrey); color: var(--wikt-palette-grey-3, #999); } .wiktku-mod-val-wrap { display: flex; align-items: center; gap: 0.25em; width: 100%; margin-top: 0.15em; } .wiktku-mod-val-input { flex: 0 1 14em; max-width: 14em; padding: 3px 6px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; } .wiktku-mod-confirm, .wiktku-mod-cancel { flex: 0 0 auto; width: 1.6em; height: 1.6em; padding: 0; line-height: 1; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); cursor: pointer; } .wiktku-mod-confirm { color: #178a17; border-color: #178a17; } .wiktku-mod-cancel { color: var(--wikt-palette-red-9, #d33); border-color: var(--wikt-palette-red-9, #d33); } .wiktku-resize-wrap { position: relative; display: block; } /* Independent of .wiktku-resize-wrap (created separately by ensureLinebreakBackdrop() in start.js, only for textareas that ever get flagged with a linebreak) so it doesn't depend on load order relative to wiktkuMakeManualResizable(). Plain block, no size of its own — purely a position:relative anchor for the backdrop. */ .wiktku-linebreak-wrap { position: relative; display: block; } .wiktku-resize-grip { position: absolute; right: 2px; bottom: 2px; width: 14px; height: 14px; cursor: ns-resize; touch-action: none; opacity: 0.5; z-index: 2; background-image: linear-gradient(135deg, transparent 0 50%, var(--wikt-palette-grey-9, #767676) 50% 100%); background-repeat: no-repeat; } .wiktku-resize-grip:hover, .wiktku-resize-grip:active { opacity: 0.9; } /* =================================================================== Searchable dropdown (wrapNativeSelect in start.js) .wiktku-native-select-wrap > input.wiktku-ac-input (search box) > ul.wiktku-ac-results (result list) > select (hidden, holds the value) =================================================================== */ .wiktku-native-select-wrap { display: inline-block; position: relative; vertical-align: top; } /* Matches the width the native select would have had (see select.wiktku-start-narrow). */ .wiktku-native-select-wrap input[type="search"], input.wiktku-ac-input { display: block; width: 20em; max-width: 100%; box-sizing: border-box; padding: 3px 6px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); color: inherit; font-size: inherit; font-family: inherit; transition: border-color 0.1s ease, box-shadow 0.1s ease; } input.wiktku-ac-input:focus { border-color: var(--wikt-palette-blue-9); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9); outline: 0; } input.wiktku-ac-input::placeholder { color: var(--wikt-palette-grey-9); opacity: 1; } /* Hide Safari/Chrome's built-in search decorations. */ input.wiktku-ac-input::-webkit-search-decoration, input.wiktku-ac-input::-webkit-search-cancel-button, input.wiktku-ac-input::-webkit-search-results-button { -webkit-appearance: none; appearance: none; } /* ── Result list ── */ /* top/bottom/max-height are overridden inline by showResults() when it flips the list above the box; these are just its defaults. */ ul.wiktku-ac-results { position: absolute; z-index: 9999; top: 100%; bottom: auto; left: 0; margin: 0; padding: 0; list-style: none; width: 20em; max-width: 90vw; max-height: 13em; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; background: var(--wikt-palette-white); border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; box-shadow: 0 3px 10px rgba(0, 0, 0, 0.15); } ul.wiktku-ac-results li { margin: 0; padding: 4px 8px; cursor: pointer; font-size: 0.92em; display: flex; align-items: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* .wiktku-ac-active is the keyboard cursor; hover mirrors it; :active covers the touch press state. */ ul.wiktku-ac-results li.wiktku-ac-active, ul.wiktku-ac-results li:hover { background: var(--wikt-palette-lightblue); } ul.wiktku-ac-results li:active { background: var(--wikt-palette-blue-9); color: var(--wikt-palette-white); } /* Touch devices: bigger tap targets, no sticky hover. */ @media (pointer: coarse) { ul.wiktku-ac-results li { padding: 6px 10px; min-height: 2.2em; font-size: 1em; } ul.wiktku-ac-results li:hover { background: transparent; } ul.wiktku-ac-results li.wiktku-ac-active { background: var(--wikt-palette-lightblue); } input.wiktku-ac-input { /* >=16px stops iOS Safari zooming the page when the box is focused. */ font-size: 16px; min-height: 2.2em; } } /* Item 5 (Wikihez, 14 Tebax 2026): inline preview + confirm panel shown before inserting an auto-content pronunciation template (ku-IPA, ku-kîte, …) — deliberately part of the form's own layout rather than a browser confirm()/prompt() dialog, per "dont use userinput use something more advanced". */ .wiktku-pron-preview { margin: 6px 0; padding: 8px 10px; border: 1px solid var(--wikt-palette-blue-9, #3366cc); border-radius: 6px; background: var(--wikt-palette-paleblue, #eaf3ff); } .wiktku-pron-preview-label { font-size: 0.88em; font-weight: 600; color: var(--wikt-palette-grey-9, #555); margin-bottom: 3px; } .wiktku-pron-preview-body { font-family: monospace; font-size: 1em; white-space: pre-wrap; word-break: break-word; margin-bottom: 6px; } .wiktku-pron-preview-actions { display: flex; gap: 6px; } .wiktku-pron-preview-confirm, .wiktku-pron-preview-cancel { font-size: 0.88em; padding: 3px 10px; border-radius: 4px; cursor: pointer; border: 1px solid var(--wikt-palette-lightgrey, #a2a9b1); background: var(--wikt-palette-white, #fff); } .wiktku-pron-preview-confirm { border-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-blue-9, #3366cc); font-weight: 600; } .wiktku-pron-preview-confirm:disabled { opacity: 0.5; cursor: wait; } .wiktku-pron-preview-cancel:hover { background: var(--wikt-palette-grey-0, #f8f9fa); } /* Template pickers fill their container since the search box, not the <select>, is what the user sees. */ .wiktku-pron-wrap .wiktku-native-select-wrap, .wiktku-etym-wrap .wiktku-native-select-wrap, .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { width: 100%; } .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 0.88em; } .wiktku-cavkani-wrap .wiktku-native-select-wrap, .wiktku-cavkani-wrap .wiktku-native-select-wrap input.wiktku-ac-input { width: 100%; } /* Template selector inside a sense block. */ .wiktku-dfn-tpl-row .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 0.88em; } /* Language/dialect rows: picker must line up with the word field beside it. */ .wiktku-lang-row .wiktku-native-select-wrap { flex: 0 0 auto; } #wiktku-start-form textarea.wiktku-dfn-mane, #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t, #wiktku-start-form textarea.wiktku-dfn-quote-src-manual, #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text, #wiktku-start-form .wiktku-tewandin-wrap textarea.wiktku-tewandin-text, #wiktku-start-form textarea.wiktku-cavkani-text, #wiktku-start-form textarea.wiktku-dfn-tercime, #wiktku-start-form textarea.wiktku-dfn-izah { --wiktku-ta-rows: 2; height: calc(var(--wiktku-ta-rows) * 1.35em + 6px); min-height: calc(var(--wiktku-ta-rows) * 1.35em + 6px); } #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text, #wiktku-start-form textarea.wiktku-dfn-izah { --wiktku-ta-rows: 3; } #wiktku-start-form textarea.wiktku-cavkani-text { --wiktku-ta-rows: 4; } /* Nimûne + Jêgirtin (citation) boxes, and their tr/t sub-fields: at least 4 rows so there's room to actually write an example/quote. */ #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t, #wiktku-start-form textarea.wiktku-dfn-quote-src-manual { --wiktku-ta-rows: 4; } /* Nimûne/jêgirtin box currently contains a typed/pasted linebreak — the border is nudged so the user notices before it's silently turned into <br> on output. The break itself is marked precisely, not the whole box, via a mirrored backdrop layer (see below and highlightLinebreak()/buildLinebreakBackdropHtml() in start.js). */ #wiktku-start-form textarea.wiktku-has-linebreak { border-color: var(--wikt-palette-yellow6, #ac6600) !important; } /* Backdrop layer: sits behind the textarea showing the same text, with a highlighted marker at each line that's followed by a break. Its font/padding/box-sizing/line-height are copied from the textarea via computed style (see syncLinebreakBackdropMetrics() in start.js), not shared CSS classes — most of this box's own rules are written as "textarea.foo", which a <div> with the same class wouldn't match. Only created lazily, the first time a given textarea actually has a break — see ensureLinebreakBackdrop(). */ .wiktku-linebreak-backdrop { position: absolute; inset: 0; z-index: 0; margin: 0; overflow: hidden; white-space: pre-wrap; word-wrap: break-word; color: transparent; background: transparent !important; border-color: transparent !important; box-shadow: none !important; resize: none !important; pointer-events: none; } /* Raise the real textarea above its backdrop so typing/selection/caret behave completely normally; the backdrop's mark shows through only where the real textarea's own background is transparent. */ #wiktku-start-form textarea.wiktku-has-linebreak-source { position: relative; z-index: 1; background-color: transparent; } .wiktku-linebreak-mark { background-color: var(--wikt-palette-yellow6, #ac6600); color: var(--wikt-palette-white, #fff); border-radius: 2px; } /* ── Tercime + Îzah boxes ── */ .wiktku-dfn-nonku-wrap { display: flex; flex-direction: column; gap: 3px; } .wiktku-dfn-nimune-sub, .wiktku-dfn-quote-sub { margin-top: 3px; margin-left: 1em; padding-left: 0.6em; border-left: 2px solid var(--wikt-palette-lightgrey); display: flex; flex-direction: column; gap: 3px; } .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t { min-width: 8em; padding-top: 2px !important; padding-bottom: 2px !important; line-height: 1.35 !important; font-size: 0.88em; } /* ── Sense list (Mane step) — numbered badges instead of the browser's default flat "1." marker, so each sense reads as a distinct block. ── */ ol.wiktku-dfn-list { list-style: none; margin: 0; padding: 0; counter-reset: wiktku-dfn-sense; } ol.wiktku-dfn-list > li.wiktku-dfn-sense { position: relative; counter-increment: wiktku-dfn-sense; padding-left: 2.1em; margin-bottom: 0.9em; } ol.wiktku-dfn-list > li.wiktku-dfn-sense:not(:last-child) { padding-bottom: 0.9em; border-bottom: 1px dashed var(--wikt-palette-grey-3, #e0e0e0); } ol.wiktku-dfn-list > li.wiktku-dfn-sense::before { content: counter(wiktku-dfn-sense); position: absolute; left: 0; top: 1px; width: 1.6em; height: 1.6em; border-radius: 50%; background: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); font-size: 0.85em; font-weight: 700; display: flex; align-items: center; justify-content: center; } /* Template selector row inside a sense block */ .wiktku-dfn-tpl-row { margin-bottom: 3px; } /* ── Sub-field titles (Etîket, Kategorî, Hevmane, Dijmane, Nimûne, Jêgirtin, …) — previously plain unstyled run-on text. Each group now reads as a small labelled field: the term stands out, the izah hint stays quiet, and the block gets its own breathing room. ── */ .wiktku-dfn-subgroup { margin-top: 0.5em; padding-top: 0.4em; border-top: 1px dashed var(--wikt-palette-grey-3, #e0e0e0); } .wiktku-dfn-subgroup:first-of-type { margin-top: 0.3em; padding-top: 0; border-top: none; } .wiktku-dfn-sublabel { display: block; margin-bottom: 3px; font-size: 0.88em; } .wiktku-dfn-sublabel-term { font-weight: 600; color: var(--wikt-palette-blue-9, #3366cc); letter-spacing: 0.03em; font-size: 0.92em; } .wiktku-dfn-sublabel-hint { color: var(--wikt-palette-grey-9, #767676); font-style: italic; } .wiktku-pron-wrap, .wiktku-etym-wrap, .wiktku-tewandin-wrap, .wiktku-cavkani-wrap { display: flex; flex-direction: column; gap: 3px; } /* ── POS section tabs ── Modernized into rounded pills instead of flat file-folder tabs. */ #wiktku-section-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 0.6em; align-items: center; } #wiktku-section-tabs .wiktku-section-tab { padding: 3px 12px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 999px; background: var(--wikt-palette-dullcyan); cursor: pointer; font-size: 0.86em; user-select: none; transition: background 0.12s ease, border-color 0.12s ease; } #wiktku-section-tabs .wiktku-section-tab:hover { border-color: var(--wikt-palette-blue-9, #3366cc); } #wiktku-section-tabs .wiktku-section-tab.wiktku-tab-active { background: var(--wikt-palette-blue-9, #3366cc); border-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); font-weight: 600; } /* ── Step-group tabs (Mane / Bilêvkirin / Beşên din — see STEP_GROUPS in start.js) ── Sits directly under the pill-style section tabs above; styled as an underlined secondary nav so the two bars stay visually distinct. */ #wiktku-group-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 0.8em; border-bottom: 2px solid var(--wikt-palette-lightgrey); } #wiktku-group-tabs .wiktku-group-tab { position: relative; padding: 7px 14px 8px; margin-bottom: -2px; border-bottom: 3px solid transparent; border-radius: 3px 3px 0 0; cursor: pointer; font-size: 0.95em; font-weight: 600; color: var(--wikt-palette-grey-9, #333); background: var(--wikt-palette-grey-0, #f8f9fa); user-select: none; transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease; } #wiktku-group-tabs .wiktku-group-tab:hover { color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-paleblue, #eaf3ff); } #wiktku-group-tabs .wiktku-group-tab.wiktku-tab-active { border-bottom-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); background: var(--wikt-palette-blue-9, #3366cc); font-weight: 700; } /* Small dot marking a tab that still has an unfilled required field hidden inside it (see updateGroupTabIndicators in start.js). Cleared automatically once that tab becomes the active one. */ #wiktku-group-tabs .wiktku-group-tab.wiktku-tab-missing::after { content: ""; position: absolute; top: 4px; right: -1px; width: 6px; height: 6px; border-radius: 50%; background: var(--wikt-palette-red-9, #d33); } .wiktku-lang-row-list { margin: 0; padding: 0; list-style: none; } .wiktku-lang-row { display: flex; align-items: flex-start; gap: 6px; margin-bottom: 3px; flex-wrap: wrap; } .wiktku-lang-row-words { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 3px; } /* Dûnde/Werger/Zarava rows: align the picker's height with the adjacent word textarea (see .wiktku-start-narrow above). */ .wiktku-lang-row .wiktku-native-select-wrap input.wiktku-ac-input { height: calc(1.7em + 10px); min-height: calc(1.7em + 10px); padding-top: 4px; padding-bottom: 4px; } /* ── Werger / Bi zaravayên din groups: one per gloss, shared spacing ── */ #wiktku-start-trans .wiktku-trans-group, #wiktku-start-zarava .wiktku-zarava-group { margin-bottom: 0.6em; } #wiktku-start-trans .wiktku-trans-group:last-child, #wiktku-start-zarava .wiktku-zarava-group:last-child { margin-bottom: 0; } #wiktku-start-trans .wiktku-trans-group-label, #wiktku-start-zarava .wiktku-zarava-group-label { font-weight: 600; font-size: 0.88em; margin-bottom: 3px; } .wiktku-dfn-jeder-group { margin-top: 3px; } .wiktku-dfn-quote-src-sel { font-size: 0.88em; margin-top: 3px; display: block; } .wiktku-dfn-quote-src-fields { display: flex; flex-direction: column; gap: 3px; margin-top: 3px; } /* Stacked layout: textarea gets its own full-width row, button + status sit below it on their own row. Simpler and more robust than sharing a row with the button — that required the textarea's own resize-wrap div (added by wiktkuMakeManualResizable in start.js) to correctly inherit flex-grow, which kept being fragile across breakpoints. */ .wiktku-dfn-quote-citoid { display: flex; flex-direction: column; align-items: stretch; gap: 0.4em; margin-top: 3px; margin-bottom: 3px; } .wiktku-dfn-quote-citoid-input { width: 100%; max-width: 100%; box-sizing: border-box; } /* Column flex + align-items:stretch (above) is what makes the textarea's .wiktku-resize-wrap (see wiktkuMakeManualResizable in start.js) reach full width automatically — stretch fills the cross axis for any block child, no flex-grow needed on the wrap itself. The button and status text, right below the textarea, opt back out of that stretch so they stay their natural (small) size instead of also going full width. */ .wiktku-dfn-quote-citoid-btn, .wiktku-dfn-quote-citoid-status { align-self: flex-start; } .wiktku-dfn-quote-src-cat-status { display: block; font-size: 0.82em; color: var(--wikt-palette-lightgrey, #767676); margin-top: 2px; } .wiktku-dfn-quote-src-row { display: flex; align-items: baseline; gap: 4px; flex-wrap: wrap; } .wiktku-dfn-quote-src-row label { font-size: 0.82em; white-space: nowrap; min-width: 8em; } textarea.wiktku-dfn-quote-src-input { flex: 1 1 12em; max-width: 100%; box-sizing: border-box; } @media (max-width: 720px) { .wiktku-lang-row { flex-direction: column; } /* Re-assert against the wiki's own mobile skin heading styles, which can apply their own mobile-breakpoint rules to this real <h3> and load after ours in the cascade — see the rule itself, above, for why this needs guarding at all. */ #wiktku-start-form .wiktku-start-step-name { font-size: 1.05em !important; margin: 0 0 0.2em !important; line-height: 1.2 !important; border: 0 !important; padding: 0 !important; } /* Single column: search box and list use the full width. Narrow textareas (Etîket, Hevmane, Dûnde/Jê/Têkildar/Binêre herwiha word boxes, citation source fields, …) join them here too — at a fixed 20em width they used to poke out past the step card on narrow screens. */ .wiktku-native-select-wrap, input.wiktku-ac-input, ul.wiktku-ac-results, #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield.wiktku-start-narrow { width: 100%; max-width: 100%; } .wiktku-mod-val-input { flex: 1 1 auto; max-width: 100%; } #wiktku-start-form textarea.wiktku-dfn-mane, #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text { --wiktku-ta-rows: 3; font-size: 1em; } #wiktku-start-form .wiktku-tewandin-wrap textarea.wiktku-tewandin-text, #wiktku-start-form textarea.wiktku-cavkani-text { --wiktku-ta-rows: 4; font-size: 1em; } /* Nimûne + Jêgirtin and their tr/t sub-fields: keep at least 4 rows on mobile too, rather than shrinking further than the desktop size. */ #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t { --wiktku-ta-rows: 4; font-size: 1em; } /* Citoid URL/DOI/ISBN box: taller tap target (~2 lines) on mobile, and now that this field is a <textarea> (see start.js) its placeholder can actually wrap into that space — a plain <input>'s placeholder can never wrap, no matter its height. */ .wiktku-dfn-quote-citoid-input { min-height: calc(2 * 1.35em + 10px); font-size: 1em; } .wiktku-dfn-nimune-sub, .wiktku-dfn-quote-sub { margin-left: 0.5em; padding-left: 0.4em; } .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 1em; min-height: 2.2em; } .wiktku-dfn-quote-src-row label { min-width: 6em; } #wiktku-start-form textarea.wiktku-dfn-quote-src-input { width: 100%; flex: 1 1 100%; } .wiktku-start-step { padding: 0.5em 0.6em; } } /* =================================================================== Night mode Palette.css already flips every --wikt-palette-* var for night mode, so rules built from those vars need nothing here. This hook is only for real colours that can't be a palette var — here, the panel border, since a drop shadow is invisible against an equally dark page. Not needed: li:active's white text already flips to a dark colour at night via --wikt-palette-white, so it stays legible on its own. =================================================================== */ @media screen { html.skin-theme-clientpref-night .wiktku-ac-results { /* Border stands in for the shadow, invisible on a dark page. */ border-color: var(--wikt-palette-grey-5); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.6); } html.skin-theme-clientpref-night .wiktku-start-step, html.skin-theme-clientpref-night .wiktku-start-step:hover, html.skin-theme-clientpref-night .wiktku-start-step:focus-within { box-shadow: none; } } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os .wiktku-ac-results { border-color: var(--wikt-palette-grey-5); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.6); } html.skin-theme-clientpref-os .wiktku-start-step, html.skin-theme-clientpref-os .wiktku-start-step:hover, html.skin-theme-clientpref-os .wiktku-start-step:focus-within { box-shadow: none; } } /* "Zimanek lê zêde bike" portlet icon (Minerva/mobile) — Feather-core-edit.svg via CSS mask, matching Minerva's own icon pattern. */ .minerva-icon-portletlink-ca-wiktku-addlang { -webkit-mask-image: url("https://upload.wikimedia.org/wikipedia/commons/d/d7/Feather-core-edit.svg"); mask-image: url("https://upload.wikimedia.org/wikipedia/commons/d/d7/Feather-core-edit.svg"); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-position: center; mask-position: center; -webkit-mask-size: 20px; mask-size: 20px; background-color: currentColor; background-image: none; } /* ── posparams step (live wikitext + helper widgets) ── */ .wiktku-posparams-wrap { display: flex; flex-direction: column; gap: 6px; } .wiktku-posparams-helpers { display: flex; flex-direction: column; gap: 4px; } .wiktku-posparams-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; } .wiktku-posparams-row label { /* Rewiye tine, 14 Tebax 2026: these were the smallest labels on the whole card (0.9em, one step below everything else) — the mobile breakpoint already bumps this to 1em below; matching that on desktop too instead of only fixing it for mobile. */ font-size: 1em; min-width: 10em; padding-right: 0; } .wiktku-posparams-text { width: 100%; box-sizing: border-box; font-family: monospace; font-size: 0.9em; } .wiktku-posparams-opt-toggle { font-size: 0.85em; margin-top: 2px; display: inline-block; } .wiktku-posparams-opt-panel { display: flex; flex-direction: column; gap: 2px; padding: 4px 0 2px 1em; } .wiktku-posparams-opt-row { display: flex; align-items: center; gap: 4px; font-size: 0.85em; } /* ── resim step (one or more images) ── */ .wiktku-resim-list { display: flex; flex-direction: column; gap: 6px; } .wiktku-resim-item { display: flex; flex-direction: column; gap: 4px; } .wiktku-resim-item .wiktku-posparams-row { flex-direction: column; align-items: flex-start; gap: 2px; } .wiktku-resim-item .wiktku-posparams-row label { min-width: 0; font-size: 0.9em; } /* ── dfn: "hide/show all subsections" link ── Same show/hide-link pattern as "Tercîhên pêşketî" (posparams), but toggles a class on the whole dfn stepDiv rather than one panel, so a single click hides the etîket/kategorî/hevmane/dijmane/nimûne/ jêgirtin/etc. subgroups across every sense block at once (see steps.dfn.build in start.js). */ .wiktku-dfn-subs-toggle { font-size: 0.85em; font-weight: 500; display: inline-block; margin: 2px 0 8px; color: var(--wikt-palette-blue-9, #3366cc); text-decoration: none; } .wiktku-dfn-subs-toggle:hover { text-decoration: underline; } /* Only the ADVANCED subgroups collapse now (Ghybu, 14 Tebax 2026): Nimûne, Jêgirtin, Hevmane and Dijmane stay open because they are what people actually come here to fill in — see steps.dfn.allGroups, whose adv: flag is what puts this class on a group. */ #wiktku-start-form li.wiktku-sense-adv-hidden .wiktku-dfn-subgroup-adv { display: none !important; } /* The toggle sits between the primary groups and the advanced ones, so it needs no rule of its own beyond a little breathing room. */ #wiktku-start-form .wiktku-sense-adv-row { margin-top: 14px; } /* =================================================================== Desktop text bump The modifier pills/buttons and posparams helper text (labels, "Tercîhên pêşketî" opt panel) use fairly small font-sizes that read fine on mobile — narrow-viewport rendering effectively scales them up — but look too small on a full desktop screen at their literal em size. Bump them up past the 720px breakpoint only; mobile keeps the original sizing above. =================================================================== */ @media (min-width: 721px) { .wiktku-mod-btn, .wiktku-mod-confirm, .wiktku-mod-cancel { width: 1.8em; height: 1.8em; font-size: 1.1em; } .wiktku-mod-pill { font-size: 0.95em; padding: 3px 10px; } .wiktku-mod-val-input { font-size: 0.95em; } .wiktku-posparams-row label { font-size: 1em; } .wiktku-posparams-text { font-size: 1em; } .wiktku-posparams-opt-toggle { font-size: 0.95em; } .wiktku-posparams-opt-row { font-size: 0.95em; } .wiktku-dfn-subs-toggle { font-size: 0.95em; } /* Item 2 (Wikihez, 14 Tebax 2026): "sê-stûnî" — the same side-by-side, multi-column card layout Ghybu asked for on POS/Cîns/Jimar now applies to every posparams helper field (transliteration, gendered forms, comparative/superlative, hanja, verb-tense roots, …), not just those first two. Desktop-only per Wikihez's note that this isn't supported on mobile — the plain stacked list above stays as-is below this breakpoint. Rows are toggled via jQuery .show()/.hide() (inline display:block/none) same as before; the grid only changes how visible rows are arranged, not which ones are visible. */ .wiktku-posparams-helpers { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px 16px; align-items: start; } .wiktku-posparams-helpers > .wiktku-posparams-row { flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 3px; } .wiktku-posparams-helpers > .wiktku-posparams-row label { min-width: 0; } .wiktku-posparams-helpers > .wiktku-posparams-row .wiktku-posparams-field, .wiktku-posparams-helpers > .wiktku-posparams-row select.wiktku-posparams-cinsiyet-sel, .wiktku-posparams-helpers > .wiktku-posparams-row select.wiktku-posparams-lektur-sel { width: 100%; max-width: 100%; box-sizing: border-box; } /* The "Jimar" row added for item 1 lives here too (see start.js) — no extra CSS needed, it's just another .wiktku-posparams-row. */ /* These two aren't per-field rows — span the full card width so the collapsed toggle and its checkbox list don't get squeezed into one narrow column. */ .wiktku-posparams-helpers > .wiktku-posparams-opt-toggle, .wiktku-posparams-helpers > .wiktku-posparams-opt-panel { grid-column: 1 / -1; } } /* =================================================================== SÊWIRANA NÛ — design system layer =================================================================== From the "Cerdevanê ketanê — sêwirana nû" spec (15 Tebax 2026). Appended rather than merged into the rules above on purpose: everything before this point is layout (what sits next to what, which row wraps where) and still does its job. This block is purely the visual skin — colour, type, weight, radius, spacing — so it comes last and wins, and so a future revert is a delete of one contiguous section. Two deliberate deviations from the spec document: 1. No @import of Spectral / IBM Plex from Google Fonts. Wikimedia wikis send a Content-Security-Policy that blocks third-party font hosts, so the import would fail silently and we would ship a broken-looking fallback nobody chose. The stacks below name the spec's faces first (so they are used if the wiki ever installs them locally) and then fall back to faces with the same feel: a transitional serif for headings, the UI sans for body, the platform mono for wikitext. 2. Blue is spent, not sprayed. Ghybu, 14 Tebax 2026: "hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe?" — so section headings are near-black now and the accent is reserved for things you can act on: focus, links, the active tab, the primary button, chips. =================================================================== */ #wiktku-start-form { /* Surfaces */ --wikt-page: #f4efe5; --wikt-card: #fffdf8; --wikt-card-sunken: #fbf8f1; --wikt-rule: #ded6c8; /* structural hairline */ --wikt-rule-soft: #efe8db; /* inside a card */ --wikt-field-edge: #cfc7b8; --wikt-field-bg: #fff; --wikt-code-bg: #f7f4ec; --wikt-card-edge: #e6dfd2; /* Ink */ --wikt-ink: #1c1a17; --wikt-ink-2: #3d3830; --wikt-ink-3: #57514a; --wikt-muted: #8a8378; --wikt-placeholder: #b3ab9e; /* Accent + status */ --wikt-accent: #2a5db0; --wikt-accent-deep: #22406f; --wikt-accent-tint: #eef2fa; --wikt-accent-edge: #d5def0; --wikt-danger: #9c3a28; --wikt-on-accent: #fff; /* text on a filled accent button */ --wikt-link-under: rgba(42, 93, 176, 0.35); /* Shape */ --wikt-r-field: 10px; --wikt-r-card: 14px; --wikt-r-pill: 999px; --wikt-tap: 44px; /* minimum field height */ --wikt-serif: Spectral, "Iowan Old Style", Georgia, "Times New Roman", serif; --wikt-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif; --wikt-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-family: var(--wikt-sans); font-size: 15px; line-height: 1.55; color: var(--wikt-ink); background: var(--wikt-page); padding: 24px; border-radius: var(--wikt-r-card); } /* ── Cards ─────────────────────────────────────────────────────────── The old card had a 4px blue left bar and two shadows. The spec is explicit — "Ti sî (shadow) tune; tenê xetên 1px" — so the card is now a flat cream panel held by a single hairline. */ #wiktku-start-form .wiktku-start-step { background: var(--wikt-card); border: 1px solid var(--wikt-card-edge); border-left: 1px solid var(--wikt-card-edge); border-radius: var(--wikt-r-card); box-shadow: none; padding: 24px 24px 20px; margin-bottom: 16px; transition: border-color 0.12s ease; } #wiktku-start-form .wiktku-start-step:hover, #wiktku-start-form .wiktku-start-step:focus-within { box-shadow: none; border-color: var(--wikt-rule); } /* The fused pos + posparams pair keeps reading as one card. */ #wiktku-start-form #wiktku-start-pos { border-radius: var(--wikt-r-card) var(--wikt-r-card) 0 0; border-bottom: none; padding-bottom: 8px; } #wiktku-start-form #wiktku-start-posparams { border-radius: 0 0 var(--wikt-r-card) var(--wikt-r-card); border-top: none; padding-top: 4px; } /* ── Type ──────────────────────────────────────────────────────────── Step headings: serif, regular weight, near-black. Previously bold, letterspaced and blue — three signals doing one job. */ #wiktku-start-form .wiktku-start-step-name { font-family: var(--wikt-serif); font-size: 24px !important; font-weight: 400; letter-spacing: -0.01em; line-height: 1.15; color: var(--wikt-ink); margin: 0 0 12px; } /* display:block matters: this is a <label>, so it was sharing a line with the control it introduces wherever start.js didn't emit a <br>. */ #wiktku-start-form .wiktku-start-step-question { display: block; font-size: 15px; font-weight: 400; color: var(--wikt-ink-3); margin: 0 0 12px; line-height: 1.6; max-width: 62ch; } /* Wikihez, 15 Tebax 2026: posparams' "Cins/zayend" title was removed (question_fmt now returns "" for navdêr/serenav) — collapse the label entirely when empty instead of leaving its margin behind as a blank gap. Harmless no-op for every other step, whose question text is never empty. */ #wiktku-start-form .wiktku-start-step-question:empty { display: none; margin: 0; } /* Same reason — a field label belongs above its field, not beside it. */ #wiktku-start-form .wiktku-posparams-row label, #wiktku-start-form .wiktku-dfn-sublabel { display: block; margin-bottom: 6px; padding-right: 0; } /* Field labels: small, medium weight, full-strength ink — they label a control, so they should not read as body copy. */ #wiktku-start-form .wiktku-start-step label, #wiktku-start-form .wiktku-posparams-row label, #wiktku-start-form .wiktku-dfn-sublabel { font-size: 13px; font-weight: 500; color: var(--wikt-ink); letter-spacing: 0.01em; } /* The parenthetical/example half of a label is supporting text. */ #wiktku-start-form .wiktku-dfn-sublabel-hint, #wiktku-start-form .wiktku-step-hint { font-weight: 400; font-style: italic; color: var(--wikt-muted); font-size: 12.5px; } /* ── Fields ────────────────────────────────────────────────────────── One shape for every control: 1px edge, 10px radius, 44px tall. */ #wiktku-start-form input[type="text"], #wiktku-start-form input[type="search"], #wiktku-start-form input.wiktku-ac-input, #wiktku-start-form textarea, #wiktku-start-form select { font-family: var(--wikt-sans); font-size: 15px; color: var(--wikt-ink); background: var(--wikt-field-bg); border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-field); padding: 10px 14px; box-shadow: none; transition: border-color 0.12s ease, box-shadow 0.12s ease; } #wiktku-start-form input[type="text"], #wiktku-start-form input[type="search"], #wiktku-start-form select { min-height: var(--wikt-tap); } #wiktku-start-form textarea { line-height: 1.6; } /* Wikitext and anything template-shaped reads as code. */ #wiktku-start-form .wiktku-posparams-text, #wiktku-start-form .wiktku-pron-text, #wiktku-start-form .wiktku-etym-text, #wiktku-start-form .wiktku-cavkani-text, #wiktku-start-form .wiktku-tewandin-text, #wiktku-start-form .wiktku-pron-preview-body { font-family: var(--wikt-mono); font-size: 13.5px; background: var(--wikt-code-bg); border-color: var(--wikt-card-edge); } #wiktku-start-form ::placeholder { color: var(--wikt-placeholder); opacity: 1; } /* Focus: accent edge + 3px tint halo. The only "elevation" in the design. */ #wiktku-start-form input[type="text"]:focus, #wiktku-start-form input[type="search"]:focus, #wiktku-start-form textarea:focus, #wiktku-start-form select:focus, #wiktku-start-form input.wiktku-ac-input:focus { border-color: var(--wikt-accent); box-shadow: 0 0 0 3px var(--wikt-accent-tint); outline: 0; } /* The searchable picker's visible input is the field, so it takes the field shape too (it otherwise inherits an older, boxier rule). */ #wiktku-start-form input.wiktku-ac-input { min-height: var(--wikt-tap); border-radius: var(--wikt-r-field); border-color: var(--wikt-field-edge); font-size: 15px; } #wiktku-start-form .wiktku-ac-results { border: 1px solid var(--wikt-rule); border-radius: var(--wikt-r-field); background: var(--wikt-card); box-shadow: none; } #wiktku-start-form .wiktku-ac-results li.wiktku-ac-active, #wiktku-start-form .wiktku-ac-results li:hover { background: var(--wikt-accent-tint); color: var(--wikt-accent-deep); } /* ── Tabs → the accent's main job ──────────────────────────────────── Active tab: tint fill + 3px accent underline, per the spec's "xala hûrgulî" note. Inactive tabs are plain text. */ #wiktku-start-form #wiktku-group-tabs, #wiktku-start-form #wiktku-section-tabs { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; border-bottom: 1px solid var(--wikt-rule); margin-bottom: 16px; padding-bottom: 0; } /* Wikihez, 15 Tebax 2026: "should persist when scrolling down… able to click them anytime". Both bars are direct children of #wiktku-start-form (a tall container spanning the whole wizard), so a sticky child stays stuck for as long as any part of the form is in view — not just its own original height — which is exactly the range we want here. Background is opaque so step-card content scrolling underneath doesn't show through the strip while it's pinned. Section-tabs pins to the very top; group-tabs pins right below it, at an offset equal to section-tabs' actual rendered height — set as the --wiktku-stabs-h custom property by syncStickyTabsOffset() in start.js, since flex-wrap means that height isn't a fixed number (long section lists / narrow viewports wrap it onto a second line). Falls back to 0 before the first sync (e.g. no lang chosen yet, section-tabs hidden). */ #wiktku-start-form #wiktku-section-tabs { position: sticky; top: 0; z-index: 20; background: var(--wikt-card); } #wiktku-start-form #wiktku-group-tabs { position: sticky; top: var(--wiktku-stabs-h, 0px); z-index: 19; background: var(--wikt-card); } #wiktku-start-form .wiktku-group-tab, #wiktku-start-form .wiktku-section-tab { font-size: 13.5px; font-weight: 500; color: var(--wikt-ink-3); background: transparent; border: 0; border-bottom: 3px solid transparent; border-radius: var(--wikt-r-pill) var(--wikt-r-pill) 0 0; padding: 9px 14px 11px; cursor: pointer; transition: background 0.12s ease, color 0.12s ease; } #wiktku-start-form .wiktku-group-tab:hover, #wiktku-start-form .wiktku-section-tab:hover { background: var(--wikt-card-sunken); color: var(--wikt-ink); } #wiktku-start-form .wiktku-group-tab.wiktku-tab-active, #wiktku-start-form .wiktku-section-tab.wiktku-tab-active { background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom-color: var(--wikt-accent); } /* ── Progressive-disclosure toggles ────────────────────────────────── Shared by "Tercîhên pêşketî" (posparams) and "Malûmatên pêşketî" (Mane). Both are now the main way the form stays short, so they get a real affordance — a rotating chevron and a count of what is behind them — instead of a small blue link. */ #wiktku-start-form .wiktku-adv-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin: 4px 0 12px; padding-top: 16px; border-top: 1px solid var(--wikt-rule-soft); } #wiktku-start-form .wiktku-adv-toggle { display: inline-flex; align-items: center; gap: 10px; font-size: 14px; font-weight: 500; color: var(--wikt-accent); text-decoration: none; cursor: pointer; } #wiktku-start-form .wiktku-adv-toggle:hover .wiktku-adv-toggle-text { text-decoration: underline; } #wiktku-start-form .wiktku-adv-toggle-chevron { width: 22px; height: 22px; flex: 0 0 22px; display: grid; place-items: center; font-size: 11px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); border-radius: 6px; transform: rotate(-90deg); transition: transform 0.15s ease; } /* Open state: dfn flips the class on the step, posparams on the link. */ #wiktku-start-form .wiktku-adv-toggle.wiktku-adv-open .wiktku-adv-toggle-chevron, #wiktku-start-dfn:not(.wiktku-dfn-subs-hidden) .wiktku-adv-toggle-chevron { transform: rotate(0deg); } #wiktku-start-form .wiktku-posparams-adv-panel { border: 1px solid var(--wikt-rule-soft); border-radius: 12px; background: var(--wikt-card-sunken); padding: 20px 18px; margin-bottom: 4px; } /* ── posparams grid ────────────────────────────────────────────────── "Tor, ne rêz" — two columns, nothing narrower than 220px, so the six gender/number fields stop being a six-across scanline. */ @media (min-width: 721px) { #wiktku-start-form .wiktku-posparams-helpers, #wiktku-start-form .wiktku-posparams-adv-panel { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 18px 22px; align-items: start; } #wiktku-start-form .wiktku-posparams-adv-panel > .wiktku-posparams-row, #wiktku-start-form .wiktku-posparams-helpers > .wiktku-posparams-row { flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 7px; } #wiktku-start-form .wiktku-posparams-helpers > .wiktku-adv-toggle-row, #wiktku-start-form .wiktku-posparams-helpers > .wiktku-posparams-adv-panel, #wiktku-start-form .wiktku-posparams-adv-panel > .wiktku-posparams-opt-panel { grid-column: 1 / -1; } } #wiktku-start-form .wiktku-posparams-opt-panel { border-top: 1px solid var(--wikt-rule-soft); padding-top: 14px; margin-top: 4px; } #wiktku-start-form .wiktku-posparams-opt-row { font-size: 13px; color: var(--wikt-ink-3); } /* ── Sense blocks ──────────────────────────────────────────────────── Each sense is a sunken panel inside the Mane card, with its number as an accent counter — so "how many meanings am I writing" is legible at a glance. */ #wiktku-start-form .wiktku-dfn-subgroup { margin: 14px 0 0; padding-top: 14px; border-top: 1px solid var(--wikt-rule-soft); } /* Nimûne leads the list now, and a divider above the first item would be a rule against the sense's own text. (Needed explicitly: the older :first-of-type rule further up is a class selector and loses to the id-scoped one above.) */ #wiktku-start-form .wiktku-dfn-subgroup:first-of-type { margin-top: 8px; padding-top: 0; border-top: none; } #wiktku-start-form .wiktku-dfn-sublabel-term { color: var(--wikt-ink); } /* Every sense sub-field is a plain white field like any other. Older rules gave several of them a tinted fill, which read as "disabled" next to the white Mane box directly above them. */ #wiktku-start-form .wiktku-dfn-subfield, #wiktku-start-form textarea.wiktku-dfn-mane { background: var(--wikt-field-bg); border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-field); } /* No "1." "2." markers on the sub-lists. Ghybu, 14 Tebax 2026, on exactly this: numbered rows read as a form you must fill from the top down, when really each row is just "another one if you have another one" — and with a block-level textarea per row the marker also lands on its own line above the field, which looks like a stray character. */ #wiktku-start-form .wiktku-dfn-sublist { margin: 0; padding-left: 0; list-style: none; } #wiktku-start-form .wiktku-dfn-sublist > li { margin-bottom: 6px; } /* ── Chips: tags, modifiers, template pills ──────────────────────────── */ #wiktku-start-form .wiktku-mod-pill, #wiktku-start-form .wiktku-besendin-select + .wiktku-chip { background: var(--wikt-accent-tint); color: var(--wikt-accent-deep); border: 1px solid var(--wikt-accent-edge); border-radius: var(--wikt-r-pill); font-size: 13px; padding: 6px 12px; } #wiktku-start-form .wiktku-mod-btn, #wiktku-start-form .wiktku-mod-confirm, #wiktku-start-form .wiktku-mod-cancel { border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); border-radius: 8px; } /* ── Footer + buttons ──────────────────────────────────────────────── Spec: one primary pill, everything else quiet. The two red buttons sitting next to it are the loudest thing on the old screen for no reason — they become outline buttons in the danger colour instead of filled ones. */ #wiktku-start-form #wiktku-start-footer { background: var(--wikt-card-sunken); border-top: 1px solid var(--wikt-rule); border-radius: 0 0 var(--wikt-r-card) var(--wikt-r-card); padding: 16px 20px; gap: 10px; } #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement-button { border-radius: var(--wikt-r-pill) !important; font-family: var(--wikt-sans); font-size: 14px; font-weight: 500; padding: 11px 22px; box-shadow: none !important; min-height: var(--wikt-tap); } #wiktku-start-form #wiktku-unhide-editform .oo-ui-buttonElement-button { background: var(--wikt-accent) !important; border-color: var(--wikt-accent) !important; color: var(--wikt-on-accent) !important; } /* Destructive actions: outline, not fill. */ #wiktku-start-form #wiktku-start-footer .oo-ui-flaggedElement-destructive .oo-ui-buttonElement-button { background: var(--wikt-card) !important; border-color: var(--wikt-danger) !important; color: var(--wikt-danger) !important; } #wiktku-start-form #wiktku-last-saved { font-family: var(--wikt-mono); font-size: 12px; color: var(--wikt-muted); } /* ── Beşên din picker ──────────────────────────────────────────────── This dropdown is now the entry point to eighteen sections, so it gets room and a label rather than sitting flush under the tab bar. */ #wiktku-start-form .wiktku-besendin-picker { margin: 0 0 20px; padding: 16px 18px; background: var(--wikt-card); border: 1px solid var(--wikt-card-edge); border-radius: 12px; } #wiktku-start-form .wiktku-besendin-picker .wiktku-native-select-wrap, #wiktku-start-form .wiktku-besendin-picker input.wiktku-ac-input { width: 100%; max-width: 28em; } /* ── Notices ─────────────────────────────────────────────────────────── */ #wiktku-start-form .wiktku-addlang-notice { background: var(--wikt-accent-tint); border: 1px solid var(--wikt-accent-edge); border-radius: var(--wikt-r-field); color: var(--wikt-ink-2); padding: 12px 16px; margin-bottom: 16px; } #wiktku-start-form .wiktku-pron-preview { background: var(--wikt-accent-tint); border-color: var(--wikt-accent-edge); border-radius: 12px; } #wiktku-start-form .wiktku-pron-preview-confirm, #wiktku-start-form .wiktku-pron-preview-cancel { border-radius: var(--wikt-r-pill); padding: 8px 16px; min-height: 36px; } /* Links carry the accent and a soft underline, per the spec's `a` rule. */ #wiktku-start-form a { color: var(--wikt-accent); text-decoration: none; border-bottom: 1px solid var(--wikt-link-under); } #wiktku-start-form a:hover { color: var(--wikt-accent-deep); } #wiktku-start-form .wiktku-adv-toggle, #wiktku-start-form .wiktku-group-tab, #wiktku-start-form .wiktku-section-tab { border-bottom-style: solid; } #wiktku-start-form .wiktku-adv-toggle { border-bottom: 0; } /* =================================================================== Dark mode =================================================================== Every colour above is a token on #wiktku-start-form, so night mode is a swap of that one block — no rule is duplicated. Three selectors, because MediaWiki has three states and guessing wrong is worse than not supporting it: an explicit night choice, "follow my OS" plus an OS that says dark, and skins old enough to set no theme class at all (older mobile output), where prefers-color-scheme is the only signal available. The :not() chain on the last one keeps it from overriding someone who explicitly asked for day mode. The palette is warm, not neutral grey — a straight inversion of a cream design lands on blue-grey and loses the character of it. Accent lightens to #7ba7e8: #2a5db0 on a dark card is around 2.4:1, which fails contrast and reads as near-black. =================================================================== */ html.skin-theme-clientpref-night #wiktku-start-form, html.skin-nightmode #wiktku-start-form { --wikt-page: #171613; --wikt-card: #201e1a; --wikt-card-sunken: #1a1916; --wikt-card-edge: #322e28; --wikt-rule: #3a3630; --wikt-rule-soft: #2c2924; --wikt-field-edge: #4a453d; --wikt-field-bg: #191815; --wikt-code-bg: #14130f; --wikt-ink: #ece7dd; --wikt-ink-2: #d5cfc4; --wikt-ink-3: #b3aca1; --wikt-muted: #8f887c; --wikt-placeholder: #6d675e; --wikt-accent: #7ba7e8; --wikt-accent-deep: #cfe0f8; --wikt-accent-tint: #1c2839; --wikt-accent-edge: #35496b; --wikt-danger: #e5907c; --wikt-on-accent: #14213a; --wikt-link-under: rgba(123, 167, 232, 0.4); } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os #wiktku-start-form, html:not(.skin-theme-clientpref-day):not(.skin-theme-clientpref-night):not(.skin-theme-clientpref-os) #wiktku-start-form { --wikt-page: #171613; --wikt-card: #201e1a; --wikt-card-sunken: #1a1916; --wikt-card-edge: #322e28; --wikt-rule: #3a3630; --wikt-rule-soft: #2c2924; --wikt-field-edge: #4a453d; --wikt-field-bg: #191815; --wikt-code-bg: #14130f; --wikt-ink: #ece7dd; --wikt-ink-2: #d5cfc4; --wikt-ink-3: #b3aca1; --wikt-muted: #8f887c; --wikt-placeholder: #6d675e; --wikt-accent: #7ba7e8; --wikt-accent-deep: #cfe0f8; --wikt-accent-tint: #1c2839; --wikt-accent-edge: #35496b; --wikt-danger: #e5907c; --wikt-on-accent: #14213a; --wikt-link-under: rgba(123, 167, 232, 0.4); } } /* A handful of pre-design-layer rules still name literal light colours (they predate the tokens). Rather than hunt every one, neutralise the ones that actually show through in night mode. */ html.skin-theme-clientpref-night #wiktku-start-form .wiktku-ac-results, html.skin-nightmode #wiktku-start-form .wiktku-ac-results { background: var(--wikt-card); border-color: var(--wikt-rule); color: var(--wikt-ink); } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os #wiktku-start-form .wiktku-ac-results, html:not(.skin-theme-clientpref-day):not(.skin-theme-clientpref-night):not(.skin-theme-clientpref-os) #wiktku-start-form .wiktku-ac-results { background: var(--wikt-card); border-color: var(--wikt-rule); color: var(--wikt-ink); } } /* =================================================================== Autocomplete list: stop it escaping its card =================================================================== ul.wiktku-ac-results carried a hard `width: 20em` regardless of the field it belongs to. On the full-width pickers — "Çavkanî hilbijêre" is the obvious one — the list is absolutely positioned at the wrapper's left edge, so a fixed 20em runs straight past the card's right border whenever the card is narrower than that. The wrapper is shrink-to-fit around its input, so `width: 100%` here means "exactly as wide as the field I belong to" — which is what a combobox should do — while min-width keeps the short pickers readable and max-width stops either from leaving the viewport. */ #wiktku-start-form ul.wiktku-ac-results { width: 100%; min-width: min(18em, 100%); max-width: min(92vw, 34em); box-sizing: border-box; border-radius: var(--wikt-r-field); box-shadow: none; } /* And the wrapper itself must not exceed the card it sits in. */ #wiktku-start-form .wiktku-native-select-wrap { max-width: 100%; } #wiktku-start-form .wiktku-cavkani-wrap .wiktku-native-select-wrap, #wiktku-start-form .wiktku-cavkani-wrap input.wiktku-ac-input, #wiktku-start-form .wiktku-pron-wrap .wiktku-native-select-wrap, #wiktku-start-form .wiktku-etym-wrap .wiktku-native-select-wrap { width: 100%; max-width: 100%; box-sizing: border-box; } /* =================================================================== Mobile: the footer was the loudest thing on a small screen =================================================================== Four 44px-tall pills with 22px of side padding wrap into three rows and eat most of a phone viewport — and the footer is sticky, so that stays on screen the whole time. Below 720px the primary button keeps its full size (it is the one you press) and everything else shrinks to a secondary scale. =================================================================== */ @media (max-width: 720px) { #wiktku-start-form { padding: 12px; font-size: 14px; } #wiktku-start-form .wiktku-start-step { padding: 16px 14px 14px; border-radius: 12px; } #wiktku-start-form .wiktku-start-step-name { font-size: 20px !important; } #wiktku-start-form #wiktku-start-footer { padding: 10px 12px; gap: 6px; row-gap: 8px; } #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement-button { font-size: 13px; padding: 8px 14px; min-height: 38px; } /* The one you actually press stays thumb-sized. */ #wiktku-start-form #wiktku-unhide-editform .oo-ui-buttonElement-button { font-size: 14px; padding: 10px 20px; min-height: var(--wikt-tap); } /* Secondary actions share a row instead of each claiming a full one. */ #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement { flex: 0 1 auto; } #wiktku-start-form #wiktku-last-saved { flex: 1 0 100%; order: 10; font-size: 11px; white-space: normal; } #wiktku-start-form .wiktku-adv-toggle-row { gap: 8px; } } /* =================================================================== IPA character palette (v3 spec) =================================================================== Click-to-insert chart under Bilêvkirin, after fr.wiktionary's. Two sub-tabs — a short Kurmancî set that opens by default, and the full chart — because ~20 of the ~180 IPA symbols ever occur in Kurmancî and showing all of them first is the same "wall of fields" problem this redesign exists to fix. =================================================================== */ #wiktku-start-form .wiktku-ipa-panel { border: 1px solid var(--wikt-card-edge); border-radius: 12px; background: var(--wikt-card-sunken); padding: 0 0 12px; margin-bottom: 8px; overflow: hidden; } #wiktku-start-form .wiktku-ipa-subtabs { display: flex; align-items: center; gap: 4px; padding: 8px 12px 0; border-bottom: 1px solid var(--wikt-rule-soft); margin-bottom: 12px; flex-wrap: wrap; } #wiktku-start-form .wiktku-ipa-subtab { font-size: 13px; font-weight: 500; color: var(--wikt-ink-3); padding: 7px 12px 9px; border-bottom: 3px solid transparent; border-radius: 8px 8px 0 0; cursor: pointer; } #wiktku-start-form .wiktku-ipa-subtab:hover { background: var(--wikt-card); color: var(--wikt-ink); } #wiktku-start-form .wiktku-ipa-subtab.wiktku-tab-active { background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom-color: var(--wikt-accent); } /* Templates are not characters, so they sit apart from the chart — pinned to the right of the sub-tab row. */ #wiktku-start-form .wiktku-ipa-tplbtns { margin-left: auto; display: flex; gap: 6px; padding-bottom: 6px; } #wiktku-start-form .wiktku-ipa-tplbtn { font-family: var(--wikt-mono); font-size: 12px; padding: 6px 10px; border-radius: 7px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); cursor: pointer; white-space: nowrap; } #wiktku-start-form .wiktku-ipa-tplbtn:hover { border-color: var(--wikt-accent); } #wiktku-start-form .wiktku-ipa-grid { display: flex; flex-direction: column; gap: 8px; padding: 0 12px; } #wiktku-start-form .wiktku-ipa-row { display: flex; align-items: flex-start; gap: 10px; } #wiktku-start-form .wiktku-ipa-rowlabel { flex: 0 0 74px; font-size: 11.5px; color: var(--wikt-muted); padding-top: 8px; line-height: 1.3; } #wiktku-start-form .wiktku-ipa-keys { display: flex; flex-wrap: wrap; gap: 4px; flex: 1 1 auto; } #wiktku-start-form .wiktku-ipa-key { width: 30px; height: 30px; padding: 0; border-radius: 8px; border: 1px solid var(--wikt-field-edge); background: var(--wikt-field-bg); color: var(--wikt-ink); font-family: var(--wikt-mono); font-size: 14px; line-height: 1; cursor: pointer; display: grid; place-items: center; transition: background 0.1s ease, border-color 0.1s ease; } #wiktku-start-form .wiktku-ipa-key:hover { background: var(--wikt-accent-tint); border-color: var(--wikt-accent); color: var(--wikt-accent-deep); } #wiktku-start-form .wiktku-ipa-key:active { transform: translateY(1px); } /* Ligatures like d͡ʒ and long vowels need a little more room than one glyph; let those keys grow instead of clipping. */ #wiktku-start-form .wiktku-ipa-key { width: auto; min-width: 30px; padding: 0 5px; } /* A combining mark is shown on a dotted circle so it has something to attach to; only the mark itself is inserted. */ #wiktku-start-form .wiktku-ipa-key-combining { color: var(--wikt-ink-2); } @media (max-width: 720px) { #wiktku-start-form .wiktku-ipa-row { flex-direction: column; gap: 3px; } #wiktku-start-form .wiktku-ipa-rowlabel { flex: 0 0 auto; padding-top: 0; } #wiktku-start-form .wiktku-ipa-key { min-width: 34px; height: 34px; } } /* ── "+ Beş zêde bike" menu ────────────────────────────────────────── Adding a part of speech and adding Bilêvkirin are different actions, so the button opens a small menu instead of doing one of them. */ #wiktku-start-form .wiktku-addsection-menu { position: absolute; z-index: 60; margin-top: 6px; min-width: 15em; background: var(--wikt-card); border: 1px solid var(--wikt-rule); border-radius: 10px; padding: 4px; display: flex; flex-direction: column; } #wiktku-start-form .wiktku-addsection-item { display: flex; flex-direction: column; gap: 1px; padding: 8px 10px; border-radius: 7px; border-bottom: 0; text-decoration: none; color: var(--wikt-ink); } #wiktku-start-form .wiktku-addsection-item:hover { background: var(--wikt-accent-tint); } #wiktku-start-form .wiktku-addsection-item-label { font-size: 13.5px; font-weight: 500; } #wiktku-start-form .wiktku-addsection-item-hint { font-size: 11.5px; color: var(--wikt-muted); } #wiktku-start-form #wiktku-section-tabs .oo-ui-buttonElement { position: relative; } /* Bilêvkirin is a peer of the POS sections but not a part of speech — a hairline before it marks the boundary. */ #wiktku-start-form .wiktku-section-tab-pron { margin-left: 6px; border-left: 1px solid var(--wikt-rule); padding-left: 14px; border-radius: 0; } /* =================================================================== Per-sense accordion (v3 spec) =================================================================== "Tenê maneya ku tê nivîsandin vekirî ye" — each meaning is a closed box showing its own text, so a four-sense entry fits on one screen instead of scrolling for a minute. A sense with nothing in it is never collapsed: the trailing empty one is how you add the next meaning, so hiding it would hide the only way forward. =================================================================== */ #wiktku-start-form li.wiktku-dfn-sense { border: 1px solid var(--wikt-card-edge); border-radius: 12px; background: var(--wikt-card); margin-bottom: 10px; padding: 0; list-style: none; overflow: visible; } #wiktku-start-form .wiktku-dfn-sense-header { display: flex; align-items: center; gap: 10px; padding: 12px 14px; cursor: pointer; border-radius: 12px; user-select: none; } #wiktku-start-form li.wiktku-dfn-sense:not(.wiktku-sense-collapsed) .wiktku-dfn-sense-header { border-bottom: 1px solid var(--wikt-rule-soft); border-radius: 12px 12px 0 0; } #wiktku-start-form .wiktku-dfn-sense-header:hover { background: var(--wikt-card-sunken); } #wiktku-start-form .wiktku-dfn-sense-num { flex: 0 0 22px; height: 22px; border-radius: 999px; background: var(--wikt-accent); color: var(--wikt-on-accent); font-family: var(--wikt-mono); font-size: 12px; display: grid; place-items: center; } #wiktku-start-form .wiktku-dfn-sense-title { font-size: 13.5px; font-weight: 500; white-space: nowrap; } /* The summary is the point of a collapsed row, so it only shows there. */ #wiktku-start-form .wiktku-dfn-sense-summary { flex: 1 1 auto; min-width: 0; font-size: 13px; color: var(--wikt-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: none; } #wiktku-start-form li.wiktku-sense-collapsed .wiktku-dfn-sense-summary { display: block; } #wiktku-start-form .wiktku-dfn-sense-chevron { margin-left: auto; color: var(--wikt-muted); font-size: 12px; transition: transform 0.15s ease; } #wiktku-start-form li.wiktku-sense-collapsed .wiktku-dfn-sense-chevron { transform: rotate(-90deg); } #wiktku-start-form .wiktku-dfn-sense-body { padding: 14px; } #wiktku-start-form li.wiktku-sense-collapsed .wiktku-dfn-sense-body { display: none; } /* =================================================================== Template rows in the pickers (v3 spec) =================================================================== "Ti cihê ku şablon tê hilbijartin bêyî 🔗 û i namîne" — one row shape everywhere a template is chosen. Rewiye tine's original complaint was that "guharto? kevnbûyî? ku-Latn? şaşnivîs?" mean nothing to a newcomer; the ⓘ answers that without leaving the form, and the 🔗 is there for when it doesn't. =================================================================== */ #wiktku-start-form ul.wiktku-ac-results li.wiktku-ac-tplrow { display: flex; align-items: center; gap: 8px; min-height: 44px; white-space: normal; padding: 6px 10px; } #wiktku-start-form .wiktku-ac-tpltext { flex: 1 1 auto; min-width: 0; font-family: var(--wikt-mono); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* Status, not category: green is the one to reach for, yellow means "only if you specifically need it" (kevnbûyî, şaşnivîs, kêmpeyda). */ #wiktku-start-form .wiktku-tpl-dot { flex: 0 0 8px; width: 8px; height: 8px; border-radius: 999px; } #wiktku-start-form .wiktku-tpl-dot-ok { background: #3d8a55; } #wiktku-start-form .wiktku-tpl-dot-special { background: #c9971f; } #wiktku-start-form .wiktku-tpl-icons { flex: 0 0 auto; display: flex; gap: 5px; align-items: center; } #wiktku-start-form .wiktku-tpl-icon { width: 26px; height: 26px; display: grid; place-items: center; font-size: 12px; line-height: 1; cursor: pointer; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom: 1px solid var(--wikt-accent-edge); text-decoration: none; padding: 0; } #wiktku-start-form .wiktku-tpl-icon-link { border-radius: 7px; } #wiktku-start-form .wiktku-tpl-icon-info { border-radius: 999px; font-family: var(--wikt-serif); font-style: italic; font-weight: 600; background: transparent; border-color: var(--wikt-field-edge); color: var(--wikt-muted); } #wiktku-start-form .wiktku-tpl-icon:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); background: var(--wikt-accent-tint); } /* ── The ⓘ panel ───────────────────────────────────────────────────── Three parts, in the spec's order: what it does, its parameters, and a way out to the template page. */ #wiktku-start-form .wiktku-tpl-info { position: relative; margin: 8px 0 4px; padding: 14px 16px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); border-radius: 12px; font-size: 13.5px; line-height: 1.6; color: var(--wikt-ink-2); } #wiktku-start-form .wiktku-tpl-info-name { font-family: var(--wikt-mono); font-size: 13px; color: var(--wikt-accent-deep); margin-bottom: 6px; } #wiktku-start-form .wiktku-tpl-info-params { margin-top: 8px; } #wiktku-start-form .wiktku-tpl-info-params-title { font-size: 12px; color: var(--wikt-muted); margin-bottom: 2px; } #wiktku-start-form .wiktku-tpl-info-params ul { margin: 0; padding-left: 18px; font-family: var(--wikt-mono); font-size: 12.5px; } #wiktku-start-form .wiktku-tpl-info-link { display: inline-block; margin-top: 10px; font-size: 13px; } #wiktku-start-form .wiktku-tpl-info-close { position: absolute; top: 8px; right: 8px; width: 24px; height: 24px; border-radius: 999px; border: 0; background: transparent; color: var(--wikt-muted); cursor: pointer; font-size: 13px; line-height: 1; } #wiktku-start-form .wiktku-tpl-info-close:hover { background: var(--wikt-card); color: var(--wikt-ink); } /* =================================================================== Footer overflow "⋯" (v3 spec) =================================================================== Bişîne and "Edîtora çavkaniyê veke" stay on the bar; the two cache actions, the saved-at note and Tercîh move in here. Four equal-weight buttons (two of them red) made the destructive ones as loud as the one you actually want, and on a phone the sticky footer wrapped to three rows. =================================================================== */ #wiktku-start-form .wiktku-more-wrap { position: relative; margin-left: auto; flex: 0 0 auto; } #wiktku-start-form .wiktku-more-btn { width: 36px; height: 36px; border-radius: 999px; border: 1px solid var(--wikt-field-edge); background: var(--wikt-card); color: var(--wikt-muted); font-size: 16px; line-height: 1; cursor: pointer; display: grid; place-items: center; } #wiktku-start-form .wiktku-more-btn:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); } #wiktku-start-form .wiktku-more-menu { position: absolute; right: 0; bottom: calc(100% + 8px); z-index: 70; min-width: 17em; background: var(--wikt-card); border: 1px solid var(--wikt-rule); border-radius: 12px; padding: 6px; display: flex; flex-direction: column; gap: 2px; } #wiktku-start-form .wiktku-more-item { display: flex; align-items: center; gap: 8px; } /* The buttons inside the menu are menu rows, not buttons on a bar. */ #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement { flex: 1 1 auto; } #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement-button { display: block; width: 100%; text-align: left; border: 0 !important; background: transparent !important; border-radius: 7px !important; padding: 9px 10px; min-height: 0; font-weight: 400; color: var(--wikt-ink) !important; } #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement-button:hover { background: var(--wikt-accent-tint) !important; } #wiktku-start-form .wiktku-more-item-danger .oo-ui-buttonElement-button { color: var(--wikt-danger) !important; } #wiktku-start-form .wiktku-more-item-prefs .wiktku-prefs-btn { width: 26px; height: 26px; flex: 0 0 26px; border: 0; background-color: transparent; } #wiktku-start-form .wiktku-more-item-label { font-size: 13.5px; } #wiktku-start-form .wiktku-more-sep { height: 1px; background: var(--wikt-rule-soft); margin: 4px 2px; } #wiktku-start-form .wiktku-more-note { padding: 4px 10px 2px; } #wiktku-start-form .wiktku-more-note #wiktku-last-saved { white-space: normal; } /* The accordion header carries the sense number now, so the older CSS counter badge on the <li> would draw a second one behind it. Retire the counter and its indent — the header owns this. */ #wiktku-start-form ol.wiktku-dfn-list > li.wiktku-dfn-sense::before { content: none; } #wiktku-start-form ol.wiktku-dfn-list > li.wiktku-dfn-sense { padding-left: 0; padding-bottom: 0; border-bottom: 0; margin-bottom: 10px; } #wiktku-start-form ol.wiktku-dfn-list > li.wiktku-dfn-sense:not(:last-child) { padding-bottom: 0; border-bottom: 0; } /* ── "+ Mane zêde bike" ────────────────────────────────────────────── Senses are added deliberately now instead of appearing the moment you type. An always-present empty second sense read as an unfinished form on entries that only ever have one meaning. */ #wiktku-start-form .wiktku-add-sense { display: inline-flex; align-items: center; gap: 8px; margin-top: 4px; padding: 10px 18px; border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-pill); background: var(--wikt-card); color: var(--wikt-ink-2); font-family: var(--wikt-sans); font-size: 13.5px; cursor: pointer; min-height: 40px; } #wiktku-start-form .wiktku-add-sense:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); background: var(--wikt-accent-tint); } #wiktku-start-form .wiktku-add-sense-plus { color: var(--wikt-accent); font-size: 15px; line-height: 1; } /* ── Şablon picker, demoted to a link ──────────────────────────────── Picking a template replaces the definition rather than adding to it, so it is an alternative route, not the first control in the sense. Hidden behind one line of text until it is actually wanted. */ #wiktku-start-form .wiktku-dfn-tpl-link { display: inline-block; margin-top: 8px; font-size: 12.5px; color: var(--wikt-muted); border-bottom: 1px solid transparent; } #wiktku-start-form .wiktku-dfn-tpl-link:hover { color: var(--wikt-accent); border-bottom-color: var(--wikt-link-under); } #wiktku-start-form .wiktku-dfn-tpl-row { margin-top: 10px; padding-top: 12px; border-top: 1px solid var(--wikt-rule-soft); } /* ── Template-row icons on touch screens ───────────────────────────── 26px is fine for a mouse and too small for a thumb, and these two sit right next to each other at the end of a row you can also tap to select. Give them real targets and some separation on small screens. */ @media (max-width: 720px), (pointer: coarse) { #wiktku-start-form .wiktku-tpl-icon { width: 34px; height: 34px; font-size: 14px; } #wiktku-start-form .wiktku-tpl-icons { gap: 8px; padding-left: 4px; } #wiktku-start-form ul.wiktku-ac-results li.wiktku-ac-tplrow { min-height: 50px; } } /* The rendered pronunciation preview is real parser output, so it needs to sit as content rather than in the monospace wikitext treatment the panel inherits. */ #wiktku-start-form .wiktku-pron-preview-body { font-family: var(--wikt-sans); font-size: 15px; background: var(--wikt-card); border: 1px solid var(--wikt-accent-edge); border-radius: 8px; padding: 10px 12px; white-space: normal; } #wiktku-start-form .wiktku-pron-preview-body .IPA, #wiktku-start-form .wiktku-pron-preview-body code, #wiktku-start-form .wiktku-pron-preview-body tt { font-family: var(--wikt-mono); } /* Parser output brings its own margins; strip the outer ones so the preview box doesn't gain a blank first line. */ #wiktku-start-form .wiktku-pron-preview-body > *:first-child { margin-top: 0; } #wiktku-start-form .wiktku-pron-preview-body > *:last-child { margin-bottom: 0; } imda3zhhiakrjccp2naowvcxh1a0x0s 6333819 6333817 2026-08-15T14:37:44Z Wikihez 7344 6333819 css text/css /* =================================================================== #editform while the wizard is active =================================================================== */ /* Keeps #editform genuinely laid out instead of display:none*/ .wiktku-offscreen { position: absolute !important; left: -9999px !important; top: 0 !important; width: 100%; max-width: 100%; visibility: hidden; } /* =================================================================== Base scale =================================================================== */ #wiktku-start-form { font-size: 0.92em; line-height: 1.35; } #wiktku-start-form * { box-sizing: border-box; } .wiktku-addlang-notice { margin: 0 0 0.8em; padding: 0.6em 0.8em; background: var(--wikt-palette-paleblue); border: 1px solid var(--wikt-palette-lightgrey); border-radius: 4px; } /* =================================================================== Step cards a compact card with a left accent bar, so each step reads as a distinct unit =================================================================== */ .wiktku-start-step { padding: 0.7em 0.9em; margin-bottom: 0.6em; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-left: 4px solid var(--wikt-palette-blue-9, #3366cc); border-radius: 6px; background: var(--wikt-palette-white); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); transition: border-left-color 0.15s ease, box-shadow 0.15s ease; } .wiktku-start-step:hover { box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08); } .wiktku-start-step:focus-within { border-left-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); } /* Ghybu, 14 Tebax 2026: "Cureyê rêzimanî" and "Parametreyên cureyê rêzimanî" should read as one question, not two. Fuse the posparams card onto the bottom of the pos card (shared left accent bar, no border/gap between them) and drop its own big heading in favor of the smaller, pos-specific label start.js now sets via question_fmt ("Cins/zayend" / "Cureyê lêkerê" / "Taybetmendî"). posparams.visible only turns this div on once a pos is chosen, and it always renders immediately after #wiktku-start-pos in the DOM, so this pairing is safe. */ #wiktku-start-pos { border-radius: 6px 6px 0 0; margin-bottom: 0; border-bottom: none; } #wiktku-start-posparams { border-radius: 0 0 6px 6px; border-top: none; padding-top: 0.3em; } #wiktku-start-posparams .wiktku-start-step-name { display: none; } /* Scoped to #wiktku-start-form (not just .wiktku-start-step-name) and !important on font-size: this is a real <h3> tag (see start.js), so the wiki skin's own default heading styles can otherwise win over a plain class rule and render it unpredictably (varies by skin/ viewport — this was previously landing at a different effective size on desktop Vector vs. mobile Minerva purely by skin-default accident, not by design). The heading now leads the visual hierarchy through both size AND colour (tinted to match the card's accent bar), while .wiktku-start-step-question below is deliberately lighter-weight and muted so the two never compete for attention. */ #wiktku-start-form .wiktku-start-step-name { font-size: 1.1em !important; font-weight: 700; letter-spacing: 0.03em; margin: 0 0 0.3em; line-height: 1.2; color: var(--wikt-palette-blue-9, #3366cc); border: 0; padding: 0; } /* Rewiye tine, 14 Tebax 2026: "pûnto jî biçûk in, xwendina wan hinek zehmet e" — the question text and the many small per-field labels (Cinsiyet:, Rehê dema niha:, …) were sized noticeably smaller than the heading above them; bumped both a step so the whole card reads at a more consistent, comfortable size instead of the heading standing out and everything under it feeling like fine print. */ .wiktku-start-step-question { font-size: 1em; font-weight: 400; color: var(--wikt-palette-grey-9, #555); margin: 0 0 0.5em; line-height: 1.45; } .wiktku-start-step label { padding-right: 1.2em; font-size: 1em; } /* Rewiye tine, 14 Tebax 2026: short reassurance notes next to the fields that most confused a first-time user (Bilêvkirin's template dropdown, Mane's per-sense template dropdown) — muted so they read as a hint, not another question competing with .wiktku-start-step-question. */ .wiktku-step-hint { font-size: 0.88em; font-style: italic; color: var(--wikt-palette-grey-8, #72777d); margin: 0 0 0.5em; line-height: 1.4; } /* Same specificity as the rule just above, so it must come after to actually win: the name label isn't a field label needing right padding or the form's base label size, it's a heading. */ #wiktku-start-form .wiktku-start-step-name label { padding-right: 0; font-size: inherit !important; color: inherit; } input[type="text"].wiktku-start-step-field { width: 100%; padding: 5px 8px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 4px; transition: border-color 0.12s ease, box-shadow 0.12s ease; } input[type="text"].wiktku-start-step-field:focus { border-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9, #3366cc); outline: 0; } input[type="text"].wiktku-start-step-field.wiktku-start-narrow { width: 20em; } /* Only used by selects that opt out via .wiktku-plain-select; other selects get their width from the searchable picker instead (see input.wiktku-ac-input). */ select.wiktku-start-narrow, input.wiktku-dfn-tpl-title { width: 20em; max-width: 100%; box-sizing: border-box; } #wiktku-start-spinner { float: right; margin-left: 1em; } #wiktku-start-footer { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5em; padding: 0.6em 0.2em; position: sticky; bottom: 0; background: var(--wikt-palette-white); border-top: 1px solid var(--wikt-palette-grey-3, #e0e0e0); z-index: 5; } /* Quiet, non-competing text — sits next to the cache buttons so the person can tell at a glance whether their latest edits are backed up, without it fighting the buttons for attention. */ #wiktku-last-saved { font-size: 0.85em; color: var(--wikt-palette-grey-9, #767676); white-space: nowrap; } /* ── Tercîh (settings) icon button — sits in the footer next to the cache buttons. Uses the Codex "settings" (color-subtle) icon from Commons directly rather than an OOUI icon-pack module, so it renders the exact requested glyph without pulling in an extra dependency. */ .wiktku-prefs-btn { width: 2.2em; height: 2.2em; flex: 0 0 auto; padding: 0; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-radius: 2px; background-color: var(--wikt-palette-white); background-image: url(//upload.wikimedia.org/wikipedia/commons/e/e0/Codex_icon_settings_color-subtle.svg); background-repeat: no-repeat; background-position: center; background-size: 1.2em 1.2em; cursor: pointer; } .wiktku-prefs-btn:hover { background-color: var(--wikt-palette-grey-0, #f8f9fa); } .wiktku-prefs-btn:active { background-color: var(--wikt-palette-grey-1, #eaecf0); } /* Tercîh dialog body — OOUI's bare ProcessDialog body has no inset of its own, so text/fields otherwise sit flush against the window edges. */ .wiktku-prefs-dialog-body { padding: 1em 1.2em; } /* ── "Bişîne" click feedback ── */ @keyframes wiktku-btn-flash-pulse { 0% { box-shadow: 0 0 0 0 rgba(51, 102, 204, 0.55); } 70% { box-shadow: 0 0 0 9px rgba(51, 102, 204, 0); } 100% { box-shadow: 0 0 0 0 rgba(51, 102, 204, 0); } } #wiktku-unhide-editform.wiktku-btn-flash { animation: wiktku-btn-flash-pulse 0.5s ease-out; } /* Persistent state while the wikitext is being built/submitted, set alongside OOUI's own setDisabled(true) so it reads clearly even if the skin's default disabled style is subtle. */ #wiktku-unhide-editform.wiktku-btn-sending .oo-ui-buttonElement-button { background-color: var(--wikt-palette-grey-9, #767676) !important; border-color: var(--wikt-palette-grey-9, #767676) !important; cursor: progress; opacity: 1 !important; } /* Wikihez, 14 Tebax 2026 (item 7): looks exactly like OOUI's own disabled state, but ISN'T one — the button stays a real, clickable widget so its click handler can still run and explain why (see wiktkuNotify call next to wiktkuContentGateOk in start.js). A true setDisabled(true) here would swallow the click before that message could ever show. */ #wiktku-unhide-editform.wiktku-btn-soft-disabled .oo-ui-buttonElement-button { opacity: 0.5; cursor: not-allowed; } /* ── "Beşên din" picker (item 3) ── */ .wiktku-besendin-picker { margin: 0.6em 0 1em; } .wiktku-besendin-picker .wiktku-besendin-select { width: 100%; max-width: 24em; } #wiktku-start-form textarea.wiktku-start-step-field, #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield { resize: vertical !important; overflow: auto !important; box-sizing: border-box !important; vertical-align: top; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; transition: border-color 0.1s ease, box-shadow 0.1s ease; } /* Modern focus state to match the searchable-picker inputs. */ #wiktku-start-form textarea.wiktku-start-step-field:focus, #wiktku-start-form textarea.wiktku-start-narrow:focus, #wiktku-start-form textarea.wiktku-dfn-subfield:focus { border-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9, #3366cc); outline: 0; } /* Standard: every textarea in the form is full width by default */ #wiktku-start-form textarea:not(.wiktku-start-narrow) { width: 100%; max-width: 100%; box-sizing: border-box; } #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield.wiktku-start-narrow { width: 20em; max-width: 100%; min-width: 8em; height: calc(1.7em + 10px); min-height: calc(1.7em + 10px); padding-top: 4px !important; padding-bottom: 4px !important; line-height: 1.35 !important; resize: none !important; } /* Exception: "Sernav" / "Sernavê orjînal" citation-source fields (kitêb, kovar, malper, …) — long enough to be worth 2 rows and manual resizing. */ #wiktku-start-form textarea.wiktku-dfn-quote-src-input.wiktku-dfn-quote-src-input--title { height: calc(2 * 1.35em + 10px); min-height: calc(2 * 1.35em + 10px); } /* ── Manual drag-to-resize handle ── */ #wiktku-start-form textarea:not(.wiktku-start-narrow) { resize: none !important; } /* Inline modifier button (⊕) */ .wiktku-word-li { display: flex; align-items: flex-start; flex-wrap: wrap; gap: 0.3em; } .wiktku-mod-btn { flex: 0 0 auto; width: 1.6em; height: 1.6em; padding: 0; line-height: 1; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); color: var(--wikt-palette-blue-9, #3366cc); font-size: 1em; cursor: pointer; } .wiktku-mod-btn:hover { border-color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-paleblue, #eaf3ff); } .wiktku-mod-picker { display: flex; flex-wrap: wrap; gap: 0.25em; width: 100%; margin-top: 0.15em; padding: 0.35em; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; background: var(--wikt-palette-white); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); } .wiktku-mod-pill { padding: 2px 8px; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-radius: 12px; background: var(--wikt-palette-paleblue, #eaf3ff); font-size: 0.85em; white-space: nowrap; cursor: pointer; } .wiktku-mod-pill:hover { border-color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); } .wiktku-mod-pill:disabled, .wiktku-mod-pill.wiktku-mod-pill-used { border-color: var(--wikt-palette-grey-3, #e0e0e0); background: var(--wikt-palette-lightgrey); color: var(--wikt-palette-grey-3, #999); cursor: not-allowed; opacity: 0.6; } .wiktku-mod-pill:disabled:hover, .wiktku-mod-pill.wiktku-mod-pill-used:hover { border-color: var(--wikt-palette-grey-3, #e0e0e0); background: var(--wikt-palette-lightgrey); color: var(--wikt-palette-grey-3, #999); } .wiktku-mod-val-wrap { display: flex; align-items: center; gap: 0.25em; width: 100%; margin-top: 0.15em; } .wiktku-mod-val-input { flex: 0 1 14em; max-width: 14em; padding: 3px 6px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; } .wiktku-mod-confirm, .wiktku-mod-cancel { flex: 0 0 auto; width: 1.6em; height: 1.6em; padding: 0; line-height: 1; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); cursor: pointer; } .wiktku-mod-confirm { color: #178a17; border-color: #178a17; } .wiktku-mod-cancel { color: var(--wikt-palette-red-9, #d33); border-color: var(--wikt-palette-red-9, #d33); } .wiktku-resize-wrap { position: relative; display: block; } /* Independent of .wiktku-resize-wrap (created separately by ensureLinebreakBackdrop() in start.js, only for textareas that ever get flagged with a linebreak) so it doesn't depend on load order relative to wiktkuMakeManualResizable(). Plain block, no size of its own — purely a position:relative anchor for the backdrop. */ .wiktku-linebreak-wrap { position: relative; display: block; } .wiktku-resize-grip { position: absolute; right: 2px; bottom: 2px; width: 14px; height: 14px; cursor: ns-resize; touch-action: none; opacity: 0.5; z-index: 2; background-image: linear-gradient(135deg, transparent 0 50%, var(--wikt-palette-grey-9, #767676) 50% 100%); background-repeat: no-repeat; } .wiktku-resize-grip:hover, .wiktku-resize-grip:active { opacity: 0.9; } /* =================================================================== Searchable dropdown (wrapNativeSelect in start.js) .wiktku-native-select-wrap > input.wiktku-ac-input (search box) > ul.wiktku-ac-results (result list) > select (hidden, holds the value) =================================================================== */ .wiktku-native-select-wrap { display: inline-block; position: relative; vertical-align: top; } /* Matches the width the native select would have had (see select.wiktku-start-narrow). */ .wiktku-native-select-wrap input[type="search"], input.wiktku-ac-input { display: block; width: 20em; max-width: 100%; box-sizing: border-box; padding: 3px 6px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); color: inherit; font-size: inherit; font-family: inherit; transition: border-color 0.1s ease, box-shadow 0.1s ease; } input.wiktku-ac-input:focus { border-color: var(--wikt-palette-blue-9); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9); outline: 0; } input.wiktku-ac-input::placeholder { color: var(--wikt-palette-grey-9); opacity: 1; } /* Hide Safari/Chrome's built-in search decorations. */ input.wiktku-ac-input::-webkit-search-decoration, input.wiktku-ac-input::-webkit-search-cancel-button, input.wiktku-ac-input::-webkit-search-results-button { -webkit-appearance: none; appearance: none; } /* ── Result list ── */ /* top/bottom/max-height are overridden inline by showResults() when it flips the list above the box; these are just its defaults. */ ul.wiktku-ac-results { position: absolute; z-index: 9999; top: 100%; bottom: auto; left: 0; margin: 0; padding: 0; list-style: none; width: 20em; max-width: 90vw; max-height: 13em; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; background: var(--wikt-palette-white); border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; box-shadow: 0 3px 10px rgba(0, 0, 0, 0.15); } ul.wiktku-ac-results li { margin: 0; padding: 4px 8px; cursor: pointer; font-size: 0.92em; display: flex; align-items: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* .wiktku-ac-active is the keyboard cursor; hover mirrors it; :active covers the touch press state. */ ul.wiktku-ac-results li.wiktku-ac-active, ul.wiktku-ac-results li:hover { background: var(--wikt-palette-lightblue); } ul.wiktku-ac-results li:active { background: var(--wikt-palette-blue-9); color: var(--wikt-palette-white); } /* Touch devices: bigger tap targets, no sticky hover. */ @media (pointer: coarse) { ul.wiktku-ac-results li { padding: 6px 10px; min-height: 2.2em; font-size: 1em; } ul.wiktku-ac-results li:hover { background: transparent; } ul.wiktku-ac-results li.wiktku-ac-active { background: var(--wikt-palette-lightblue); } input.wiktku-ac-input { /* >=16px stops iOS Safari zooming the page when the box is focused. */ font-size: 16px; min-height: 2.2em; } } /* Item 5 (Wikihez, 14 Tebax 2026): inline preview + confirm panel shown before inserting an auto-content pronunciation template (ku-IPA, ku-kîte, …) — deliberately part of the form's own layout rather than a browser confirm()/prompt() dialog, per "dont use userinput use something more advanced". */ .wiktku-pron-preview { margin: 6px 0; padding: 8px 10px; border: 1px solid var(--wikt-palette-blue-9, #3366cc); border-radius: 6px; background: var(--wikt-palette-paleblue, #eaf3ff); } .wiktku-pron-preview-label { font-size: 0.88em; font-weight: 600; color: var(--wikt-palette-grey-9, #555); margin-bottom: 3px; } .wiktku-pron-preview-body { font-family: monospace; font-size: 1em; white-space: pre-wrap; word-break: break-word; margin-bottom: 6px; } .wiktku-pron-preview-actions { display: flex; gap: 6px; } .wiktku-pron-preview-confirm, .wiktku-pron-preview-cancel { font-size: 0.88em; padding: 3px 10px; border-radius: 4px; cursor: pointer; border: 1px solid var(--wikt-palette-lightgrey, #a2a9b1); background: var(--wikt-palette-white, #fff); } .wiktku-pron-preview-confirm { border-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-blue-9, #3366cc); font-weight: 600; } .wiktku-pron-preview-confirm:disabled { opacity: 0.5; cursor: wait; } .wiktku-pron-preview-cancel:hover { background: var(--wikt-palette-grey-0, #f8f9fa); } /* Template pickers fill their container since the search box, not the <select>, is what the user sees. */ .wiktku-pron-wrap .wiktku-native-select-wrap, .wiktku-etym-wrap .wiktku-native-select-wrap, .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { width: 100%; } .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 0.88em; } .wiktku-cavkani-wrap .wiktku-native-select-wrap, .wiktku-cavkani-wrap .wiktku-native-select-wrap input.wiktku-ac-input { width: 100%; } /* Template selector inside a sense block. */ .wiktku-dfn-tpl-row .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 0.88em; } /* Language/dialect rows: picker must line up with the word field beside it. */ .wiktku-lang-row .wiktku-native-select-wrap { flex: 0 0 auto; } #wiktku-start-form textarea.wiktku-dfn-mane, #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t, #wiktku-start-form textarea.wiktku-dfn-quote-src-manual, #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text, #wiktku-start-form .wiktku-tewandin-wrap textarea.wiktku-tewandin-text, #wiktku-start-form textarea.wiktku-cavkani-text, #wiktku-start-form textarea.wiktku-dfn-tercime, #wiktku-start-form textarea.wiktku-dfn-izah { --wiktku-ta-rows: 2; height: calc(var(--wiktku-ta-rows) * 1.35em + 6px); min-height: calc(var(--wiktku-ta-rows) * 1.35em + 6px); } #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text, #wiktku-start-form textarea.wiktku-dfn-izah { --wiktku-ta-rows: 3; } #wiktku-start-form textarea.wiktku-cavkani-text { --wiktku-ta-rows: 4; } /* Nimûne + Jêgirtin (citation) boxes, and their tr/t sub-fields: at least 4 rows so there's room to actually write an example/quote. */ #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t, #wiktku-start-form textarea.wiktku-dfn-quote-src-manual { --wiktku-ta-rows: 4; } /* Nimûne/jêgirtin box currently contains a typed/pasted linebreak — the border is nudged so the user notices before it's silently turned into <br> on output. The break itself is marked precisely, not the whole box, via a mirrored backdrop layer (see below and highlightLinebreak()/buildLinebreakBackdropHtml() in start.js). */ #wiktku-start-form textarea.wiktku-has-linebreak { border-color: var(--wikt-palette-yellow6, #ac6600) !important; } /* Backdrop layer: sits behind the textarea showing the same text, with a highlighted marker at each line that's followed by a break. Its font/padding/box-sizing/line-height are copied from the textarea via computed style (see syncLinebreakBackdropMetrics() in start.js), not shared CSS classes — most of this box's own rules are written as "textarea.foo", which a <div> with the same class wouldn't match. Only created lazily, the first time a given textarea actually has a break — see ensureLinebreakBackdrop(). */ .wiktku-linebreak-backdrop { position: absolute; inset: 0; z-index: 0; margin: 0; overflow: hidden; white-space: pre-wrap; word-wrap: break-word; color: transparent; background: transparent !important; border-color: transparent !important; box-shadow: none !important; resize: none !important; pointer-events: none; } /* Raise the real textarea above its backdrop so typing/selection/caret behave completely normally; the backdrop's mark shows through only where the real textarea's own background is transparent. */ #wiktku-start-form textarea.wiktku-has-linebreak-source { position: relative; z-index: 1; background-color: transparent; } .wiktku-linebreak-mark { background-color: var(--wikt-palette-yellow6, #ac6600); color: var(--wikt-palette-white, #fff); border-radius: 2px; } /* ── Tercime + Îzah boxes ── */ .wiktku-dfn-nonku-wrap { display: flex; flex-direction: column; gap: 3px; } .wiktku-dfn-nimune-sub, .wiktku-dfn-quote-sub { margin-top: 3px; margin-left: 1em; padding-left: 0.6em; border-left: 2px solid var(--wikt-palette-lightgrey); display: flex; flex-direction: column; gap: 3px; } .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t { min-width: 8em; padding-top: 2px !important; padding-bottom: 2px !important; line-height: 1.35 !important; font-size: 0.88em; } /* ── Sense list (Mane step) — numbered badges instead of the browser's default flat "1." marker, so each sense reads as a distinct block. ── */ ol.wiktku-dfn-list { list-style: none; margin: 0; padding: 0; counter-reset: wiktku-dfn-sense; } ol.wiktku-dfn-list > li.wiktku-dfn-sense { position: relative; counter-increment: wiktku-dfn-sense; padding-left: 2.1em; margin-bottom: 0.9em; } ol.wiktku-dfn-list > li.wiktku-dfn-sense:not(:last-child) { padding-bottom: 0.9em; border-bottom: 1px dashed var(--wikt-palette-grey-3, #e0e0e0); } ol.wiktku-dfn-list > li.wiktku-dfn-sense::before { content: counter(wiktku-dfn-sense); position: absolute; left: 0; top: 1px; width: 1.6em; height: 1.6em; border-radius: 50%; background: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); font-size: 0.85em; font-weight: 700; display: flex; align-items: center; justify-content: center; } /* Template selector row inside a sense block */ .wiktku-dfn-tpl-row { margin-bottom: 3px; } /* ── Sub-field titles (Etîket, Kategorî, Hevmane, Dijmane, Nimûne, Jêgirtin, …) — previously plain unstyled run-on text. Each group now reads as a small labelled field: the term stands out, the izah hint stays quiet, and the block gets its own breathing room. ── */ .wiktku-dfn-subgroup { margin-top: 0.5em; padding-top: 0.4em; border-top: 1px dashed var(--wikt-palette-grey-3, #e0e0e0); } .wiktku-dfn-subgroup:first-of-type { margin-top: 0.3em; padding-top: 0; border-top: none; } .wiktku-dfn-sublabel { display: block; margin-bottom: 3px; font-size: 0.88em; } .wiktku-dfn-sublabel-term { font-weight: 600; color: var(--wikt-palette-blue-9, #3366cc); letter-spacing: 0.03em; font-size: 0.92em; } .wiktku-dfn-sublabel-hint { color: var(--wikt-palette-grey-9, #767676); font-style: italic; } .wiktku-pron-wrap, .wiktku-etym-wrap, .wiktku-tewandin-wrap, .wiktku-cavkani-wrap { display: flex; flex-direction: column; gap: 3px; } /* ── POS section tabs ── Modernized into rounded pills instead of flat file-folder tabs. */ #wiktku-section-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 0.6em; align-items: center; } #wiktku-section-tabs .wiktku-section-tab { padding: 3px 12px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 999px; background: var(--wikt-palette-dullcyan); cursor: pointer; font-size: 0.86em; user-select: none; transition: background 0.12s ease, border-color 0.12s ease; } #wiktku-section-tabs .wiktku-section-tab:hover { border-color: var(--wikt-palette-blue-9, #3366cc); } #wiktku-section-tabs .wiktku-section-tab.wiktku-tab-active { background: var(--wikt-palette-blue-9, #3366cc); border-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); font-weight: 600; } /* ── Step-group tabs (Mane / Bilêvkirin / Beşên din — see STEP_GROUPS in start.js) ── Sits directly under the pill-style section tabs above; styled as an underlined secondary nav so the two bars stay visually distinct. */ #wiktku-group-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 0.8em; border-bottom: 2px solid var(--wikt-palette-lightgrey); } #wiktku-group-tabs .wiktku-group-tab { position: relative; padding: 7px 14px 8px; margin-bottom: -2px; border-bottom: 3px solid transparent; border-radius: 3px 3px 0 0; cursor: pointer; font-size: 0.95em; font-weight: 600; color: var(--wikt-palette-grey-9, #333); background: var(--wikt-palette-grey-0, #f8f9fa); user-select: none; transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease; } #wiktku-group-tabs .wiktku-group-tab:hover { color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-paleblue, #eaf3ff); } #wiktku-group-tabs .wiktku-group-tab.wiktku-tab-active { border-bottom-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); background: var(--wikt-palette-blue-9, #3366cc); font-weight: 700; } /* Small dot marking a tab that still has an unfilled required field hidden inside it (see updateGroupTabIndicators in start.js). Cleared automatically once that tab becomes the active one. */ #wiktku-group-tabs .wiktku-group-tab.wiktku-tab-missing::after { content: ""; position: absolute; top: 4px; right: -1px; width: 6px; height: 6px; border-radius: 50%; background: var(--wikt-palette-red-9, #d33); } .wiktku-lang-row-list { margin: 0; padding: 0; list-style: none; } .wiktku-lang-row { display: flex; align-items: flex-start; gap: 6px; margin-bottom: 3px; flex-wrap: wrap; } .wiktku-lang-row-words { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 3px; } /* Dûnde/Werger/Zarava rows: align the picker's height with the adjacent word textarea (see .wiktku-start-narrow above). */ .wiktku-lang-row .wiktku-native-select-wrap input.wiktku-ac-input { height: calc(1.7em + 10px); min-height: calc(1.7em + 10px); padding-top: 4px; padding-bottom: 4px; } /* ── Werger / Bi zaravayên din groups: one per gloss, shared spacing ── */ #wiktku-start-trans .wiktku-trans-group, #wiktku-start-zarava .wiktku-zarava-group { margin-bottom: 0.6em; } #wiktku-start-trans .wiktku-trans-group:last-child, #wiktku-start-zarava .wiktku-zarava-group:last-child { margin-bottom: 0; } #wiktku-start-trans .wiktku-trans-group-label, #wiktku-start-zarava .wiktku-zarava-group-label { font-weight: 600; font-size: 0.88em; margin-bottom: 3px; } .wiktku-dfn-jeder-group { margin-top: 3px; } .wiktku-dfn-quote-src-sel { font-size: 0.88em; margin-top: 3px; display: block; } .wiktku-dfn-quote-src-fields { display: flex; flex-direction: column; gap: 3px; margin-top: 3px; } /* Stacked layout: textarea gets its own full-width row, button + status sit below it on their own row. Simpler and more robust than sharing a row with the button — that required the textarea's own resize-wrap div (added by wiktkuMakeManualResizable in start.js) to correctly inherit flex-grow, which kept being fragile across breakpoints. */ .wiktku-dfn-quote-citoid { display: flex; flex-direction: column; align-items: stretch; gap: 0.4em; margin-top: 3px; margin-bottom: 3px; } .wiktku-dfn-quote-citoid-input { width: 100%; max-width: 100%; box-sizing: border-box; } /* Column flex + align-items:stretch (above) is what makes the textarea's .wiktku-resize-wrap (see wiktkuMakeManualResizable in start.js) reach full width automatically — stretch fills the cross axis for any block child, no flex-grow needed on the wrap itself. The button and status text, right below the textarea, opt back out of that stretch so they stay their natural (small) size instead of also going full width. */ .wiktku-dfn-quote-citoid-btn, .wiktku-dfn-quote-citoid-status { align-self: flex-start; } .wiktku-dfn-quote-src-cat-status { display: block; font-size: 0.82em; color: var(--wikt-palette-lightgrey, #767676); margin-top: 2px; } .wiktku-dfn-quote-src-row { display: flex; align-items: baseline; gap: 4px; flex-wrap: wrap; } .wiktku-dfn-quote-src-row label { font-size: 0.82em; white-space: nowrap; min-width: 8em; } textarea.wiktku-dfn-quote-src-input { flex: 1 1 12em; max-width: 100%; box-sizing: border-box; } @media (max-width: 720px) { .wiktku-lang-row { flex-direction: column; } /* Re-assert against the wiki's own mobile skin heading styles, which can apply their own mobile-breakpoint rules to this real <h3> and load after ours in the cascade — see the rule itself, above, for why this needs guarding at all. */ #wiktku-start-form .wiktku-start-step-name { font-size: 1.05em !important; margin: 0 0 0.2em !important; line-height: 1.2 !important; border: 0 !important; padding: 0 !important; } /* Single column: search box and list use the full width. Narrow textareas (Etîket, Hevmane, Dûnde/Jê/Têkildar/Binêre herwiha word boxes, citation source fields, …) join them here too — at a fixed 20em width they used to poke out past the step card on narrow screens. */ .wiktku-native-select-wrap, input.wiktku-ac-input, ul.wiktku-ac-results, #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield.wiktku-start-narrow { width: 100%; max-width: 100%; } .wiktku-mod-val-input { flex: 1 1 auto; max-width: 100%; } #wiktku-start-form textarea.wiktku-dfn-mane, #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text { --wiktku-ta-rows: 3; font-size: 1em; } #wiktku-start-form .wiktku-tewandin-wrap textarea.wiktku-tewandin-text, #wiktku-start-form textarea.wiktku-cavkani-text { --wiktku-ta-rows: 4; font-size: 1em; } /* Nimûne + Jêgirtin and their tr/t sub-fields: keep at least 4 rows on mobile too, rather than shrinking further than the desktop size. */ #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t { --wiktku-ta-rows: 4; font-size: 1em; } /* Citoid URL/DOI/ISBN box: taller tap target (~2 lines) on mobile, and now that this field is a <textarea> (see start.js) its placeholder can actually wrap into that space — a plain <input>'s placeholder can never wrap, no matter its height. */ .wiktku-dfn-quote-citoid-input { min-height: calc(2 * 1.35em + 10px); font-size: 1em; } .wiktku-dfn-nimune-sub, .wiktku-dfn-quote-sub { margin-left: 0.5em; padding-left: 0.4em; } .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 1em; min-height: 2.2em; } .wiktku-dfn-quote-src-row label { min-width: 6em; } #wiktku-start-form textarea.wiktku-dfn-quote-src-input { width: 100%; flex: 1 1 100%; } .wiktku-start-step { padding: 0.5em 0.6em; } } /* =================================================================== Night mode Palette.css already flips every --wikt-palette-* var for night mode, so rules built from those vars need nothing here. This hook is only for real colours that can't be a palette var — here, the panel border, since a drop shadow is invisible against an equally dark page. Not needed: li:active's white text already flips to a dark colour at night via --wikt-palette-white, so it stays legible on its own. =================================================================== */ @media screen { html.skin-theme-clientpref-night .wiktku-ac-results { /* Border stands in for the shadow, invisible on a dark page. */ border-color: var(--wikt-palette-grey-5); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.6); } html.skin-theme-clientpref-night .wiktku-start-step, html.skin-theme-clientpref-night .wiktku-start-step:hover, html.skin-theme-clientpref-night .wiktku-start-step:focus-within { box-shadow: none; } } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os .wiktku-ac-results { border-color: var(--wikt-palette-grey-5); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.6); } html.skin-theme-clientpref-os .wiktku-start-step, html.skin-theme-clientpref-os .wiktku-start-step:hover, html.skin-theme-clientpref-os .wiktku-start-step:focus-within { box-shadow: none; } } /* "Zimanek lê zêde bike" portlet icon (Minerva/mobile) — Feather-core-edit.svg via CSS mask, matching Minerva's own icon pattern. */ .minerva-icon-portletlink-ca-wiktku-addlang { -webkit-mask-image: url("https://upload.wikimedia.org/wikipedia/commons/d/d7/Feather-core-edit.svg"); mask-image: url("https://upload.wikimedia.org/wikipedia/commons/d/d7/Feather-core-edit.svg"); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-position: center; mask-position: center; -webkit-mask-size: 20px; mask-size: 20px; background-color: currentColor; background-image: none; } /* ── posparams step (live wikitext + helper widgets) ── */ .wiktku-posparams-wrap { display: flex; flex-direction: column; gap: 6px; } .wiktku-posparams-helpers { display: flex; flex-direction: column; gap: 4px; } .wiktku-posparams-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; } .wiktku-posparams-row label { /* Rewiye tine, 14 Tebax 2026: these were the smallest labels on the whole card (0.9em, one step below everything else) — the mobile breakpoint already bumps this to 1em below; matching that on desktop too instead of only fixing it for mobile. */ font-size: 1em; min-width: 10em; padding-right: 0; } .wiktku-posparams-text { width: 100%; box-sizing: border-box; font-family: monospace; font-size: 0.9em; } .wiktku-posparams-opt-toggle { font-size: 0.85em; margin-top: 2px; display: inline-block; } .wiktku-posparams-opt-panel { display: flex; flex-direction: column; gap: 2px; padding: 4px 0 2px 1em; } .wiktku-posparams-opt-row { display: flex; align-items: center; gap: 4px; font-size: 0.85em; } /* ── resim step (one or more images) ── */ .wiktku-resim-list { display: flex; flex-direction: column; gap: 6px; } .wiktku-resim-item { display: flex; flex-direction: column; gap: 4px; } .wiktku-resim-item .wiktku-posparams-row { flex-direction: column; align-items: flex-start; gap: 2px; } .wiktku-resim-item .wiktku-posparams-row label { min-width: 0; font-size: 0.9em; } /* ── dfn: "hide/show all subsections" link ── Same show/hide-link pattern as "Tercîhên pêşketî" (posparams), but toggles a class on the whole dfn stepDiv rather than one panel, so a single click hides the etîket/kategorî/hevmane/dijmane/nimûne/ jêgirtin/etc. subgroups across every sense block at once (see steps.dfn.build in start.js). */ .wiktku-dfn-subs-toggle { font-size: 0.85em; font-weight: 500; display: inline-block; margin: 2px 0 8px; color: var(--wikt-palette-blue-9, #3366cc); text-decoration: none; } .wiktku-dfn-subs-toggle:hover { text-decoration: underline; } /* Only the ADVANCED subgroups collapse now (Ghybu, 14 Tebax 2026): Nimûne, Jêgirtin, Hevmane and Dijmane stay open because they are what people actually come here to fill in — see steps.dfn.allGroups, whose adv: flag is what puts this class on a group. */ #wiktku-start-form li.wiktku-sense-adv-hidden .wiktku-dfn-subgroup-adv { display: none !important; } /* The toggle sits between the primary groups and the advanced ones, so it needs no rule of its own beyond a little breathing room. */ #wiktku-start-form .wiktku-sense-adv-row { margin-top: 14px; } /* =================================================================== Desktop text bump The modifier pills/buttons and posparams helper text (labels, "Tercîhên pêşketî" opt panel) use fairly small font-sizes that read fine on mobile — narrow-viewport rendering effectively scales them up — but look too small on a full desktop screen at their literal em size. Bump them up past the 720px breakpoint only; mobile keeps the original sizing above. =================================================================== */ @media (min-width: 721px) { .wiktku-mod-btn, .wiktku-mod-confirm, .wiktku-mod-cancel { width: 1.8em; height: 1.8em; font-size: 1.1em; } .wiktku-mod-pill { font-size: 0.95em; padding: 3px 10px; } .wiktku-mod-val-input { font-size: 0.95em; } .wiktku-posparams-row label { font-size: 1em; } .wiktku-posparams-text { font-size: 1em; } .wiktku-posparams-opt-toggle { font-size: 0.95em; } .wiktku-posparams-opt-row { font-size: 0.95em; } .wiktku-dfn-subs-toggle { font-size: 0.95em; } /* Item 2 (Wikihez, 14 Tebax 2026): "sê-stûnî" — the same side-by-side, multi-column card layout Ghybu asked for on POS/Cîns/Jimar now applies to every posparams helper field (transliteration, gendered forms, comparative/superlative, hanja, verb-tense roots, …), not just those first two. Desktop-only per Wikihez's note that this isn't supported on mobile — the plain stacked list above stays as-is below this breakpoint. Rows are toggled via jQuery .show()/.hide() (inline display:block/none) same as before; the grid only changes how visible rows are arranged, not which ones are visible. */ .wiktku-posparams-helpers { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px 16px; align-items: start; } .wiktku-posparams-helpers > .wiktku-posparams-row { flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 3px; } .wiktku-posparams-helpers > .wiktku-posparams-row label { min-width: 0; } .wiktku-posparams-helpers > .wiktku-posparams-row .wiktku-posparams-field, .wiktku-posparams-helpers > .wiktku-posparams-row select.wiktku-posparams-cinsiyet-sel, .wiktku-posparams-helpers > .wiktku-posparams-row select.wiktku-posparams-lektur-sel { width: 100%; max-width: 100%; box-sizing: border-box; } /* The "Jimar" row added for item 1 lives here too (see start.js) — no extra CSS needed, it's just another .wiktku-posparams-row. */ /* These two aren't per-field rows — span the full card width so the collapsed toggle and its checkbox list don't get squeezed into one narrow column. */ .wiktku-posparams-helpers > .wiktku-posparams-opt-toggle, .wiktku-posparams-helpers > .wiktku-posparams-opt-panel { grid-column: 1 / -1; } } /* =================================================================== SÊWIRANA NÛ — design system layer =================================================================== From the "Cerdevanê ketanê — sêwirana nû" spec (15 Tebax 2026). Appended rather than merged into the rules above on purpose: everything before this point is layout (what sits next to what, which row wraps where) and still does its job. This block is purely the visual skin — colour, type, weight, radius, spacing — so it comes last and wins, and so a future revert is a delete of one contiguous section. Two deliberate deviations from the spec document: 1. No @import of Spectral / IBM Plex from Google Fonts. Wikimedia wikis send a Content-Security-Policy that blocks third-party font hosts, so the import would fail silently and we would ship a broken-looking fallback nobody chose. The stacks below name the spec's faces first (so they are used if the wiki ever installs them locally) and then fall back to faces with the same feel: a transitional serif for headings, the UI sans for body, the platform mono for wikitext. 2. Blue is spent, not sprayed. Ghybu, 14 Tebax 2026: "hemû bi rengê şîn hatine çêkirin, nizanim beşên din (===) bi rengê gewr an reş çito dibe?" — so section headings are near-black now and the accent is reserved for things you can act on: focus, links, the active tab, the primary button, chips. =================================================================== */ #wiktku-start-form { /* Surfaces */ --wikt-page: #f4efe5; --wikt-card: #fffdf8; --wikt-card-sunken: #fbf8f1; --wikt-rule: #ded6c8; /* structural hairline */ --wikt-rule-soft: #efe8db; /* inside a card */ --wikt-field-edge: #cfc7b8; --wikt-field-bg: #fff; --wikt-code-bg: #f7f4ec; --wikt-card-edge: #e6dfd2; /* Ink */ --wikt-ink: #1c1a17; --wikt-ink-2: #3d3830; --wikt-ink-3: #57514a; --wikt-muted: #8a8378; --wikt-placeholder: #b3ab9e; /* Accent + status */ --wikt-accent: #2a5db0; --wikt-accent-deep: #22406f; --wikt-accent-tint: #eef2fa; --wikt-accent-edge: #d5def0; --wikt-danger: #9c3a28; --wikt-on-accent: #fff; /* text on a filled accent button */ --wikt-link-under: rgba(42, 93, 176, 0.35); /* Shape */ --wikt-r-field: 10px; --wikt-r-card: 14px; --wikt-r-pill: 999px; --wikt-tap: 44px; /* minimum field height */ --wikt-serif: Spectral, "Iowan Old Style", Georgia, "Times New Roman", serif; --wikt-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif; --wikt-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-family: var(--wikt-sans); font-size: 15px; line-height: 1.55; color: var(--wikt-ink); background: var(--wikt-page); padding: 24px; border-radius: var(--wikt-r-card); } /* ── Cards ─────────────────────────────────────────────────────────── The old card had a 4px blue left bar and two shadows. The spec is explicit — "Ti sî (shadow) tune; tenê xetên 1px" — so the card is now a flat cream panel held by a single hairline. */ #wiktku-start-form .wiktku-start-step { background: var(--wikt-card); border: 1px solid var(--wikt-card-edge); border-left: 1px solid var(--wikt-card-edge); border-radius: var(--wikt-r-card); box-shadow: none; padding: 24px 24px 20px; margin-bottom: 16px; transition: border-color 0.12s ease; } #wiktku-start-form .wiktku-start-step:hover, #wiktku-start-form .wiktku-start-step:focus-within { box-shadow: none; border-color: var(--wikt-rule); } /* The fused pos + posparams pair keeps reading as one card. */ #wiktku-start-form #wiktku-start-pos { border-radius: var(--wikt-r-card) var(--wikt-r-card) 0 0; border-bottom: none; padding-bottom: 8px; } #wiktku-start-form #wiktku-start-posparams { border-radius: 0 0 var(--wikt-r-card) var(--wikt-r-card); border-top: none; padding-top: 4px; } /* ── Type ──────────────────────────────────────────────────────────── Step headings: serif, regular weight, near-black. Previously bold, letterspaced and blue — three signals doing one job. */ #wiktku-start-form .wiktku-start-step-name { font-family: var(--wikt-serif); font-size: 24px !important; font-weight: 400; letter-spacing: -0.01em; line-height: 1.15; color: var(--wikt-ink); margin: 0 0 12px; } /* display:block matters: this is a <label>, so it was sharing a line with the control it introduces wherever start.js didn't emit a <br>. */ #wiktku-start-form .wiktku-start-step-question { display: block; font-size: 15px; font-weight: 400; color: var(--wikt-ink-3); margin: 0 0 12px; line-height: 1.6; max-width: 62ch; } /* Wikihez, 15 Tebax 2026: posparams' "Cins/zayend" title was removed (question_fmt now returns "" for navdêr/serenav) — collapse the label entirely when empty instead of leaving its margin behind as a blank gap. Harmless no-op for every other step, whose question text is never empty. */ #wiktku-start-form .wiktku-start-step-question:empty { display: none; margin: 0; } /* Same reason — a field label belongs above its field, not beside it. */ #wiktku-start-form .wiktku-posparams-row label, #wiktku-start-form .wiktku-dfn-sublabel { display: block; margin-bottom: 6px; padding-right: 0; } /* Field labels: small, medium weight, full-strength ink — they label a control, so they should not read as body copy. */ #wiktku-start-form .wiktku-start-step label, #wiktku-start-form .wiktku-posparams-row label, #wiktku-start-form .wiktku-dfn-sublabel { font-size: 13px; font-weight: 500; color: var(--wikt-ink); letter-spacing: 0.01em; } /* The parenthetical/example half of a label is supporting text. */ #wiktku-start-form .wiktku-dfn-sublabel-hint, #wiktku-start-form .wiktku-step-hint { font-weight: 400; font-style: italic; color: var(--wikt-muted); font-size: 12.5px; } /* ── Fields ────────────────────────────────────────────────────────── One shape for every control: 1px edge, 10px radius, 44px tall. */ #wiktku-start-form input[type="text"], #wiktku-start-form input[type="search"], #wiktku-start-form input.wiktku-ac-input, #wiktku-start-form textarea, #wiktku-start-form select { font-family: var(--wikt-sans); font-size: 15px; color: var(--wikt-ink); background: var(--wikt-field-bg); border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-field); padding: 10px 14px; box-shadow: none; transition: border-color 0.12s ease, box-shadow 0.12s ease; } #wiktku-start-form input[type="text"], #wiktku-start-form input[type="search"], #wiktku-start-form select { min-height: var(--wikt-tap); } #wiktku-start-form textarea { line-height: 1.6; } /* Wikitext and anything template-shaped reads as code. */ #wiktku-start-form .wiktku-posparams-text, #wiktku-start-form .wiktku-pron-text, #wiktku-start-form .wiktku-etym-text, #wiktku-start-form .wiktku-cavkani-text, #wiktku-start-form .wiktku-tewandin-text, #wiktku-start-form .wiktku-pron-preview-body { font-family: var(--wikt-mono); font-size: 13.5px; background: var(--wikt-code-bg); border-color: var(--wikt-card-edge); } #wiktku-start-form ::placeholder { color: var(--wikt-placeholder); opacity: 1; } /* Focus: accent edge + 3px tint halo. The only "elevation" in the design. */ #wiktku-start-form input[type="text"]:focus, #wiktku-start-form input[type="search"]:focus, #wiktku-start-form textarea:focus, #wiktku-start-form select:focus, #wiktku-start-form input.wiktku-ac-input:focus { border-color: var(--wikt-accent); box-shadow: 0 0 0 3px var(--wikt-accent-tint); outline: 0; } /* The searchable picker's visible input is the field, so it takes the field shape too (it otherwise inherits an older, boxier rule). */ #wiktku-start-form input.wiktku-ac-input { min-height: var(--wikt-tap); border-radius: var(--wikt-r-field); border-color: var(--wikt-field-edge); font-size: 15px; } #wiktku-start-form .wiktku-ac-results { border: 1px solid var(--wikt-rule); border-radius: var(--wikt-r-field); background: var(--wikt-card); box-shadow: none; } #wiktku-start-form .wiktku-ac-results li.wiktku-ac-active, #wiktku-start-form .wiktku-ac-results li:hover { background: var(--wikt-accent-tint); color: var(--wikt-accent-deep); } /* ── Tabs → the accent's main job ──────────────────────────────────── Active tab: tint fill + 3px accent underline, per the spec's "xala hûrgulî" note. Inactive tabs are plain text. */ #wiktku-start-form #wiktku-group-tabs, #wiktku-start-form #wiktku-section-tabs { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; border-bottom: 1px solid var(--wikt-rule); margin-bottom: 16px; padding-bottom: 0; } /* Wikihez, 15 Tebax 2026: "should persist when scrolling down… able to click them anytime". Both bars are direct children of #wiktku-start-form (a tall container spanning the whole wizard), so a sticky child stays stuck for as long as any part of the form is in view — not just its own original height — which is exactly the range we want here. Background is opaque so step-card content scrolling underneath doesn't show through the strip while it's pinned. Section-tabs pins just below --wiktku-siteheader-h; group-tabs pins below that plus section-tabs' own rendered height (--wiktku-stabs-h). Both custom properties are set by syncStickyTabsOffset() in start.js. --wiktku-siteheader-h is the fix for Wikihez, 15 Tebax 2026 (item 2): "on desktop only Mane/Etîmolojî is sticky, Bilêvkirin/Beş zêde bike isn't". Root cause: Vector 2022 (desktop) has its OWN sticky header (.vector-sticky-header) that fixes itself to the real top:0 once you scroll past the page title — Minerva (mobile) has no such element, which is why mobile was already fine. Pinning section-tabs to top:0 put it directly behind Vector's header (invisible, "not sticky" from the reader's side); group-tabs' offset happened to be tall enough to mostly clear it, which is why only that bar looked fine. Both custom properties fall back to 0 (no extra offset) before the first sync, or on any skin/page without a Vector sticky header. */ #wiktku-start-form #wiktku-section-tabs { position: sticky; top: var(--wiktku-siteheader-h, 0px); z-index: 20; background: var(--wikt-card); } #wiktku-start-form #wiktku-group-tabs { position: sticky; top: calc(var(--wiktku-siteheader-h, 0px) + var(--wiktku-stabs-h, 0px)); z-index: 19; background: var(--wikt-card); } #wiktku-start-form .wiktku-group-tab, #wiktku-start-form .wiktku-section-tab { font-size: 13.5px; font-weight: 500; color: var(--wikt-ink-3); background: transparent; border: 0; border-bottom: 3px solid transparent; border-radius: var(--wikt-r-pill) var(--wikt-r-pill) 0 0; padding: 9px 14px 11px; cursor: pointer; transition: background 0.12s ease, color 0.12s ease; } #wiktku-start-form .wiktku-group-tab:hover, #wiktku-start-form .wiktku-section-tab:hover { background: var(--wikt-card-sunken); color: var(--wikt-ink); } #wiktku-start-form .wiktku-group-tab.wiktku-tab-active, #wiktku-start-form .wiktku-section-tab.wiktku-tab-active { background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom-color: var(--wikt-accent); } /* ── Progressive-disclosure toggles ────────────────────────────────── Shared by "Tercîhên pêşketî" (posparams) and "Malûmatên pêşketî" (Mane). Both are now the main way the form stays short, so they get a real affordance — a rotating chevron and a count of what is behind them — instead of a small blue link. */ #wiktku-start-form .wiktku-adv-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin: 4px 0 12px; padding-top: 16px; border-top: 1px solid var(--wikt-rule-soft); } #wiktku-start-form .wiktku-adv-toggle { display: inline-flex; align-items: center; gap: 10px; font-size: 14px; font-weight: 500; color: var(--wikt-accent); text-decoration: none; cursor: pointer; } #wiktku-start-form .wiktku-adv-toggle:hover .wiktku-adv-toggle-text { text-decoration: underline; } #wiktku-start-form .wiktku-adv-toggle-chevron { width: 22px; height: 22px; flex: 0 0 22px; display: grid; place-items: center; font-size: 11px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); border-radius: 6px; transform: rotate(-90deg); transition: transform 0.15s ease; } /* Open state: dfn flips the class on the step, posparams on the link. */ #wiktku-start-form .wiktku-adv-toggle.wiktku-adv-open .wiktku-adv-toggle-chevron, #wiktku-start-dfn:not(.wiktku-dfn-subs-hidden) .wiktku-adv-toggle-chevron { transform: rotate(0deg); } #wiktku-start-form .wiktku-posparams-adv-panel { border: 1px solid var(--wikt-rule-soft); border-radius: 12px; background: var(--wikt-card-sunken); padding: 20px 18px; margin-bottom: 4px; } /* ── posparams grid ────────────────────────────────────────────────── "Tor, ne rêz" — two columns, nothing narrower than 220px, so the six gender/number fields stop being a six-across scanline. */ @media (min-width: 721px) { #wiktku-start-form .wiktku-posparams-helpers, #wiktku-start-form .wiktku-posparams-adv-panel { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 18px 22px; align-items: start; } #wiktku-start-form .wiktku-posparams-adv-panel > .wiktku-posparams-row, #wiktku-start-form .wiktku-posparams-helpers > .wiktku-posparams-row { flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 7px; } #wiktku-start-form .wiktku-posparams-helpers > .wiktku-adv-toggle-row, #wiktku-start-form .wiktku-posparams-helpers > .wiktku-posparams-adv-panel, #wiktku-start-form .wiktku-posparams-adv-panel > .wiktku-posparams-opt-panel { grid-column: 1 / -1; } } #wiktku-start-form .wiktku-posparams-opt-panel { border-top: 1px solid var(--wikt-rule-soft); padding-top: 14px; margin-top: 4px; } #wiktku-start-form .wiktku-posparams-opt-row { font-size: 13px; color: var(--wikt-ink-3); } /* ── Sense blocks ──────────────────────────────────────────────────── Each sense is a sunken panel inside the Mane card, with its number as an accent counter — so "how many meanings am I writing" is legible at a glance. */ #wiktku-start-form .wiktku-dfn-subgroup { margin: 14px 0 0; padding-top: 14px; border-top: 1px solid var(--wikt-rule-soft); } /* Nimûne leads the list now, and a divider above the first item would be a rule against the sense's own text. (Needed explicitly: the older :first-of-type rule further up is a class selector and loses to the id-scoped one above.) */ #wiktku-start-form .wiktku-dfn-subgroup:first-of-type { margin-top: 8px; padding-top: 0; border-top: none; } #wiktku-start-form .wiktku-dfn-sublabel-term { color: var(--wikt-ink); } /* Every sense sub-field is a plain white field like any other. Older rules gave several of them a tinted fill, which read as "disabled" next to the white Mane box directly above them. */ #wiktku-start-form .wiktku-dfn-subfield, #wiktku-start-form textarea.wiktku-dfn-mane { background: var(--wikt-field-bg); border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-field); } /* No "1." "2." markers on the sub-lists. Ghybu, 14 Tebax 2026, on exactly this: numbered rows read as a form you must fill from the top down, when really each row is just "another one if you have another one" — and with a block-level textarea per row the marker also lands on its own line above the field, which looks like a stray character. */ #wiktku-start-form .wiktku-dfn-sublist { margin: 0; padding-left: 0; list-style: none; } #wiktku-start-form .wiktku-dfn-sublist > li { margin-bottom: 6px; } /* ── Chips: tags, modifiers, template pills ──────────────────────────── */ #wiktku-start-form .wiktku-mod-pill, #wiktku-start-form .wiktku-besendin-select + .wiktku-chip { background: var(--wikt-accent-tint); color: var(--wikt-accent-deep); border: 1px solid var(--wikt-accent-edge); border-radius: var(--wikt-r-pill); font-size: 13px; padding: 6px 12px; } #wiktku-start-form .wiktku-mod-btn, #wiktku-start-form .wiktku-mod-confirm, #wiktku-start-form .wiktku-mod-cancel { border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); border-radius: 8px; } /* ── Footer + buttons ──────────────────────────────────────────────── Spec: one primary pill, everything else quiet. The two red buttons sitting next to it are the loudest thing on the old screen for no reason — they become outline buttons in the danger colour instead of filled ones. */ #wiktku-start-form #wiktku-start-footer { background: var(--wikt-card-sunken); border-top: 1px solid var(--wikt-rule); border-radius: 0 0 var(--wikt-r-card) var(--wikt-r-card); padding: 16px 20px; gap: 10px; } #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement-button { border-radius: var(--wikt-r-pill) !important; font-family: var(--wikt-sans); font-size: 14px; font-weight: 500; padding: 11px 22px; box-shadow: none !important; min-height: var(--wikt-tap); } #wiktku-start-form #wiktku-unhide-editform .oo-ui-buttonElement-button { background: var(--wikt-accent) !important; border-color: var(--wikt-accent) !important; color: var(--wikt-on-accent) !important; } /* Destructive actions: outline, not fill. */ #wiktku-start-form #wiktku-start-footer .oo-ui-flaggedElement-destructive .oo-ui-buttonElement-button { background: var(--wikt-card) !important; border-color: var(--wikt-danger) !important; color: var(--wikt-danger) !important; } #wiktku-start-form #wiktku-last-saved { font-family: var(--wikt-mono); font-size: 12px; color: var(--wikt-muted); } /* ── Beşên din picker ──────────────────────────────────────────────── This dropdown is now the entry point to eighteen sections, so it gets room and a label rather than sitting flush under the tab bar. */ #wiktku-start-form .wiktku-besendin-picker { margin: 0 0 20px; padding: 16px 18px; background: var(--wikt-card); border: 1px solid var(--wikt-card-edge); border-radius: 12px; } #wiktku-start-form .wiktku-besendin-picker .wiktku-native-select-wrap, #wiktku-start-form .wiktku-besendin-picker input.wiktku-ac-input { width: 100%; max-width: 28em; } /* ── Notices ─────────────────────────────────────────────────────────── */ #wiktku-start-form .wiktku-addlang-notice { background: var(--wikt-accent-tint); border: 1px solid var(--wikt-accent-edge); border-radius: var(--wikt-r-field); color: var(--wikt-ink-2); padding: 12px 16px; margin-bottom: 16px; } #wiktku-start-form .wiktku-pron-preview { background: var(--wikt-accent-tint); border-color: var(--wikt-accent-edge); border-radius: 12px; } #wiktku-start-form .wiktku-pron-preview-confirm, #wiktku-start-form .wiktku-pron-preview-cancel { border-radius: var(--wikt-r-pill); padding: 8px 16px; min-height: 36px; } /* Links carry the accent and a soft underline, per the spec's `a` rule. */ #wiktku-start-form a { color: var(--wikt-accent); text-decoration: none; border-bottom: 1px solid var(--wikt-link-under); } #wiktku-start-form a:hover { color: var(--wikt-accent-deep); } #wiktku-start-form .wiktku-adv-toggle, #wiktku-start-form .wiktku-group-tab, #wiktku-start-form .wiktku-section-tab { border-bottom-style: solid; } #wiktku-start-form .wiktku-adv-toggle { border-bottom: 0; } /* =================================================================== Dark mode =================================================================== Every colour above is a token on #wiktku-start-form, so night mode is a swap of that one block — no rule is duplicated. Three selectors, because MediaWiki has three states and guessing wrong is worse than not supporting it: an explicit night choice, "follow my OS" plus an OS that says dark, and skins old enough to set no theme class at all (older mobile output), where prefers-color-scheme is the only signal available. The :not() chain on the last one keeps it from overriding someone who explicitly asked for day mode. The palette is warm, not neutral grey — a straight inversion of a cream design lands on blue-grey and loses the character of it. Accent lightens to #7ba7e8: #2a5db0 on a dark card is around 2.4:1, which fails contrast and reads as near-black. =================================================================== */ html.skin-theme-clientpref-night #wiktku-start-form, html.skin-nightmode #wiktku-start-form { --wikt-page: #171613; --wikt-card: #201e1a; --wikt-card-sunken: #1a1916; --wikt-card-edge: #322e28; --wikt-rule: #3a3630; --wikt-rule-soft: #2c2924; --wikt-field-edge: #4a453d; --wikt-field-bg: #191815; --wikt-code-bg: #14130f; --wikt-ink: #ece7dd; --wikt-ink-2: #d5cfc4; --wikt-ink-3: #b3aca1; --wikt-muted: #8f887c; --wikt-placeholder: #6d675e; --wikt-accent: #7ba7e8; --wikt-accent-deep: #cfe0f8; --wikt-accent-tint: #1c2839; --wikt-accent-edge: #35496b; --wikt-danger: #e5907c; --wikt-on-accent: #14213a; --wikt-link-under: rgba(123, 167, 232, 0.4); } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os #wiktku-start-form, html:not(.skin-theme-clientpref-day):not(.skin-theme-clientpref-night):not(.skin-theme-clientpref-os) #wiktku-start-form { --wikt-page: #171613; --wikt-card: #201e1a; --wikt-card-sunken: #1a1916; --wikt-card-edge: #322e28; --wikt-rule: #3a3630; --wikt-rule-soft: #2c2924; --wikt-field-edge: #4a453d; --wikt-field-bg: #191815; --wikt-code-bg: #14130f; --wikt-ink: #ece7dd; --wikt-ink-2: #d5cfc4; --wikt-ink-3: #b3aca1; --wikt-muted: #8f887c; --wikt-placeholder: #6d675e; --wikt-accent: #7ba7e8; --wikt-accent-deep: #cfe0f8; --wikt-accent-tint: #1c2839; --wikt-accent-edge: #35496b; --wikt-danger: #e5907c; --wikt-on-accent: #14213a; --wikt-link-under: rgba(123, 167, 232, 0.4); } } /* A handful of pre-design-layer rules still name literal light colours (they predate the tokens). Rather than hunt every one, neutralise the ones that actually show through in night mode. */ html.skin-theme-clientpref-night #wiktku-start-form .wiktku-ac-results, html.skin-nightmode #wiktku-start-form .wiktku-ac-results { background: var(--wikt-card); border-color: var(--wikt-rule); color: var(--wikt-ink); } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os #wiktku-start-form .wiktku-ac-results, html:not(.skin-theme-clientpref-day):not(.skin-theme-clientpref-night):not(.skin-theme-clientpref-os) #wiktku-start-form .wiktku-ac-results { background: var(--wikt-card); border-color: var(--wikt-rule); color: var(--wikt-ink); } } /* =================================================================== Autocomplete list: stop it escaping its card =================================================================== ul.wiktku-ac-results carried a hard `width: 20em` regardless of the field it belongs to. On the full-width pickers — "Çavkanî hilbijêre" is the obvious one — the list is absolutely positioned at the wrapper's left edge, so a fixed 20em runs straight past the card's right border whenever the card is narrower than that. The wrapper is shrink-to-fit around its input, so `width: 100%` here means "exactly as wide as the field I belong to" — which is what a combobox should do — while min-width keeps the short pickers readable and max-width stops either from leaving the viewport. */ #wiktku-start-form ul.wiktku-ac-results { width: 100%; min-width: min(18em, 100%); max-width: min(92vw, 34em); box-sizing: border-box; border-radius: var(--wikt-r-field); box-shadow: none; } /* And the wrapper itself must not exceed the card it sits in. */ #wiktku-start-form .wiktku-native-select-wrap { max-width: 100%; } #wiktku-start-form .wiktku-cavkani-wrap .wiktku-native-select-wrap, #wiktku-start-form .wiktku-cavkani-wrap input.wiktku-ac-input, #wiktku-start-form .wiktku-pron-wrap .wiktku-native-select-wrap, #wiktku-start-form .wiktku-etym-wrap .wiktku-native-select-wrap { width: 100%; max-width: 100%; box-sizing: border-box; } /* =================================================================== Mobile: the footer was the loudest thing on a small screen =================================================================== Four 44px-tall pills with 22px of side padding wrap into three rows and eat most of a phone viewport — and the footer is sticky, so that stays on screen the whole time. Below 720px the primary button keeps its full size (it is the one you press) and everything else shrinks to a secondary scale. =================================================================== */ @media (max-width: 720px) { #wiktku-start-form { padding: 12px; font-size: 14px; } #wiktku-start-form .wiktku-start-step { padding: 16px 14px 14px; border-radius: 12px; } #wiktku-start-form .wiktku-start-step-name { font-size: 20px !important; } #wiktku-start-form #wiktku-start-footer { padding: 10px 12px; gap: 6px; row-gap: 8px; } #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement-button { font-size: 13px; padding: 8px 14px; min-height: 38px; } /* The one you actually press stays thumb-sized. */ #wiktku-start-form #wiktku-unhide-editform .oo-ui-buttonElement-button { font-size: 14px; padding: 10px 20px; min-height: var(--wikt-tap); } /* Secondary actions share a row instead of each claiming a full one. */ #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement { flex: 0 1 auto; } #wiktku-start-form #wiktku-last-saved { flex: 1 0 100%; order: 10; font-size: 11px; white-space: normal; } #wiktku-start-form .wiktku-adv-toggle-row { gap: 8px; } } /* =================================================================== IPA character palette (v3 spec) =================================================================== Click-to-insert chart under Bilêvkirin, after fr.wiktionary's. Two sub-tabs — a short Kurmancî set that opens by default, and the full chart — because ~20 of the ~180 IPA symbols ever occur in Kurmancî and showing all of them first is the same "wall of fields" problem this redesign exists to fix. =================================================================== */ #wiktku-start-form .wiktku-ipa-panel { border: 1px solid var(--wikt-card-edge); border-radius: 12px; background: var(--wikt-card-sunken); padding: 0 0 12px; margin-bottom: 8px; overflow: hidden; } #wiktku-start-form .wiktku-ipa-subtabs { display: flex; align-items: center; gap: 4px; padding: 8px 12px 0; border-bottom: 1px solid var(--wikt-rule-soft); margin-bottom: 12px; flex-wrap: wrap; } #wiktku-start-form .wiktku-ipa-subtab { font-size: 13px; font-weight: 500; color: var(--wikt-ink-3); padding: 7px 12px 9px; border-bottom: 3px solid transparent; border-radius: 8px 8px 0 0; cursor: pointer; } #wiktku-start-form .wiktku-ipa-subtab:hover { background: var(--wikt-card); color: var(--wikt-ink); } #wiktku-start-form .wiktku-ipa-subtab.wiktku-tab-active { background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom-color: var(--wikt-accent); } /* Templates are not characters, so they sit apart from the chart — pinned to the right of the sub-tab row. */ #wiktku-start-form .wiktku-ipa-tplbtns { margin-left: auto; display: flex; gap: 6px; padding-bottom: 6px; } #wiktku-start-form .wiktku-ipa-tplbtn { font-family: var(--wikt-mono); font-size: 12px; padding: 6px 10px; border-radius: 7px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); cursor: pointer; white-space: nowrap; } #wiktku-start-form .wiktku-ipa-tplbtn:hover { border-color: var(--wikt-accent); } #wiktku-start-form .wiktku-ipa-grid { display: flex; flex-direction: column; gap: 8px; padding: 0 12px; } #wiktku-start-form .wiktku-ipa-row { display: flex; align-items: flex-start; gap: 10px; } #wiktku-start-form .wiktku-ipa-rowlabel { flex: 0 0 74px; font-size: 11.5px; color: var(--wikt-muted); padding-top: 8px; line-height: 1.3; } #wiktku-start-form .wiktku-ipa-keys { display: flex; flex-wrap: wrap; gap: 4px; flex: 1 1 auto; } #wiktku-start-form .wiktku-ipa-key { width: 30px; height: 30px; padding: 0; border-radius: 8px; border: 1px solid var(--wikt-field-edge); background: var(--wikt-field-bg); color: var(--wikt-ink); font-family: var(--wikt-mono); font-size: 14px; line-height: 1; cursor: pointer; display: grid; place-items: center; transition: background 0.1s ease, border-color 0.1s ease; } #wiktku-start-form .wiktku-ipa-key:hover { background: var(--wikt-accent-tint); border-color: var(--wikt-accent); color: var(--wikt-accent-deep); } #wiktku-start-form .wiktku-ipa-key:active { transform: translateY(1px); } /* Ligatures like d͡ʒ and long vowels need a little more room than one glyph; let those keys grow instead of clipping. */ #wiktku-start-form .wiktku-ipa-key { width: auto; min-width: 30px; padding: 0 5px; } /* A combining mark is shown on a dotted circle so it has something to attach to; only the mark itself is inserted. */ #wiktku-start-form .wiktku-ipa-key-combining { color: var(--wikt-ink-2); } @media (max-width: 720px) { #wiktku-start-form .wiktku-ipa-row { flex-direction: column; gap: 3px; } #wiktku-start-form .wiktku-ipa-rowlabel { flex: 0 0 auto; padding-top: 0; } #wiktku-start-form .wiktku-ipa-key { min-width: 34px; height: 34px; } } /* ── "+ Beş zêde bike" menu ────────────────────────────────────────── Adding a part of speech and adding Bilêvkirin are different actions, so the button opens a small menu instead of doing one of them. */ #wiktku-start-form .wiktku-addsection-menu { position: absolute; z-index: 60; margin-top: 6px; min-width: 15em; background: var(--wikt-card); border: 1px solid var(--wikt-rule); border-radius: 10px; padding: 4px; display: flex; flex-direction: column; } #wiktku-start-form .wiktku-addsection-item { display: flex; flex-direction: column; gap: 1px; padding: 8px 10px; border-radius: 7px; border-bottom: 0; text-decoration: none; color: var(--wikt-ink); } #wiktku-start-form .wiktku-addsection-item:hover { background: var(--wikt-accent-tint); } #wiktku-start-form .wiktku-addsection-item-label { font-size: 13.5px; font-weight: 500; } #wiktku-start-form .wiktku-addsection-item-hint { font-size: 11.5px; color: var(--wikt-muted); } #wiktku-start-form #wiktku-section-tabs .oo-ui-buttonElement { position: relative; } /* Bilêvkirin is a peer of the POS sections but not a part of speech — a hairline before it marks the boundary. */ #wiktku-start-form .wiktku-section-tab-pron { margin-left: 6px; border-left: 1px solid var(--wikt-rule); padding-left: 14px; border-radius: 0; } /* =================================================================== Per-sense accordion (v3 spec) =================================================================== "Tenê maneya ku tê nivîsandin vekirî ye" — each meaning is a closed box showing its own text, so a four-sense entry fits on one screen instead of scrolling for a minute. A sense with nothing in it is never collapsed: the trailing empty one is how you add the next meaning, so hiding it would hide the only way forward. =================================================================== */ #wiktku-start-form li.wiktku-dfn-sense { border: 1px solid var(--wikt-card-edge); border-radius: 12px; background: var(--wikt-card); margin-bottom: 10px; padding: 0; list-style: none; overflow: visible; } #wiktku-start-form .wiktku-dfn-sense-header { display: flex; align-items: center; gap: 10px; padding: 12px 14px; cursor: pointer; border-radius: 12px; user-select: none; } #wiktku-start-form li.wiktku-dfn-sense:not(.wiktku-sense-collapsed) .wiktku-dfn-sense-header { border-bottom: 1px solid var(--wikt-rule-soft); border-radius: 12px 12px 0 0; } #wiktku-start-form .wiktku-dfn-sense-header:hover { background: var(--wikt-card-sunken); } #wiktku-start-form .wiktku-dfn-sense-num { flex: 0 0 22px; height: 22px; border-radius: 999px; background: var(--wikt-accent); color: var(--wikt-on-accent); font-family: var(--wikt-mono); font-size: 12px; display: grid; place-items: center; } #wiktku-start-form .wiktku-dfn-sense-title { font-size: 13.5px; font-weight: 500; white-space: nowrap; } /* The summary is the point of a collapsed row, so it only shows there. */ #wiktku-start-form .wiktku-dfn-sense-summary { flex: 1 1 auto; min-width: 0; font-size: 13px; color: var(--wikt-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: none; } #wiktku-start-form li.wiktku-sense-collapsed .wiktku-dfn-sense-summary { display: block; } #wiktku-start-form .wiktku-dfn-sense-chevron { margin-left: auto; color: var(--wikt-muted); font-size: 12px; transition: transform 0.15s ease; } #wiktku-start-form li.wiktku-sense-collapsed .wiktku-dfn-sense-chevron { transform: rotate(-90deg); } #wiktku-start-form .wiktku-dfn-sense-body { padding: 14px; } #wiktku-start-form li.wiktku-sense-collapsed .wiktku-dfn-sense-body { display: none; } /* =================================================================== Template rows in the pickers (v3 spec) =================================================================== "Ti cihê ku şablon tê hilbijartin bêyî 🔗 û i namîne" — one row shape everywhere a template is chosen. Rewiye tine's original complaint was that "guharto? kevnbûyî? ku-Latn? şaşnivîs?" mean nothing to a newcomer; the ⓘ answers that without leaving the form, and the 🔗 is there for when it doesn't. =================================================================== */ #wiktku-start-form ul.wiktku-ac-results li.wiktku-ac-tplrow { display: flex; align-items: center; gap: 8px; min-height: 44px; white-space: normal; padding: 6px 10px; } #wiktku-start-form .wiktku-ac-tpltext { flex: 1 1 auto; min-width: 0; font-family: var(--wikt-mono); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* Status, not category: green is the one to reach for, yellow means "only if you specifically need it" (kevnbûyî, şaşnivîs, kêmpeyda). */ #wiktku-start-form .wiktku-tpl-dot { flex: 0 0 8px; width: 8px; height: 8px; border-radius: 999px; } #wiktku-start-form .wiktku-tpl-dot-ok { background: #3d8a55; } #wiktku-start-form .wiktku-tpl-dot-special { background: #c9971f; } #wiktku-start-form .wiktku-tpl-icons { flex: 0 0 auto; display: flex; gap: 5px; align-items: center; } #wiktku-start-form .wiktku-tpl-icon { width: 26px; height: 26px; display: grid; place-items: center; font-size: 12px; line-height: 1; cursor: pointer; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom: 1px solid var(--wikt-accent-edge); text-decoration: none; padding: 0; } #wiktku-start-form .wiktku-tpl-icon-link { border-radius: 7px; } #wiktku-start-form .wiktku-tpl-icon-info { border-radius: 999px; font-family: var(--wikt-serif); font-style: italic; font-weight: 600; background: transparent; border-color: var(--wikt-field-edge); color: var(--wikt-muted); } #wiktku-start-form .wiktku-tpl-icon:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); background: var(--wikt-accent-tint); } /* ── The ⓘ panel ───────────────────────────────────────────────────── Three parts, in the spec's order: what it does, its parameters, and a way out to the template page. */ #wiktku-start-form .wiktku-tpl-info { position: relative; margin: 8px 0 4px; padding: 14px 16px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); border-radius: 12px; font-size: 13.5px; line-height: 1.6; color: var(--wikt-ink-2); } #wiktku-start-form .wiktku-tpl-info-name { font-family: var(--wikt-mono); font-size: 13px; color: var(--wikt-accent-deep); margin-bottom: 6px; } #wiktku-start-form .wiktku-tpl-info-params { margin-top: 8px; } #wiktku-start-form .wiktku-tpl-info-params-title { font-size: 12px; color: var(--wikt-muted); margin-bottom: 2px; } #wiktku-start-form .wiktku-tpl-info-params ul { margin: 0; padding-left: 18px; font-family: var(--wikt-mono); font-size: 12.5px; } #wiktku-start-form .wiktku-tpl-info-link { display: inline-block; margin-top: 10px; font-size: 13px; } #wiktku-start-form .wiktku-tpl-info-close { position: absolute; top: 8px; right: 8px; width: 24px; height: 24px; border-radius: 999px; border: 0; background: transparent; color: var(--wikt-muted); cursor: pointer; font-size: 13px; line-height: 1; } #wiktku-start-form .wiktku-tpl-info-close:hover { background: var(--wikt-card); color: var(--wikt-ink); } /* =================================================================== Footer overflow "⋯" (v3 spec) =================================================================== Bişîne and "Edîtora çavkaniyê veke" stay on the bar; the two cache actions, the saved-at note and Tercîh move in here. Four equal-weight buttons (two of them red) made the destructive ones as loud as the one you actually want, and on a phone the sticky footer wrapped to three rows. =================================================================== */ #wiktku-start-form .wiktku-more-wrap { position: relative; margin-left: auto; flex: 0 0 auto; } #wiktku-start-form .wiktku-more-btn { width: 36px; height: 36px; border-radius: 999px; border: 1px solid var(--wikt-field-edge); background: var(--wikt-card); color: var(--wikt-muted); font-size: 16px; line-height: 1; cursor: pointer; display: grid; place-items: center; } #wiktku-start-form .wiktku-more-btn:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); } #wiktku-start-form .wiktku-more-menu { position: absolute; right: 0; bottom: calc(100% + 8px); z-index: 70; min-width: 17em; background: var(--wikt-card); border: 1px solid var(--wikt-rule); border-radius: 12px; padding: 6px; display: flex; flex-direction: column; gap: 2px; } #wiktku-start-form .wiktku-more-item { display: flex; align-items: center; gap: 8px; } /* The buttons inside the menu are menu rows, not buttons on a bar. */ #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement { flex: 1 1 auto; } #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement-button { display: block; width: 100%; text-align: left; border: 0 !important; background: transparent !important; border-radius: 7px !important; padding: 9px 10px; min-height: 0; font-weight: 400; color: var(--wikt-ink) !important; } #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement-button:hover { background: var(--wikt-accent-tint) !important; } #wiktku-start-form .wiktku-more-item-danger .oo-ui-buttonElement-button { color: var(--wikt-danger) !important; } #wiktku-start-form .wiktku-more-item-prefs .wiktku-prefs-btn { width: 26px; height: 26px; flex: 0 0 26px; border: 0; background-color: transparent; } #wiktku-start-form .wiktku-more-item-label { font-size: 13.5px; } #wiktku-start-form .wiktku-more-sep { height: 1px; background: var(--wikt-rule-soft); margin: 4px 2px; } #wiktku-start-form .wiktku-more-note { padding: 4px 10px 2px; } #wiktku-start-form .wiktku-more-note #wiktku-last-saved { white-space: normal; } /* The accordion header carries the sense number now, so the older CSS counter badge on the <li> would draw a second one behind it. Retire the counter and its indent — the header owns this. */ #wiktku-start-form ol.wiktku-dfn-list > li.wiktku-dfn-sense::before { content: none; } #wiktku-start-form ol.wiktku-dfn-list > li.wiktku-dfn-sense { padding-left: 0; padding-bottom: 0; border-bottom: 0; margin-bottom: 10px; } #wiktku-start-form ol.wiktku-dfn-list > li.wiktku-dfn-sense:not(:last-child) { padding-bottom: 0; border-bottom: 0; } /* ── "+ Mane zêde bike" ────────────────────────────────────────────── Senses are added deliberately now instead of appearing the moment you type. An always-present empty second sense read as an unfinished form on entries that only ever have one meaning. */ #wiktku-start-form .wiktku-add-sense { display: inline-flex; align-items: center; gap: 8px; margin-top: 4px; padding: 10px 18px; border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-pill); background: var(--wikt-card); color: var(--wikt-ink-2); font-family: var(--wikt-sans); font-size: 13.5px; cursor: pointer; min-height: 40px; } #wiktku-start-form .wiktku-add-sense:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); background: var(--wikt-accent-tint); } #wiktku-start-form .wiktku-add-sense-plus { color: var(--wikt-accent); font-size: 15px; line-height: 1; } /* ── Şablon picker, demoted to a link ──────────────────────────────── Picking a template replaces the definition rather than adding to it, so it is an alternative route, not the first control in the sense. Hidden behind one line of text until it is actually wanted. */ #wiktku-start-form .wiktku-dfn-tpl-link { display: inline-block; margin-top: 8px; font-size: 12.5px; color: var(--wikt-muted); border-bottom: 1px solid transparent; } #wiktku-start-form .wiktku-dfn-tpl-link:hover { color: var(--wikt-accent); border-bottom-color: var(--wikt-link-under); } #wiktku-start-form .wiktku-dfn-tpl-row { margin-top: 10px; padding-top: 12px; border-top: 1px solid var(--wikt-rule-soft); } /* ── Template-row icons on touch screens ───────────────────────────── 26px is fine for a mouse and too small for a thumb, and these two sit right next to each other at the end of a row you can also tap to select. Give them real targets and some separation on small screens. */ @media (max-width: 720px), (pointer: coarse) { #wiktku-start-form .wiktku-tpl-icon { width: 34px; height: 34px; font-size: 14px; } #wiktku-start-form .wiktku-tpl-icons { gap: 8px; padding-left: 4px; } #wiktku-start-form ul.wiktku-ac-results li.wiktku-ac-tplrow { min-height: 50px; } } /* The rendered pronunciation preview is real parser output, so it needs to sit as content rather than in the monospace wikitext treatment the panel inherits. */ #wiktku-start-form .wiktku-pron-preview-body { font-family: var(--wikt-sans); font-size: 15px; background: var(--wikt-card); border: 1px solid var(--wikt-accent-edge); border-radius: 8px; padding: 10px 12px; white-space: normal; } #wiktku-start-form .wiktku-pron-preview-body .IPA, #wiktku-start-form .wiktku-pron-preview-body code, #wiktku-start-form .wiktku-pron-preview-body tt { font-family: var(--wikt-mono); } /* Parser output brings its own margins; strip the outer ones so the preview box doesn't gain a blank first line. */ #wiktku-start-form .wiktku-pron-preview-body > *:first-child { margin-top: 0; } #wiktku-start-form .wiktku-pron-preview-body > *:last-child { margin-bottom: 0; } ph2akh7n073dc2grrbdqn5ub83ij3g6 6333826 6333819 2026-08-15T15:04:29Z Wikihez 7344 6333826 css text/css /* =================================================================== #editform while the wizard is active =================================================================== */ /* Keeps #editform genuinely laid out instead of display:none*/ .wiktku-offscreen { position: absolute !important; left: -9999px !important; top: 0 !important; width: 100%; max-width: 100%; visibility: hidden; } /* =================================================================== Base scale =================================================================== */ #wiktku-start-form { font-size: 0.92em; line-height: 1.35; } #wiktku-start-form * { box-sizing: border-box; } .wiktku-addlang-notice { margin: 0 0 0.8em; padding: 0.6em 0.8em; background: var(--wikt-palette-paleblue); border: 1px solid var(--wikt-palette-lightgrey); border-radius: 4px; } /* =================================================================== Step cards a compact card with a left accent bar, so each step reads as a distinct unit =================================================================== */ .wiktku-start-step { padding: 0.7em 0.9em; margin-bottom: 0.6em; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-left: 4px solid var(--wikt-palette-blue-9, #3366cc); border-radius: 6px; background: var(--wikt-palette-white); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); transition: border-left-color 0.15s ease, box-shadow 0.15s ease; } .wiktku-start-step:hover { box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08); } .wiktku-start-step:focus-within { border-left-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); } /* Fuses the posparams card onto the bottom of the pos card (shared left accent bar, no border/gap) since posparams always renders directly after #wiktku-start-pos once a pos is chosen. */ #wiktku-start-pos { border-radius: 6px 6px 0 0; margin-bottom: 0; border-bottom: none; } #wiktku-start-posparams { border-radius: 0 0 6px 6px; border-top: none; padding-top: 0.3em; } #wiktku-start-posparams .wiktku-start-step-name { display: none; } /* Scoped and !important: this is a real <h3> tag (see start.js), so the skin's default heading styles would otherwise override a plain class rule. Coloured to match the card's accent bar; .wiktku-start-step-question below stays lighter/muted so the two don't compete. */ #wiktku-start-form .wiktku-start-step-name { font-size: 1.1em !important; font-weight: 700; letter-spacing: 0.03em; margin: 0 0 0.3em; line-height: 1.2; color: var(--wikt-palette-blue-9, #3366cc); border: 0; padding: 0; } /* Sized close to the heading so the card reads consistently instead of the text below it looking like fine print. */ .wiktku-start-step-question { font-size: 1em; font-weight: 400; color: var(--wikt-palette-grey-9, #555); margin: 0 0 0.5em; line-height: 1.45; } .wiktku-start-step label { padding-right: 1.2em; font-size: 1em; } /* Muted hint text next to a field, styled to read as a hint rather than another question competing with .wiktku-start-step-question. */ .wiktku-step-hint { font-size: 0.88em; font-style: italic; color: var(--wikt-palette-grey-8, #72777d); margin: 0 0 0.5em; line-height: 1.4; } /* Same specificity as the rule just above, so it must come after to actually win: the name label isn't a field label needing right padding or the form's base label size, it's a heading. */ #wiktku-start-form .wiktku-start-step-name label { padding-right: 0; font-size: inherit !important; color: inherit; } input[type="text"].wiktku-start-step-field { width: 100%; padding: 5px 8px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 4px; transition: border-color 0.12s ease, box-shadow 0.12s ease; } input[type="text"].wiktku-start-step-field:focus { border-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9, #3366cc); outline: 0; } input[type="text"].wiktku-start-step-field.wiktku-start-narrow { width: 20em; } /* Only used by selects that opt out via .wiktku-plain-select; other selects get their width from the searchable picker instead (see input.wiktku-ac-input). */ select.wiktku-start-narrow, input.wiktku-dfn-tpl-title { width: 20em; max-width: 100%; box-sizing: border-box; } #wiktku-start-spinner { float: right; margin-left: 1em; } #wiktku-start-footer { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5em; padding: 0.6em 0.2em; position: sticky; bottom: 0; background: var(--wikt-palette-white); border-top: 1px solid var(--wikt-palette-grey-3, #e0e0e0); z-index: 5; } /* Quiet, non-competing text — sits next to the cache buttons so the person can tell at a glance whether their latest edits are backed up, without it fighting the buttons for attention. */ #wiktku-last-saved { font-size: 0.85em; color: var(--wikt-palette-grey-9, #767676); white-space: nowrap; } /* ── Tercîh (settings) icon button — sits in the footer next to the cache buttons. Uses the Codex "settings" (color-subtle) icon from Commons directly rather than an OOUI icon-pack module, so it renders the exact requested glyph without pulling in an extra dependency. */ .wiktku-prefs-btn { width: 2.2em; height: 2.2em; flex: 0 0 auto; padding: 0; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-radius: 2px; background-color: var(--wikt-palette-white); background-image: url(//upload.wikimedia.org/wikipedia/commons/e/e0/Codex_icon_settings_color-subtle.svg); background-repeat: no-repeat; background-position: center; background-size: 1.2em 1.2em; cursor: pointer; } .wiktku-prefs-btn:hover { background-color: var(--wikt-palette-grey-0, #f8f9fa); } .wiktku-prefs-btn:active { background-color: var(--wikt-palette-grey-1, #eaecf0); } /* Tercîh dialog body — OOUI's bare ProcessDialog body has no inset of its own, so text/fields otherwise sit flush against the window edges. */ .wiktku-prefs-dialog-body { padding: 1em 1.2em; } /* ── "Bişîne" click feedback ── */ @keyframes wiktku-btn-flash-pulse { 0% { box-shadow: 0 0 0 0 rgba(51, 102, 204, 0.55); } 70% { box-shadow: 0 0 0 9px rgba(51, 102, 204, 0); } 100% { box-shadow: 0 0 0 0 rgba(51, 102, 204, 0); } } #wiktku-unhide-editform.wiktku-btn-flash { animation: wiktku-btn-flash-pulse 0.5s ease-out; } /* Persistent state while the wikitext is being built/submitted, set alongside OOUI's own setDisabled(true) so it reads clearly even if the skin's default disabled style is subtle. */ #wiktku-unhide-editform.wiktku-btn-sending .oo-ui-buttonElement-button { background-color: var(--wikt-palette-grey-9, #767676) !important; border-color: var(--wikt-palette-grey-9, #767676) !important; cursor: progress; opacity: 1 !important; } /* Looks like OOUI's disabled state but isn't one — the button stays clickable so its handler can still run and explain why (see the wiktkuNotify call next to wiktkuContentGateOk in start.js). */ #wiktku-unhide-editform.wiktku-btn-soft-disabled .oo-ui-buttonElement-button { opacity: 0.5; cursor: not-allowed; } /* ── "Beşên din" picker ── */ .wiktku-besendin-picker { margin: 0.6em 0 1em; } .wiktku-besendin-picker .wiktku-besendin-select { width: 100%; max-width: 24em; } #wiktku-start-form textarea.wiktku-start-step-field, #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield { resize: vertical !important; overflow: auto !important; box-sizing: border-box !important; vertical-align: top; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; transition: border-color 0.1s ease, box-shadow 0.1s ease; } /* Modern focus state to match the searchable-picker inputs. */ #wiktku-start-form textarea.wiktku-start-step-field:focus, #wiktku-start-form textarea.wiktku-start-narrow:focus, #wiktku-start-form textarea.wiktku-dfn-subfield:focus { border-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9, #3366cc); outline: 0; } /* Standard: every textarea in the form is full width by default */ #wiktku-start-form textarea:not(.wiktku-start-narrow) { width: 100%; max-width: 100%; box-sizing: border-box; } #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield.wiktku-start-narrow { width: 20em; max-width: 100%; min-width: 8em; height: calc(1.7em + 10px); min-height: calc(1.7em + 10px); padding-top: 4px !important; padding-bottom: 4px !important; line-height: 1.35 !important; resize: none !important; } /* Exception: "Sernav" / "Sernavê orjînal" citation-source fields (kitêb, kovar, malper, …) — long enough to be worth 2 rows and manual resizing. */ #wiktku-start-form textarea.wiktku-dfn-quote-src-input.wiktku-dfn-quote-src-input--title { height: calc(2 * 1.35em + 10px); min-height: calc(2 * 1.35em + 10px); } /* ── Manual drag-to-resize handle ── */ #wiktku-start-form textarea:not(.wiktku-start-narrow) { resize: none !important; } /* Inline modifier button (⊕) */ .wiktku-word-li { display: flex; align-items: flex-start; flex-wrap: wrap; gap: 0.3em; } .wiktku-mod-btn { flex: 0 0 auto; width: 1.6em; height: 1.6em; padding: 0; line-height: 1; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); color: var(--wikt-palette-blue-9, #3366cc); font-size: 1em; cursor: pointer; } .wiktku-mod-btn:hover { border-color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-paleblue, #eaf3ff); } .wiktku-mod-picker { display: flex; flex-wrap: wrap; gap: 0.25em; width: 100%; margin-top: 0.15em; padding: 0.35em; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; background: var(--wikt-palette-white); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); } .wiktku-mod-pill { padding: 2px 8px; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-radius: 12px; background: var(--wikt-palette-paleblue, #eaf3ff); font-size: 0.85em; white-space: nowrap; cursor: pointer; } .wiktku-mod-pill:hover { border-color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); } .wiktku-mod-pill:disabled, .wiktku-mod-pill.wiktku-mod-pill-used { border-color: var(--wikt-palette-grey-3, #e0e0e0); background: var(--wikt-palette-lightgrey); color: var(--wikt-palette-grey-3, #999); cursor: not-allowed; opacity: 0.6; } .wiktku-mod-pill:disabled:hover, .wiktku-mod-pill.wiktku-mod-pill-used:hover { border-color: var(--wikt-palette-grey-3, #e0e0e0); background: var(--wikt-palette-lightgrey); color: var(--wikt-palette-grey-3, #999); } .wiktku-mod-val-wrap { display: flex; align-items: center; gap: 0.25em; width: 100%; margin-top: 0.15em; } .wiktku-mod-val-input { flex: 0 1 14em; max-width: 14em; padding: 3px 6px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; } .wiktku-mod-confirm, .wiktku-mod-cancel { flex: 0 0 auto; width: 1.6em; height: 1.6em; padding: 0; line-height: 1; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); cursor: pointer; } .wiktku-mod-confirm { color: #178a17; border-color: #178a17; } .wiktku-mod-cancel { color: var(--wikt-palette-red-9, #d33); border-color: var(--wikt-palette-red-9, #d33); } .wiktku-resize-wrap { position: relative; display: block; } /* Separate from .wiktku-resize-wrap (used only for textareas flagged with a linebreak); plain position:relative anchor for the backdrop, no size of its own. */ .wiktku-linebreak-wrap { position: relative; display: block; } .wiktku-resize-grip { position: absolute; right: 2px; bottom: 2px; width: 14px; height: 14px; cursor: ns-resize; touch-action: none; opacity: 0.5; z-index: 2; background-image: linear-gradient(135deg, transparent 0 50%, var(--wikt-palette-grey-9, #767676) 50% 100%); background-repeat: no-repeat; } .wiktku-resize-grip:hover, .wiktku-resize-grip:active { opacity: 0.9; } /* =================================================================== Searchable dropdown (wrapNativeSelect in start.js) .wiktku-native-select-wrap > input.wiktku-ac-input (search box) > ul.wiktku-ac-results (result list) > select (hidden, holds the value) =================================================================== */ .wiktku-native-select-wrap { display: inline-block; position: relative; vertical-align: top; } /* Matches the width the native select would have had (see select.wiktku-start-narrow). */ .wiktku-native-select-wrap input[type="search"], input.wiktku-ac-input { display: block; width: 20em; max-width: 100%; box-sizing: border-box; padding: 3px 6px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); color: inherit; font-size: inherit; font-family: inherit; transition: border-color 0.1s ease, box-shadow 0.1s ease; } input.wiktku-ac-input:focus { border-color: var(--wikt-palette-blue-9); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9); outline: 0; } input.wiktku-ac-input::placeholder { color: var(--wikt-palette-grey-9); opacity: 1; } /* Hide Safari/Chrome's built-in search decorations. */ input.wiktku-ac-input::-webkit-search-decoration, input.wiktku-ac-input::-webkit-search-cancel-button, input.wiktku-ac-input::-webkit-search-results-button { -webkit-appearance: none; appearance: none; } /* ── Result list ── */ /* top/bottom/max-height are overridden inline by showResults() when it flips the list above the box; these are just its defaults. */ ul.wiktku-ac-results { position: absolute; z-index: 9999; top: 100%; bottom: auto; left: 0; margin: 0; padding: 0; list-style: none; width: 20em; max-width: 90vw; max-height: 13em; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; background: var(--wikt-palette-white); border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; box-shadow: 0 3px 10px rgba(0, 0, 0, 0.15); } ul.wiktku-ac-results li { margin: 0; padding: 4px 8px; cursor: pointer; font-size: 0.92em; display: flex; align-items: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* .wiktku-ac-active is the keyboard cursor; hover mirrors it; :active covers the touch press state. */ ul.wiktku-ac-results li.wiktku-ac-active, ul.wiktku-ac-results li:hover { background: var(--wikt-palette-lightblue); } ul.wiktku-ac-results li:active { background: var(--wikt-palette-blue-9); color: var(--wikt-palette-white); } /* Touch devices: bigger tap targets, no sticky hover. */ @media (pointer: coarse) { ul.wiktku-ac-results li { padding: 6px 10px; min-height: 2.2em; font-size: 1em; } ul.wiktku-ac-results li:hover { background: transparent; } ul.wiktku-ac-results li.wiktku-ac-active { background: var(--wikt-palette-lightblue); } input.wiktku-ac-input { /* >=16px stops iOS Safari zooming the page when the box is focused. */ font-size: 16px; min-height: 2.2em; } } /* Inline preview + confirm panel shown before inserting an auto-content pronunciation template, part of the form layout rather than a browser confirm()/prompt() dialog. */ .wiktku-pron-preview { margin: 6px 0; padding: 8px 10px; border: 1px solid var(--wikt-palette-blue-9, #3366cc); border-radius: 6px; background: var(--wikt-palette-paleblue, #eaf3ff); } .wiktku-pron-preview-label { font-size: 0.88em; font-weight: 600; color: var(--wikt-palette-grey-9, #555); margin-bottom: 3px; } .wiktku-pron-preview-body { font-family: monospace; font-size: 1em; white-space: pre-wrap; word-break: break-word; margin-bottom: 6px; } .wiktku-pron-preview-actions { display: flex; gap: 6px; } .wiktku-pron-preview-confirm, .wiktku-pron-preview-cancel { font-size: 0.88em; padding: 3px 10px; border-radius: 4px; cursor: pointer; border: 1px solid var(--wikt-palette-lightgrey, #a2a9b1); background: var(--wikt-palette-white, #fff); } .wiktku-pron-preview-confirm { border-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-blue-9, #3366cc); font-weight: 600; } .wiktku-pron-preview-confirm:disabled { opacity: 0.5; cursor: wait; } .wiktku-pron-preview-cancel:hover { background: var(--wikt-palette-grey-0, #f8f9fa); } /* Template pickers fill their container since the search box, not the <select>, is what the user sees. */ .wiktku-pron-wrap .wiktku-native-select-wrap, .wiktku-etym-wrap .wiktku-native-select-wrap, .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { width: 100%; } .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 0.88em; } .wiktku-cavkani-wrap .wiktku-native-select-wrap, .wiktku-cavkani-wrap .wiktku-native-select-wrap input.wiktku-ac-input { width: 100%; } /* Template selector inside a sense block. */ .wiktku-dfn-tpl-row .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 0.88em; } /* Language/dialect rows: picker must line up with the word field beside it. */ .wiktku-lang-row .wiktku-native-select-wrap { flex: 0 0 auto; } #wiktku-start-form textarea.wiktku-dfn-mane, #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t, #wiktku-start-form textarea.wiktku-dfn-quote-src-manual, #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text, #wiktku-start-form .wiktku-tewandin-wrap textarea.wiktku-tewandin-text, #wiktku-start-form textarea.wiktku-cavkani-text, #wiktku-start-form textarea.wiktku-dfn-tercime, #wiktku-start-form textarea.wiktku-dfn-izah { --wiktku-ta-rows: 2; height: calc(var(--wiktku-ta-rows) * 1.35em + 6px); min-height: calc(var(--wiktku-ta-rows) * 1.35em + 6px); } #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text, #wiktku-start-form textarea.wiktku-dfn-izah { --wiktku-ta-rows: 3; } #wiktku-start-form textarea.wiktku-cavkani-text { --wiktku-ta-rows: 4; } /* Nimûne + Jêgirtin (citation) boxes, and their tr/t sub-fields: at least 4 rows so there's room to actually write an example/quote. */ #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t, #wiktku-start-form textarea.wiktku-dfn-quote-src-manual { --wiktku-ta-rows: 4; } /* Nudges the border when the box contains a typed/pasted linebreak, so the user notices before it's silently turned into <br> on output; the break itself is marked via a mirrored backdrop layer (see below). */ #wiktku-start-form textarea.wiktku-has-linebreak { border-color: var(--wikt-palette-yellow6, #ac6600) !important; } /* Sits behind the textarea showing the same text, with a highlighted marker at each line followed by a break; font/padding/line-height are copied from the textarea via computed style, not shared CSS classes. */ .wiktku-linebreak-backdrop { position: absolute; inset: 0; z-index: 0; margin: 0; overflow: hidden; white-space: pre-wrap; word-wrap: break-word; color: transparent; background: transparent !important; border-color: transparent !important; box-shadow: none !important; resize: none !important; pointer-events: none; } /* Raise the real textarea above its backdrop so typing/selection/caret behave completely normally; the backdrop's mark shows through only where the real textarea's own background is transparent. */ #wiktku-start-form textarea.wiktku-has-linebreak-source { position: relative; z-index: 1; background-color: transparent; } .wiktku-linebreak-mark { background-color: var(--wikt-palette-yellow6, #ac6600); color: var(--wikt-palette-white, #fff); border-radius: 2px; } /* ── Tercime + Îzah boxes ── */ .wiktku-dfn-nonku-wrap { display: flex; flex-direction: column; gap: 3px; } .wiktku-dfn-nimune-sub, .wiktku-dfn-quote-sub { margin-top: 3px; margin-left: 1em; padding-left: 0.6em; border-left: 2px solid var(--wikt-palette-lightgrey); display: flex; flex-direction: column; gap: 3px; } .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t { min-width: 8em; padding-top: 2px !important; padding-bottom: 2px !important; line-height: 1.35 !important; font-size: 0.88em; } /* ── Sense list (Mane step) — numbered badges instead of the browser's default flat "1." marker, so each sense reads as a distinct block. ── */ ol.wiktku-dfn-list { list-style: none; margin: 0; padding: 0; counter-reset: wiktku-dfn-sense; } ol.wiktku-dfn-list > li.wiktku-dfn-sense { position: relative; counter-increment: wiktku-dfn-sense; padding-left: 2.1em; margin-bottom: 0.9em; } ol.wiktku-dfn-list > li.wiktku-dfn-sense:not(:last-child) { padding-bottom: 0.9em; border-bottom: 1px dashed var(--wikt-palette-grey-3, #e0e0e0); } ol.wiktku-dfn-list > li.wiktku-dfn-sense::before { content: counter(wiktku-dfn-sense); position: absolute; left: 0; top: 1px; width: 1.6em; height: 1.6em; border-radius: 50%; background: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); font-size: 0.85em; font-weight: 700; display: flex; align-items: center; justify-content: center; } /* Template selector row inside a sense block */ .wiktku-dfn-tpl-row { margin-bottom: 3px; } /* ── Sub-field titles (Etîket, Kategorî, Hevmane, Dijmane, Nimûne, Jêgirtin, …): each group reads as a small labelled field — the term stands out, the hint stays quiet. ── */ .wiktku-dfn-subgroup { margin-top: 0.5em; padding-top: 0.4em; border-top: 1px dashed var(--wikt-palette-grey-3, #e0e0e0); } .wiktku-dfn-subgroup:first-of-type { margin-top: 0.3em; padding-top: 0; border-top: none; } .wiktku-dfn-sublabel { display: block; margin-bottom: 3px; font-size: 0.88em; } .wiktku-dfn-sublabel-term { font-weight: 600; color: var(--wikt-palette-blue-9, #3366cc); letter-spacing: 0.03em; font-size: 0.92em; } .wiktku-dfn-sublabel-hint { color: var(--wikt-palette-grey-9, #767676); font-style: italic; } .wiktku-pron-wrap, .wiktku-etym-wrap, .wiktku-tewandin-wrap, .wiktku-cavkani-wrap { display: flex; flex-direction: column; gap: 3px; } /* ── POS section tabs — rounded pill style ── */ #wiktku-section-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 0.6em; align-items: center; } #wiktku-section-tabs .wiktku-section-tab { padding: 3px 12px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 999px; background: var(--wikt-palette-dullcyan); cursor: pointer; font-size: 0.86em; user-select: none; transition: background 0.12s ease, border-color 0.12s ease; } #wiktku-section-tabs .wiktku-section-tab:hover { border-color: var(--wikt-palette-blue-9, #3366cc); } #wiktku-section-tabs .wiktku-section-tab.wiktku-tab-active { background: var(--wikt-palette-blue-9, #3366cc); border-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); font-weight: 600; } /* ── Step-group tabs (Mane / Bilêvkirin / Beşên din — see STEP_GROUPS in start.js) ── Sits directly under the pill-style section tabs above; styled as an underlined secondary nav so the two bars stay visually distinct. */ #wiktku-group-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 0.8em; border-bottom: 2px solid var(--wikt-palette-lightgrey); } #wiktku-group-tabs .wiktku-group-tab { position: relative; padding: 7px 14px 8px; margin-bottom: -2px; border-bottom: 3px solid transparent; border-radius: 3px 3px 0 0; cursor: pointer; font-size: 0.95em; font-weight: 600; color: var(--wikt-palette-grey-9, #333); background: var(--wikt-palette-grey-0, #f8f9fa); user-select: none; transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease; } #wiktku-group-tabs .wiktku-group-tab:hover { color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-paleblue, #eaf3ff); } #wiktku-group-tabs .wiktku-group-tab.wiktku-tab-active { border-bottom-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); background: var(--wikt-palette-blue-9, #3366cc); font-weight: 700; } /* Small dot marking a tab that still has an unfilled required field hidden inside it (see updateGroupTabIndicators in start.js). Cleared automatically once that tab becomes the active one. */ #wiktku-group-tabs .wiktku-group-tab.wiktku-tab-missing::after { content: ""; position: absolute; top: 4px; right: -1px; width: 6px; height: 6px; border-radius: 50%; background: var(--wikt-palette-red-9, #d33); } .wiktku-lang-row-list { margin: 0; padding: 0; list-style: none; } .wiktku-lang-row { display: flex; align-items: flex-start; gap: 6px; margin-bottom: 3px; flex-wrap: wrap; } .wiktku-lang-row-words { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 3px; } /* Dûnde/Werger/Zarava rows: align the picker's height with the adjacent word textarea (see .wiktku-start-narrow above). */ .wiktku-lang-row .wiktku-native-select-wrap input.wiktku-ac-input { height: calc(1.7em + 10px); min-height: calc(1.7em + 10px); padding-top: 4px; padding-bottom: 4px; } /* ── Werger / Bi zaravayên din groups: one per gloss, shared spacing ── */ #wiktku-start-trans .wiktku-trans-group, #wiktku-start-zarava .wiktku-zarava-group { margin-bottom: 0.6em; } #wiktku-start-trans .wiktku-trans-group:last-child, #wiktku-start-zarava .wiktku-zarava-group:last-child { margin-bottom: 0; } #wiktku-start-trans .wiktku-trans-group-label, #wiktku-start-zarava .wiktku-zarava-group-label { font-weight: 600; font-size: 0.88em; margin-bottom: 3px; } .wiktku-dfn-jeder-group { margin-top: 3px; } .wiktku-dfn-quote-src-sel { font-size: 0.88em; margin-top: 3px; display: block; } .wiktku-dfn-quote-src-fields { display: flex; flex-direction: column; gap: 3px; margin-top: 3px; } /* Stacked layout: textarea gets its own full-width row, button + status sit below it on their own row. */ .wiktku-dfn-quote-citoid { display: flex; flex-direction: column; align-items: stretch; gap: 0.4em; margin-top: 3px; margin-bottom: 3px; } .wiktku-dfn-quote-citoid-input { width: 100%; max-width: 100%; box-sizing: border-box; } /* Column flex + align-items:stretch (above) makes the textarea's .wiktku-resize-wrap reach full width automatically; button and status text opt back out via align-self so they keep their natural size. */ .wiktku-dfn-quote-citoid-btn, .wiktku-dfn-quote-citoid-status { align-self: flex-start; } .wiktku-dfn-quote-src-cat-status { display: block; font-size: 0.82em; color: var(--wikt-palette-lightgrey, #767676); margin-top: 2px; } .wiktku-dfn-quote-src-row { display: flex; align-items: baseline; gap: 4px; flex-wrap: wrap; } .wiktku-dfn-quote-src-row label { font-size: 0.82em; white-space: nowrap; min-width: 8em; } textarea.wiktku-dfn-quote-src-input { flex: 1 1 12em; max-width: 100%; box-sizing: border-box; } @media (max-width: 720px) { .wiktku-lang-row { flex-direction: column; } /* Re-asserts against the skin's own mobile-breakpoint heading styles, which load after ours in the cascade. */ #wiktku-start-form .wiktku-start-step-name { font-size: 1.05em !important; margin: 0 0 0.2em !important; line-height: 1.2 !important; border: 0 !important; padding: 0 !important; } /* Single column: search box, list, and narrow textareas (Etîket, Hevmane, Dûnde/Jê/Têkildar/Binêre herwiha word boxes, citation source fields, …) all use the full width. */ .wiktku-native-select-wrap, input.wiktku-ac-input, ul.wiktku-ac-results, #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield.wiktku-start-narrow { width: 100%; max-width: 100%; } .wiktku-mod-val-input { flex: 1 1 auto; max-width: 100%; } #wiktku-start-form textarea.wiktku-dfn-mane, #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text { --wiktku-ta-rows: 3; font-size: 1em; } #wiktku-start-form .wiktku-tewandin-wrap textarea.wiktku-tewandin-text, #wiktku-start-form textarea.wiktku-cavkani-text { --wiktku-ta-rows: 4; font-size: 1em; } /* Nimûne + Jêgirtin and their tr/t sub-fields: keep at least 4 rows on mobile too, rather than shrinking further than the desktop size. */ #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t { --wiktku-ta-rows: 4; font-size: 1em; } /* Citoid URL/DOI/ISBN box: taller tap target (~2 lines) on mobile, and now that this field is a <textarea> (see start.js) its placeholder can actually wrap into that space — a plain <input>'s placeholder can never wrap, no matter its height. */ .wiktku-dfn-quote-citoid-input { min-height: calc(2 * 1.35em + 10px); font-size: 1em; } .wiktku-dfn-nimune-sub, .wiktku-dfn-quote-sub { margin-left: 0.5em; padding-left: 0.4em; } .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 1em; min-height: 2.2em; } .wiktku-dfn-quote-src-row label { min-width: 6em; } #wiktku-start-form textarea.wiktku-dfn-quote-src-input { width: 100%; flex: 1 1 100%; } .wiktku-start-step { padding: 0.5em 0.6em; } } /* =================================================================== Night mode Palette.css already flips --wikt-palette-* vars for night mode; this hook only covers real colours (panel border) that aren't a palette var, since a drop shadow is invisible against an equally dark page. =================================================================== */ @media screen { html.skin-theme-clientpref-night .wiktku-ac-results { /* Border stands in for the shadow, invisible on a dark page. */ border-color: var(--wikt-palette-grey-5); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.6); } html.skin-theme-clientpref-night .wiktku-start-step, html.skin-theme-clientpref-night .wiktku-start-step:hover, html.skin-theme-clientpref-night .wiktku-start-step:focus-within { box-shadow: none; } } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os .wiktku-ac-results { border-color: var(--wikt-palette-grey-5); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.6); } html.skin-theme-clientpref-os .wiktku-start-step, html.skin-theme-clientpref-os .wiktku-start-step:hover, html.skin-theme-clientpref-os .wiktku-start-step:focus-within { box-shadow: none; } } /* "Zimanek lê zêde bike" portlet icon (Minerva/mobile) — Feather-core-edit.svg via CSS mask, matching Minerva's own icon pattern. */ .minerva-icon-portletlink-ca-wiktku-addlang { -webkit-mask-image: url("https://upload.wikimedia.org/wikipedia/commons/d/d7/Feather-core-edit.svg"); mask-image: url("https://upload.wikimedia.org/wikipedia/commons/d/d7/Feather-core-edit.svg"); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-position: center; mask-position: center; -webkit-mask-size: 20px; mask-size: 20px; background-color: currentColor; background-image: none; } /* ── posparams step (live wikitext + helper widgets) ── */ .wiktku-posparams-wrap { display: flex; flex-direction: column; gap: 6px; } .wiktku-posparams-helpers { display: flex; flex-direction: column; gap: 4px; } .wiktku-posparams-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; } .wiktku-posparams-row label { font-size: 1em; min-width: 10em; padding-right: 0; } .wiktku-posparams-text { width: 100%; box-sizing: border-box; font-family: monospace; font-size: 0.9em; } .wiktku-posparams-opt-toggle { font-size: 0.85em; margin-top: 2px; display: inline-block; } .wiktku-posparams-opt-panel { display: flex; flex-direction: column; gap: 2px; padding: 4px 0 2px 1em; } .wiktku-posparams-opt-row { display: flex; align-items: center; gap: 4px; font-size: 0.85em; } /* ── resim step (one or more images) ── */ .wiktku-resim-list { display: flex; flex-direction: column; gap: 6px; } .wiktku-resim-item { display: flex; flex-direction: column; gap: 4px; } .wiktku-resim-item .wiktku-posparams-row { flex-direction: column; align-items: flex-start; gap: 2px; } .wiktku-resim-item .wiktku-posparams-row label { min-width: 0; font-size: 0.9em; } /* ── dfn: "hide/show all subsections" link ── Toggles a class on the whole dfn stepDiv so one click hides the etîket/kategorî/hevmane/dijmane/nimûne/jêgirtin/etc. subgroups across every sense block at once. */ .wiktku-dfn-subs-toggle { font-size: 0.85em; font-weight: 500; display: inline-block; margin: 2px 0 8px; color: var(--wikt-palette-blue-9, #3366cc); text-decoration: none; } .wiktku-dfn-subs-toggle:hover { text-decoration: underline; } /* Only the ADVANCED subgroups collapse: Nimûne, Jêgirtin, Hevmane and Dijmane stay open because they are what people come here to fill in. */ #wiktku-start-form li.wiktku-sense-adv-hidden .wiktku-dfn-subgroup-adv { display: none !important; } /* The toggle sits between the primary groups and the advanced ones, so it needs no rule of its own beyond a little breathing room. */ #wiktku-start-form .wiktku-sense-adv-row { margin-top: 14px; } /* =================================================================== Desktop text bump Modifier pills/buttons and posparams helper text read fine at their small mobile sizes but look too small on desktop, so bump them up past the 720px breakpoint only. =================================================================== */ @media (min-width: 721px) { .wiktku-mod-btn, .wiktku-mod-confirm, .wiktku-mod-cancel { width: 1.8em; height: 1.8em; font-size: 1.1em; } .wiktku-mod-pill { font-size: 0.95em; padding: 3px 10px; } .wiktku-mod-val-input { font-size: 0.95em; } .wiktku-posparams-row label { font-size: 1em; } .wiktku-posparams-text { font-size: 1em; } .wiktku-posparams-opt-toggle { font-size: 0.95em; } .wiktku-posparams-opt-row { font-size: 0.95em; } .wiktku-dfn-subs-toggle { font-size: 0.95em; } /* Multi-column card layout for posparams helper fields (transliteration, gendered forms, comparative/superlative, hanja, verb-tense roots, …), desktop-only. Rows are shown/hidden via jQuery inline display; the grid only rearranges visible rows, not which ones are visible. */ .wiktku-posparams-helpers { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px 16px; align-items: start; } .wiktku-posparams-helpers > .wiktku-posparams-row { flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 3px; } .wiktku-posparams-helpers > .wiktku-posparams-row label { min-width: 0; } .wiktku-posparams-helpers > .wiktku-posparams-row .wiktku-posparams-field, .wiktku-posparams-helpers > .wiktku-posparams-row select.wiktku-posparams-cinsiyet-sel, .wiktku-posparams-helpers > .wiktku-posparams-row select.wiktku-posparams-lektur-sel { width: 100%; max-width: 100%; box-sizing: border-box; } /* The "Jimar" row lives here too — just another .wiktku-posparams-row, no extra CSS needed. */ /* These two aren't per-field rows — span the full card width so the collapsed toggle and its checkbox list don't get squeezed into one narrow column. */ .wiktku-posparams-helpers > .wiktku-posparams-opt-toggle, .wiktku-posparams-helpers > .wiktku-posparams-opt-panel { grid-column: 1 / -1; } } /* =================================================================== SÊWIRANA NÛ — design system layer =================================================================== Purely the visual skin (colour, type, weight, radius, spacing), layered after the layout rules above so it wins the cascade. No @import of Spectral / IBM Plex from Google Fonts: Wikimedia's CSP blocks third-party font hosts, so the stacks below name the spec's faces first (used if the wiki installs them locally) and fall back to faces with the same feel. Accent colour is reserved for actionable elements (focus, links, the active tab, the primary button, chips); section headings are near-black. =================================================================== */ #wiktku-start-form { /* Surfaces */ --wikt-page: #f4efe5; --wikt-card: #fffdf8; --wikt-card-sunken: #fbf8f1; --wikt-rule: #ded6c8; /* structural hairline */ --wikt-rule-soft: #efe8db; /* inside a card */ --wikt-field-edge: #cfc7b8; --wikt-field-bg: #fff; --wikt-code-bg: #f7f4ec; --wikt-card-edge: #e6dfd2; /* Ink */ --wikt-ink: #1c1a17; --wikt-ink-2: #3d3830; --wikt-ink-3: #57514a; --wikt-muted: #8a8378; --wikt-placeholder: #b3ab9e; /* Accent + status */ --wikt-accent: #2a5db0; --wikt-accent-deep: #22406f; --wikt-accent-tint: #eef2fa; --wikt-accent-edge: #d5def0; --wikt-danger: #9c3a28; --wikt-on-accent: #fff; /* text on a filled accent button */ --wikt-link-under: rgba(42, 93, 176, 0.35); /* Shape */ --wikt-r-field: 10px; --wikt-r-card: 14px; --wikt-r-pill: 999px; --wikt-tap: 44px; /* minimum field height */ --wikt-serif: Spectral, "Iowan Old Style", Georgia, "Times New Roman", serif; --wikt-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif; --wikt-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-family: var(--wikt-sans); font-size: 15px; line-height: 1.55; color: var(--wikt-ink); background: var(--wikt-page); padding: 24px; border-radius: var(--wikt-r-card); } /* ── Cards ─────────────────────────────────────────────────────────── Flat cream panel held by a single hairline border, no shadow. */ #wiktku-start-form .wiktku-start-step { background: var(--wikt-card); border: 1px solid var(--wikt-card-edge); border-left: 1px solid var(--wikt-card-edge); border-radius: var(--wikt-r-card); box-shadow: none; padding: 24px 24px 20px; margin-bottom: 16px; transition: border-color 0.12s ease; } #wiktku-start-form .wiktku-start-step:hover, #wiktku-start-form .wiktku-start-step:focus-within { box-shadow: none; border-color: var(--wikt-rule); } /* The fused pos + posparams pair keeps reading as one card. */ #wiktku-start-form #wiktku-start-pos { border-radius: var(--wikt-r-card) var(--wikt-r-card) 0 0; border-bottom: none; padding-bottom: 8px; } #wiktku-start-form #wiktku-start-posparams { border-radius: 0 0 var(--wikt-r-card) var(--wikt-r-card); border-top: none; padding-top: 4px; } /* ── Type ──────────────────────────────────────────────────────────── Step headings: serif, regular weight, near-black. */ #wiktku-start-form .wiktku-start-step-name { font-family: var(--wikt-serif); font-size: 24px !important; font-weight: 400; letter-spacing: -0.01em; line-height: 1.15; color: var(--wikt-ink); margin: 0 0 12px; } /* display:block matters: this is a <label>, so it was sharing a line with the control it introduces wherever start.js didn't emit a <br>. */ #wiktku-start-form .wiktku-start-step-question { display: block; font-size: 15px; font-weight: 400; color: var(--wikt-ink-3); margin: 0 0 12px; line-height: 1.6; max-width: 62ch; } /* Collapses the label entirely when empty (posparams' "Cins/zayend" title can be blank) instead of leaving its margin behind as a gap; a no-op for every other step, whose question text is never empty. */ #wiktku-start-form .wiktku-start-step-question:empty { display: none; margin: 0; } /* Same reason — a field label belongs above its field, not beside it. */ #wiktku-start-form .wiktku-posparams-row label, #wiktku-start-form .wiktku-dfn-sublabel { display: block; margin-bottom: 6px; padding-right: 0; } /* Field labels: small, medium weight, full-strength ink — they label a control, so they should not read as body copy. */ #wiktku-start-form .wiktku-start-step label, #wiktku-start-form .wiktku-posparams-row label, #wiktku-start-form .wiktku-dfn-sublabel { font-size: 13px; font-weight: 500; color: var(--wikt-ink); letter-spacing: 0.01em; } /* The parenthetical/example half of a label is supporting text. */ #wiktku-start-form .wiktku-dfn-sublabel-hint, #wiktku-start-form .wiktku-step-hint { font-weight: 400; font-style: italic; color: var(--wikt-muted); font-size: 12.5px; } /* ── Fields ────────────────────────────────────────────────────────── One shape for every control: 1px edge, 10px radius, 44px tall. */ #wiktku-start-form input[type="text"], #wiktku-start-form input[type="search"], #wiktku-start-form input.wiktku-ac-input, #wiktku-start-form textarea, #wiktku-start-form select { font-family: var(--wikt-sans); font-size: 15px; color: var(--wikt-ink); background: var(--wikt-field-bg); border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-field); padding: 10px 14px; box-shadow: none; transition: border-color 0.12s ease, box-shadow 0.12s ease; } #wiktku-start-form input[type="text"], #wiktku-start-form input[type="search"], #wiktku-start-form select { min-height: var(--wikt-tap); } #wiktku-start-form textarea { line-height: 1.6; } /* Wikitext and anything template-shaped reads as code. */ #wiktku-start-form .wiktku-posparams-text, #wiktku-start-form .wiktku-pron-text, #wiktku-start-form .wiktku-etym-text, #wiktku-start-form .wiktku-cavkani-text, #wiktku-start-form .wiktku-tewandin-text, #wiktku-start-form .wiktku-pron-preview-body { font-family: var(--wikt-mono); font-size: 13.5px; background: var(--wikt-code-bg); border-color: var(--wikt-card-edge); } #wiktku-start-form ::placeholder { color: var(--wikt-placeholder); opacity: 1; } /* Focus: accent edge + 3px tint halo. The only "elevation" in the design. */ #wiktku-start-form input[type="text"]:focus, #wiktku-start-form input[type="search"]:focus, #wiktku-start-form textarea:focus, #wiktku-start-form select:focus, #wiktku-start-form input.wiktku-ac-input:focus { border-color: var(--wikt-accent); box-shadow: 0 0 0 3px var(--wikt-accent-tint); outline: 0; } /* The searchable picker's visible input is the field, so it takes the field shape too (it otherwise inherits an older, boxier rule). */ #wiktku-start-form input.wiktku-ac-input { min-height: var(--wikt-tap); border-radius: var(--wikt-r-field); border-color: var(--wikt-field-edge); font-size: 15px; } #wiktku-start-form .wiktku-ac-results { border: 1px solid var(--wikt-rule); border-radius: var(--wikt-r-field); background: var(--wikt-card); box-shadow: none; } #wiktku-start-form .wiktku-ac-results li.wiktku-ac-active, #wiktku-start-form .wiktku-ac-results li:hover { background: var(--wikt-accent-tint); color: var(--wikt-accent-deep); } /* ── Tabs → the accent's main job ──────────────────────────────────── Active tab: tint fill + 3px accent underline, per the spec's "xala hûrgulî" note. Inactive tabs are plain text. */ #wiktku-start-form #wiktku-group-tabs, #wiktku-start-form #wiktku-section-tabs { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; border-bottom: 1px solid var(--wikt-rule); margin-bottom: 16px; padding-bottom: 0; } /* Both bars are direct children of #wiktku-start-form, so a sticky child stays stuck for as long as any part of the form is in view. Background is opaque so content scrolling underneath doesn't show through. Section-tabs pins below --wiktku-siteheader-h — an offset for Vector 2022's own sticky header, which otherwise sits on top of it at top:0 (Minerva has no such header, so mobile needs no offset); group-tabs pins below that plus --wiktku-stabs-h (section-tabs' own height). Both custom properties are set by syncStickyTabsOffset() in start.js and fall back to 0 on skins without a Vector sticky header. */ #wiktku-start-form #wiktku-section-tabs { position: sticky; top: var(--wiktku-siteheader-h, 0px); z-index: 20; background: var(--wikt-card); } #wiktku-start-form #wiktku-group-tabs { position: sticky; top: calc(var(--wiktku-siteheader-h, 0px) + var(--wiktku-stabs-h, 0px)); z-index: 19; background: var(--wikt-card); } #wiktku-start-form .wiktku-group-tab, #wiktku-start-form .wiktku-section-tab { font-size: 13.5px; font-weight: 500; color: var(--wikt-ink-3); background: transparent; border: 0; border-bottom: 3px solid transparent; border-radius: var(--wikt-r-pill) var(--wikt-r-pill) 0 0; padding: 9px 14px 11px; cursor: pointer; transition: background 0.12s ease, color 0.12s ease; } #wiktku-start-form .wiktku-group-tab:hover, #wiktku-start-form .wiktku-section-tab:hover { background: var(--wikt-card-sunken); color: var(--wikt-ink); } #wiktku-start-form .wiktku-group-tab.wiktku-tab-active, #wiktku-start-form .wiktku-section-tab.wiktku-tab-active { background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom-color: var(--wikt-accent); } /* ── Progressive-disclosure toggles ────────────────────────────────── Shared by "Tercîhên pêşketî" (posparams) and "Malûmatên pêşketî" (Mane): a rotating chevron plus a count of what's hidden. */ #wiktku-start-form .wiktku-adv-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin: 4px 0 12px; padding-top: 16px; border-top: 1px solid var(--wikt-rule-soft); } #wiktku-start-form .wiktku-adv-toggle { display: inline-flex; align-items: center; gap: 10px; font-size: 14px; font-weight: 500; color: var(--wikt-accent); text-decoration: none; cursor: pointer; } #wiktku-start-form .wiktku-adv-toggle:hover .wiktku-adv-toggle-text { text-decoration: underline; } #wiktku-start-form .wiktku-adv-toggle-chevron { width: 22px; height: 22px; flex: 0 0 22px; display: grid; place-items: center; font-size: 11px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); border-radius: 6px; transform: rotate(-90deg); transition: transform 0.15s ease; } /* Open state: dfn flips the class on the step, posparams on the link. */ #wiktku-start-form .wiktku-adv-toggle.wiktku-adv-open .wiktku-adv-toggle-chevron, #wiktku-start-dfn:not(.wiktku-dfn-subs-hidden) .wiktku-adv-toggle-chevron { transform: rotate(0deg); } #wiktku-start-form .wiktku-posparams-adv-panel { border: 1px solid var(--wikt-rule-soft); border-radius: 12px; background: var(--wikt-card-sunken); padding: 20px 18px; margin-bottom: 4px; } /* ── posparams grid ────────────────────────────────────────────────── "Tor, ne rêz" — two columns, nothing narrower than 220px, so the six gender/number fields stop being a six-across scanline. */ @media (min-width: 721px) { #wiktku-start-form .wiktku-posparams-helpers, #wiktku-start-form .wiktku-posparams-adv-panel { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 18px 22px; align-items: start; } #wiktku-start-form .wiktku-posparams-adv-panel > .wiktku-posparams-row, #wiktku-start-form .wiktku-posparams-helpers > .wiktku-posparams-row { flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 7px; } #wiktku-start-form .wiktku-posparams-helpers > .wiktku-adv-toggle-row, #wiktku-start-form .wiktku-posparams-helpers > .wiktku-posparams-adv-panel, #wiktku-start-form .wiktku-posparams-adv-panel > .wiktku-posparams-opt-panel { grid-column: 1 / -1; } } #wiktku-start-form .wiktku-posparams-opt-panel { border-top: 1px solid var(--wikt-rule-soft); padding-top: 14px; margin-top: 4px; } #wiktku-start-form .wiktku-posparams-opt-row { font-size: 13px; color: var(--wikt-ink-3); } /* ── Sense blocks ──────────────────────────────────────────────────── Each sense is a sunken panel inside the Mane card, with its number as an accent counter — so "how many meanings am I writing" is legible at a glance. */ #wiktku-start-form .wiktku-dfn-subgroup { margin: 14px 0 0; padding-top: 14px; border-top: 1px solid var(--wikt-rule-soft); } /* No divider above the first item — it would be a rule against the sense's own text. Needed explicitly: the earlier :first-of-type rule is a class selector and loses to this id-scoped one. */ #wiktku-start-form .wiktku-dfn-subgroup:first-of-type { margin-top: 8px; padding-top: 0; border-top: none; } #wiktku-start-form .wiktku-dfn-sublabel-term { color: var(--wikt-ink); } /* Plain white field like any other, not a tinted fill — a tint would read as "disabled" next to the white Mane box above it. */ #wiktku-start-form .wiktku-dfn-subfield, #wiktku-start-form textarea.wiktku-dfn-mane { background: var(--wikt-field-bg); border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-field); } /* No "1." "2." markers on the sub-lists: numbered rows would read as a form to fill top-down, when each row is really "another one if you have one" — and the marker would land on its own line above the block-level textarea, looking like a stray character. */ #wiktku-start-form .wiktku-dfn-sublist { margin: 0; padding-left: 0; list-style: none; } #wiktku-start-form .wiktku-dfn-sublist > li { margin-bottom: 6px; } /* ── Chips: tags, modifiers, template pills ──────────────────────────── */ #wiktku-start-form .wiktku-mod-pill, #wiktku-start-form .wiktku-besendin-select + .wiktku-chip { background: var(--wikt-accent-tint); color: var(--wikt-accent-deep); border: 1px solid var(--wikt-accent-edge); border-radius: var(--wikt-r-pill); font-size: 13px; padding: 6px 12px; } #wiktku-start-form .wiktku-mod-btn, #wiktku-start-form .wiktku-mod-confirm, #wiktku-start-form .wiktku-mod-cancel { border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); border-radius: 8px; } /* ── Footer + buttons ──────────────────────────────────────────────── One primary filled pill; destructive actions are outline-only in the danger colour so they stay quiet next to it. */ #wiktku-start-form #wiktku-start-footer { background: var(--wikt-card-sunken); border-top: 1px solid var(--wikt-rule); border-radius: 0 0 var(--wikt-r-card) var(--wikt-r-card); padding: 16px 20px; gap: 10px; } #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement-button { border-radius: var(--wikt-r-pill) !important; font-family: var(--wikt-sans); font-size: 14px; font-weight: 500; padding: 11px 22px; box-shadow: none !important; min-height: var(--wikt-tap); } #wiktku-start-form #wiktku-unhide-editform .oo-ui-buttonElement-button { background: var(--wikt-accent) !important; border-color: var(--wikt-accent) !important; color: var(--wikt-on-accent) !important; } /* Destructive actions: outline, not fill. */ #wiktku-start-form #wiktku-start-footer .oo-ui-flaggedElement-destructive .oo-ui-buttonElement-button { background: var(--wikt-card) !important; border-color: var(--wikt-danger) !important; color: var(--wikt-danger) !important; } #wiktku-start-form #wiktku-last-saved { font-family: var(--wikt-mono); font-size: 12px; color: var(--wikt-muted); } /* ── Beşên din picker ──────────────────────────────────────────────── This dropdown is now the entry point to eighteen sections, so it gets room and a label rather than sitting flush under the tab bar. */ #wiktku-start-form .wiktku-besendin-picker { margin: 0 0 20px; padding: 16px 18px; background: var(--wikt-card); border: 1px solid var(--wikt-card-edge); border-radius: 12px; } #wiktku-start-form .wiktku-besendin-picker .wiktku-native-select-wrap, #wiktku-start-form .wiktku-besendin-picker input.wiktku-ac-input { width: 100%; max-width: 28em; } /* ── Notices ─────────────────────────────────────────────────────────── */ #wiktku-start-form .wiktku-addlang-notice { background: var(--wikt-accent-tint); border: 1px solid var(--wikt-accent-edge); border-radius: var(--wikt-r-field); color: var(--wikt-ink-2); padding: 12px 16px; margin-bottom: 16px; } #wiktku-start-form .wiktku-pron-preview { background: var(--wikt-accent-tint); border-color: var(--wikt-accent-edge); border-radius: 12px; } #wiktku-start-form .wiktku-pron-preview-confirm, #wiktku-start-form .wiktku-pron-preview-cancel { border-radius: var(--wikt-r-pill); padding: 8px 16px; min-height: 36px; } /* Links carry the accent and a soft underline, per the spec's `a` rule. */ #wiktku-start-form a { color: var(--wikt-accent); text-decoration: none; border-bottom: 1px solid var(--wikt-link-under); } #wiktku-start-form a:hover { color: var(--wikt-accent-deep); } #wiktku-start-form .wiktku-adv-toggle, #wiktku-start-form .wiktku-group-tab, #wiktku-start-form .wiktku-section-tab { border-bottom-style: solid; } #wiktku-start-form .wiktku-adv-toggle { border-bottom: 0; } /* =================================================================== Dark mode =================================================================== Every colour above is a token on #wiktku-start-form, so this is a swap of that one block. Only applies given an explicit dark signal (skin-theme-clientpref-night / skin-nightmode, or skin-theme-clientpref-os plus prefers-color-scheme: dark) — no bare prefers-color-scheme fallback, since legacy Vector sets no theme class either and would otherwise go dark with nothing else on the page to match. Palette is warm, not neutral grey, to keep the cream design's character. Accent lightens to #7ba7e8 since #2a5db0 on a dark card is ~2.4:1 contrast and reads as near-black. =================================================================== */ html.skin-theme-clientpref-night #wiktku-start-form, html.skin-nightmode #wiktku-start-form { --wikt-page: #171613; --wikt-card: #201e1a; --wikt-card-sunken: #1a1916; --wikt-card-edge: #322e28; --wikt-rule: #3a3630; --wikt-rule-soft: #2c2924; --wikt-field-edge: #4a453d; --wikt-field-bg: #191815; --wikt-code-bg: #14130f; --wikt-ink: #ece7dd; --wikt-ink-2: #d5cfc4; --wikt-ink-3: #b3aca1; --wikt-muted: #8f887c; --wikt-placeholder: #6d675e; --wikt-accent: #7ba7e8; --wikt-accent-deep: #cfe0f8; --wikt-accent-tint: #1c2839; --wikt-accent-edge: #35496b; --wikt-danger: #e5907c; --wikt-on-accent: #14213a; --wikt-link-under: rgba(123, 167, 232, 0.4); } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os #wiktku-start-form { --wikt-page: #171613; --wikt-card: #201e1a; --wikt-card-sunken: #1a1916; --wikt-card-edge: #322e28; --wikt-rule: #3a3630; --wikt-rule-soft: #2c2924; --wikt-field-edge: #4a453d; --wikt-field-bg: #191815; --wikt-code-bg: #14130f; --wikt-ink: #ece7dd; --wikt-ink-2: #d5cfc4; --wikt-ink-3: #b3aca1; --wikt-muted: #8f887c; --wikt-placeholder: #6d675e; --wikt-accent: #7ba7e8; --wikt-accent-deep: #cfe0f8; --wikt-accent-tint: #1c2839; --wikt-accent-edge: #35496b; --wikt-danger: #e5907c; --wikt-on-accent: #14213a; --wikt-link-under: rgba(123, 167, 232, 0.4); } } /* A handful of rules still name literal light colours instead of tokens; neutralise the ones that actually show through in night mode. */ html.skin-theme-clientpref-night #wiktku-start-form .wiktku-ac-results, html.skin-nightmode #wiktku-start-form .wiktku-ac-results { background: var(--wikt-card); border-color: var(--wikt-rule); color: var(--wikt-ink); } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os #wiktku-start-form .wiktku-ac-results { background: var(--wikt-card); border-color: var(--wikt-rule); color: var(--wikt-ink); } } /* =================================================================== Autocomplete list: stop it escaping its card =================================================================== A fixed width would run past the card's border on full-width pickers, since the list is absolutely positioned at the wrapper's left edge. width:100% ties it to the (shrink-to-fit) wrapper's input width instead; min/max-width keep short pickers readable and stop viewport overflow. */ #wiktku-start-form ul.wiktku-ac-results { width: 100%; min-width: min(18em, 100%); max-width: min(92vw, 34em); box-sizing: border-box; border-radius: var(--wikt-r-field); box-shadow: none; } /* And the wrapper itself must not exceed the card it sits in. */ #wiktku-start-form .wiktku-native-select-wrap { max-width: 100%; } #wiktku-start-form .wiktku-cavkani-wrap .wiktku-native-select-wrap, #wiktku-start-form .wiktku-cavkani-wrap input.wiktku-ac-input, #wiktku-start-form .wiktku-pron-wrap .wiktku-native-select-wrap, #wiktku-start-form .wiktku-etym-wrap .wiktku-native-select-wrap { width: 100%; max-width: 100%; box-sizing: border-box; } /* =================================================================== Mobile footer =================================================================== Below 720px the primary button keeps its full size and everything else shrinks to a secondary scale, so the sticky footer doesn't dominate a phone viewport. =================================================================== */ @media (max-width: 720px) { #wiktku-start-form { padding: 12px; font-size: 14px; } #wiktku-start-form .wiktku-start-step { padding: 16px 14px 14px; border-radius: 12px; } #wiktku-start-form .wiktku-start-step-name { font-size: 20px !important; } #wiktku-start-form #wiktku-start-footer { padding: 10px 12px; gap: 6px; row-gap: 8px; } #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement-button { font-size: 13px; padding: 8px 14px; min-height: 38px; } /* The one you actually press stays thumb-sized. */ #wiktku-start-form #wiktku-unhide-editform .oo-ui-buttonElement-button { font-size: 14px; padding: 10px 20px; min-height: var(--wikt-tap); } /* Secondary actions share a row instead of each claiming a full one. */ #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement { flex: 0 1 auto; } #wiktku-start-form #wiktku-last-saved { flex: 1 0 100%; order: 10; font-size: 11px; white-space: normal; } #wiktku-start-form .wiktku-adv-toggle-row { gap: 8px; } } /* =================================================================== IPA character palette (v3 spec) =================================================================== Click-to-insert chart under Bilêvkirin, after fr.wiktionary's. Two sub-tabs — a short Kurmancî set that opens by default, and the full chart — because ~20 of the ~180 IPA symbols ever occur in Kurmancî and showing all of them first is the same "wall of fields" problem this redesign exists to fix. =================================================================== */ #wiktku-start-form .wiktku-ipa-panel { border: 1px solid var(--wikt-card-edge); border-radius: 12px; background: var(--wikt-card-sunken); padding: 0 0 12px; margin-bottom: 8px; overflow: hidden; } #wiktku-start-form .wiktku-ipa-subtabs { display: flex; align-items: center; gap: 4px; padding: 8px 12px 0; border-bottom: 1px solid var(--wikt-rule-soft); margin-bottom: 12px; flex-wrap: wrap; } #wiktku-start-form .wiktku-ipa-subtab { font-size: 13px; font-weight: 500; color: var(--wikt-ink-3); padding: 7px 12px 9px; border-bottom: 3px solid transparent; border-radius: 8px 8px 0 0; cursor: pointer; } #wiktku-start-form .wiktku-ipa-subtab:hover { background: var(--wikt-card); color: var(--wikt-ink); } #wiktku-start-form .wiktku-ipa-subtab.wiktku-tab-active { background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom-color: var(--wikt-accent); } /* Templates are not characters, so they sit apart from the chart — pinned to the right of the sub-tab row. */ #wiktku-start-form .wiktku-ipa-tplbtns { margin-left: auto; display: flex; gap: 6px; padding-bottom: 6px; } #wiktku-start-form .wiktku-ipa-tplbtn { font-family: var(--wikt-mono); font-size: 12px; padding: 6px 10px; border-radius: 7px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); cursor: pointer; white-space: nowrap; } #wiktku-start-form .wiktku-ipa-tplbtn:hover { border-color: var(--wikt-accent); } #wiktku-start-form .wiktku-ipa-grid { display: flex; flex-direction: column; gap: 8px; padding: 0 12px; } #wiktku-start-form .wiktku-ipa-row { display: flex; align-items: flex-start; gap: 10px; } #wiktku-start-form .wiktku-ipa-rowlabel { flex: 0 0 74px; font-size: 11.5px; color: var(--wikt-muted); padding-top: 8px; line-height: 1.3; } #wiktku-start-form .wiktku-ipa-keys { display: flex; flex-wrap: wrap; gap: 4px; flex: 1 1 auto; } #wiktku-start-form .wiktku-ipa-key { width: 30px; height: 30px; padding: 0; border-radius: 8px; border: 1px solid var(--wikt-field-edge); background: var(--wikt-field-bg); color: var(--wikt-ink); font-family: var(--wikt-mono); font-size: 14px; line-height: 1; cursor: pointer; display: grid; place-items: center; transition: background 0.1s ease, border-color 0.1s ease; } #wiktku-start-form .wiktku-ipa-key:hover { background: var(--wikt-accent-tint); border-color: var(--wikt-accent); color: var(--wikt-accent-deep); } #wiktku-start-form .wiktku-ipa-key:active { transform: translateY(1px); } /* Ligatures like d͡ʒ and long vowels need a little more room than one glyph; let those keys grow instead of clipping. */ #wiktku-start-form .wiktku-ipa-key { width: auto; min-width: 30px; padding: 0 5px; } /* A combining mark is shown on a dotted circle so it has something to attach to; only the mark itself is inserted. */ #wiktku-start-form .wiktku-ipa-key-combining { color: var(--wikt-ink-2); } @media (max-width: 720px) { #wiktku-start-form .wiktku-ipa-row { flex-direction: column; gap: 3px; } #wiktku-start-form .wiktku-ipa-rowlabel { flex: 0 0 auto; padding-top: 0; } #wiktku-start-form .wiktku-ipa-key { min-width: 34px; height: 34px; } } /* ── "+ Beş zêde bike" menu ────────────────────────────────────────── Adding a part of speech and adding Bilêvkirin are different actions, so the button opens a small menu instead of doing one of them. */ #wiktku-start-form .wiktku-addsection-menu { position: absolute; z-index: 60; margin-top: 6px; min-width: 15em; background: var(--wikt-card); border: 1px solid var(--wikt-rule); border-radius: 10px; padding: 4px; display: flex; flex-direction: column; } #wiktku-start-form .wiktku-addsection-item { display: flex; flex-direction: column; gap: 1px; padding: 8px 10px; border-radius: 7px; border-bottom: 0; text-decoration: none; color: var(--wikt-ink); } #wiktku-start-form .wiktku-addsection-item:hover { background: var(--wikt-accent-tint); } #wiktku-start-form .wiktku-addsection-item-label { font-size: 13.5px; font-weight: 500; } #wiktku-start-form .wiktku-addsection-item-hint { font-size: 11.5px; color: var(--wikt-muted); } #wiktku-start-form #wiktku-section-tabs .oo-ui-buttonElement { position: relative; } /* Bilêvkirin is a peer of the POS sections but not a part of speech — a hairline before it marks the boundary. */ #wiktku-start-form .wiktku-section-tab-pron { margin-left: 6px; border-left: 1px solid var(--wikt-rule); padding-left: 14px; border-radius: 0; } /* =================================================================== Per-sense accordion (v3 spec) =================================================================== "Tenê maneya ku tê nivîsandin vekirî ye" — each meaning is a closed box showing its own text, so a four-sense entry fits on one screen instead of scrolling for a minute. A sense with nothing in it is never collapsed: the trailing empty one is how you add the next meaning, so hiding it would hide the only way forward. =================================================================== */ #wiktku-start-form li.wiktku-dfn-sense { border: 1px solid var(--wikt-card-edge); border-radius: 12px; background: var(--wikt-card); margin-bottom: 10px; padding: 0; list-style: none; overflow: visible; } #wiktku-start-form .wiktku-dfn-sense-header { display: flex; align-items: center; gap: 10px; padding: 12px 14px; cursor: pointer; border-radius: 12px; user-select: none; } #wiktku-start-form li.wiktku-dfn-sense:not(.wiktku-sense-collapsed) .wiktku-dfn-sense-header { border-bottom: 1px solid var(--wikt-rule-soft); border-radius: 12px 12px 0 0; } #wiktku-start-form .wiktku-dfn-sense-header:hover { background: var(--wikt-card-sunken); } #wiktku-start-form .wiktku-dfn-sense-num { flex: 0 0 22px; height: 22px; border-radius: 999px; background: var(--wikt-accent); color: var(--wikt-on-accent); font-family: var(--wikt-mono); font-size: 12px; display: grid; place-items: center; } #wiktku-start-form .wiktku-dfn-sense-title { font-size: 13.5px; font-weight: 500; white-space: nowrap; } /* The summary is the point of a collapsed row, so it only shows there. */ #wiktku-start-form .wiktku-dfn-sense-summary { flex: 1 1 auto; min-width: 0; font-size: 13px; color: var(--wikt-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: none; } #wiktku-start-form li.wiktku-sense-collapsed .wiktku-dfn-sense-summary { display: block; } #wiktku-start-form .wiktku-dfn-sense-chevron { margin-left: auto; color: var(--wikt-muted); font-size: 12px; transition: transform 0.15s ease; } #wiktku-start-form li.wiktku-sense-collapsed .wiktku-dfn-sense-chevron { transform: rotate(-90deg); } #wiktku-start-form .wiktku-dfn-sense-body { padding: 14px; } #wiktku-start-form li.wiktku-sense-collapsed .wiktku-dfn-sense-body { display: none; } /* =================================================================== Template rows in the pickers (v3 spec) =================================================================== One row shape everywhere a template is chosen: the ⓘ explains terms like "guharto/kevnbûyî/ku-Latn/şaşnivîs" without leaving the form, and the 🔗 links out for when it doesn't. =================================================================== */ #wiktku-start-form ul.wiktku-ac-results li.wiktku-ac-tplrow { display: flex; align-items: center; gap: 8px; min-height: 44px; white-space: normal; padding: 6px 10px; } #wiktku-start-form .wiktku-ac-tpltext { flex: 1 1 auto; min-width: 0; font-family: var(--wikt-mono); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* Status, not category: green is the one to reach for, yellow means "only if you specifically need it" (kevnbûyî, şaşnivîs, kêmpeyda). */ #wiktku-start-form .wiktku-tpl-dot { flex: 0 0 8px; width: 8px; height: 8px; border-radius: 999px; } #wiktku-start-form .wiktku-tpl-dot-ok { background: #3d8a55; } #wiktku-start-form .wiktku-tpl-dot-special { background: #c9971f; } #wiktku-start-form .wiktku-tpl-icons { flex: 0 0 auto; display: flex; gap: 5px; align-items: center; } #wiktku-start-form .wiktku-tpl-icon { width: 26px; height: 26px; display: grid; place-items: center; font-size: 12px; line-height: 1; cursor: pointer; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom: 1px solid var(--wikt-accent-edge); text-decoration: none; padding: 0; } #wiktku-start-form .wiktku-tpl-icon-link { border-radius: 7px; } #wiktku-start-form .wiktku-tpl-icon-info { border-radius: 999px; font-family: var(--wikt-serif); font-style: italic; font-weight: 600; background: transparent; border-color: var(--wikt-field-edge); color: var(--wikt-muted); } #wiktku-start-form .wiktku-tpl-icon:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); background: var(--wikt-accent-tint); } /* ── The ⓘ panel ───────────────────────────────────────────────────── Three parts, in the spec's order: what it does, its parameters, and a way out to the template page. */ #wiktku-start-form .wiktku-tpl-info { position: relative; margin: 8px 0 4px; padding: 14px 16px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); border-radius: 12px; font-size: 13.5px; line-height: 1.6; color: var(--wikt-ink-2); } #wiktku-start-form .wiktku-tpl-info-name { font-family: var(--wikt-mono); font-size: 13px; color: var(--wikt-accent-deep); margin-bottom: 6px; } #wiktku-start-form .wiktku-tpl-info-params { margin-top: 8px; } #wiktku-start-form .wiktku-tpl-info-params-title { font-size: 12px; color: var(--wikt-muted); margin-bottom: 2px; } #wiktku-start-form .wiktku-tpl-info-params ul { margin: 0; padding-left: 18px; font-family: var(--wikt-mono); font-size: 12.5px; } #wiktku-start-form .wiktku-tpl-info-link { display: inline-block; margin-top: 10px; font-size: 13px; } #wiktku-start-form .wiktku-tpl-info-close { position: absolute; top: 8px; right: 8px; width: 24px; height: 24px; border-radius: 999px; border: 0; background: transparent; color: var(--wikt-muted); cursor: pointer; font-size: 13px; line-height: 1; } #wiktku-start-form .wiktku-tpl-info-close:hover { background: var(--wikt-card); color: var(--wikt-ink); } /* =================================================================== Footer overflow "⋯" (v3 spec) =================================================================== Bişîne and "Edîtora çavkaniyê veke" stay on the bar; the cache actions, saved-at note and Tercîh move in here so the destructive buttons don't compete for attention and the sticky footer stays to one row on a phone. =================================================================== */ #wiktku-start-form .wiktku-more-wrap { position: relative; margin-left: auto; flex: 0 0 auto; } #wiktku-start-form .wiktku-more-btn { width: 36px; height: 36px; border-radius: 999px; border: 1px solid var(--wikt-field-edge); background: var(--wikt-card); color: var(--wikt-muted); font-size: 16px; line-height: 1; cursor: pointer; display: grid; place-items: center; } #wiktku-start-form .wiktku-more-btn:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); } #wiktku-start-form .wiktku-more-menu { position: absolute; right: 0; bottom: calc(100% + 8px); z-index: 70; min-width: 17em; background: var(--wikt-card); border: 1px solid var(--wikt-rule); border-radius: 12px; padding: 6px; display: flex; flex-direction: column; gap: 2px; } #wiktku-start-form .wiktku-more-item { display: flex; align-items: center; gap: 8px; } /* The buttons inside the menu are menu rows, not buttons on a bar. */ #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement { flex: 1 1 auto; } #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement-button { display: block; width: 100%; text-align: left; border: 0 !important; background: transparent !important; border-radius: 7px !important; padding: 9px 10px; min-height: 0; font-weight: 400; color: var(--wikt-ink) !important; } #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement-button:hover { background: var(--wikt-accent-tint) !important; } #wiktku-start-form .wiktku-more-item-danger .oo-ui-buttonElement-button { color: var(--wikt-danger) !important; } #wiktku-start-form .wiktku-more-item-prefs .wiktku-prefs-btn { width: 26px; height: 26px; flex: 0 0 26px; border: 0; background-color: transparent; } #wiktku-start-form .wiktku-more-item-label { font-size: 13.5px; } #wiktku-start-form .wiktku-more-sep { height: 1px; background: var(--wikt-rule-soft); margin: 4px 2px; } #wiktku-start-form .wiktku-more-note { padding: 4px 10px 2px; } #wiktku-start-form .wiktku-more-note #wiktku-last-saved { white-space: normal; } /* The accordion header already shows the sense number, so the counter badge on the <li> is disabled to avoid drawing a second one. */ #wiktku-start-form ol.wiktku-dfn-list > li.wiktku-dfn-sense::before { content: none; } #wiktku-start-form ol.wiktku-dfn-list > li.wiktku-dfn-sense { padding-left: 0; padding-bottom: 0; border-bottom: 0; margin-bottom: 10px; } #wiktku-start-form ol.wiktku-dfn-list > li.wiktku-dfn-sense:not(:last-child) { padding-bottom: 0; border-bottom: 0; } /* ── "+ Mane zêde bike" ────────────────────────────────────────────── Senses are added deliberately via this button rather than appearing automatically, so a one-meaning entry doesn't show an empty second sense that reads as an unfinished form. */ #wiktku-start-form .wiktku-add-sense { display: inline-flex; align-items: center; gap: 8px; margin-top: 4px; padding: 10px 18px; border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-pill); background: var(--wikt-card); color: var(--wikt-ink-2); font-family: var(--wikt-sans); font-size: 13.5px; cursor: pointer; min-height: 40px; } #wiktku-start-form .wiktku-add-sense:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); background: var(--wikt-accent-tint); } #wiktku-start-form .wiktku-add-sense-plus { color: var(--wikt-accent); font-size: 15px; line-height: 1; } /* ── Şablon picker, demoted to a link ──────────────────────────────── Picking a template replaces the definition rather than adding to it, so it is an alternative route, not the first control in the sense. Hidden behind one line of text until it is actually wanted. */ #wiktku-start-form .wiktku-dfn-tpl-link { display: inline-block; margin-top: 8px; font-size: 12.5px; color: var(--wikt-muted); border-bottom: 1px solid transparent; } #wiktku-start-form .wiktku-dfn-tpl-link:hover { color: var(--wikt-accent); border-bottom-color: var(--wikt-link-under); } #wiktku-start-form .wiktku-dfn-tpl-row { margin-top: 10px; padding-top: 12px; border-top: 1px solid var(--wikt-rule-soft); } /* ── Template-row icons on touch screens ───────────────────────────── 26px is fine for a mouse and too small for a thumb, and these two sit right next to each other at the end of a row you can also tap to select. Give them real targets and some separation on small screens. */ @media (max-width: 720px), (pointer: coarse) { #wiktku-start-form .wiktku-tpl-icon { width: 34px; height: 34px; font-size: 14px; } #wiktku-start-form .wiktku-tpl-icons { gap: 8px; padding-left: 4px; } #wiktku-start-form ul.wiktku-ac-results li.wiktku-ac-tplrow { min-height: 50px; } } /* The rendered pronunciation preview is real parser output, so it needs to sit as content rather than in the monospace wikitext treatment the panel inherits. */ #wiktku-start-form .wiktku-pron-preview-body { font-family: var(--wikt-sans); font-size: 15px; background: var(--wikt-card); border: 1px solid var(--wikt-accent-edge); border-radius: 8px; padding: 10px 12px; white-space: normal; } #wiktku-start-form .wiktku-pron-preview-body .IPA, #wiktku-start-form .wiktku-pron-preview-body code, #wiktku-start-form .wiktku-pron-preview-body tt { font-family: var(--wikt-mono); } /* Parser output brings its own margins; strip the outer ones so the preview box doesn't gain a blank first line. */ #wiktku-start-form .wiktku-pron-preview-body > *:first-child { margin-top: 0; } #wiktku-start-form .wiktku-pron-preview-body > *:last-child { margin-bottom: 0; } goiskvpam16lq7gw01fbbiu7gii9tgn 6333832 6333826 2026-08-15T15:14:10Z Wikihez 7344 6333832 css text/css /* =================================================================== #editform while the wizard is active =================================================================== */ /* Keeps #editform genuinely laid out instead of display:none*/ .wiktku-offscreen { position: absolute !important; left: -9999px !important; top: 0 !important; width: 100%; max-width: 100%; visibility: hidden; } /* =================================================================== Base scale =================================================================== */ #wiktku-start-form { font-size: 0.92em; line-height: 1.35; } #wiktku-start-form * { box-sizing: border-box; } .wiktku-addlang-notice { margin: 0 0 0.8em; padding: 0.6em 0.8em; background: var(--wikt-palette-paleblue); border: 1px solid var(--wikt-palette-lightgrey); border-radius: 4px; } /* =================================================================== Step cards a compact card with a left accent bar, so each step reads as a distinct unit =================================================================== */ .wiktku-start-step { padding: 0.7em 0.9em; margin-bottom: 0.6em; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-left: 4px solid var(--wikt-palette-blue-9, #3366cc); border-radius: 6px; background: var(--wikt-palette-white); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); transition: border-left-color 0.15s ease, box-shadow 0.15s ease; } .wiktku-start-step:hover { box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08); } .wiktku-start-step:focus-within { border-left-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); } /* Fuses the posparams card onto the bottom of the pos card (shared left accent bar, no border/gap) since posparams always renders directly after #wiktku-start-pos once a pos is chosen. */ #wiktku-start-pos { border-radius: 6px 6px 0 0; margin-bottom: 0; border-bottom: none; } #wiktku-start-posparams { border-radius: 0 0 6px 6px; border-top: none; padding-top: 0.3em; } #wiktku-start-posparams .wiktku-start-step-name { display: none; } /* Scoped and !important: this is a real <h3> tag (see start.js), so the skin's default heading styles would otherwise override a plain class rule. Coloured to match the card's accent bar; .wiktku-start-step-question below stays lighter/muted so the two don't compete. */ #wiktku-start-form .wiktku-start-step-name { font-size: 1.1em !important; font-weight: 700; letter-spacing: 0.03em; margin: 0 0 0.3em; line-height: 1.2; color: var(--wikt-palette-blue-9, #3366cc); border: 0; padding: 0; } /* Sized close to the heading so the card reads consistently instead of the text below it looking like fine print. */ .wiktku-start-step-question { font-size: 1em; font-weight: 400; color: var(--wikt-palette-grey-9, #555); margin: 0 0 0.5em; line-height: 1.45; } .wiktku-start-step label { padding-right: 1.2em; font-size: 1em; } /* Muted hint text next to a field, styled to read as a hint rather than another question competing with .wiktku-start-step-question. */ .wiktku-step-hint { font-size: 0.88em; font-style: italic; color: var(--wikt-palette-grey-8, #72777d); margin: 0 0 0.5em; line-height: 1.4; } /* Same specificity as the rule just above, so it must come after to actually win: the name label isn't a field label needing right padding or the form's base label size, it's a heading. */ #wiktku-start-form .wiktku-start-step-name label { padding-right: 0; font-size: inherit !important; color: inherit; } input[type="text"].wiktku-start-step-field { width: 100%; padding: 5px 8px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 4px; transition: border-color 0.12s ease, box-shadow 0.12s ease; } input[type="text"].wiktku-start-step-field:focus { border-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9, #3366cc); outline: 0; } input[type="text"].wiktku-start-step-field.wiktku-start-narrow { width: 20em; } /* Only used by selects that opt out via .wiktku-plain-select; other selects get their width from the searchable picker instead (see input.wiktku-ac-input). */ select.wiktku-start-narrow, input.wiktku-dfn-tpl-title { width: 20em; max-width: 100%; box-sizing: border-box; } #wiktku-start-spinner { float: right; margin-left: 1em; } #wiktku-start-footer { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5em; padding: 0.6em 0.2em; position: sticky; bottom: 0; background: var(--wikt-palette-white); border-top: 1px solid var(--wikt-palette-grey-3, #e0e0e0); z-index: 5; } /* Quiet, non-competing text — sits next to the cache buttons so the person can tell at a glance whether their latest edits are backed up, without it fighting the buttons for attention. */ #wiktku-last-saved { font-size: 0.85em; color: var(--wikt-palette-grey-9, #767676); white-space: nowrap; } /* ── Tercîh (settings) icon button — sits in the footer next to the cache buttons. Uses the Codex "settings" (color-subtle) icon from Commons directly rather than an OOUI icon-pack module, so it renders the exact requested glyph without pulling in an extra dependency. */ .wiktku-prefs-btn { width: 2.2em; height: 2.2em; flex: 0 0 auto; padding: 0; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-radius: 2px; background-color: var(--wikt-palette-white); background-image: url(//upload.wikimedia.org/wikipedia/commons/e/e0/Codex_icon_settings_color-subtle.svg); background-repeat: no-repeat; background-position: center; background-size: 1.2em 1.2em; cursor: pointer; } .wiktku-prefs-btn:hover { background-color: var(--wikt-palette-grey-0, #f8f9fa); } .wiktku-prefs-btn:active { background-color: var(--wikt-palette-grey-1, #eaecf0); } /* Tercîh dialog body — OOUI's bare ProcessDialog body has no inset of its own, so text/fields otherwise sit flush against the window edges. */ .wiktku-prefs-dialog-body { padding: 1em 1.2em; } /* ── "Bişîne" click feedback ── */ @keyframes wiktku-btn-flash-pulse { 0% { box-shadow: 0 0 0 0 rgba(51, 102, 204, 0.55); } 70% { box-shadow: 0 0 0 9px rgba(51, 102, 204, 0); } 100% { box-shadow: 0 0 0 0 rgba(51, 102, 204, 0); } } #wiktku-unhide-editform.wiktku-btn-flash { animation: wiktku-btn-flash-pulse 0.5s ease-out; } /* Persistent state while the wikitext is being built/submitted, set alongside OOUI's own setDisabled(true) so it reads clearly even if the skin's default disabled style is subtle. */ #wiktku-unhide-editform.wiktku-btn-sending .oo-ui-buttonElement-button { background-color: var(--wikt-palette-grey-9, #767676) !important; border-color: var(--wikt-palette-grey-9, #767676) !important; cursor: progress; opacity: 1 !important; } /* Looks like OOUI's disabled state but isn't one — the button stays clickable so its handler can still run and explain why (see the wiktkuNotify call next to wiktkuContentGateOk in start.js). */ #wiktku-unhide-editform.wiktku-btn-soft-disabled .oo-ui-buttonElement-button { opacity: 0.5; cursor: not-allowed; } /* ── "Beşên din" picker ── */ .wiktku-besendin-picker { margin: 0.6em 0 1em; } .wiktku-besendin-picker .wiktku-besendin-select { width: 100%; max-width: 24em; } #wiktku-start-form textarea.wiktku-start-step-field, #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield { resize: vertical !important; overflow: auto !important; box-sizing: border-box !important; vertical-align: top; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; transition: border-color 0.1s ease, box-shadow 0.1s ease; } /* Modern focus state to match the searchable-picker inputs. */ #wiktku-start-form textarea.wiktku-start-step-field:focus, #wiktku-start-form textarea.wiktku-start-narrow:focus, #wiktku-start-form textarea.wiktku-dfn-subfield:focus { border-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9, #3366cc); outline: 0; } /* Standard: every textarea in the form is full width by default */ #wiktku-start-form textarea:not(.wiktku-start-narrow) { width: 100%; max-width: 100%; box-sizing: border-box; } #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield.wiktku-start-narrow { width: 20em; max-width: 100%; min-width: 8em; height: calc(1.7em + 10px); min-height: calc(1.7em + 10px); padding-top: 4px !important; padding-bottom: 4px !important; line-height: 1.35 !important; resize: none !important; } /* Exception: "Sernav" / "Sernavê orjînal" citation-source fields (kitêb, kovar, malper, …) — long enough to be worth 2 rows and manual resizing. */ #wiktku-start-form textarea.wiktku-dfn-quote-src-input.wiktku-dfn-quote-src-input--title { height: calc(2 * 1.35em + 10px); min-height: calc(2 * 1.35em + 10px); } /* ── Manual drag-to-resize handle ── */ #wiktku-start-form textarea:not(.wiktku-start-narrow) { resize: none !important; } /* Inline modifier button (⊕) */ .wiktku-word-li { display: flex; align-items: flex-start; flex-wrap: wrap; gap: 0.3em; } .wiktku-mod-btn { flex: 0 0 auto; width: 1.6em; height: 1.6em; padding: 0; line-height: 1; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); color: var(--wikt-palette-blue-9, #3366cc); font-size: 1em; cursor: pointer; } .wiktku-mod-btn:hover { border-color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-paleblue, #eaf3ff); } .wiktku-mod-picker { display: flex; flex-wrap: wrap; gap: 0.25em; width: 100%; margin-top: 0.15em; padding: 0.35em; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; background: var(--wikt-palette-white); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); } .wiktku-mod-pill { padding: 2px 8px; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-radius: 12px; background: var(--wikt-palette-paleblue, #eaf3ff); font-size: 0.85em; white-space: nowrap; cursor: pointer; } .wiktku-mod-pill:hover { border-color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); } .wiktku-mod-pill:disabled, .wiktku-mod-pill.wiktku-mod-pill-used { border-color: var(--wikt-palette-grey-3, #e0e0e0); background: var(--wikt-palette-lightgrey); color: var(--wikt-palette-grey-3, #999); cursor: not-allowed; opacity: 0.6; } .wiktku-mod-pill:disabled:hover, .wiktku-mod-pill.wiktku-mod-pill-used:hover { border-color: var(--wikt-palette-grey-3, #e0e0e0); background: var(--wikt-palette-lightgrey); color: var(--wikt-palette-grey-3, #999); } .wiktku-mod-val-wrap { display: flex; align-items: center; gap: 0.25em; width: 100%; margin-top: 0.15em; } .wiktku-mod-val-input { flex: 0 1 14em; max-width: 14em; padding: 3px 6px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; } .wiktku-mod-confirm, .wiktku-mod-cancel { flex: 0 0 auto; width: 1.6em; height: 1.6em; padding: 0; line-height: 1; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); cursor: pointer; } .wiktku-mod-confirm { color: #178a17; border-color: #178a17; } .wiktku-mod-cancel { color: var(--wikt-palette-red-9, #d33); border-color: var(--wikt-palette-red-9, #d33); } .wiktku-resize-wrap { position: relative; display: block; } /* Separate from .wiktku-resize-wrap (used only for textareas flagged with a linebreak); plain position:relative anchor for the backdrop, no size of its own. */ .wiktku-linebreak-wrap { position: relative; display: block; } .wiktku-resize-grip { position: absolute; right: 2px; bottom: 2px; width: 14px; height: 14px; cursor: ns-resize; touch-action: none; opacity: 0.5; z-index: 2; background-image: linear-gradient(135deg, transparent 0 50%, var(--wikt-palette-grey-9, #767676) 50% 100%); background-repeat: no-repeat; } .wiktku-resize-grip:hover, .wiktku-resize-grip:active { opacity: 0.9; } /* =================================================================== Searchable dropdown (wrapNativeSelect in start.js) .wiktku-native-select-wrap > input.wiktku-ac-input (search box) > ul.wiktku-ac-results (result list) > select (hidden, holds the value) =================================================================== */ .wiktku-native-select-wrap { display: inline-block; position: relative; vertical-align: top; } /* Matches the width the native select would have had (see select.wiktku-start-narrow). */ .wiktku-native-select-wrap input[type="search"], input.wiktku-ac-input { display: block; width: 20em; max-width: 100%; box-sizing: border-box; padding: 3px 6px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); color: inherit; font-size: inherit; font-family: inherit; transition: border-color 0.1s ease, box-shadow 0.1s ease; } input.wiktku-ac-input:focus { border-color: var(--wikt-palette-blue-9); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9); outline: 0; } input.wiktku-ac-input::placeholder { color: var(--wikt-palette-grey-9); opacity: 1; } /* Hide Safari/Chrome's built-in search decorations. */ input.wiktku-ac-input::-webkit-search-decoration, input.wiktku-ac-input::-webkit-search-cancel-button, input.wiktku-ac-input::-webkit-search-results-button { -webkit-appearance: none; appearance: none; } /* ── Result list ── */ /* top/bottom/max-height are overridden inline by showResults() when it flips the list above the box; these are just its defaults. */ ul.wiktku-ac-results { position: absolute; z-index: 9999; top: 100%; bottom: auto; left: 0; margin: 0; padding: 0; list-style: none; width: 20em; max-width: 90vw; max-height: 13em; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; background: var(--wikt-palette-white); border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; box-shadow: 0 3px 10px rgba(0, 0, 0, 0.15); } ul.wiktku-ac-results li { margin: 0; padding: 4px 8px; cursor: pointer; font-size: 0.92em; display: flex; align-items: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* .wiktku-ac-active is the keyboard cursor; hover mirrors it; :active covers the touch press state. */ ul.wiktku-ac-results li.wiktku-ac-active, ul.wiktku-ac-results li:hover { background: var(--wikt-palette-lightblue); } ul.wiktku-ac-results li:active { background: var(--wikt-palette-blue-9); color: var(--wikt-palette-white); } /* Touch devices: bigger tap targets, no sticky hover. */ @media (pointer: coarse) { ul.wiktku-ac-results li { padding: 6px 10px; min-height: 2.2em; font-size: 1em; } ul.wiktku-ac-results li:hover { background: transparent; } ul.wiktku-ac-results li.wiktku-ac-active { background: var(--wikt-palette-lightblue); } input.wiktku-ac-input { /* >=16px stops iOS Safari zooming the page when the box is focused. */ font-size: 16px; min-height: 2.2em; } } /* Inline preview + confirm panel shown before inserting an auto-content pronunciation template, part of the form layout rather than a browser confirm()/prompt() dialog. */ .wiktku-pron-preview { margin: 6px 0; padding: 8px 10px; border: 1px solid var(--wikt-palette-blue-9, #3366cc); border-radius: 6px; background: var(--wikt-palette-paleblue, #eaf3ff); } .wiktku-pron-preview-label { font-size: 0.88em; font-weight: 600; color: var(--wikt-palette-grey-9, #555); margin-bottom: 3px; } .wiktku-pron-preview-body { font-family: monospace; font-size: 1em; white-space: pre-wrap; word-break: break-word; margin-bottom: 6px; } .wiktku-pron-preview-actions { display: flex; gap: 6px; } .wiktku-pron-preview-confirm, .wiktku-pron-preview-cancel { font-size: 0.88em; padding: 3px 10px; border-radius: 4px; cursor: pointer; border: 1px solid var(--wikt-palette-lightgrey, #a2a9b1); background: var(--wikt-palette-white, #fff); } .wiktku-pron-preview-confirm { border-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-blue-9, #3366cc); font-weight: 600; } .wiktku-pron-preview-confirm:disabled { opacity: 0.5; cursor: wait; } .wiktku-pron-preview-cancel:hover { background: var(--wikt-palette-grey-0, #f8f9fa); } /* Template pickers fill their container since the search box, not the <select>, is what the user sees. */ .wiktku-pron-wrap .wiktku-native-select-wrap, .wiktku-etym-wrap .wiktku-native-select-wrap, .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { width: 100%; } .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 0.88em; } .wiktku-cavkani-wrap .wiktku-native-select-wrap, .wiktku-cavkani-wrap .wiktku-native-select-wrap input.wiktku-ac-input { width: 100%; } /* Template selector inside a sense block. */ .wiktku-dfn-tpl-row .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 0.88em; } /* Language/dialect rows: picker must line up with the word field beside it. */ .wiktku-lang-row .wiktku-native-select-wrap { flex: 0 0 auto; } #wiktku-start-form textarea.wiktku-dfn-mane, #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t, #wiktku-start-form textarea.wiktku-dfn-quote-src-manual, #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text, #wiktku-start-form .wiktku-tewandin-wrap textarea.wiktku-tewandin-text, #wiktku-start-form textarea.wiktku-cavkani-text, #wiktku-start-form textarea.wiktku-dfn-tercime, #wiktku-start-form textarea.wiktku-dfn-izah { --wiktku-ta-rows: 2; height: calc(var(--wiktku-ta-rows) * 1.35em + 6px); min-height: calc(var(--wiktku-ta-rows) * 1.35em + 6px); } #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text, #wiktku-start-form textarea.wiktku-dfn-izah { --wiktku-ta-rows: 3; } #wiktku-start-form textarea.wiktku-cavkani-text { --wiktku-ta-rows: 4; } /* Nimûne + Jêgirtin (citation) boxes, and their tr/t sub-fields: at least 4 rows so there's room to actually write an example/quote. */ #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t, #wiktku-start-form textarea.wiktku-dfn-quote-src-manual { --wiktku-ta-rows: 4; } /* Nudges the border when the box contains a typed/pasted linebreak, so the user notices before it's silently turned into <br> on output; the break itself is marked via a mirrored backdrop layer (see below). */ #wiktku-start-form textarea.wiktku-has-linebreak { border-color: var(--wikt-palette-yellow6, #ac6600) !important; } /* Sits behind the textarea showing the same text, with a highlighted marker at each line followed by a break; font/padding/line-height are copied from the textarea via computed style, not shared CSS classes. */ .wiktku-linebreak-backdrop { position: absolute; inset: 0; z-index: 0; margin: 0; overflow: hidden; white-space: pre-wrap; word-wrap: break-word; color: transparent; background: transparent !important; border-color: transparent !important; box-shadow: none !important; resize: none !important; pointer-events: none; } /* Raise the real textarea above its backdrop so typing/selection/caret behave completely normally; the backdrop's mark shows through only where the real textarea's own background is transparent. */ #wiktku-start-form textarea.wiktku-has-linebreak-source { position: relative; z-index: 1; background-color: transparent; } .wiktku-linebreak-mark { background-color: var(--wikt-palette-yellow6, #ac6600); color: var(--wikt-palette-white, #fff); border-radius: 2px; } /* ── Tercime + Îzah boxes ── */ .wiktku-dfn-nonku-wrap { display: flex; flex-direction: column; gap: 3px; } .wiktku-dfn-nimune-sub, .wiktku-dfn-quote-sub { margin-top: 3px; margin-left: 1em; padding-left: 0.6em; border-left: 2px solid var(--wikt-palette-lightgrey); display: flex; flex-direction: column; gap: 3px; } .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t { min-width: 8em; padding-top: 2px !important; padding-bottom: 2px !important; line-height: 1.35 !important; font-size: 0.88em; } /* Sense list (Mane step) — one sense visible at a time, switched via .wiktku-dfn-sense-tabs. */ ol.wiktku-dfn-list { list-style: none; margin: 0; padding: 0; } ol.wiktku-dfn-list > li.wiktku-dfn-sense { margin-bottom: 0.9em; } /* Template selector row inside a sense block */ .wiktku-dfn-tpl-row { margin-bottom: 3px; } /* ── Sub-field titles (Etîket, Kategorî, Hevmane, Dijmane, Nimûne, Jêgirtin, …): each group reads as a small labelled field — the term stands out, the hint stays quiet. ── */ .wiktku-dfn-subgroup { margin-top: 0.5em; padding-top: 0.4em; border-top: 1px dashed var(--wikt-palette-grey-3, #e0e0e0); } .wiktku-dfn-subgroup:first-of-type { margin-top: 0.3em; padding-top: 0; border-top: none; } .wiktku-dfn-sublabel { display: block; margin-bottom: 3px; font-size: 0.88em; } .wiktku-dfn-sublabel-term { font-weight: 600; color: var(--wikt-palette-blue-9, #3366cc); letter-spacing: 0.03em; font-size: 0.92em; } .wiktku-dfn-sublabel-hint { color: var(--wikt-palette-grey-9, #767676); font-style: italic; } .wiktku-pron-wrap, .wiktku-etym-wrap, .wiktku-tewandin-wrap, .wiktku-cavkani-wrap { display: flex; flex-direction: column; gap: 3px; } /* ── POS section tabs — rounded pill style ── */ #wiktku-section-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 0.6em; align-items: center; } #wiktku-section-tabs .wiktku-section-tab { padding: 3px 12px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 999px; background: var(--wikt-palette-dullcyan); cursor: pointer; font-size: 0.86em; user-select: none; transition: background 0.12s ease, border-color 0.12s ease; } #wiktku-section-tabs .wiktku-section-tab:hover { border-color: var(--wikt-palette-blue-9, #3366cc); } #wiktku-section-tabs .wiktku-section-tab.wiktku-tab-active { background: var(--wikt-palette-blue-9, #3366cc); border-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); font-weight: 600; } /* ── Step-group tabs (Mane / Bilêvkirin / Beşên din — see STEP_GROUPS in start.js) ── Sits directly under the pill-style section tabs above; styled as an underlined secondary nav so the two bars stay visually distinct. */ #wiktku-group-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 0.8em; border-bottom: 2px solid var(--wikt-palette-lightgrey); } #wiktku-group-tabs .wiktku-group-tab { position: relative; padding: 7px 14px 8px; margin-bottom: -2px; border-bottom: 3px solid transparent; border-radius: 3px 3px 0 0; cursor: pointer; font-size: 0.95em; font-weight: 600; color: var(--wikt-palette-grey-9, #333); background: var(--wikt-palette-grey-0, #f8f9fa); user-select: none; transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease; } #wiktku-group-tabs .wiktku-group-tab:hover { color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-paleblue, #eaf3ff); } #wiktku-group-tabs .wiktku-group-tab.wiktku-tab-active { border-bottom-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); background: var(--wikt-palette-blue-9, #3366cc); font-weight: 700; } /* Small dot marking a tab that still has an unfilled required field hidden inside it (see updateGroupTabIndicators in start.js). Cleared automatically once that tab becomes the active one. */ #wiktku-group-tabs .wiktku-group-tab.wiktku-tab-missing::after { content: ""; position: absolute; top: 4px; right: -1px; width: 6px; height: 6px; border-radius: 50%; background: var(--wikt-palette-red-9, #d33); } .wiktku-lang-row-list { margin: 0; padding: 0; list-style: none; } .wiktku-lang-row { display: flex; align-items: flex-start; gap: 6px; margin-bottom: 3px; flex-wrap: wrap; } .wiktku-lang-row-words { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 3px; } /* Dûnde/Werger/Zarava rows: align the picker's height with the adjacent word textarea (see .wiktku-start-narrow above). */ .wiktku-lang-row .wiktku-native-select-wrap input.wiktku-ac-input { height: calc(1.7em + 10px); min-height: calc(1.7em + 10px); padding-top: 4px; padding-bottom: 4px; } /* ── Werger / Bi zaravayên din groups: one per gloss, shared spacing ── */ #wiktku-start-trans .wiktku-trans-group, #wiktku-start-zarava .wiktku-zarava-group { margin-bottom: 0.6em; } #wiktku-start-trans .wiktku-trans-group:last-child, #wiktku-start-zarava .wiktku-zarava-group:last-child { margin-bottom: 0; } #wiktku-start-trans .wiktku-trans-group-label, #wiktku-start-zarava .wiktku-zarava-group-label { font-weight: 600; font-size: 0.88em; margin-bottom: 3px; } .wiktku-dfn-jeder-group { margin-top: 3px; } .wiktku-dfn-quote-src-sel { font-size: 0.88em; margin-top: 3px; display: block; } .wiktku-dfn-quote-src-fields { display: flex; flex-direction: column; gap: 3px; margin-top: 3px; } /* Stacked layout: textarea gets its own full-width row, button + status sit below it on their own row. */ .wiktku-dfn-quote-citoid { display: flex; flex-direction: column; align-items: stretch; gap: 0.4em; margin-top: 3px; margin-bottom: 3px; } .wiktku-dfn-quote-citoid-input { width: 100%; max-width: 100%; box-sizing: border-box; } /* Column flex + align-items:stretch (above) makes the textarea's .wiktku-resize-wrap reach full width automatically; button and status text opt back out via align-self so they keep their natural size. */ .wiktku-dfn-quote-citoid-btn, .wiktku-dfn-quote-citoid-status { align-self: flex-start; } .wiktku-dfn-quote-src-cat-status { display: block; font-size: 0.82em; color: var(--wikt-palette-lightgrey, #767676); margin-top: 2px; } .wiktku-dfn-quote-src-row { display: flex; align-items: baseline; gap: 4px; flex-wrap: wrap; } .wiktku-dfn-quote-src-row label { font-size: 0.82em; white-space: nowrap; min-width: 8em; } textarea.wiktku-dfn-quote-src-input { flex: 1 1 12em; max-width: 100%; box-sizing: border-box; } @media (max-width: 720px) { .wiktku-lang-row { flex-direction: column; } /* Re-asserts against the skin's own mobile-breakpoint heading styles, which load after ours in the cascade. */ #wiktku-start-form .wiktku-start-step-name { font-size: 1.05em !important; margin: 0 0 0.2em !important; line-height: 1.2 !important; border: 0 !important; padding: 0 !important; } /* Single column: search box, list, and narrow textareas (Etîket, Hevmane, Dûnde/Jê/Têkildar/Binêre herwiha word boxes, citation source fields, …) all use the full width. */ .wiktku-native-select-wrap, input.wiktku-ac-input, ul.wiktku-ac-results, #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield.wiktku-start-narrow { width: 100%; max-width: 100%; } .wiktku-mod-val-input { flex: 1 1 auto; max-width: 100%; } #wiktku-start-form textarea.wiktku-dfn-mane, #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text { --wiktku-ta-rows: 3; font-size: 1em; } #wiktku-start-form .wiktku-tewandin-wrap textarea.wiktku-tewandin-text, #wiktku-start-form textarea.wiktku-cavkani-text { --wiktku-ta-rows: 4; font-size: 1em; } /* Nimûne + Jêgirtin and their tr/t sub-fields: keep at least 4 rows on mobile too, rather than shrinking further than the desktop size. */ #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t { --wiktku-ta-rows: 4; font-size: 1em; } /* Citoid URL/DOI/ISBN box: taller tap target (~2 lines) on mobile, and now that this field is a <textarea> (see start.js) its placeholder can actually wrap into that space — a plain <input>'s placeholder can never wrap, no matter its height. */ .wiktku-dfn-quote-citoid-input { min-height: calc(2 * 1.35em + 10px); font-size: 1em; } .wiktku-dfn-nimune-sub, .wiktku-dfn-quote-sub { margin-left: 0.5em; padding-left: 0.4em; } .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 1em; min-height: 2.2em; } .wiktku-dfn-quote-src-row label { min-width: 6em; } #wiktku-start-form textarea.wiktku-dfn-quote-src-input { width: 100%; flex: 1 1 100%; } .wiktku-start-step { padding: 0.5em 0.6em; } } /* =================================================================== Night mode Palette.css already flips --wikt-palette-* vars for night mode; this hook only covers real colours (panel border) that aren't a palette var, since a drop shadow is invisible against an equally dark page. =================================================================== */ @media screen { html.skin-theme-clientpref-night .wiktku-ac-results { /* Border stands in for the shadow, invisible on a dark page. */ border-color: var(--wikt-palette-grey-5); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.6); } html.skin-theme-clientpref-night .wiktku-start-step, html.skin-theme-clientpref-night .wiktku-start-step:hover, html.skin-theme-clientpref-night .wiktku-start-step:focus-within { box-shadow: none; } } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os .wiktku-ac-results { border-color: var(--wikt-palette-grey-5); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.6); } html.skin-theme-clientpref-os .wiktku-start-step, html.skin-theme-clientpref-os .wiktku-start-step:hover, html.skin-theme-clientpref-os .wiktku-start-step:focus-within { box-shadow: none; } } /* "Zimanek lê zêde bike" portlet icon (Minerva/mobile) — Feather-core-edit.svg via CSS mask, matching Minerva's own icon pattern. */ .minerva-icon-portletlink-ca-wiktku-addlang { -webkit-mask-image: url("https://upload.wikimedia.org/wikipedia/commons/d/d7/Feather-core-edit.svg"); mask-image: url("https://upload.wikimedia.org/wikipedia/commons/d/d7/Feather-core-edit.svg"); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-position: center; mask-position: center; -webkit-mask-size: 20px; mask-size: 20px; background-color: currentColor; background-image: none; } /* ── posparams step (live wikitext + helper widgets) ── */ .wiktku-posparams-wrap { display: flex; flex-direction: column; gap: 6px; } .wiktku-posparams-helpers { display: flex; flex-direction: column; gap: 4px; } .wiktku-posparams-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; } .wiktku-posparams-row label { font-size: 1em; min-width: 10em; padding-right: 0; } .wiktku-posparams-text { width: 100%; box-sizing: border-box; font-family: monospace; font-size: 0.9em; } .wiktku-posparams-opt-toggle { font-size: 0.85em; margin-top: 2px; display: inline-block; } .wiktku-posparams-opt-panel { display: flex; flex-direction: column; gap: 2px; padding: 4px 0 2px 1em; } .wiktku-posparams-opt-row { display: flex; align-items: center; gap: 4px; font-size: 0.85em; } /* ── resim step (one or more images) ── */ .wiktku-resim-list { display: flex; flex-direction: column; gap: 6px; } .wiktku-resim-item { display: flex; flex-direction: column; gap: 4px; } .wiktku-resim-item .wiktku-posparams-row { flex-direction: column; align-items: flex-start; gap: 2px; } .wiktku-resim-item .wiktku-posparams-row label { min-width: 0; font-size: 0.9em; } /* ── dfn: "hide/show all subsections" link ── Toggles a class on the whole dfn stepDiv so one click hides the etîket/kategorî/hevmane/dijmane/nimûne/jêgirtin/etc. subgroups across every sense block at once. */ .wiktku-dfn-subs-toggle { font-size: 0.85em; font-weight: 500; display: inline-block; margin: 2px 0 8px; color: var(--wikt-palette-blue-9, #3366cc); text-decoration: none; } .wiktku-dfn-subs-toggle:hover { text-decoration: underline; } /* Only the ADVANCED subgroups collapse: Nimûne, Jêgirtin, Hevmane and Dijmane stay open because they are what people come here to fill in. */ #wiktku-start-form li.wiktku-sense-adv-hidden .wiktku-dfn-subgroup-adv { display: none !important; } /* The toggle sits between the primary groups and the advanced ones, so it needs no rule of its own beyond a little breathing room. */ #wiktku-start-form .wiktku-sense-adv-row { margin-top: 14px; } /* =================================================================== Desktop text bump Modifier pills/buttons and posparams helper text read fine at their small mobile sizes but look too small on desktop, so bump them up past the 720px breakpoint only. =================================================================== */ @media (min-width: 721px) { .wiktku-mod-btn, .wiktku-mod-confirm, .wiktku-mod-cancel { width: 1.8em; height: 1.8em; font-size: 1.1em; } .wiktku-mod-pill { font-size: 0.95em; padding: 3px 10px; } .wiktku-mod-val-input { font-size: 0.95em; } .wiktku-posparams-row label { font-size: 1em; } .wiktku-posparams-text { font-size: 1em; } .wiktku-posparams-opt-toggle { font-size: 0.95em; } .wiktku-posparams-opt-row { font-size: 0.95em; } .wiktku-dfn-subs-toggle { font-size: 0.95em; } /* Multi-column card layout for posparams helper fields (transliteration, gendered forms, comparative/superlative, hanja, verb-tense roots, …), desktop-only. Rows are shown/hidden via jQuery inline display; the grid only rearranges visible rows, not which ones are visible. */ .wiktku-posparams-helpers { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px 16px; align-items: start; } .wiktku-posparams-helpers > .wiktku-posparams-row { flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 3px; } .wiktku-posparams-helpers > .wiktku-posparams-row label { min-width: 0; } .wiktku-posparams-helpers > .wiktku-posparams-row .wiktku-posparams-field, .wiktku-posparams-helpers > .wiktku-posparams-row select.wiktku-posparams-cinsiyet-sel, .wiktku-posparams-helpers > .wiktku-posparams-row select.wiktku-posparams-lektur-sel { width: 100%; max-width: 100%; box-sizing: border-box; } /* The "Jimar" row lives here too — just another .wiktku-posparams-row, no extra CSS needed. */ /* These two aren't per-field rows — span the full card width so the collapsed toggle and its checkbox list don't get squeezed into one narrow column. */ .wiktku-posparams-helpers > .wiktku-posparams-opt-toggle, .wiktku-posparams-helpers > .wiktku-posparams-opt-panel { grid-column: 1 / -1; } } /* =================================================================== SÊWIRANA NÛ — design system layer =================================================================== Purely the visual skin (colour, type, weight, radius, spacing), layered after the layout rules above so it wins the cascade. No @import of Spectral / IBM Plex from Google Fonts: Wikimedia's CSP blocks third-party font hosts, so the stacks below name the spec's faces first (used if the wiki installs them locally) and fall back to faces with the same feel. Accent colour is reserved for actionable elements (focus, links, the active tab, the primary button, chips); section headings are near-black. =================================================================== */ #wiktku-start-form { /* Surfaces */ --wikt-page: #f4efe5; --wikt-card: #fffdf8; --wikt-card-sunken: #fbf8f1; --wikt-rule: #ded6c8; /* structural hairline */ --wikt-rule-soft: #efe8db; /* inside a card */ --wikt-field-edge: #cfc7b8; --wikt-field-bg: #fff; --wikt-code-bg: #f7f4ec; --wikt-card-edge: #e6dfd2; /* Ink */ --wikt-ink: #1c1a17; --wikt-ink-2: #3d3830; --wikt-ink-3: #57514a; --wikt-muted: #8a8378; --wikt-placeholder: #b3ab9e; /* Accent + status */ --wikt-accent: #2a5db0; --wikt-accent-deep: #22406f; --wikt-accent-tint: #eef2fa; --wikt-accent-edge: #d5def0; --wikt-danger: #9c3a28; --wikt-on-accent: #fff; /* text on a filled accent button */ --wikt-link-under: rgba(42, 93, 176, 0.35); /* Shape */ --wikt-r-field: 10px; --wikt-r-card: 14px; --wikt-r-pill: 999px; --wikt-tap: 44px; /* minimum field height */ --wikt-serif: Spectral, "Iowan Old Style", Georgia, "Times New Roman", serif; --wikt-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif; --wikt-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-family: var(--wikt-sans); font-size: 15px; line-height: 1.55; color: var(--wikt-ink); background: var(--wikt-page); padding: 24px; border-radius: var(--wikt-r-card); } /* ── Cards ─────────────────────────────────────────────────────────── Flat cream panel held by a single hairline border, no shadow. */ #wiktku-start-form .wiktku-start-step { background: var(--wikt-card); border: 1px solid var(--wikt-card-edge); border-left: 1px solid var(--wikt-card-edge); border-radius: var(--wikt-r-card); box-shadow: none; padding: 24px 24px 20px; margin-bottom: 16px; transition: border-color 0.12s ease; } #wiktku-start-form .wiktku-start-step:hover, #wiktku-start-form .wiktku-start-step:focus-within { box-shadow: none; border-color: var(--wikt-rule); } /* The fused pos + posparams pair keeps reading as one card. */ #wiktku-start-form #wiktku-start-pos { border-radius: var(--wikt-r-card) var(--wikt-r-card) 0 0; border-bottom: none; padding-bottom: 8px; } #wiktku-start-form #wiktku-start-posparams { border-radius: 0 0 var(--wikt-r-card) var(--wikt-r-card); border-top: none; padding-top: 4px; } /* ── Type ──────────────────────────────────────────────────────────── Step headings: serif, regular weight, near-black. */ #wiktku-start-form .wiktku-start-step-name { font-family: var(--wikt-serif); font-size: 24px !important; font-weight: 400; letter-spacing: -0.01em; line-height: 1.15; color: var(--wikt-ink); margin: 0 0 12px; } /* display:block matters: this is a <label>, so it was sharing a line with the control it introduces wherever start.js didn't emit a <br>. */ #wiktku-start-form .wiktku-start-step-question { display: block; font-size: 15px; font-weight: 400; color: var(--wikt-ink-3); margin: 0 0 12px; line-height: 1.6; max-width: 62ch; } /* Collapses the label entirely when empty (posparams' "Cins/zayend" title can be blank) instead of leaving its margin behind as a gap; a no-op for every other step, whose question text is never empty. */ #wiktku-start-form .wiktku-start-step-question:empty { display: none; margin: 0; } /* Same reason — a field label belongs above its field, not beside it. */ #wiktku-start-form .wiktku-posparams-row label, #wiktku-start-form .wiktku-dfn-sublabel { display: block; margin-bottom: 6px; padding-right: 0; } /* Field labels: small, medium weight, full-strength ink — they label a control, so they should not read as body copy. */ #wiktku-start-form .wiktku-start-step label, #wiktku-start-form .wiktku-posparams-row label, #wiktku-start-form .wiktku-dfn-sublabel { font-size: 13px; font-weight: 500; color: var(--wikt-ink); letter-spacing: 0.01em; } /* The parenthetical/example half of a label is supporting text. */ #wiktku-start-form .wiktku-dfn-sublabel-hint, #wiktku-start-form .wiktku-step-hint { font-weight: 400; font-style: italic; color: var(--wikt-muted); font-size: 12.5px; } /* ── Fields ────────────────────────────────────────────────────────── One shape for every control: 1px edge, 10px radius, 44px tall. */ #wiktku-start-form input[type="text"], #wiktku-start-form input[type="search"], #wiktku-start-form input.wiktku-ac-input, #wiktku-start-form textarea, #wiktku-start-form select { font-family: var(--wikt-sans); font-size: 15px; color: var(--wikt-ink); background: var(--wikt-field-bg); border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-field); padding: 10px 14px; box-shadow: none; transition: border-color 0.12s ease, box-shadow 0.12s ease; } #wiktku-start-form input[type="text"], #wiktku-start-form input[type="search"], #wiktku-start-form select { min-height: var(--wikt-tap); } #wiktku-start-form textarea { line-height: 1.6; } /* Wikitext and anything template-shaped reads as code. */ #wiktku-start-form .wiktku-posparams-text, #wiktku-start-form .wiktku-pron-text, #wiktku-start-form .wiktku-etym-text, #wiktku-start-form .wiktku-cavkani-text, #wiktku-start-form .wiktku-tewandin-text, #wiktku-start-form .wiktku-pron-preview-body { font-family: var(--wikt-mono); font-size: 13.5px; background: var(--wikt-code-bg); border-color: var(--wikt-card-edge); } #wiktku-start-form ::placeholder { color: var(--wikt-placeholder); opacity: 1; } /* Focus: accent edge + 3px tint halo. The only "elevation" in the design. */ #wiktku-start-form input[type="text"]:focus, #wiktku-start-form input[type="search"]:focus, #wiktku-start-form textarea:focus, #wiktku-start-form select:focus, #wiktku-start-form input.wiktku-ac-input:focus { border-color: var(--wikt-accent); box-shadow: 0 0 0 3px var(--wikt-accent-tint); outline: 0; } /* The searchable picker's visible input is the field, so it takes the field shape too (it otherwise inherits an older, boxier rule). */ #wiktku-start-form input.wiktku-ac-input { min-height: var(--wikt-tap); border-radius: var(--wikt-r-field); border-color: var(--wikt-field-edge); font-size: 15px; } #wiktku-start-form .wiktku-ac-results { border: 1px solid var(--wikt-rule); border-radius: var(--wikt-r-field); background: var(--wikt-card); box-shadow: none; } #wiktku-start-form .wiktku-ac-results li.wiktku-ac-active, #wiktku-start-form .wiktku-ac-results li:hover { background: var(--wikt-accent-tint); color: var(--wikt-accent-deep); } /* ── Tabs → the accent's main job ──────────────────────────────────── Active tab: tint fill + 3px accent underline, per the spec's "xala hûrgulî" note. Inactive tabs are plain text. */ #wiktku-start-form #wiktku-group-tabs, #wiktku-start-form #wiktku-section-tabs { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; border-bottom: 1px solid var(--wikt-rule); margin-bottom: 16px; padding-bottom: 0; } /* Both bars are direct children of #wiktku-start-form, so a sticky child stays stuck for as long as any part of the form is in view. Background is opaque so content scrolling underneath doesn't show through. Section-tabs pins below --wiktku-siteheader-h — an offset for Vector 2022's own sticky header, which otherwise sits on top of it at top:0 (Minerva has no such header, so mobile needs no offset); group-tabs pins below that plus --wiktku-stabs-h (section-tabs' own height). Both custom properties are set by syncStickyTabsOffset() in start.js and fall back to 0 on skins without a Vector sticky header. */ #wiktku-start-form #wiktku-section-tabs { position: sticky; top: var(--wiktku-siteheader-h, 0px); z-index: 20; background: var(--wikt-card); } #wiktku-start-form #wiktku-group-tabs { position: sticky; top: calc(var(--wiktku-siteheader-h, 0px) + var(--wiktku-stabs-h, 0px)); z-index: 19; background: var(--wikt-card); } #wiktku-start-form .wiktku-group-tab, #wiktku-start-form .wiktku-section-tab { font-size: 13.5px; font-weight: 500; color: var(--wikt-ink-3); background: transparent; border: 0; border-bottom: 3px solid transparent; border-radius: var(--wikt-r-pill) var(--wikt-r-pill) 0 0; padding: 9px 14px 11px; cursor: pointer; transition: background 0.12s ease, color 0.12s ease; } #wiktku-start-form .wiktku-group-tab:hover, #wiktku-start-form .wiktku-section-tab:hover { background: var(--wikt-card-sunken); color: var(--wikt-ink); } #wiktku-start-form .wiktku-group-tab.wiktku-tab-active, #wiktku-start-form .wiktku-section-tab.wiktku-tab-active { background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom-color: var(--wikt-accent); } /* ── Progressive-disclosure toggles ────────────────────────────────── Shared by "Tercîhên pêşketî" (posparams) and "Malûmatên pêşketî" (Mane): a rotating chevron plus a count of what's hidden. */ #wiktku-start-form .wiktku-adv-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin: 4px 0 12px; padding-top: 16px; border-top: 1px solid var(--wikt-rule-soft); } #wiktku-start-form .wiktku-adv-toggle { display: inline-flex; align-items: center; gap: 10px; font-size: 14px; font-weight: 500; color: var(--wikt-accent); text-decoration: none; cursor: pointer; } #wiktku-start-form .wiktku-adv-toggle:hover .wiktku-adv-toggle-text { text-decoration: underline; } #wiktku-start-form .wiktku-adv-toggle-chevron { width: 22px; height: 22px; flex: 0 0 22px; display: grid; place-items: center; font-size: 11px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); border-radius: 6px; transform: rotate(-90deg); transition: transform 0.15s ease; } /* Open state: dfn flips the class on the step, posparams on the link. */ #wiktku-start-form .wiktku-adv-toggle.wiktku-adv-open .wiktku-adv-toggle-chevron, #wiktku-start-dfn:not(.wiktku-dfn-subs-hidden) .wiktku-adv-toggle-chevron { transform: rotate(0deg); } #wiktku-start-form .wiktku-posparams-adv-panel { border: 1px solid var(--wikt-rule-soft); border-radius: 12px; background: var(--wikt-card-sunken); padding: 20px 18px; margin-bottom: 4px; } /* ── posparams grid ────────────────────────────────────────────────── "Tor, ne rêz" — two columns, nothing narrower than 220px, so the six gender/number fields stop being a six-across scanline. */ @media (min-width: 721px) { #wiktku-start-form .wiktku-posparams-helpers, #wiktku-start-form .wiktku-posparams-adv-panel { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 18px 22px; align-items: start; } #wiktku-start-form .wiktku-posparams-adv-panel > .wiktku-posparams-row, #wiktku-start-form .wiktku-posparams-helpers > .wiktku-posparams-row { flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 7px; } #wiktku-start-form .wiktku-posparams-helpers > .wiktku-adv-toggle-row, #wiktku-start-form .wiktku-posparams-helpers > .wiktku-posparams-adv-panel, #wiktku-start-form .wiktku-posparams-adv-panel > .wiktku-posparams-opt-panel { grid-column: 1 / -1; } } #wiktku-start-form .wiktku-posparams-opt-panel { border-top: 1px solid var(--wikt-rule-soft); padding-top: 14px; margin-top: 4px; } #wiktku-start-form .wiktku-posparams-opt-row { font-size: 13px; color: var(--wikt-ink-3); } /* ── Sense blocks ──────────────────────────────────────────────────── Each sense is a sunken panel inside the Mane card, with its number as an accent counter — so "how many meanings am I writing" is legible at a glance. */ #wiktku-start-form .wiktku-dfn-subgroup { margin: 14px 0 0; padding-top: 14px; border-top: 1px solid var(--wikt-rule-soft); } /* No divider above the first item — it would be a rule against the sense's own text. Needed explicitly: the earlier :first-of-type rule is a class selector and loses to this id-scoped one. */ #wiktku-start-form .wiktku-dfn-subgroup:first-of-type { margin-top: 8px; padding-top: 0; border-top: none; } #wiktku-start-form .wiktku-dfn-sublabel-term { color: var(--wikt-ink); } /* Plain white field like any other, not a tinted fill — a tint would read as "disabled" next to the white Mane box above it. */ #wiktku-start-form .wiktku-dfn-subfield, #wiktku-start-form textarea.wiktku-dfn-mane { background: var(--wikt-field-bg); border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-field); } /* No "1." "2." markers on the sub-lists: numbered rows would read as a form to fill top-down, when each row is really "another one if you have one" — and the marker would land on its own line above the block-level textarea, looking like a stray character. */ #wiktku-start-form .wiktku-dfn-sublist { margin: 0; padding-left: 0; list-style: none; } #wiktku-start-form .wiktku-dfn-sublist > li { margin-bottom: 6px; } /* ── Chips: tags, modifiers, template pills ──────────────────────────── */ #wiktku-start-form .wiktku-mod-pill, #wiktku-start-form .wiktku-besendin-select + .wiktku-chip { background: var(--wikt-accent-tint); color: var(--wikt-accent-deep); border: 1px solid var(--wikt-accent-edge); border-radius: var(--wikt-r-pill); font-size: 13px; padding: 6px 12px; } #wiktku-start-form .wiktku-mod-btn, #wiktku-start-form .wiktku-mod-confirm, #wiktku-start-form .wiktku-mod-cancel { border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); border-radius: 8px; } /* ── Footer + buttons ──────────────────────────────────────────────── One primary filled pill; destructive actions are outline-only in the danger colour so they stay quiet next to it. */ #wiktku-start-form #wiktku-start-footer { background: var(--wikt-card-sunken); border-top: 1px solid var(--wikt-rule); border-radius: 0 0 var(--wikt-r-card) var(--wikt-r-card); padding: 16px 20px; gap: 10px; } #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement-button { border-radius: var(--wikt-r-pill) !important; font-family: var(--wikt-sans); font-size: 14px; font-weight: 500; padding: 11px 22px; box-shadow: none !important; min-height: var(--wikt-tap); } #wiktku-start-form #wiktku-unhide-editform .oo-ui-buttonElement-button { background: var(--wikt-accent) !important; border-color: var(--wikt-accent) !important; color: var(--wikt-on-accent) !important; } /* Destructive actions: outline, not fill. */ #wiktku-start-form #wiktku-start-footer .oo-ui-flaggedElement-destructive .oo-ui-buttonElement-button { background: var(--wikt-card) !important; border-color: var(--wikt-danger) !important; color: var(--wikt-danger) !important; } #wiktku-start-form #wiktku-last-saved { font-family: var(--wikt-mono); font-size: 12px; color: var(--wikt-muted); } /* ── Beşên din picker ──────────────────────────────────────────────── This dropdown is now the entry point to eighteen sections, so it gets room and a label rather than sitting flush under the tab bar. */ #wiktku-start-form .wiktku-besendin-picker { margin: 0 0 20px; padding: 16px 18px; background: var(--wikt-card); border: 1px solid var(--wikt-card-edge); border-radius: 12px; } #wiktku-start-form .wiktku-besendin-picker .wiktku-native-select-wrap, #wiktku-start-form .wiktku-besendin-picker input.wiktku-ac-input { width: 100%; max-width: 28em; } /* ── Notices ─────────────────────────────────────────────────────────── */ #wiktku-start-form .wiktku-addlang-notice { background: var(--wikt-accent-tint); border: 1px solid var(--wikt-accent-edge); border-radius: var(--wikt-r-field); color: var(--wikt-ink-2); padding: 12px 16px; margin-bottom: 16px; } #wiktku-start-form .wiktku-pron-preview { background: var(--wikt-accent-tint); border-color: var(--wikt-accent-edge); border-radius: 12px; } #wiktku-start-form .wiktku-pron-preview-confirm, #wiktku-start-form .wiktku-pron-preview-cancel { border-radius: var(--wikt-r-pill); padding: 8px 16px; min-height: 36px; } /* Links carry the accent and a soft underline, per the spec's `a` rule. */ #wiktku-start-form a { color: var(--wikt-accent); text-decoration: none; border-bottom: 1px solid var(--wikt-link-under); } #wiktku-start-form a:hover { color: var(--wikt-accent-deep); } #wiktku-start-form .wiktku-adv-toggle, #wiktku-start-form .wiktku-group-tab, #wiktku-start-form .wiktku-section-tab { border-bottom-style: solid; } #wiktku-start-form .wiktku-adv-toggle { border-bottom: 0; } /* =================================================================== Dark mode =================================================================== Every colour above is a token on #wiktku-start-form, so this is a swap of that one block. Only applies given an explicit dark signal (skin-theme-clientpref-night / skin-nightmode, or skin-theme-clientpref-os plus prefers-color-scheme: dark) — no bare prefers-color-scheme fallback, since legacy Vector sets no theme class either and would otherwise go dark with nothing else on the page to match. Palette is warm, not neutral grey, to keep the cream design's character. Accent lightens to #7ba7e8 since #2a5db0 on a dark card is ~2.4:1 contrast and reads as near-black. =================================================================== */ html.skin-theme-clientpref-night #wiktku-start-form, html.skin-nightmode #wiktku-start-form { --wikt-page: #171613; --wikt-card: #201e1a; --wikt-card-sunken: #1a1916; --wikt-card-edge: #322e28; --wikt-rule: #3a3630; --wikt-rule-soft: #2c2924; --wikt-field-edge: #4a453d; --wikt-field-bg: #191815; --wikt-code-bg: #14130f; --wikt-ink: #ece7dd; --wikt-ink-2: #d5cfc4; --wikt-ink-3: #b3aca1; --wikt-muted: #8f887c; --wikt-placeholder: #6d675e; --wikt-accent: #7ba7e8; --wikt-accent-deep: #cfe0f8; --wikt-accent-tint: #1c2839; --wikt-accent-edge: #35496b; --wikt-danger: #e5907c; --wikt-on-accent: #14213a; --wikt-link-under: rgba(123, 167, 232, 0.4); } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os #wiktku-start-form { --wikt-page: #171613; --wikt-card: #201e1a; --wikt-card-sunken: #1a1916; --wikt-card-edge: #322e28; --wikt-rule: #3a3630; --wikt-rule-soft: #2c2924; --wikt-field-edge: #4a453d; --wikt-field-bg: #191815; --wikt-code-bg: #14130f; --wikt-ink: #ece7dd; --wikt-ink-2: #d5cfc4; --wikt-ink-3: #b3aca1; --wikt-muted: #8f887c; --wikt-placeholder: #6d675e; --wikt-accent: #7ba7e8; --wikt-accent-deep: #cfe0f8; --wikt-accent-tint: #1c2839; --wikt-accent-edge: #35496b; --wikt-danger: #e5907c; --wikt-on-accent: #14213a; --wikt-link-under: rgba(123, 167, 232, 0.4); } } /* A handful of rules still name literal light colours instead of tokens; neutralise the ones that actually show through in night mode. */ html.skin-theme-clientpref-night #wiktku-start-form .wiktku-ac-results, html.skin-nightmode #wiktku-start-form .wiktku-ac-results { background: var(--wikt-card); border-color: var(--wikt-rule); color: var(--wikt-ink); } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os #wiktku-start-form .wiktku-ac-results { background: var(--wikt-card); border-color: var(--wikt-rule); color: var(--wikt-ink); } } /* =================================================================== Autocomplete list: stop it escaping its card =================================================================== A fixed width would run past the card's border on full-width pickers, since the list is absolutely positioned at the wrapper's left edge. width:100% ties it to the (shrink-to-fit) wrapper's input width instead; min/max-width keep short pickers readable and stop viewport overflow. */ #wiktku-start-form ul.wiktku-ac-results { width: 100%; min-width: min(18em, 100%); max-width: min(92vw, 34em); box-sizing: border-box; border-radius: var(--wikt-r-field); box-shadow: none; } /* And the wrapper itself must not exceed the card it sits in. */ #wiktku-start-form .wiktku-native-select-wrap { max-width: 100%; } #wiktku-start-form .wiktku-cavkani-wrap .wiktku-native-select-wrap, #wiktku-start-form .wiktku-cavkani-wrap input.wiktku-ac-input, #wiktku-start-form .wiktku-pron-wrap .wiktku-native-select-wrap, #wiktku-start-form .wiktku-etym-wrap .wiktku-native-select-wrap { width: 100%; max-width: 100%; box-sizing: border-box; } /* =================================================================== Mobile footer =================================================================== Below 720px the primary button keeps its full size and everything else shrinks to a secondary scale, so the sticky footer doesn't dominate a phone viewport. =================================================================== */ @media (max-width: 720px) { #wiktku-start-form { padding: 12px; font-size: 14px; } #wiktku-start-form .wiktku-start-step { padding: 16px 14px 14px; border-radius: 12px; } #wiktku-start-form .wiktku-start-step-name { font-size: 20px !important; } #wiktku-start-form #wiktku-start-footer { padding: 10px 12px; gap: 6px; row-gap: 8px; } #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement-button { font-size: 13px; padding: 8px 14px; min-height: 38px; } /* The one you actually press stays thumb-sized. */ #wiktku-start-form #wiktku-unhide-editform .oo-ui-buttonElement-button { font-size: 14px; padding: 10px 20px; min-height: var(--wikt-tap); } /* Secondary actions share a row instead of each claiming a full one. */ #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement { flex: 0 1 auto; } #wiktku-start-form #wiktku-last-saved { flex: 1 0 100%; order: 10; font-size: 11px; white-space: normal; } #wiktku-start-form .wiktku-adv-toggle-row { gap: 8px; } } /* =================================================================== IPA character palette (v3 spec) =================================================================== Click-to-insert chart under Bilêvkirin, after fr.wiktionary's. Two sub-tabs — a short Kurmancî set that opens by default, and the full chart — because ~20 of the ~180 IPA symbols ever occur in Kurmancî and showing all of them first is the same "wall of fields" problem this redesign exists to fix. =================================================================== */ #wiktku-start-form .wiktku-ipa-panel { border: 1px solid var(--wikt-card-edge); border-radius: 12px; background: var(--wikt-card-sunken); padding: 0 0 12px; margin-bottom: 8px; overflow: hidden; } #wiktku-start-form .wiktku-ipa-subtabs { display: flex; align-items: center; gap: 4px; padding: 8px 12px 0; border-bottom: 1px solid var(--wikt-rule-soft); margin-bottom: 12px; flex-wrap: wrap; } #wiktku-start-form .wiktku-ipa-subtab { font-size: 13px; font-weight: 500; color: var(--wikt-ink-3); padding: 7px 12px 9px; border-bottom: 3px solid transparent; border-radius: 8px 8px 0 0; cursor: pointer; } #wiktku-start-form .wiktku-ipa-subtab:hover { background: var(--wikt-card); color: var(--wikt-ink); } #wiktku-start-form .wiktku-ipa-subtab.wiktku-tab-active { background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom-color: var(--wikt-accent); } /* Templates are not characters, so they sit apart from the chart — pinned to the right of the sub-tab row. */ #wiktku-start-form .wiktku-ipa-tplbtns { margin-left: auto; display: flex; gap: 6px; padding-bottom: 6px; } #wiktku-start-form .wiktku-ipa-tplbtn { font-family: var(--wikt-mono); font-size: 12px; padding: 6px 10px; border-radius: 7px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); cursor: pointer; white-space: nowrap; } #wiktku-start-form .wiktku-ipa-tplbtn:hover { border-color: var(--wikt-accent); } #wiktku-start-form .wiktku-ipa-grid { display: flex; flex-direction: column; gap: 8px; padding: 0 12px; } #wiktku-start-form .wiktku-ipa-row { display: flex; align-items: flex-start; gap: 10px; } #wiktku-start-form .wiktku-ipa-rowlabel { flex: 0 0 74px; font-size: 11.5px; color: var(--wikt-muted); padding-top: 8px; line-height: 1.3; } #wiktku-start-form .wiktku-ipa-keys { display: flex; flex-wrap: wrap; gap: 4px; flex: 1 1 auto; } #wiktku-start-form .wiktku-ipa-key { width: 30px; height: 30px; padding: 0; border-radius: 8px; border: 1px solid var(--wikt-field-edge); background: var(--wikt-field-bg); color: var(--wikt-ink); font-family: var(--wikt-mono); font-size: 14px; line-height: 1; cursor: pointer; display: grid; place-items: center; transition: background 0.1s ease, border-color 0.1s ease; } #wiktku-start-form .wiktku-ipa-key:hover { background: var(--wikt-accent-tint); border-color: var(--wikt-accent); color: var(--wikt-accent-deep); } #wiktku-start-form .wiktku-ipa-key:active { transform: translateY(1px); } /* Ligatures like d͡ʒ and long vowels need a little more room than one glyph; let those keys grow instead of clipping. */ #wiktku-start-form .wiktku-ipa-key { width: auto; min-width: 30px; padding: 0 5px; } /* A combining mark is shown on a dotted circle so it has something to attach to; only the mark itself is inserted. */ #wiktku-start-form .wiktku-ipa-key-combining { color: var(--wikt-ink-2); } @media (max-width: 720px) { #wiktku-start-form .wiktku-ipa-row { flex-direction: column; gap: 3px; } #wiktku-start-form .wiktku-ipa-rowlabel { flex: 0 0 auto; padding-top: 0; } #wiktku-start-form .wiktku-ipa-key { min-width: 34px; height: 34px; } } /* ── "+ Beş zêde bike" menu ────────────────────────────────────────── Adding a part of speech and adding Bilêvkirin are different actions, so the button opens a small menu instead of doing one of them. */ #wiktku-start-form .wiktku-addsection-menu { position: absolute; z-index: 60; margin-top: 6px; min-width: 15em; background: var(--wikt-card); border: 1px solid var(--wikt-rule); border-radius: 10px; padding: 4px; display: flex; flex-direction: column; } #wiktku-start-form .wiktku-addsection-item { display: flex; flex-direction: column; gap: 1px; padding: 8px 10px; border-radius: 7px; border-bottom: 0; text-decoration: none; color: var(--wikt-ink); } #wiktku-start-form .wiktku-addsection-item:hover { background: var(--wikt-accent-tint); } #wiktku-start-form .wiktku-addsection-item-label { font-size: 13.5px; font-weight: 500; } #wiktku-start-form .wiktku-addsection-item-hint { font-size: 11.5px; color: var(--wikt-muted); } #wiktku-start-form #wiktku-section-tabs .oo-ui-buttonElement { position: relative; } /* Bilêvkirin is a peer of the POS sections but not a part of speech — a hairline before it marks the boundary. */ #wiktku-start-form .wiktku-section-tab-pron { margin-left: 6px; border-left: 1px solid var(--wikt-rule); padding-left: 14px; border-radius: 0; } /* =================================================================== Per-sense tabs =================================================================== "Mane 1 / Mane 2 / + Mane zêde bike" switches which sense is shown; only the active one is in the flow, so a multi-sense entry doesn't turn into a long scroll. */ #wiktku-start-form .wiktku-dfn-sense-tabs { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; border-bottom: 1px solid var(--wikt-rule); margin-bottom: 14px; } #wiktku-start-form .wiktku-dfn-sense-tab { font-size: 13px; font-weight: 500; color: var(--wikt-ink-3); background: transparent; border: 0; border-bottom: 3px solid transparent; border-radius: var(--wikt-r-pill) var(--wikt-r-pill) 0 0; padding: 7px 12px 9px; cursor: pointer; user-select: none; transition: background 0.12s ease, color 0.12s ease; } #wiktku-start-form .wiktku-dfn-sense-tab:hover { background: var(--wikt-card-sunken); color: var(--wikt-ink); } #wiktku-start-form .wiktku-dfn-sense-tab.wiktku-tab-active { background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom-color: var(--wikt-accent); } #wiktku-start-form li.wiktku-dfn-sense { border: 1px solid var(--wikt-card-edge); border-radius: 12px; background: var(--wikt-card); margin-bottom: 10px; padding: 14px; list-style: none; overflow: visible; } #wiktku-start-form li.wiktku-dfn-sense.wiktku-sense-collapsed { display: none; } /* =================================================================== Template rows in the pickers (v3 spec) =================================================================== One row shape everywhere a template is chosen: the ⓘ explains terms like "guharto/kevnbûyî/ku-Latn/şaşnivîs" without leaving the form, and the 🔗 links out for when it doesn't. =================================================================== */ #wiktku-start-form ul.wiktku-ac-results li.wiktku-ac-tplrow { display: flex; align-items: center; gap: 8px; min-height: 44px; white-space: normal; padding: 6px 10px; } #wiktku-start-form .wiktku-ac-tpltext { flex: 1 1 auto; min-width: 0; font-family: var(--wikt-mono); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* Status, not category: green is the one to reach for, yellow means "only if you specifically need it" (kevnbûyî, şaşnivîs, kêmpeyda). */ #wiktku-start-form .wiktku-tpl-dot { flex: 0 0 8px; width: 8px; height: 8px; border-radius: 999px; } #wiktku-start-form .wiktku-tpl-dot-ok { background: #3d8a55; } #wiktku-start-form .wiktku-tpl-dot-special { background: #c9971f; } #wiktku-start-form .wiktku-tpl-icons { flex: 0 0 auto; display: flex; gap: 5px; align-items: center; } #wiktku-start-form .wiktku-tpl-icon { width: 26px; height: 26px; display: grid; place-items: center; font-size: 12px; line-height: 1; cursor: pointer; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom: 1px solid var(--wikt-accent-edge); text-decoration: none; padding: 0; } #wiktku-start-form .wiktku-tpl-icon-link { border-radius: 7px; } #wiktku-start-form .wiktku-tpl-icon-info { border-radius: 999px; font-family: var(--wikt-serif); font-style: italic; font-weight: 600; background: transparent; border-color: var(--wikt-field-edge); color: var(--wikt-muted); } #wiktku-start-form .wiktku-tpl-icon:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); background: var(--wikt-accent-tint); } /* ── The ⓘ panel ───────────────────────────────────────────────────── Three parts, in the spec's order: what it does, its parameters, and a way out to the template page. */ #wiktku-start-form .wiktku-tpl-info { position: relative; margin: 8px 0 4px; padding: 14px 16px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); border-radius: 12px; font-size: 13.5px; line-height: 1.6; color: var(--wikt-ink-2); } #wiktku-start-form .wiktku-tpl-info-name { font-family: var(--wikt-mono); font-size: 13px; color: var(--wikt-accent-deep); margin-bottom: 6px; } #wiktku-start-form .wiktku-tpl-info-params { margin-top: 8px; } #wiktku-start-form .wiktku-tpl-info-params-title { font-size: 12px; color: var(--wikt-muted); margin-bottom: 2px; } #wiktku-start-form .wiktku-tpl-info-params ul { margin: 0; padding-left: 18px; font-family: var(--wikt-mono); font-size: 12.5px; } #wiktku-start-form .wiktku-tpl-info-link { display: inline-block; margin-top: 10px; font-size: 13px; } #wiktku-start-form .wiktku-tpl-info-close { position: absolute; top: 8px; right: 8px; width: 24px; height: 24px; border-radius: 999px; border: 0; background: transparent; color: var(--wikt-muted); cursor: pointer; font-size: 13px; line-height: 1; } #wiktku-start-form .wiktku-tpl-info-close:hover { background: var(--wikt-card); color: var(--wikt-ink); } /* =================================================================== Footer overflow "⋯" (v3 spec) =================================================================== Bişîne and "Edîtora çavkaniyê veke" stay on the bar; the cache actions, saved-at note and Tercîh move in here so the destructive buttons don't compete for attention and the sticky footer stays to one row on a phone. =================================================================== */ #wiktku-start-form .wiktku-more-wrap { position: relative; margin-left: auto; flex: 0 0 auto; } #wiktku-start-form .wiktku-more-btn { width: 36px; height: 36px; border-radius: 999px; border: 1px solid var(--wikt-field-edge); background: var(--wikt-card); color: var(--wikt-muted); font-size: 16px; line-height: 1; cursor: pointer; display: grid; place-items: center; } #wiktku-start-form .wiktku-more-btn:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); } #wiktku-start-form .wiktku-more-menu { position: absolute; right: 0; bottom: calc(100% + 8px); z-index: 70; min-width: 17em; background: var(--wikt-card); border: 1px solid var(--wikt-rule); border-radius: 12px; padding: 6px; display: flex; flex-direction: column; gap: 2px; } #wiktku-start-form .wiktku-more-item { display: flex; align-items: center; gap: 8px; } /* The buttons inside the menu are menu rows, not buttons on a bar. */ #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement { flex: 1 1 auto; } #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement-button { display: block; width: 100%; text-align: left; border: 0 !important; background: transparent !important; border-radius: 7px !important; padding: 9px 10px; min-height: 0; font-weight: 400; color: var(--wikt-ink) !important; } #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement-button:hover { background: var(--wikt-accent-tint) !important; } #wiktku-start-form .wiktku-more-item-danger .oo-ui-buttonElement-button { color: var(--wikt-danger) !important; } #wiktku-start-form .wiktku-more-item-prefs .wiktku-prefs-btn { width: 26px; height: 26px; flex: 0 0 26px; border: 0; background-color: transparent; } #wiktku-start-form .wiktku-more-item-label { font-size: 13.5px; } #wiktku-start-form .wiktku-more-sep { height: 1px; background: var(--wikt-rule-soft); margin: 4px 2px; } #wiktku-start-form .wiktku-more-note { padding: 4px 10px 2px; } #wiktku-start-form .wiktku-more-note #wiktku-last-saved { white-space: normal; } /* "+ Mane zêde bike" sits as the last item in .wiktku-dfn-sense-tabs. */ #wiktku-start-form .wiktku-add-sense { display: inline-flex; align-items: center; gap: 6px; margin: 3px 0; padding: 6px 14px; border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-pill); background: var(--wikt-card); color: var(--wikt-ink-2); font-family: var(--wikt-sans); font-size: 13px; cursor: pointer; min-height: 34px; } #wiktku-start-form .wiktku-add-sense:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); background: var(--wikt-accent-tint); } #wiktku-start-form .wiktku-add-sense-plus { color: var(--wikt-accent); font-size: 15px; line-height: 1; } /* ── Şablon picker, demoted to a link ──────────────────────────────── Picking a template replaces the definition rather than adding to it, so it is an alternative route, not the first control in the sense. Hidden behind one line of text until it is actually wanted. */ #wiktku-start-form .wiktku-dfn-tpl-link { display: inline-block; margin-top: 8px; font-size: 12.5px; color: var(--wikt-muted); border-bottom: 1px solid transparent; } #wiktku-start-form .wiktku-dfn-tpl-link:hover { color: var(--wikt-accent); border-bottom-color: var(--wikt-link-under); } #wiktku-start-form .wiktku-dfn-tpl-row { margin-top: 10px; padding-top: 12px; border-top: 1px solid var(--wikt-rule-soft); } /* ── Template-row icons on touch screens ───────────────────────────── 26px is fine for a mouse and too small for a thumb, and these two sit right next to each other at the end of a row you can also tap to select. Give them real targets and some separation on small screens. */ @media (max-width: 720px), (pointer: coarse) { #wiktku-start-form .wiktku-tpl-icon { width: 34px; height: 34px; font-size: 14px; } #wiktku-start-form .wiktku-tpl-icons { gap: 8px; padding-left: 4px; } #wiktku-start-form ul.wiktku-ac-results li.wiktku-ac-tplrow { min-height: 50px; } } /* The rendered pronunciation preview is real parser output, so it needs to sit as content rather than in the monospace wikitext treatment the panel inherits. */ #wiktku-start-form .wiktku-pron-preview-body { font-family: var(--wikt-sans); font-size: 15px; background: var(--wikt-card); border: 1px solid var(--wikt-accent-edge); border-radius: 8px; padding: 10px 12px; white-space: normal; } #wiktku-start-form .wiktku-pron-preview-body .IPA, #wiktku-start-form .wiktku-pron-preview-body code, #wiktku-start-form .wiktku-pron-preview-body tt { font-family: var(--wikt-mono); } /* Parser output brings its own margins; strip the outer ones so the preview box doesn't gain a blank first line. */ #wiktku-start-form .wiktku-pron-preview-body > *:first-child { margin-top: 0; } #wiktku-start-form .wiktku-pron-preview-body > *:last-child { margin-bottom: 0; } hztfzdxv3krc96l7kihoptc4v7te51s 6333856 6333832 2026-08-15T17:46:03Z Wikihez 7344 6333856 css text/css /* =================================================================== #editform while the wizard is active =================================================================== */ /* Keeps #editform genuinely laid out instead of display:none*/ .wiktku-offscreen { position: absolute !important; left: -9999px !important; top: 0 !important; width: 100%; max-width: 100%; visibility: hidden; } /* =================================================================== Base scale =================================================================== */ #wiktku-start-form { font-size: 0.92em; line-height: 1.35; } #wiktku-start-form * { box-sizing: border-box; } .wiktku-addlang-notice { margin: 0 0 0.8em; padding: 0.6em 0.8em; background: var(--wikt-palette-paleblue); border: 1px solid var(--wikt-palette-lightgrey); border-radius: 4px; } /* =================================================================== Step cards a compact card with a left accent bar, so each step reads as a distinct unit =================================================================== */ .wiktku-start-step { padding: 0.7em 0.9em; margin-bottom: 0.6em; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-left: 4px solid var(--wikt-palette-blue-9, #3366cc); border-radius: 6px; background: var(--wikt-palette-white); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); transition: border-left-color 0.15s ease, box-shadow 0.15s ease; } .wiktku-start-step:hover { box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08); } .wiktku-start-step:focus-within { border-left-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); } /* Fuses the posparams card onto the bottom of the pos card (shared left accent bar, no border/gap) since posparams always renders directly after #wiktku-start-pos once a pos is chosen. */ #wiktku-start-pos { border-radius: 6px 6px 0 0; margin-bottom: 0; border-bottom: none; } #wiktku-start-posparams { border-radius: 0 0 6px 6px; border-top: none; padding-top: 0.3em; } #wiktku-start-posparams .wiktku-start-step-name { display: none; } /* Scoped and !important: this is a real <h3> tag (see start.js), so the skin's default heading styles would otherwise override a plain class rule. Coloured to match the card's accent bar; .wiktku-start-step-question below stays lighter/muted so the two don't compete. */ #wiktku-start-form .wiktku-start-step-name { font-size: 1.1em !important; font-weight: 700; letter-spacing: 0.03em; margin: 0 0 0.3em; line-height: 1.2; color: var(--wikt-palette-blue-9, #3366cc); border: 0; padding: 0; } /* Sized close to the heading so the card reads consistently instead of the text below it looking like fine print. */ .wiktku-start-step-question { font-size: 1em; font-weight: 400; color: var(--wikt-palette-grey-9, #555); margin: 0 0 0.5em; line-height: 1.45; } .wiktku-start-step label { padding-right: 1.2em; font-size: 1em; } /* Muted hint text next to a field, styled to read as a hint rather than another question competing with .wiktku-start-step-question. */ .wiktku-step-hint { font-size: 0.88em; font-style: italic; color: var(--wikt-palette-grey-8, #72777d); margin: 0 0 0.5em; line-height: 1.4; } /* Same specificity as the rule just above, so it must come after to actually win: the name label isn't a field label needing right padding or the form's base label size, it's a heading. */ #wiktku-start-form .wiktku-start-step-name label { padding-right: 0; font-size: inherit !important; color: inherit; } input[type="text"].wiktku-start-step-field { width: 100%; padding: 5px 8px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 4px; transition: border-color 0.12s ease, box-shadow 0.12s ease; } input[type="text"].wiktku-start-step-field:focus { border-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9, #3366cc); outline: 0; } input[type="text"].wiktku-start-step-field.wiktku-start-narrow { width: 20em; } /* Only used by selects that opt out via .wiktku-plain-select; other selects get their width from the searchable picker instead (see input.wiktku-ac-input). */ select.wiktku-start-narrow, input.wiktku-dfn-tpl-title { width: 20em; max-width: 100%; box-sizing: border-box; } #wiktku-start-spinner { float: right; margin-left: 1em; } #wiktku-start-footer { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5em; padding: 0.6em 0.2em; position: sticky; bottom: 0; background: var(--wikt-palette-white); border-top: 1px solid var(--wikt-palette-grey-3, #e0e0e0); z-index: 5; } /* Quiet, non-competing text — sits next to the cache buttons so the person can tell at a glance whether their latest edits are backed up, without it fighting the buttons for attention. */ #wiktku-last-saved { font-size: 0.85em; color: var(--wikt-palette-grey-9, #767676); white-space: nowrap; } /* ── Tercîh (settings) icon button — sits in the footer next to the cache buttons. Uses the Codex "settings" (color-subtle) icon from Commons directly rather than an OOUI icon-pack module, so it renders the exact requested glyph without pulling in an extra dependency. */ .wiktku-prefs-btn { width: 2.2em; height: 2.2em; flex: 0 0 auto; padding: 0; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-radius: 2px; background-color: var(--wikt-palette-white); background-image: url(//upload.wikimedia.org/wikipedia/commons/e/e0/Codex_icon_settings_color-subtle.svg); background-repeat: no-repeat; background-position: center; background-size: 1.2em 1.2em; cursor: pointer; } .wiktku-prefs-btn:hover { background-color: var(--wikt-palette-grey-0, #f8f9fa); } .wiktku-prefs-btn:active { background-color: var(--wikt-palette-grey-1, #eaecf0); } /* Tercîh dialog body — OOUI's bare ProcessDialog body has no inset of its own, so text/fields otherwise sit flush against the window edges. */ .wiktku-prefs-dialog-body { padding: 1em 1.2em; } /* ── "Bişîne" click feedback ── */ @keyframes wiktku-btn-flash-pulse { 0% { box-shadow: 0 0 0 0 rgba(51, 102, 204, 0.55); } 70% { box-shadow: 0 0 0 9px rgba(51, 102, 204, 0); } 100% { box-shadow: 0 0 0 0 rgba(51, 102, 204, 0); } } #wiktku-unhide-editform.wiktku-btn-flash { animation: wiktku-btn-flash-pulse 0.5s ease-out; } /* Persistent state while the wikitext is being built/submitted, set alongside OOUI's own setDisabled(true) so it reads clearly even if the skin's default disabled style is subtle. */ #wiktku-unhide-editform.wiktku-btn-sending .oo-ui-buttonElement-button { background-color: var(--wikt-palette-grey-9, #767676) !important; border-color: var(--wikt-palette-grey-9, #767676) !important; cursor: progress; opacity: 1 !important; } /* Looks like OOUI's disabled state but isn't one — the button stays clickable so its handler can still run and explain why (see the wiktkuNotify call next to wiktkuContentGateOk in start.js). */ #wiktku-unhide-editform.wiktku-btn-soft-disabled .oo-ui-buttonElement-button { opacity: 0.5; cursor: not-allowed; } /* ── "Beşên din" picker ── */ .wiktku-besendin-picker { margin: 0.6em 0 1em; } .wiktku-besendin-picker .wiktku-besendin-select { width: 100%; max-width: 24em; } #wiktku-start-form textarea.wiktku-start-step-field, #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield { resize: vertical !important; overflow: auto !important; box-sizing: border-box !important; vertical-align: top; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; transition: border-color 0.1s ease, box-shadow 0.1s ease; } /* Modern focus state to match the searchable-picker inputs. */ #wiktku-start-form textarea.wiktku-start-step-field:focus, #wiktku-start-form textarea.wiktku-start-narrow:focus, #wiktku-start-form textarea.wiktku-dfn-subfield:focus { border-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9, #3366cc); outline: 0; } /* Standard: every textarea in the form is full width by default */ #wiktku-start-form textarea:not(.wiktku-start-narrow) { width: 100%; max-width: 100%; box-sizing: border-box; } #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield.wiktku-start-narrow { width: 20em; max-width: 100%; min-width: 8em; height: calc(1.7em + 10px); min-height: calc(1.7em + 10px); padding-top: 4px !important; padding-bottom: 4px !important; line-height: 1.35 !important; resize: none !important; } /* Exception: "Sernav" / "Sernavê orjînal" citation-source fields (kitêb, kovar, malper, …) — long enough to be worth 2 rows and manual resizing. */ #wiktku-start-form textarea.wiktku-dfn-quote-src-input.wiktku-dfn-quote-src-input--title { height: calc(2 * 1.35em + 10px); min-height: calc(2 * 1.35em + 10px); } /* ── Manual drag-to-resize handle ── */ #wiktku-start-form textarea:not(.wiktku-start-narrow) { resize: none !important; } /* Inline modifier button (⊕) */ .wiktku-word-li { display: flex; align-items: flex-start; flex-wrap: wrap; gap: 0.3em; } .wiktku-mod-btn { flex: 0 0 auto; width: 1.6em; height: 1.6em; padding: 0; line-height: 1; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); color: var(--wikt-palette-blue-9, #3366cc); font-size: 1em; cursor: pointer; } .wiktku-mod-btn:hover { border-color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-paleblue, #eaf3ff); } .wiktku-mod-picker { display: flex; flex-wrap: wrap; gap: 0.25em; width: 100%; margin-top: 0.15em; padding: 0.35em; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; background: var(--wikt-palette-white); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); } .wiktku-mod-pill { padding: 2px 8px; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-radius: 12px; background: var(--wikt-palette-paleblue, #eaf3ff); font-size: 0.85em; white-space: nowrap; cursor: pointer; } .wiktku-mod-pill:hover { border-color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); } .wiktku-mod-pill:disabled, .wiktku-mod-pill.wiktku-mod-pill-used { border-color: var(--wikt-palette-grey-3, #e0e0e0); background: var(--wikt-palette-lightgrey); color: var(--wikt-palette-grey-3, #999); cursor: not-allowed; opacity: 0.6; } .wiktku-mod-pill:disabled:hover, .wiktku-mod-pill.wiktku-mod-pill-used:hover { border-color: var(--wikt-palette-grey-3, #e0e0e0); background: var(--wikt-palette-lightgrey); color: var(--wikt-palette-grey-3, #999); } .wiktku-mod-val-wrap { display: flex; align-items: center; gap: 0.25em; width: 100%; margin-top: 0.15em; } .wiktku-mod-val-input { flex: 0 1 14em; max-width: 14em; padding: 3px 6px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; } .wiktku-mod-confirm, .wiktku-mod-cancel { flex: 0 0 auto; width: 1.6em; height: 1.6em; padding: 0; line-height: 1; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); cursor: pointer; } .wiktku-mod-confirm { color: #178a17; border-color: #178a17; } .wiktku-mod-cancel { color: var(--wikt-palette-red-9, #d33); border-color: var(--wikt-palette-red-9, #d33); } .wiktku-resize-wrap { position: relative; display: block; } /* Separate from .wiktku-resize-wrap (used only for textareas flagged with a linebreak); plain position:relative anchor for the backdrop, no size of its own. */ .wiktku-linebreak-wrap { position: relative; display: block; } .wiktku-resize-grip { position: absolute; right: 2px; bottom: 2px; width: 14px; height: 14px; cursor: ns-resize; touch-action: none; opacity: 0.5; z-index: 2; background-image: linear-gradient(135deg, transparent 0 50%, var(--wikt-palette-grey-9, #767676) 50% 100%); background-repeat: no-repeat; } .wiktku-resize-grip:hover, .wiktku-resize-grip:active { opacity: 0.9; } /* =================================================================== Searchable dropdown (wrapNativeSelect in start.js) .wiktku-native-select-wrap > input.wiktku-ac-input (search box) > ul.wiktku-ac-results (result list) > select (hidden, holds the value) =================================================================== */ .wiktku-native-select-wrap { display: inline-block; position: relative; vertical-align: top; } /* Matches the width the native select would have had (see select.wiktku-start-narrow). */ .wiktku-native-select-wrap input[type="search"], input.wiktku-ac-input { display: block; width: 20em; max-width: 100%; box-sizing: border-box; padding: 3px 6px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); color: inherit; font-size: inherit; font-family: inherit; transition: border-color 0.1s ease, box-shadow 0.1s ease; } input.wiktku-ac-input:focus { border-color: var(--wikt-palette-blue-9); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9); outline: 0; } input.wiktku-ac-input::placeholder { color: var(--wikt-palette-grey-9); opacity: 1; } /* Hide Safari/Chrome's built-in search decorations. */ input.wiktku-ac-input::-webkit-search-decoration, input.wiktku-ac-input::-webkit-search-cancel-button, input.wiktku-ac-input::-webkit-search-results-button { -webkit-appearance: none; appearance: none; } /* ── Result list ── */ /* top/bottom/max-height are overridden inline by showResults() when it flips the list above the box; these are just its defaults. */ ul.wiktku-ac-results { position: absolute; z-index: 9999; top: 100%; bottom: auto; left: 0; margin: 0; padding: 0; list-style: none; width: 20em; max-width: 90vw; max-height: 13em; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; background: var(--wikt-palette-white); border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; box-shadow: 0 3px 10px rgba(0, 0, 0, 0.15); } ul.wiktku-ac-results li { margin: 0; padding: 4px 8px; cursor: pointer; font-size: 0.92em; display: flex; align-items: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* .wiktku-ac-active is the keyboard cursor; hover mirrors it; :active covers the touch press state. */ ul.wiktku-ac-results li.wiktku-ac-active, ul.wiktku-ac-results li:hover { background: var(--wikt-palette-lightblue); } ul.wiktku-ac-results li:active { background: var(--wikt-palette-blue-9); color: var(--wikt-palette-white); } /* Touch devices: bigger tap targets, no sticky hover. */ @media (pointer: coarse) { ul.wiktku-ac-results li { padding: 6px 10px; min-height: 2.2em; font-size: 1em; } ul.wiktku-ac-results li:hover { background: transparent; } ul.wiktku-ac-results li.wiktku-ac-active { background: var(--wikt-palette-lightblue); } input.wiktku-ac-input { /* >=16px stops iOS Safari zooming the page when the box is focused. */ font-size: 16px; min-height: 2.2em; } } /* Inline preview + confirm panel shown before inserting an auto-content pronunciation template, part of the form layout rather than a browser confirm()/prompt() dialog. */ .wiktku-pron-preview { margin: 6px 0; padding: 8px 10px; border: 1px solid var(--wikt-palette-blue-9, #3366cc); border-radius: 6px; background: var(--wikt-palette-paleblue, #eaf3ff); } .wiktku-pron-preview-label { font-size: 0.88em; font-weight: 600; color: var(--wikt-palette-grey-9, #555); margin-bottom: 3px; } .wiktku-pron-preview-body { font-family: monospace; font-size: 1em; white-space: pre-wrap; word-break: break-word; margin-bottom: 6px; } .wiktku-pron-preview-actions { display: flex; gap: 6px; } .wiktku-pron-preview-confirm, .wiktku-pron-preview-cancel { font-size: 0.88em; padding: 3px 10px; border-radius: 4px; cursor: pointer; border: 1px solid var(--wikt-palette-lightgrey, #a2a9b1); background: var(--wikt-palette-white, #fff); } .wiktku-pron-preview-confirm { border-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-blue-9, #3366cc); font-weight: 600; } .wiktku-pron-preview-confirm:disabled { opacity: 0.5; cursor: wait; } .wiktku-pron-preview-cancel:hover { background: var(--wikt-palette-grey-0, #f8f9fa); } /* Template pickers fill their container since the search box, not the <select>, is what the user sees. */ .wiktku-pron-wrap .wiktku-native-select-wrap, .wiktku-etym-wrap .wiktku-native-select-wrap, .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { width: 100%; } .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 0.88em; } .wiktku-cavkani-wrap .wiktku-native-select-wrap, .wiktku-cavkani-wrap .wiktku-native-select-wrap input.wiktku-ac-input { width: 100%; } /* Template selector inside a sense block. */ .wiktku-dfn-tpl-row .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 0.88em; } /* Language/dialect rows: picker must line up with the word field beside it. */ .wiktku-lang-row .wiktku-native-select-wrap { flex: 0 0 auto; } #wiktku-start-form textarea.wiktku-dfn-mane, #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t, #wiktku-start-form textarea.wiktku-dfn-quote-src-manual, #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text, #wiktku-start-form .wiktku-tewandin-wrap textarea.wiktku-tewandin-text, #wiktku-start-form textarea.wiktku-cavkani-text, #wiktku-start-form textarea.wiktku-dfn-tercime, #wiktku-start-form textarea.wiktku-dfn-izah { --wiktku-ta-rows: 2; height: calc(var(--wiktku-ta-rows) * 1.35em + 6px); min-height: calc(var(--wiktku-ta-rows) * 1.35em + 6px); } #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text, #wiktku-start-form textarea.wiktku-dfn-izah { --wiktku-ta-rows: 3; } #wiktku-start-form textarea.wiktku-cavkani-text { --wiktku-ta-rows: 4; } /* Nimûne + Jêgirtin (citation) boxes, and their tr/t sub-fields: at least 4 rows so there's room to actually write an example/quote. */ #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t, #wiktku-start-form textarea.wiktku-dfn-quote-src-manual { --wiktku-ta-rows: 4; } /* Nudges the border when the box contains a typed/pasted linebreak, so the user notices before it's silently turned into <br> on output; the break itself is marked via a mirrored backdrop layer (see below). */ #wiktku-start-form textarea.wiktku-has-linebreak { border-color: var(--wikt-palette-yellow6, #ac6600) !important; } /* Sits behind the textarea showing the same text, with a highlighted marker at each line followed by a break; font/padding/line-height are copied from the textarea via computed style, not shared CSS classes. */ .wiktku-linebreak-backdrop { position: absolute; inset: 0; z-index: 0; margin: 0; overflow: hidden; white-space: pre-wrap; word-wrap: break-word; color: transparent; background: transparent !important; border-color: transparent !important; box-shadow: none !important; resize: none !important; pointer-events: none; } /* Raise the real textarea above its backdrop so typing/selection/caret behave completely normally; the backdrop's mark shows through only where the real textarea's own background is transparent. */ #wiktku-start-form textarea.wiktku-has-linebreak-source { position: relative; z-index: 1; background-color: transparent; } .wiktku-linebreak-mark { background-color: var(--wikt-palette-yellow6, #ac6600); color: var(--wikt-palette-white, #fff); border-radius: 2px; } /* ── Tercime + Îzah boxes ── */ .wiktku-dfn-nonku-wrap { display: flex; flex-direction: column; gap: 3px; } .wiktku-dfn-nimune-sub, .wiktku-dfn-quote-sub { margin-top: 3px; margin-left: 1em; padding-left: 0.6em; border-left: 2px solid var(--wikt-palette-lightgrey); display: flex; flex-direction: column; gap: 3px; } .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t { min-width: 8em; padding-top: 2px !important; padding-bottom: 2px !important; line-height: 1.35 !important; font-size: 0.88em; } /* Sense list (Mane step) — one sense visible at a time, switched via .wiktku-dfn-sense-tabs. */ ol.wiktku-dfn-list { list-style: none; margin: 0; padding: 0; } ol.wiktku-dfn-list > li.wiktku-dfn-sense { margin-bottom: 0.9em; } /* Template selector row inside a sense block */ .wiktku-dfn-tpl-row { margin-bottom: 3px; } /* ── Sub-field titles (Etîket, Kategorî, Hevmane, Dijmane, Nimûne, Jêgirtin, …): each group reads as a small labelled field — the term stands out, the hint stays quiet. ── */ .wiktku-dfn-subgroup { margin-top: 0.5em; padding-top: 0.4em; border-top: 1px dashed var(--wikt-palette-grey-3, #e0e0e0); } .wiktku-dfn-subgroup:first-of-type { margin-top: 0.3em; padding-top: 0; border-top: none; } .wiktku-dfn-sublabel { display: block; margin-bottom: 3px; font-size: 0.88em; } .wiktku-dfn-sublabel-term { font-weight: 600; color: var(--wikt-palette-blue-9, #3366cc); letter-spacing: 0.03em; font-size: 0.92em; } .wiktku-dfn-sublabel-hint { color: var(--wikt-palette-grey-9, #767676); font-style: italic; } .wiktku-pron-wrap, .wiktku-etym-wrap, .wiktku-tewandin-wrap, .wiktku-cavkani-wrap { display: flex; flex-direction: column; gap: 3px; } /* ── POS section tabs — rounded pill style ── */ #wiktku-section-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 0.6em; align-items: center; } #wiktku-section-tabs .wiktku-section-tab { padding: 3px 12px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 999px; background: var(--wikt-palette-dullcyan); cursor: pointer; font-size: 0.86em; user-select: none; transition: background 0.12s ease, border-color 0.12s ease; } #wiktku-section-tabs .wiktku-section-tab:hover { border-color: var(--wikt-palette-blue-9, #3366cc); } #wiktku-section-tabs .wiktku-section-tab.wiktku-tab-active { background: var(--wikt-palette-blue-9, #3366cc); border-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); font-weight: 600; } /* ── Step-group tabs (Mane / Bilêvkirin / Beşên din — see STEP_GROUPS in start.js) ── Sits directly under the pill-style section tabs above; styled as an underlined secondary nav so the two bars stay visually distinct. */ #wiktku-group-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 0.8em; border-bottom: 2px solid var(--wikt-palette-lightgrey); } #wiktku-group-tabs .wiktku-group-tab { position: relative; padding: 7px 14px 8px; margin-bottom: -2px; border-bottom: 3px solid transparent; border-radius: 3px 3px 0 0; cursor: pointer; font-size: 0.95em; font-weight: 600; color: var(--wikt-palette-grey-9, #333); background: var(--wikt-palette-grey-0, #f8f9fa); user-select: none; transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease; } #wiktku-group-tabs .wiktku-group-tab:hover { color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-paleblue, #eaf3ff); } #wiktku-group-tabs .wiktku-group-tab.wiktku-tab-active { border-bottom-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); background: var(--wikt-palette-blue-9, #3366cc); font-weight: 700; } /* Small dot marking a tab that still has an unfilled required field hidden inside it (see updateGroupTabIndicators in start.js). Cleared automatically once that tab becomes the active one. */ #wiktku-group-tabs .wiktku-group-tab.wiktku-tab-missing::after { content: ""; position: absolute; top: 4px; right: -1px; width: 6px; height: 6px; border-radius: 50%; background: var(--wikt-palette-red-9, #d33); } .wiktku-lang-row-list { margin: 0; padding: 0; list-style: none; } .wiktku-lang-row { display: flex; align-items: flex-start; gap: 6px; margin-bottom: 3px; flex-wrap: wrap; } .wiktku-lang-row-words { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 3px; } /* Dûnde/Werger/Zarava rows: align the picker's height with the adjacent word textarea (see .wiktku-start-narrow above). */ .wiktku-lang-row .wiktku-native-select-wrap input.wiktku-ac-input { height: calc(1.7em + 10px); min-height: calc(1.7em + 10px); padding-top: 4px; padding-bottom: 4px; } /* ── Werger / Bi zaravayên din groups: one per gloss, shared spacing ── */ #wiktku-start-trans .wiktku-trans-group, #wiktku-start-zarava .wiktku-zarava-group { margin-bottom: 0.6em; } #wiktku-start-trans .wiktku-trans-group:last-child, #wiktku-start-zarava .wiktku-zarava-group:last-child { margin-bottom: 0; } #wiktku-start-trans .wiktku-trans-group-label, #wiktku-start-zarava .wiktku-zarava-group-label { font-weight: 600; font-size: 0.88em; margin-bottom: 3px; } .wiktku-dfn-jeder-group { margin-top: 3px; } .wiktku-dfn-quote-src-sel { font-size: 0.88em; margin-top: 3px; display: block; } .wiktku-dfn-quote-src-fields { display: flex; flex-direction: column; gap: 3px; margin-top: 3px; } /* Stacked layout: textarea gets its own full-width row, button + status sit below it on their own row. */ .wiktku-dfn-quote-citoid { display: flex; flex-direction: column; align-items: stretch; gap: 0.4em; margin-top: 3px; margin-bottom: 3px; } .wiktku-dfn-quote-citoid-input { width: 100%; max-width: 100%; box-sizing: border-box; } /* Column flex + align-items:stretch (above) makes the textarea's .wiktku-resize-wrap reach full width automatically; button and status text opt back out via align-self so they keep their natural size. */ .wiktku-dfn-quote-citoid-btn, .wiktku-dfn-quote-citoid-status { align-self: flex-start; } .wiktku-dfn-quote-src-cat-status { display: block; font-size: 0.82em; color: var(--wikt-palette-lightgrey, #767676); margin-top: 2px; } .wiktku-dfn-quote-src-row { display: flex; align-items: baseline; gap: 4px; flex-wrap: wrap; } .wiktku-dfn-quote-src-row label { font-size: 0.82em; white-space: nowrap; min-width: 8em; } textarea.wiktku-dfn-quote-src-input { flex: 1 1 12em; max-width: 100%; box-sizing: border-box; } @media (max-width: 720px) { .wiktku-lang-row { flex-direction: column; } /* Re-asserts against the skin's own mobile-breakpoint heading styles, which load after ours in the cascade. */ #wiktku-start-form .wiktku-start-step-name { font-size: 1.05em !important; margin: 0 0 0.2em !important; line-height: 1.2 !important; border: 0 !important; padding: 0 !important; } /* Single column: search box, list, and narrow textareas (Etîket, Hevmane, Dûnde/Jê/Têkildar/Binêre herwiha word boxes, citation source fields, …) all use the full width. */ .wiktku-native-select-wrap, input.wiktku-ac-input, ul.wiktku-ac-results, #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield.wiktku-start-narrow { width: 100%; max-width: 100%; } .wiktku-mod-val-input { flex: 1 1 auto; max-width: 100%; } #wiktku-start-form textarea.wiktku-dfn-mane, #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text { --wiktku-ta-rows: 3; font-size: 1em; } #wiktku-start-form .wiktku-tewandin-wrap textarea.wiktku-tewandin-text, #wiktku-start-form textarea.wiktku-cavkani-text { --wiktku-ta-rows: 4; font-size: 1em; } /* Nimûne + Jêgirtin and their tr/t sub-fields: keep at least 4 rows on mobile too, rather than shrinking further than the desktop size. */ #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t { --wiktku-ta-rows: 4; font-size: 1em; } /* Citoid URL/DOI/ISBN box: taller tap target (~2 lines) on mobile, and now that this field is a <textarea> (see start.js) its placeholder can actually wrap into that space — a plain <input>'s placeholder can never wrap, no matter its height. */ .wiktku-dfn-quote-citoid-input { min-height: calc(2 * 1.35em + 10px); font-size: 1em; } .wiktku-dfn-nimune-sub, .wiktku-dfn-quote-sub { margin-left: 0.5em; padding-left: 0.4em; } .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 1em; min-height: 2.2em; } .wiktku-dfn-quote-src-row label { min-width: 6em; } #wiktku-start-form textarea.wiktku-dfn-quote-src-input { width: 100%; flex: 1 1 100%; } .wiktku-start-step { padding: 0.5em 0.6em; } } /* =================================================================== Night mode Palette.css already flips --wikt-palette-* vars for night mode; this hook only covers real colours (panel border) that aren't a palette var, since a drop shadow is invisible against an equally dark page. =================================================================== */ @media screen { html.skin-theme-clientpref-night .wiktku-ac-results { /* Border stands in for the shadow, invisible on a dark page. */ border-color: var(--wikt-palette-grey-5); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.6); } html.skin-theme-clientpref-night .wiktku-start-step, html.skin-theme-clientpref-night .wiktku-start-step:hover, html.skin-theme-clientpref-night .wiktku-start-step:focus-within { box-shadow: none; } } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os .wiktku-ac-results { border-color: var(--wikt-palette-grey-5); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.6); } html.skin-theme-clientpref-os .wiktku-start-step, html.skin-theme-clientpref-os .wiktku-start-step:hover, html.skin-theme-clientpref-os .wiktku-start-step:focus-within { box-shadow: none; } } /* "Zimanek lê zêde bike" portlet icon (Minerva/mobile) — Feather-core-edit.svg via CSS mask, matching Minerva's own icon pattern. */ .minerva-icon-portletlink-ca-wiktku-addlang { -webkit-mask-image: url("https://upload.wikimedia.org/wikipedia/commons/d/d7/Feather-core-edit.svg"); mask-image: url("https://upload.wikimedia.org/wikipedia/commons/d/d7/Feather-core-edit.svg"); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-position: center; mask-position: center; -webkit-mask-size: 20px; mask-size: 20px; background-color: currentColor; background-image: none; } /* ── posparams step (live wikitext + helper widgets) ── */ .wiktku-posparams-wrap { display: flex; flex-direction: column; gap: 6px; } .wiktku-posparams-helpers { display: flex; flex-direction: column; gap: 4px; } .wiktku-posparams-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; } .wiktku-posparams-row label { font-size: 1em; min-width: 10em; padding-right: 0; } .wiktku-posparams-text { width: 100%; box-sizing: border-box; font-family: monospace; font-size: 0.9em; } .wiktku-posparams-opt-toggle { font-size: 0.85em; margin-top: 2px; display: inline-block; } .wiktku-posparams-opt-panel { display: flex; flex-direction: column; gap: 2px; padding: 4px 0 2px 1em; } .wiktku-posparams-opt-row { display: flex; align-items: center; gap: 4px; font-size: 0.85em; } /* ── resim step (one or more images) ── */ .wiktku-resim-list { display: flex; flex-direction: column; gap: 6px; } .wiktku-resim-item { display: flex; flex-direction: column; gap: 4px; } .wiktku-resim-item .wiktku-posparams-row { flex-direction: column; align-items: flex-start; gap: 2px; } .wiktku-resim-item .wiktku-posparams-row label { min-width: 0; font-size: 0.9em; } /* ── dfn: "hide/show all subsections" link ── Toggles a class on the whole dfn stepDiv so one click hides the etîket/kategorî/hevmane/dijmane/nimûne/jêgirtin/etc. subgroups across every sense block at once. */ .wiktku-dfn-subs-toggle { font-size: 0.85em; font-weight: 500; display: inline-block; margin: 2px 0 8px; color: var(--wikt-palette-blue-9, #3366cc); text-decoration: none; } .wiktku-dfn-subs-toggle:hover { text-decoration: underline; } /* Only the ADVANCED subgroups collapse: Nimûne, Jêgirtin, Hevmane and Dijmane stay open because they are what people come here to fill in. */ #wiktku-start-form li.wiktku-sense-adv-hidden .wiktku-dfn-subgroup-adv { display: none !important; } /* The toggle sits between the primary groups and the advanced ones, so it needs no rule of its own beyond a little breathing room. */ #wiktku-start-form .wiktku-sense-adv-row { margin-top: 14px; } /* =================================================================== Desktop text bump Modifier pills/buttons and posparams helper text read fine at their small mobile sizes but look too small on desktop, so bump them up past the 720px breakpoint only. =================================================================== */ @media (min-width: 721px) { .wiktku-mod-btn, .wiktku-mod-confirm, .wiktku-mod-cancel { width: 1.8em; height: 1.8em; font-size: 1.1em; } .wiktku-mod-pill { font-size: 0.95em; padding: 3px 10px; } .wiktku-mod-val-input { font-size: 0.95em; } .wiktku-posparams-row label { font-size: 1em; } .wiktku-posparams-text { font-size: 1em; } .wiktku-posparams-opt-toggle { font-size: 0.95em; } .wiktku-posparams-opt-row { font-size: 0.95em; } .wiktku-dfn-subs-toggle { font-size: 0.95em; } /* Multi-column card layout for posparams helper fields (transliteration, gendered forms, comparative/superlative, hanja, verb-tense roots, …), desktop-only. Rows are shown/hidden via jQuery inline display; the grid only rearranges visible rows, not which ones are visible. */ .wiktku-posparams-helpers { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px 16px; align-items: start; } .wiktku-posparams-helpers > .wiktku-posparams-row { flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 3px; } .wiktku-posparams-helpers > .wiktku-posparams-row label { min-width: 0; } .wiktku-posparams-helpers > .wiktku-posparams-row .wiktku-posparams-field, .wiktku-posparams-helpers > .wiktku-posparams-row select.wiktku-posparams-cinsiyet-sel, .wiktku-posparams-helpers > .wiktku-posparams-row select.wiktku-posparams-lektur-sel { width: 100%; max-width: 100%; box-sizing: border-box; } /* The "Jimar" row lives here too — just another .wiktku-posparams-row, no extra CSS needed. */ /* These two aren't per-field rows — span the full card width so the collapsed toggle and its checkbox list don't get squeezed into one narrow column. */ .wiktku-posparams-helpers > .wiktku-posparams-opt-toggle, .wiktku-posparams-helpers > .wiktku-posparams-opt-panel { grid-column: 1 / -1; } } /* =================================================================== SÊWIRANA NÛ — design system layer =================================================================== Purely the visual skin (colour, type, weight, radius, spacing), layered after the layout rules above so it wins the cascade. No @import of Spectral / IBM Plex from Google Fonts: Wikimedia's CSP blocks third-party font hosts, so the stacks below name the spec's faces first (used if the wiki installs them locally) and fall back to faces with the same feel. Accent colour is reserved for actionable elements (focus, links, the active tab, the primary button, chips); section headings are near-black. =================================================================== */ #wiktku-start-form { /* Surfaces */ --wikt-page: #f4efe5; --wikt-card: #fffdf8; --wikt-card-sunken: #fbf8f1; --wikt-rule: #ded6c8; /* structural hairline */ --wikt-rule-soft: #efe8db; /* inside a card */ --wikt-field-edge: #cfc7b8; --wikt-field-bg: #fff; --wikt-code-bg: #f7f4ec; --wikt-card-edge: #e6dfd2; /* Ink */ --wikt-ink: #1c1a17; --wikt-ink-2: #3d3830; --wikt-ink-3: #57514a; --wikt-muted: #8a8378; --wikt-placeholder: #b3ab9e; /* Accent + status */ --wikt-accent: #2a5db0; --wikt-accent-deep: #22406f; --wikt-accent-tint: #eef2fa; --wikt-accent-edge: #d5def0; --wikt-danger: #9c3a28; --wikt-on-accent: #fff; /* text on a filled accent button */ --wikt-link-under: rgba(42, 93, 176, 0.35); /* Shape */ --wikt-r-field: 10px; --wikt-r-card: 14px; --wikt-r-pill: 999px; --wikt-tap: 44px; /* minimum field height */ --wikt-serif: Spectral, "Iowan Old Style", Georgia, "Times New Roman", serif; --wikt-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif; --wikt-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-family: var(--wikt-sans); font-size: 15px; line-height: 1.55; color: var(--wikt-ink); background: var(--wikt-page); padding: 24px; border-radius: var(--wikt-r-card); } /* ── Cards ─────────────────────────────────────────────────────────── Flat cream panel held by a single hairline border, no shadow. */ #wiktku-start-form .wiktku-start-step { background: var(--wikt-card); border: 1px solid var(--wikt-card-edge); border-left: 1px solid var(--wikt-card-edge); border-radius: var(--wikt-r-card); box-shadow: none; padding: 24px 24px 20px; margin-bottom: 16px; transition: border-color 0.12s ease; } #wiktku-start-form .wiktku-start-step:hover, #wiktku-start-form .wiktku-start-step:focus-within { box-shadow: none; border-color: var(--wikt-rule); } /* The fused pos + posparams pair keeps reading as one card. */ #wiktku-start-form #wiktku-start-pos { border-radius: var(--wikt-r-card) var(--wikt-r-card) 0 0; border-bottom: none; padding-bottom: 8px; } #wiktku-start-form #wiktku-start-posparams { border-radius: 0 0 var(--wikt-r-card) var(--wikt-r-card); border-top: none; padding-top: 4px; } /* ── Type ──────────────────────────────────────────────────────────── Step headings: serif, regular weight, near-black. */ #wiktku-start-form .wiktku-start-step-name { font-family: var(--wikt-serif); font-size: 24px !important; font-weight: 400; letter-spacing: -0.01em; line-height: 1.15; color: var(--wikt-ink); margin: 0 0 12px; } /* display:block matters: this is a <label>, so it was sharing a line with the control it introduces wherever start.js didn't emit a <br>. */ #wiktku-start-form .wiktku-start-step-question { display: block; font-size: 15px; font-weight: 400; color: var(--wikt-ink-3); margin: 0 0 12px; line-height: 1.6; max-width: 62ch; } /* Collapses the label entirely when empty (posparams' "Cins/zayend" title can be blank) instead of leaving its margin behind as a gap; a no-op for every other step, whose question text is never empty. */ #wiktku-start-form .wiktku-start-step-question:empty { display: none; margin: 0; } /* Same reason — a field label belongs above its field, not beside it. */ #wiktku-start-form .wiktku-posparams-row label, #wiktku-start-form .wiktku-dfn-sublabel { display: block; margin-bottom: 6px; padding-right: 0; } /* Field labels: small, medium weight, full-strength ink — they label a control, so they should not read as body copy. */ #wiktku-start-form .wiktku-start-step label, #wiktku-start-form .wiktku-posparams-row label, #wiktku-start-form .wiktku-dfn-sublabel { font-size: 13px; font-weight: 500; color: var(--wikt-ink); letter-spacing: 0.01em; } /* The parenthetical/example half of a label is supporting text. */ #wiktku-start-form .wiktku-dfn-sublabel-hint, #wiktku-start-form .wiktku-step-hint { font-weight: 400; font-style: italic; color: var(--wikt-muted); font-size: 12.5px; } /* ── Fields ────────────────────────────────────────────────────────── One shape for every control: 1px edge, 10px radius, 44px tall. */ #wiktku-start-form input[type="text"], #wiktku-start-form input[type="search"], #wiktku-start-form input.wiktku-ac-input, #wiktku-start-form textarea, #wiktku-start-form select { font-family: var(--wikt-sans); font-size: 15px; color: var(--wikt-ink); background: var(--wikt-field-bg); border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-field); padding: 10px 14px; box-shadow: none; transition: border-color 0.12s ease, box-shadow 0.12s ease; } #wiktku-start-form input[type="text"], #wiktku-start-form input[type="search"], #wiktku-start-form select { min-height: var(--wikt-tap); } #wiktku-start-form textarea { line-height: 1.6; } /* Wikitext and anything template-shaped reads as code. */ #wiktku-start-form .wiktku-posparams-text, #wiktku-start-form .wiktku-pron-text, #wiktku-start-form .wiktku-etym-text, #wiktku-start-form .wiktku-cavkani-text, #wiktku-start-form .wiktku-tewandin-text, #wiktku-start-form .wiktku-pron-preview-body { font-family: var(--wikt-mono); font-size: 13.5px; background: var(--wikt-code-bg); border-color: var(--wikt-card-edge); } #wiktku-start-form ::placeholder { color: var(--wikt-placeholder); opacity: 1; } /* Focus: accent edge + 3px tint halo. The only "elevation" in the design. */ #wiktku-start-form input[type="text"]:focus, #wiktku-start-form input[type="search"]:focus, #wiktku-start-form textarea:focus, #wiktku-start-form select:focus, #wiktku-start-form input.wiktku-ac-input:focus { border-color: var(--wikt-accent); box-shadow: 0 0 0 3px var(--wikt-accent-tint); outline: 0; } /* The searchable picker's visible input is the field, so it takes the field shape too (it otherwise inherits an older, boxier rule). */ #wiktku-start-form input.wiktku-ac-input { min-height: var(--wikt-tap); border-radius: var(--wikt-r-field); border-color: var(--wikt-field-edge); font-size: 15px; } #wiktku-start-form .wiktku-ac-results { border: 1px solid var(--wikt-rule); border-radius: var(--wikt-r-field); background: var(--wikt-card); box-shadow: none; } #wiktku-start-form .wiktku-ac-results li.wiktku-ac-active, #wiktku-start-form .wiktku-ac-results li:hover { background: var(--wikt-accent-tint); color: var(--wikt-accent-deep); } /* ── Tabs → the accent's main job ──────────────────────────────────── Active tab: tint fill + 3px accent underline, per the spec's "xala hûrgulî" note. Inactive tabs are plain text. */ #wiktku-start-form #wiktku-group-tabs, #wiktku-start-form #wiktku-section-tabs { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; border-bottom: 1px solid var(--wikt-rule); margin-bottom: 16px; padding-bottom: 0; } /* Both bars are direct children of #wiktku-start-form, so a sticky child stays stuck for as long as any part of the form is in view. Background is opaque so content scrolling underneath doesn't show through. Section-tabs pins below --wiktku-siteheader-h — an offset for Vector 2022's own sticky header, which otherwise sits on top of it at top:0 (Minerva has no such header, so mobile needs no offset); group-tabs pins below that plus --wiktku-stabs-h (section-tabs' own height). Both custom properties are set by syncStickyTabsOffset() in start.js and fall back to 0 on skins without a Vector sticky header. */ #wiktku-start-form #wiktku-section-tabs { position: sticky; top: var(--wiktku-siteheader-h, 0px); z-index: 20; background: var(--wikt-card); } #wiktku-start-form #wiktku-group-tabs { position: sticky; top: calc(var(--wiktku-siteheader-h, 0px) + var(--wiktku-stabs-h, 0px)); z-index: 19; background: var(--wikt-card); } #wiktku-start-form .wiktku-group-tab, #wiktku-start-form .wiktku-section-tab { display: inline-flex; align-items: center; gap: 6px; font-size: 13.5px; font-weight: 500; color: var(--wikt-ink-3); background: transparent; border: 0; border-bottom: 3px solid transparent; border-radius: var(--wikt-r-pill) var(--wikt-r-pill) 0 0; padding: 9px 10px 11px 14px; cursor: pointer; transition: background 0.12s ease, color 0.12s ease; } #wiktku-start-form .wiktku-group-tab { padding: 9px 14px 11px; } #wiktku-start-form .wiktku-group-tab:hover, #wiktku-start-form .wiktku-section-tab:hover { background: var(--wikt-card-sunken); color: var(--wikt-ink); } #wiktku-start-form .wiktku-group-tab.wiktku-tab-active, #wiktku-start-form .wiktku-section-tab.wiktku-tab-active { background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom-color: var(--wikt-accent); } /* ── Progressive-disclosure toggles ────────────────────────────────── Shared by "Tercîhên pêşketî" (posparams) and "Malûmatên pêşketî" (Mane): a rotating chevron plus a count of what's hidden. */ #wiktku-start-form .wiktku-adv-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin: 4px 0 12px; padding-top: 16px; border-top: 1px solid var(--wikt-rule-soft); } #wiktku-start-form .wiktku-adv-toggle { display: inline-flex; align-items: center; gap: 10px; font-size: 14px; font-weight: 500; color: var(--wikt-accent); text-decoration: none; cursor: pointer; } #wiktku-start-form .wiktku-adv-toggle:hover .wiktku-adv-toggle-text { text-decoration: underline; } #wiktku-start-form .wiktku-adv-toggle-chevron { width: 22px; height: 22px; flex: 0 0 22px; display: grid; place-items: center; font-size: 11px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); border-radius: 6px; transform: rotate(-90deg); transition: transform 0.15s ease; } /* Open state: dfn flips the class on the step, posparams on the link. */ #wiktku-start-form .wiktku-adv-toggle.wiktku-adv-open .wiktku-adv-toggle-chevron, #wiktku-start-dfn:not(.wiktku-dfn-subs-hidden) .wiktku-adv-toggle-chevron { transform: rotate(0deg); } #wiktku-start-form .wiktku-posparams-adv-panel { border: 1px solid var(--wikt-rule-soft); border-radius: 12px; background: var(--wikt-card-sunken); padding: 20px 18px; margin-bottom: 4px; } /* ── posparams grid ────────────────────────────────────────────────── "Tor, ne rêz" — two columns, nothing narrower than 220px, so the six gender/number fields stop being a six-across scanline. */ @media (min-width: 721px) { #wiktku-start-form .wiktku-posparams-helpers, #wiktku-start-form .wiktku-posparams-adv-panel { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 18px 22px; align-items: start; } #wiktku-start-form .wiktku-posparams-adv-panel > .wiktku-posparams-row, #wiktku-start-form .wiktku-posparams-helpers > .wiktku-posparams-row { flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 7px; } #wiktku-start-form .wiktku-posparams-helpers > .wiktku-adv-toggle-row, #wiktku-start-form .wiktku-posparams-helpers > .wiktku-posparams-adv-panel, #wiktku-start-form .wiktku-posparams-adv-panel > .wiktku-posparams-opt-panel { grid-column: 1 / -1; } } #wiktku-start-form .wiktku-posparams-opt-panel { border-top: 1px solid var(--wikt-rule-soft); padding-top: 14px; margin-top: 4px; } #wiktku-start-form .wiktku-posparams-opt-row { font-size: 13px; color: var(--wikt-ink-3); } /* ── Sense blocks ──────────────────────────────────────────────────── Each sense is a sunken panel inside the Mane card, with its number as an accent counter — so "how many meanings am I writing" is legible at a glance. */ #wiktku-start-form .wiktku-dfn-subgroup { margin: 14px 0 0; padding-top: 14px; border-top: 1px solid var(--wikt-rule-soft); } /* No divider above the first item — it would be a rule against the sense's own text. Needed explicitly: the earlier :first-of-type rule is a class selector and loses to this id-scoped one. */ #wiktku-start-form .wiktku-dfn-subgroup:first-of-type { margin-top: 8px; padding-top: 0; border-top: none; } #wiktku-start-form .wiktku-dfn-sublabel-term { color: var(--wikt-ink); } /* Plain white field like any other, not a tinted fill — a tint would read as "disabled" next to the white Mane box above it. */ #wiktku-start-form .wiktku-dfn-subfield, #wiktku-start-form textarea.wiktku-dfn-mane { background: var(--wikt-field-bg); border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-field); } /* No "1." "2." markers on the sub-lists: numbered rows would read as a form to fill top-down, when each row is really "another one if you have one" — and the marker would land on its own line above the block-level textarea, looking like a stray character. */ #wiktku-start-form .wiktku-dfn-sublist { margin: 0; padding-left: 0; list-style: none; } #wiktku-start-form .wiktku-dfn-sublist > li { margin-bottom: 6px; } /* ── Chips: tags, modifiers, template pills ──────────────────────────── */ #wiktku-start-form .wiktku-mod-pill, #wiktku-start-form .wiktku-besendin-select + .wiktku-chip { background: var(--wikt-accent-tint); color: var(--wikt-accent-deep); border: 1px solid var(--wikt-accent-edge); border-radius: var(--wikt-r-pill); font-size: 13px; padding: 6px 12px; } #wiktku-start-form .wiktku-mod-btn, #wiktku-start-form .wiktku-mod-confirm, #wiktku-start-form .wiktku-mod-cancel { border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); border-radius: 8px; } /* ── Footer + buttons ──────────────────────────────────────────────── One primary filled pill; destructive actions are outline-only in the danger colour so they stay quiet next to it. */ #wiktku-start-form #wiktku-start-footer { background: var(--wikt-card-sunken); border-top: 1px solid var(--wikt-rule); border-radius: 0 0 var(--wikt-r-card) var(--wikt-r-card); padding: 16px 20px; gap: 10px; } #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement-button { border-radius: var(--wikt-r-pill) !important; font-family: var(--wikt-sans); font-size: 14px; font-weight: 500; padding: 11px 22px; box-shadow: none !important; min-height: var(--wikt-tap); } #wiktku-start-form #wiktku-unhide-editform .oo-ui-buttonElement-button { background: var(--wikt-accent) !important; border-color: var(--wikt-accent) !important; color: var(--wikt-on-accent) !important; } /* Destructive actions: outline, not fill. */ #wiktku-start-form #wiktku-start-footer .oo-ui-flaggedElement-destructive .oo-ui-buttonElement-button { background: var(--wikt-card) !important; border-color: var(--wikt-danger) !important; color: var(--wikt-danger) !important; } #wiktku-start-form #wiktku-last-saved { font-family: var(--wikt-mono); font-size: 12px; color: var(--wikt-muted); } /* ── Beşên din picker ──────────────────────────────────────────────── This dropdown is now the entry point to eighteen sections, so it gets room and a label rather than sitting flush under the tab bar. */ #wiktku-start-form .wiktku-besendin-picker { margin: 0 0 20px; padding: 16px 18px; background: var(--wikt-card); border: 1px solid var(--wikt-card-edge); border-radius: 12px; } #wiktku-start-form .wiktku-besendin-picker .wiktku-native-select-wrap, #wiktku-start-form .wiktku-besendin-picker input.wiktku-ac-input { width: 100%; max-width: 28em; } /* ── Notices ─────────────────────────────────────────────────────────── */ #wiktku-start-form .wiktku-addlang-notice { background: var(--wikt-accent-tint); border: 1px solid var(--wikt-accent-edge); border-radius: var(--wikt-r-field); color: var(--wikt-ink-2); padding: 12px 16px; margin-bottom: 16px; } #wiktku-start-form .wiktku-pron-preview { background: var(--wikt-accent-tint); border-color: var(--wikt-accent-edge); border-radius: 12px; } #wiktku-start-form .wiktku-pron-preview-confirm, #wiktku-start-form .wiktku-pron-preview-cancel { border-radius: var(--wikt-r-pill); padding: 8px 16px; min-height: 36px; } /* Links carry the accent and a soft underline, per the spec's `a` rule. */ #wiktku-start-form a { color: var(--wikt-accent); text-decoration: none; border-bottom: 1px solid var(--wikt-link-under); } #wiktku-start-form a:hover { color: var(--wikt-accent-deep); } #wiktku-start-form .wiktku-adv-toggle, #wiktku-start-form .wiktku-group-tab, #wiktku-start-form .wiktku-section-tab { border-bottom-style: solid; } #wiktku-start-form .wiktku-adv-toggle { border-bottom: 0; } /* =================================================================== Dark mode =================================================================== Every colour above is a token on #wiktku-start-form, so this is a swap of that one block. Only applies given an explicit dark signal (skin-theme-clientpref-night / skin-nightmode, or skin-theme-clientpref-os plus prefers-color-scheme: dark) — no bare prefers-color-scheme fallback, since legacy Vector sets no theme class either and would otherwise go dark with nothing else on the page to match. Palette is warm, not neutral grey, to keep the cream design's character. Accent lightens to #7ba7e8 since #2a5db0 on a dark card is ~2.4:1 contrast and reads as near-black. =================================================================== */ html.skin-theme-clientpref-night #wiktku-start-form, html.skin-nightmode #wiktku-start-form { --wikt-page: #171613; --wikt-card: #201e1a; --wikt-card-sunken: #1a1916; --wikt-card-edge: #322e28; --wikt-rule: #3a3630; --wikt-rule-soft: #2c2924; --wikt-field-edge: #4a453d; --wikt-field-bg: #191815; --wikt-code-bg: #14130f; --wikt-ink: #ece7dd; --wikt-ink-2: #d5cfc4; --wikt-ink-3: #b3aca1; --wikt-muted: #8f887c; --wikt-placeholder: #6d675e; --wikt-accent: #7ba7e8; --wikt-accent-deep: #cfe0f8; --wikt-accent-tint: #1c2839; --wikt-accent-edge: #35496b; --wikt-danger: #e5907c; --wikt-on-accent: #14213a; --wikt-link-under: rgba(123, 167, 232, 0.4); } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os #wiktku-start-form { --wikt-page: #171613; --wikt-card: #201e1a; --wikt-card-sunken: #1a1916; --wikt-card-edge: #322e28; --wikt-rule: #3a3630; --wikt-rule-soft: #2c2924; --wikt-field-edge: #4a453d; --wikt-field-bg: #191815; --wikt-code-bg: #14130f; --wikt-ink: #ece7dd; --wikt-ink-2: #d5cfc4; --wikt-ink-3: #b3aca1; --wikt-muted: #8f887c; --wikt-placeholder: #6d675e; --wikt-accent: #7ba7e8; --wikt-accent-deep: #cfe0f8; --wikt-accent-tint: #1c2839; --wikt-accent-edge: #35496b; --wikt-danger: #e5907c; --wikt-on-accent: #14213a; --wikt-link-under: rgba(123, 167, 232, 0.4); } } /* A handful of rules still name literal light colours instead of tokens; neutralise the ones that actually show through in night mode. */ html.skin-theme-clientpref-night #wiktku-start-form .wiktku-ac-results, html.skin-nightmode #wiktku-start-form .wiktku-ac-results { background: var(--wikt-card); border-color: var(--wikt-rule); color: var(--wikt-ink); } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os #wiktku-start-form .wiktku-ac-results { background: var(--wikt-card); border-color: var(--wikt-rule); color: var(--wikt-ink); } } /* =================================================================== Autocomplete list: stop it escaping its card =================================================================== A fixed width would run past the card's border on full-width pickers, since the list is absolutely positioned at the wrapper's left edge. width:100% ties it to the (shrink-to-fit) wrapper's input width instead; min/max-width keep short pickers readable and stop viewport overflow. */ #wiktku-start-form ul.wiktku-ac-results { width: 100%; min-width: min(18em, 100%); max-width: min(92vw, 34em); box-sizing: border-box; border-radius: var(--wikt-r-field); box-shadow: none; } /* And the wrapper itself must not exceed the card it sits in. */ #wiktku-start-form .wiktku-native-select-wrap { max-width: 100%; } #wiktku-start-form .wiktku-cavkani-wrap .wiktku-native-select-wrap, #wiktku-start-form .wiktku-cavkani-wrap input.wiktku-ac-input, #wiktku-start-form .wiktku-pron-wrap .wiktku-native-select-wrap, #wiktku-start-form .wiktku-etym-wrap .wiktku-native-select-wrap { width: 100%; max-width: 100%; box-sizing: border-box; } /* =================================================================== Mobile footer =================================================================== Below 720px the primary button keeps its full size and everything else shrinks to a secondary scale, so the sticky footer doesn't dominate a phone viewport. =================================================================== */ @media (max-width: 720px) { #wiktku-start-form { padding: 12px; font-size: 14px; } #wiktku-start-form .wiktku-start-step { padding: 16px 14px 14px; border-radius: 12px; } #wiktku-start-form .wiktku-start-step-name { font-size: 20px !important; } #wiktku-start-form #wiktku-start-footer { padding: 10px 12px; gap: 6px; row-gap: 8px; } #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement-button { font-size: 13px; padding: 8px 14px; min-height: 38px; } /* The one you actually press stays thumb-sized. */ #wiktku-start-form #wiktku-unhide-editform .oo-ui-buttonElement-button { font-size: 14px; padding: 10px 20px; min-height: var(--wikt-tap); } /* Secondary actions share a row instead of each claiming a full one. */ #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement { flex: 0 1 auto; } #wiktku-start-form #wiktku-last-saved { flex: 1 0 100%; order: 10; font-size: 11px; white-space: normal; } #wiktku-start-form .wiktku-adv-toggle-row { gap: 8px; } } /* =================================================================== IPA character palette (v3 spec) =================================================================== Click-to-insert chart under Bilêvkirin, after fr.wiktionary's. Two sub-tabs — a short Kurmancî set that opens by default, and the full chart — because ~20 of the ~180 IPA symbols ever occur in Kurmancî and showing all of them first is the same "wall of fields" problem this redesign exists to fix. =================================================================== */ #wiktku-start-form .wiktku-ipa-panel { border: 1px solid var(--wikt-card-edge); border-radius: 12px; background: var(--wikt-card-sunken); padding: 0 0 12px; margin-bottom: 8px; overflow: hidden; } #wiktku-start-form .wiktku-ipa-subtabs { display: flex; align-items: center; gap: 4px; padding: 8px 12px 0; border-bottom: 1px solid var(--wikt-rule-soft); margin-bottom: 12px; flex-wrap: wrap; } #wiktku-start-form .wiktku-ipa-subtab { font-size: 13px; font-weight: 500; color: var(--wikt-ink-3); padding: 7px 12px 9px; border-bottom: 3px solid transparent; border-radius: 8px 8px 0 0; cursor: pointer; } #wiktku-start-form .wiktku-ipa-subtab:hover { background: var(--wikt-card); color: var(--wikt-ink); } #wiktku-start-form .wiktku-ipa-subtab.wiktku-tab-active { background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom-color: var(--wikt-accent); } /* Templates are not characters, so they sit apart from the chart — pinned to the right of the sub-tab row. */ #wiktku-start-form .wiktku-ipa-tplbtns { margin-left: auto; display: flex; gap: 6px; padding-bottom: 6px; } #wiktku-start-form .wiktku-ipa-tplbtn { font-family: var(--wikt-mono); font-size: 12px; padding: 6px 10px; border-radius: 7px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); cursor: pointer; white-space: nowrap; } #wiktku-start-form .wiktku-ipa-tplbtn:hover { border-color: var(--wikt-accent); } #wiktku-start-form .wiktku-ipa-grid { display: flex; flex-direction: column; gap: 8px; padding: 0 12px; } #wiktku-start-form .wiktku-ipa-row { display: flex; align-items: flex-start; gap: 10px; } #wiktku-start-form .wiktku-ipa-rowlabel { flex: 0 0 74px; font-size: 11.5px; color: var(--wikt-muted); padding-top: 8px; line-height: 1.3; } #wiktku-start-form .wiktku-ipa-keys { display: flex; flex-wrap: wrap; gap: 4px; flex: 1 1 auto; } #wiktku-start-form .wiktku-ipa-key { width: 30px; height: 30px; padding: 0; border-radius: 8px; border: 1px solid var(--wikt-field-edge); background: var(--wikt-field-bg); color: var(--wikt-ink); font-family: var(--wikt-mono); font-size: 14px; line-height: 1; cursor: pointer; display: grid; place-items: center; transition: background 0.1s ease, border-color 0.1s ease; } #wiktku-start-form .wiktku-ipa-key:hover { background: var(--wikt-accent-tint); border-color: var(--wikt-accent); color: var(--wikt-accent-deep); } #wiktku-start-form .wiktku-ipa-key:active { transform: translateY(1px); } /* Ligatures like d͡ʒ and long vowels need a little more room than one glyph; let those keys grow instead of clipping. */ #wiktku-start-form .wiktku-ipa-key { width: auto; min-width: 30px; padding: 0 5px; } /* A combining mark is shown on a dotted circle so it has something to attach to; only the mark itself is inserted. */ #wiktku-start-form .wiktku-ipa-key-combining { color: var(--wikt-ink-2); } @media (max-width: 720px) { #wiktku-start-form .wiktku-ipa-row { flex-direction: column; gap: 3px; } #wiktku-start-form .wiktku-ipa-rowlabel { flex: 0 0 auto; padding-top: 0; } #wiktku-start-form .wiktku-ipa-key { min-width: 34px; height: 34px; } } /* ── "+ Beş zêde bike" menu ────────────────────────────────────────── Adding a part of speech and adding Bilêvkirin are different actions, so the button opens a small menu instead of doing one of them. */ #wiktku-start-form .wiktku-addsection-menu { position: absolute; z-index: 60; margin-top: 6px; min-width: 15em; background: var(--wikt-card); border: 1px solid var(--wikt-rule); border-radius: 10px; padding: 4px; display: flex; flex-direction: column; } #wiktku-start-form .wiktku-addsection-item { display: flex; flex-direction: column; gap: 1px; padding: 8px 10px; border-radius: 7px; border-bottom: 0; text-decoration: none; color: var(--wikt-ink); } #wiktku-start-form .wiktku-addsection-item:hover { background: var(--wikt-accent-tint); } #wiktku-start-form .wiktku-addsection-item-label { font-size: 13.5px; font-weight: 500; } #wiktku-start-form .wiktku-addsection-item-hint { font-size: 11.5px; color: var(--wikt-muted); } #wiktku-start-form #wiktku-section-tabs .oo-ui-buttonElement { position: relative; } /* Bilêvkirin is a peer of the POS sections but not a part of speech — a hairline before it marks the boundary. */ #wiktku-start-form .wiktku-section-tab-pron { margin-left: 6px; border-left: 1px solid var(--wikt-rule); padding-left: 14px; border-radius: 0; } /* =================================================================== Per-sense tabs =================================================================== "Mane 1 / Mane 2 / + Mane zêde bike" switches which sense is shown; only the active one is in the flow, so a multi-sense entry doesn't turn into a long scroll. */ #wiktku-start-form .wiktku-dfn-sense-tabs { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; border-bottom: 1px solid var(--wikt-rule); margin-bottom: 14px; } #wiktku-start-form .wiktku-dfn-sense-tab { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 500; color: var(--wikt-ink-3); background: transparent; border: 0; border-bottom: 3px solid transparent; border-radius: var(--wikt-r-pill) var(--wikt-r-pill) 0 0; padding: 7px 8px 9px 12px; cursor: pointer; user-select: none; transition: background 0.12s ease, color 0.12s ease; } #wiktku-start-form .wiktku-dfn-sense-tab:hover { background: var(--wikt-card-sunken); color: var(--wikt-ink); } #wiktku-start-form .wiktku-dfn-sense-tab.wiktku-tab-active { background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom-color: var(--wikt-accent); } /* Shared by the Mane sense tabs and the Beş (POS section) tabs — the plain-text label part of a tab, distinct from its trash button so the two keep their own alignment (label truncates/wraps as text; the button stays a fixed-size square) instead of both stretching. */ #wiktku-start-form .wiktku-tab-label { white-space: nowrap; } /* Delete button (trash icon) on a Mane or Beş tab. Deliberately small and muted by default — it should read as "also here if you need it", not compete with the tab label — and only goes red on hover/focus, since it's a destructive, unconfirmed-by-shape action otherwise. */ #wiktku-start-form .wiktku-trash-btn { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; width: 20px; height: 20px; padding: 0; border: 0; border-radius: 5px; background: transparent; color: var(--wikt-ink-3); cursor: pointer; } #wiktku-start-form .wiktku-trash-btn svg { width: 13px; height: 13px; fill: currentColor; } #wiktku-start-form .wiktku-trash-btn:hover, #wiktku-start-form .wiktku-trash-btn:focus-visible { background: rgba(156, 58, 40, 0.14); color: var(--wikt-danger); } #wiktku-start-form li.wiktku-dfn-sense { border: 1px solid var(--wikt-card-edge); border-radius: 12px; background: var(--wikt-card); margin-bottom: 10px; padding: 14px; list-style: none; overflow: visible; } #wiktku-start-form li.wiktku-dfn-sense.wiktku-sense-collapsed { display: none; } /* =================================================================== Template rows in the pickers (v3 spec) =================================================================== One row shape everywhere a template is chosen: the ⓘ explains terms like "guharto/kevnbûyî/ku-Latn/şaşnivîs" without leaving the form, and the 🔗 links out for when it doesn't. =================================================================== */ #wiktku-start-form ul.wiktku-ac-results li.wiktku-ac-tplrow { display: flex; align-items: center; gap: 8px; min-height: 44px; white-space: normal; padding: 6px 10px; } #wiktku-start-form .wiktku-ac-tpltext { flex: 1 1 auto; min-width: 0; font-family: var(--wikt-mono); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* Status, not category: green is the one to reach for, yellow means "only if you specifically need it" (kevnbûyî, şaşnivîs, kêmpeyda). */ #wiktku-start-form .wiktku-tpl-dot { flex: 0 0 8px; width: 8px; height: 8px; border-radius: 999px; } #wiktku-start-form .wiktku-tpl-dot-ok { background: #3d8a55; } #wiktku-start-form .wiktku-tpl-dot-special { background: #c9971f; } #wiktku-start-form .wiktku-tpl-icons { flex: 0 0 auto; display: flex; gap: 5px; align-items: center; } #wiktku-start-form .wiktku-tpl-icon { width: 26px; height: 26px; display: grid; place-items: center; font-size: 12px; line-height: 1; cursor: pointer; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom: 1px solid var(--wikt-accent-edge); text-decoration: none; padding: 0; } #wiktku-start-form .wiktku-tpl-icon-link { border-radius: 7px; } #wiktku-start-form .wiktku-tpl-icon-info { border-radius: 999px; font-family: var(--wikt-serif); font-style: italic; font-weight: 600; background: transparent; border-color: var(--wikt-field-edge); color: var(--wikt-muted); } #wiktku-start-form .wiktku-tpl-icon:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); background: var(--wikt-accent-tint); } /* ── The ⓘ panel ───────────────────────────────────────────────────── Three parts, in the spec's order: what it does, its parameters, and a way out to the template page. */ #wiktku-start-form .wiktku-tpl-info { position: relative; margin: 8px 0 4px; padding: 14px 16px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); border-radius: 12px; font-size: 13.5px; line-height: 1.6; color: var(--wikt-ink-2); } #wiktku-start-form .wiktku-tpl-info-name { font-family: var(--wikt-mono); font-size: 13px; color: var(--wikt-accent-deep); margin-bottom: 6px; } #wiktku-start-form .wiktku-tpl-info-params { margin-top: 8px; } #wiktku-start-form .wiktku-tpl-info-params-title { font-size: 12px; color: var(--wikt-muted); margin-bottom: 2px; } #wiktku-start-form .wiktku-tpl-info-params ul { margin: 0; padding-left: 18px; font-family: var(--wikt-mono); font-size: 12.5px; } #wiktku-start-form .wiktku-tpl-info-link { display: inline-block; margin-top: 10px; font-size: 13px; } #wiktku-start-form .wiktku-tpl-info-close { position: absolute; top: 8px; right: 8px; width: 24px; height: 24px; border-radius: 999px; border: 0; background: transparent; color: var(--wikt-muted); cursor: pointer; font-size: 13px; line-height: 1; } #wiktku-start-form .wiktku-tpl-info-close:hover { background: var(--wikt-card); color: var(--wikt-ink); } /* =================================================================== Footer overflow "⋯" (v3 spec) =================================================================== Bişîne and "Edîtora çavkaniyê veke" stay on the bar; the cache actions, saved-at note and Tercîh move in here so the destructive buttons don't compete for attention and the sticky footer stays to one row on a phone. =================================================================== */ #wiktku-start-form .wiktku-more-wrap { position: relative; margin-left: auto; flex: 0 0 auto; } #wiktku-start-form .wiktku-more-btn { width: 36px; height: 36px; border-radius: 999px; border: 1px solid var(--wikt-field-edge); background: var(--wikt-card); color: var(--wikt-muted); font-size: 16px; line-height: 1; cursor: pointer; display: grid; place-items: center; } #wiktku-start-form .wiktku-more-btn:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); } #wiktku-start-form .wiktku-more-menu { position: absolute; right: 0; bottom: calc(100% + 8px); z-index: 70; min-width: 17em; background: var(--wikt-card); border: 1px solid var(--wikt-rule); border-radius: 12px; padding: 6px; display: flex; flex-direction: column; gap: 2px; } #wiktku-start-form .wiktku-more-item { display: flex; align-items: center; gap: 8px; } /* The buttons inside the menu are menu rows, not buttons on a bar. */ #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement { flex: 1 1 auto; } #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement-button { display: block; width: 100%; text-align: left; border: 0 !important; background: transparent !important; border-radius: 7px !important; padding: 9px 10px; min-height: 0; font-weight: 400; color: var(--wikt-ink) !important; } #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement-button:hover { background: var(--wikt-accent-tint) !important; } #wiktku-start-form .wiktku-more-item-danger .oo-ui-buttonElement-button { color: var(--wikt-danger) !important; } #wiktku-start-form .wiktku-more-item-prefs .wiktku-prefs-btn { width: 26px; height: 26px; flex: 0 0 26px; border: 0; background-color: transparent; } #wiktku-start-form .wiktku-more-item-label { font-size: 13.5px; } #wiktku-start-form .wiktku-more-sep { height: 1px; background: var(--wikt-rule-soft); margin: 4px 2px; } #wiktku-start-form .wiktku-more-note { padding: 4px 10px 2px; } #wiktku-start-form .wiktku-more-note #wiktku-last-saved { white-space: normal; } /* "+ Mane zêde bike" sits as the last item in .wiktku-dfn-sense-tabs. */ #wiktku-start-form .wiktku-add-sense { display: inline-flex; align-items: center; gap: 6px; margin: 3px 0; padding: 6px 14px; border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-pill); background: var(--wikt-card); color: var(--wikt-ink-2); font-family: var(--wikt-sans); font-size: 13px; cursor: pointer; min-height: 34px; } #wiktku-start-form .wiktku-add-sense:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); background: var(--wikt-accent-tint); } #wiktku-start-form .wiktku-add-sense-plus { color: var(--wikt-accent); font-size: 15px; line-height: 1; } /* ── Şablon picker, demoted to a link ──────────────────────────────── Picking a template replaces the definition rather than adding to it, so it is an alternative route, not the first control in the sense. Hidden behind one line of text until it is actually wanted. */ #wiktku-start-form .wiktku-dfn-tpl-link { display: inline-block; margin-top: 8px; font-size: 12.5px; color: var(--wikt-muted); border-bottom: 1px solid transparent; } #wiktku-start-form .wiktku-dfn-tpl-link:hover { color: var(--wikt-accent); border-bottom-color: var(--wikt-link-under); } #wiktku-start-form .wiktku-dfn-tpl-row { margin-top: 10px; padding-top: 12px; border-top: 1px solid var(--wikt-rule-soft); } /* ── Template-row icons on touch screens ───────────────────────────── 26px is fine for a mouse and too small for a thumb, and these two sit right next to each other at the end of a row you can also tap to select. Give them real targets and some separation on small screens. */ @media (max-width: 720px), (pointer: coarse) { #wiktku-start-form .wiktku-tpl-icon { width: 34px; height: 34px; font-size: 14px; } #wiktku-start-form .wiktku-tpl-icons { gap: 8px; padding-left: 4px; } #wiktku-start-form ul.wiktku-ac-results li.wiktku-ac-tplrow { min-height: 50px; } } /* The rendered pronunciation preview is real parser output, so it needs to sit as content rather than in the monospace wikitext treatment the panel inherits. */ #wiktku-start-form .wiktku-pron-preview-body { font-family: var(--wikt-sans); font-size: 15px; background: var(--wikt-card); border: 1px solid var(--wikt-accent-edge); border-radius: 8px; padding: 10px 12px; white-space: normal; } #wiktku-start-form .wiktku-pron-preview-body .IPA, #wiktku-start-form .wiktku-pron-preview-body code, #wiktku-start-form .wiktku-pron-preview-body tt { font-family: var(--wikt-mono); } /* Parser output brings its own margins; strip the outer ones so the preview box doesn't gain a blank first line. */ #wiktku-start-form .wiktku-pron-preview-body > *:first-child { margin-top: 0; } #wiktku-start-form .wiktku-pron-preview-body > *:last-child { margin-bottom: 0; } c9yzus7n7h0ao5k9vn4k8onc45j0z4z 6333860 6333856 2026-08-15T18:08:34Z Wikihez 7344 6333860 css text/css /* =================================================================== #editform while the wizard is active =================================================================== */ /* Keeps #editform genuinely laid out instead of display:none*/ .wiktku-offscreen { position: absolute !important; left: -9999px !important; top: 0 !important; width: 100%; max-width: 100%; visibility: hidden; } /* =================================================================== Base scale =================================================================== */ #wiktku-start-form { font-size: 0.92em; line-height: 1.35; } #wiktku-start-form * { box-sizing: border-box; } .wiktku-addlang-notice { margin: 0 0 0.8em; padding: 0.6em 0.8em; background: var(--wikt-palette-paleblue); border: 1px solid var(--wikt-palette-lightgrey); border-radius: 4px; } /* =================================================================== Step cards a compact card with a left accent bar, so each step reads as a distinct unit =================================================================== */ .wiktku-start-step { padding: 0.7em 0.9em; margin-bottom: 0.6em; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-left: 4px solid var(--wikt-palette-blue-9, #3366cc); border-radius: 6px; background: var(--wikt-palette-white); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); transition: border-left-color 0.15s ease, box-shadow 0.15s ease; } .wiktku-start-step:hover { box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08); } .wiktku-start-step:focus-within { border-left-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); } /* Fuses the posparams card onto the bottom of the pos card (shared left accent bar, no border/gap) since posparams always renders directly after #wiktku-start-pos once a pos is chosen. */ #wiktku-start-pos { border-radius: 6px 6px 0 0; margin-bottom: 0; border-bottom: none; } #wiktku-start-posparams { border-radius: 0 0 6px 6px; border-top: none; padding-top: 0.3em; } #wiktku-start-posparams .wiktku-start-step-name { display: none; } /* Scoped and !important: this is a real <h3> tag (see start.js), so the skin's default heading styles would otherwise override a plain class rule. Coloured to match the card's accent bar; .wiktku-start-step-question below stays lighter/muted so the two don't compete. */ #wiktku-start-form .wiktku-start-step-name { font-size: 1.1em !important; font-weight: 700; letter-spacing: 0.03em; margin: 0 0 0.3em; line-height: 1.2; color: var(--wikt-palette-blue-9, #3366cc); border: 0; padding: 0; } /* Sized close to the heading so the card reads consistently instead of the text below it looking like fine print. */ .wiktku-start-step-question { font-size: 1em; font-weight: 400; color: var(--wikt-palette-grey-9, #555); margin: 0 0 0.5em; line-height: 1.45; } .wiktku-start-step label { padding-right: 1.2em; font-size: 1em; } /* Muted hint text next to a field, styled to read as a hint rather than another question competing with .wiktku-start-step-question. */ .wiktku-step-hint { font-size: 0.88em; font-style: italic; color: var(--wikt-palette-grey-8, #72777d); margin: 0 0 0.5em; line-height: 1.4; } /* Same specificity as the rule just above, so it must come after to actually win: the name label isn't a field label needing right padding or the form's base label size, it's a heading. */ #wiktku-start-form .wiktku-start-step-name label { padding-right: 0; font-size: inherit !important; color: inherit; } input[type="text"].wiktku-start-step-field { width: 100%; padding: 5px 8px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 4px; transition: border-color 0.12s ease, box-shadow 0.12s ease; } input[type="text"].wiktku-start-step-field:focus { border-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9, #3366cc); outline: 0; } input[type="text"].wiktku-start-step-field.wiktku-start-narrow { width: 20em; } /* Only used by selects that opt out via .wiktku-plain-select; other selects get their width from the searchable picker instead (see input.wiktku-ac-input). */ select.wiktku-start-narrow, input.wiktku-dfn-tpl-title { width: 20em; max-width: 100%; box-sizing: border-box; } #wiktku-start-spinner { float: right; margin-left: 1em; } #wiktku-start-footer { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5em; padding: 0.6em 0.2em; position: sticky; bottom: 0; background: var(--wikt-palette-white); border-top: 1px solid var(--wikt-palette-grey-3, #e0e0e0); z-index: 5; } /* Quiet, non-competing text — sits next to the cache buttons so the person can tell at a glance whether their latest edits are backed up, without it fighting the buttons for attention. */ #wiktku-last-saved { font-size: 0.85em; color: var(--wikt-palette-grey-9, #767676); white-space: nowrap; } /* ── Tercîh (settings) icon button — sits in the footer next to the cache buttons. Uses the Codex "settings" (color-subtle) icon from Commons directly rather than an OOUI icon-pack module, so it renders the exact requested glyph without pulling in an extra dependency. */ .wiktku-prefs-btn { width: 2.2em; height: 2.2em; flex: 0 0 auto; padding: 0; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-radius: 2px; background-color: var(--wikt-palette-white); background-image: url(//upload.wikimedia.org/wikipedia/commons/e/e0/Codex_icon_settings_color-subtle.svg); background-repeat: no-repeat; background-position: center; background-size: 1.2em 1.2em; cursor: pointer; } .wiktku-prefs-btn:hover { background-color: var(--wikt-palette-grey-0, #f8f9fa); } .wiktku-prefs-btn:active { background-color: var(--wikt-palette-grey-1, #eaecf0); } /* Tercîh dialog body — OOUI's bare ProcessDialog body has no inset of its own, so text/fields otherwise sit flush against the window edges. */ .wiktku-prefs-dialog-body { padding: 1em 1.2em; } /* ── "Bişîne" click feedback ── */ @keyframes wiktku-btn-flash-pulse { 0% { box-shadow: 0 0 0 0 rgba(51, 102, 204, 0.55); } 70% { box-shadow: 0 0 0 9px rgba(51, 102, 204, 0); } 100% { box-shadow: 0 0 0 0 rgba(51, 102, 204, 0); } } #wiktku-unhide-editform.wiktku-btn-flash { animation: wiktku-btn-flash-pulse 0.5s ease-out; } /* Persistent state while the wikitext is being built/submitted, set alongside OOUI's own setDisabled(true) so it reads clearly even if the skin's default disabled style is subtle. */ #wiktku-unhide-editform.wiktku-btn-sending .oo-ui-buttonElement-button { background-color: var(--wikt-palette-grey-9, #767676) !important; border-color: var(--wikt-palette-grey-9, #767676) !important; cursor: progress; opacity: 1 !important; } /* Looks like OOUI's disabled state but isn't one — the button stays clickable so its handler can still run and explain why (see the wiktkuNotify call next to wiktkuContentGateOk in start.js). */ #wiktku-unhide-editform.wiktku-btn-soft-disabled .oo-ui-buttonElement-button { opacity: 0.5; cursor: not-allowed; } /* ── "Beşên din" picker ── */ .wiktku-besendin-picker { margin: 0.6em 0 1em; } .wiktku-besendin-picker .wiktku-besendin-select { width: 100%; max-width: 24em; } #wiktku-start-form textarea.wiktku-start-step-field, #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield { resize: vertical !important; overflow: auto !important; box-sizing: border-box !important; vertical-align: top; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; transition: border-color 0.1s ease, box-shadow 0.1s ease; } /* Modern focus state to match the searchable-picker inputs. */ #wiktku-start-form textarea.wiktku-start-step-field:focus, #wiktku-start-form textarea.wiktku-start-narrow:focus, #wiktku-start-form textarea.wiktku-dfn-subfield:focus { border-color: var(--wikt-palette-blue-9, #3366cc); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9, #3366cc); outline: 0; } /* Standard: every textarea in the form is full width by default */ #wiktku-start-form textarea:not(.wiktku-start-narrow) { width: 100%; max-width: 100%; box-sizing: border-box; } #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield.wiktku-start-narrow { width: 20em; max-width: 100%; min-width: 8em; height: calc(1.7em + 10px); min-height: calc(1.7em + 10px); padding-top: 4px !important; padding-bottom: 4px !important; line-height: 1.35 !important; resize: none !important; } /* Exception: "Sernav" / "Sernavê orjînal" citation-source fields (kitêb, kovar, malper, …) — long enough to be worth 2 rows and manual resizing. */ #wiktku-start-form textarea.wiktku-dfn-quote-src-input.wiktku-dfn-quote-src-input--title { height: calc(2 * 1.35em + 10px); min-height: calc(2 * 1.35em + 10px); } /* ── Manual drag-to-resize handle ── */ #wiktku-start-form textarea:not(.wiktku-start-narrow) { resize: none !important; } /* Inline modifier button (⊕) */ .wiktku-word-li { display: flex; align-items: flex-start; flex-wrap: wrap; gap: 0.3em; } .wiktku-mod-btn { flex: 0 0 auto; width: 1.6em; height: 1.6em; padding: 0; line-height: 1; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); color: var(--wikt-palette-blue-9, #3366cc); font-size: 1em; cursor: pointer; } .wiktku-mod-btn:hover { border-color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-paleblue, #eaf3ff); } .wiktku-mod-picker { display: flex; flex-wrap: wrap; gap: 0.25em; width: 100%; margin-top: 0.15em; padding: 0.35em; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; background: var(--wikt-palette-white); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); } .wiktku-mod-pill { padding: 2px 8px; border: 1px solid var(--wikt-palette-grey-3, #e0e0e0); border-radius: 12px; background: var(--wikt-palette-paleblue, #eaf3ff); font-size: 0.85em; white-space: nowrap; cursor: pointer; } .wiktku-mod-pill:hover { border-color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); } .wiktku-mod-pill:disabled, .wiktku-mod-pill.wiktku-mod-pill-used { border-color: var(--wikt-palette-grey-3, #e0e0e0); background: var(--wikt-palette-lightgrey); color: var(--wikt-palette-grey-3, #999); cursor: not-allowed; opacity: 0.6; } .wiktku-mod-pill:disabled:hover, .wiktku-mod-pill.wiktku-mod-pill-used:hover { border-color: var(--wikt-palette-grey-3, #e0e0e0); background: var(--wikt-palette-lightgrey); color: var(--wikt-palette-grey-3, #999); } .wiktku-mod-val-wrap { display: flex; align-items: center; gap: 0.25em; width: 100%; margin-top: 0.15em; } .wiktku-mod-val-input { flex: 0 1 14em; max-width: 14em; padding: 3px 6px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; } .wiktku-mod-confirm, .wiktku-mod-cancel { flex: 0 0 auto; width: 1.6em; height: 1.6em; padding: 0; line-height: 1; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); cursor: pointer; } .wiktku-mod-confirm { color: #178a17; border-color: #178a17; } .wiktku-mod-cancel { color: var(--wikt-palette-red-9, #d33); border-color: var(--wikt-palette-red-9, #d33); } .wiktku-resize-wrap { position: relative; display: block; } /* Separate from .wiktku-resize-wrap (used only for textareas flagged with a linebreak); plain position:relative anchor for the backdrop, no size of its own. */ .wiktku-linebreak-wrap { position: relative; display: block; } .wiktku-resize-grip { position: absolute; right: 2px; bottom: 2px; width: 14px; height: 14px; cursor: ns-resize; touch-action: none; opacity: 0.5; z-index: 2; background-image: linear-gradient(135deg, transparent 0 50%, var(--wikt-palette-grey-9, #767676) 50% 100%); background-repeat: no-repeat; } .wiktku-resize-grip:hover, .wiktku-resize-grip:active { opacity: 0.9; } /* =================================================================== Searchable dropdown (wrapNativeSelect in start.js) .wiktku-native-select-wrap > input.wiktku-ac-input (search box) > ul.wiktku-ac-results (result list) > select (hidden, holds the value) =================================================================== */ .wiktku-native-select-wrap { display: inline-block; position: relative; vertical-align: top; } /* Matches the width the native select would have had (see select.wiktku-start-narrow). */ .wiktku-native-select-wrap input[type="search"], input.wiktku-ac-input { display: block; width: 20em; max-width: 100%; box-sizing: border-box; padding: 3px 6px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); color: inherit; font-size: inherit; font-family: inherit; transition: border-color 0.1s ease, box-shadow 0.1s ease; } input.wiktku-ac-input:focus { border-color: var(--wikt-palette-blue-9); box-shadow: inset 0 0 0 1px var(--wikt-palette-blue-9); outline: 0; } input.wiktku-ac-input::placeholder { color: var(--wikt-palette-grey-9); opacity: 1; } /* Hide Safari/Chrome's built-in search decorations. */ input.wiktku-ac-input::-webkit-search-decoration, input.wiktku-ac-input::-webkit-search-cancel-button, input.wiktku-ac-input::-webkit-search-results-button { -webkit-appearance: none; appearance: none; } /* ── Result list ── */ /* top/bottom/max-height are overridden inline by showResults() when it flips the list above the box; these are just its defaults. */ ul.wiktku-ac-results { position: absolute; z-index: 9999; top: 100%; bottom: auto; left: 0; margin: 0; padding: 0; list-style: none; width: 20em; max-width: 90vw; max-height: 13em; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; background: var(--wikt-palette-white); border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px; box-shadow: 0 3px 10px rgba(0, 0, 0, 0.15); } ul.wiktku-ac-results li { margin: 0; padding: 4px 8px; cursor: pointer; font-size: 0.92em; display: flex; align-items: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* .wiktku-ac-active is the keyboard cursor; hover mirrors it; :active covers the touch press state. */ ul.wiktku-ac-results li.wiktku-ac-active, ul.wiktku-ac-results li:hover { background: var(--wikt-palette-lightblue); } ul.wiktku-ac-results li:active { background: var(--wikt-palette-blue-9); color: var(--wikt-palette-white); } /* Touch devices: bigger tap targets, no sticky hover. */ @media (pointer: coarse) { ul.wiktku-ac-results li { padding: 6px 10px; min-height: 2.2em; font-size: 1em; } ul.wiktku-ac-results li:hover { background: transparent; } ul.wiktku-ac-results li.wiktku-ac-active { background: var(--wikt-palette-lightblue); } input.wiktku-ac-input { /* >=16px stops iOS Safari zooming the page when the box is focused. */ font-size: 16px; min-height: 2.2em; } } /* Inline preview + confirm panel shown before inserting an auto-content pronunciation template, part of the form layout rather than a browser confirm()/prompt() dialog. */ .wiktku-pron-preview { margin: 6px 0; padding: 8px 10px; border: 1px solid var(--wikt-palette-blue-9, #3366cc); border-radius: 6px; background: var(--wikt-palette-paleblue, #eaf3ff); } .wiktku-pron-preview-label { font-size: 0.88em; font-weight: 600; color: var(--wikt-palette-grey-9, #555); margin-bottom: 3px; } .wiktku-pron-preview-body { font-family: monospace; font-size: 1em; white-space: pre-wrap; word-break: break-word; margin-bottom: 6px; } .wiktku-pron-preview-actions { display: flex; gap: 6px; } .wiktku-pron-preview-confirm, .wiktku-pron-preview-cancel { font-size: 0.88em; padding: 3px 10px; border-radius: 4px; cursor: pointer; border: 1px solid var(--wikt-palette-lightgrey, #a2a9b1); background: var(--wikt-palette-white, #fff); } .wiktku-pron-preview-confirm { border-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-blue-9, #3366cc); font-weight: 600; } .wiktku-pron-preview-confirm:disabled { opacity: 0.5; cursor: wait; } .wiktku-pron-preview-cancel:hover { background: var(--wikt-palette-grey-0, #f8f9fa); } /* Template pickers fill their container since the search box, not the <select>, is what the user sees. */ .wiktku-pron-wrap .wiktku-native-select-wrap, .wiktku-etym-wrap .wiktku-native-select-wrap, .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { width: 100%; } .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 0.88em; } .wiktku-cavkani-wrap .wiktku-native-select-wrap, .wiktku-cavkani-wrap .wiktku-native-select-wrap input.wiktku-ac-input { width: 100%; } /* Template selector inside a sense block. */ .wiktku-dfn-tpl-row .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 0.88em; } /* Language/dialect rows: picker must line up with the word field beside it. */ .wiktku-lang-row .wiktku-native-select-wrap { flex: 0 0 auto; } #wiktku-start-form textarea.wiktku-dfn-mane, #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t, #wiktku-start-form textarea.wiktku-dfn-quote-src-manual, #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text, #wiktku-start-form .wiktku-tewandin-wrap textarea.wiktku-tewandin-text, #wiktku-start-form textarea.wiktku-cavkani-text, #wiktku-start-form textarea.wiktku-dfn-tercime, #wiktku-start-form textarea.wiktku-dfn-izah { --wiktku-ta-rows: 2; height: calc(var(--wiktku-ta-rows) * 1.35em + 6px); min-height: calc(var(--wiktku-ta-rows) * 1.35em + 6px); } #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text, #wiktku-start-form textarea.wiktku-dfn-izah { --wiktku-ta-rows: 3; } #wiktku-start-form textarea.wiktku-cavkani-text { --wiktku-ta-rows: 4; } /* Nimûne + Jêgirtin (citation) boxes, and their tr/t sub-fields: at least 4 rows so there's room to actually write an example/quote. */ #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t, #wiktku-start-form textarea.wiktku-dfn-quote-src-manual { --wiktku-ta-rows: 4; } /* Nudges the border when the box contains a typed/pasted linebreak, so the user notices before it's silently turned into <br> on output; the break itself is marked via a mirrored backdrop layer (see below). */ #wiktku-start-form textarea.wiktku-has-linebreak { border-color: var(--wikt-palette-yellow6, #ac6600) !important; } /* Sits behind the textarea showing the same text, with a highlighted marker at each line followed by a break; font/padding/line-height are copied from the textarea via computed style, not shared CSS classes. */ .wiktku-linebreak-backdrop { position: absolute; inset: 0; z-index: 0; margin: 0; overflow: hidden; white-space: pre-wrap; word-wrap: break-word; color: transparent; background: transparent !important; border-color: transparent !important; box-shadow: none !important; resize: none !important; pointer-events: none; } /* Raise the real textarea above its backdrop so typing/selection/caret behave completely normally; the backdrop's mark shows through only where the real textarea's own background is transparent. */ #wiktku-start-form textarea.wiktku-has-linebreak-source { position: relative; z-index: 1; background-color: transparent; } .wiktku-linebreak-mark { background-color: var(--wikt-palette-yellow6, #ac6600); color: var(--wikt-palette-white, #fff); border-radius: 2px; } /* ── Tercime + Îzah boxes ── */ .wiktku-dfn-nonku-wrap { display: flex; flex-direction: column; gap: 3px; } .wiktku-dfn-nimune-sub, .wiktku-dfn-quote-sub { margin-top: 3px; margin-left: 1em; padding-left: 0.6em; border-left: 2px solid var(--wikt-palette-lightgrey); display: flex; flex-direction: column; gap: 3px; } .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t { min-width: 8em; padding-top: 2px !important; padding-bottom: 2px !important; line-height: 1.35 !important; font-size: 0.88em; } /* Sense list (Mane step) — one sense visible at a time, switched via .wiktku-dfn-sense-tabs. */ ol.wiktku-dfn-list { list-style: none; margin: 0; padding: 0; } ol.wiktku-dfn-list > li.wiktku-dfn-sense { margin-bottom: 0.9em; } /* Template selector row inside a sense block */ .wiktku-dfn-tpl-row { margin-bottom: 3px; } /* ── Sub-field titles (Etîket, Kategorî, Hevmane, Dijmane, Nimûne, Jêgirtin, …): each group reads as a small labelled field — the term stands out, the hint stays quiet. ── */ .wiktku-dfn-subgroup { margin-top: 0.5em; padding-top: 0.4em; border-top: 1px dashed var(--wikt-palette-grey-3, #e0e0e0); } .wiktku-dfn-subgroup:first-of-type { margin-top: 0.3em; padding-top: 0; border-top: none; } .wiktku-dfn-sublabel { display: block; margin-bottom: 3px; font-size: 0.88em; } .wiktku-dfn-sublabel-term { font-weight: 600; color: var(--wikt-palette-blue-9, #3366cc); letter-spacing: 0.03em; font-size: 0.92em; } .wiktku-dfn-sublabel-hint { color: var(--wikt-palette-grey-9, #767676); font-style: italic; } .wiktku-pron-wrap, .wiktku-etym-wrap, .wiktku-tewandin-wrap, .wiktku-cavkani-wrap { display: flex; flex-direction: column; gap: 3px; } /* ── POS section tabs — rounded pill style ── */ #wiktku-section-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 0.6em; align-items: center; } #wiktku-section-tabs .wiktku-section-tab { padding: 3px 12px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 999px; background: var(--wikt-palette-dullcyan); cursor: pointer; font-size: 0.86em; user-select: none; transition: background 0.12s ease, border-color 0.12s ease; } #wiktku-section-tabs .wiktku-section-tab:hover { border-color: var(--wikt-palette-blue-9, #3366cc); } #wiktku-section-tabs .wiktku-section-tab.wiktku-tab-active { background: var(--wikt-palette-blue-9, #3366cc); border-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); font-weight: 600; } /* ── Step-group tabs (Mane / Bilêvkirin / Beşên din — see STEP_GROUPS in start.js) ── Sits directly under the pill-style section tabs above; styled as an underlined secondary nav so the two bars stay visually distinct. */ #wiktku-group-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 0.8em; border-bottom: 2px solid var(--wikt-palette-lightgrey); } #wiktku-group-tabs .wiktku-group-tab { position: relative; padding: 7px 14px 8px; margin-bottom: -2px; border-bottom: 3px solid transparent; border-radius: 3px 3px 0 0; cursor: pointer; font-size: 0.95em; font-weight: 600; color: var(--wikt-palette-grey-9, #333); background: var(--wikt-palette-grey-0, #f8f9fa); user-select: none; transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease; } #wiktku-group-tabs .wiktku-group-tab:hover { color: var(--wikt-palette-blue-9, #3366cc); background: var(--wikt-palette-paleblue, #eaf3ff); } #wiktku-group-tabs .wiktku-group-tab.wiktku-tab-active { border-bottom-color: var(--wikt-palette-blue-9, #3366cc); color: var(--wikt-palette-white); background: var(--wikt-palette-blue-9, #3366cc); font-weight: 700; } /* Small dot marking a tab that still has an unfilled required field hidden inside it (see updateGroupTabIndicators in start.js). Cleared automatically once that tab becomes the active one. */ #wiktku-group-tabs .wiktku-group-tab.wiktku-tab-missing::after { content: ""; position: absolute; top: 4px; right: -1px; width: 6px; height: 6px; border-radius: 50%; background: var(--wikt-palette-red-9, #d33); } .wiktku-lang-row-list { margin: 0; padding: 0; list-style: none; } .wiktku-lang-row { display: flex; align-items: flex-start; gap: 6px; margin-bottom: 3px; flex-wrap: wrap; } .wiktku-lang-row-words { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 3px; } /* Dûnde/Werger/Zarava rows: align the picker's height with the adjacent word textarea (see .wiktku-start-narrow above). */ .wiktku-lang-row .wiktku-native-select-wrap input.wiktku-ac-input { height: calc(1.7em + 10px); min-height: calc(1.7em + 10px); padding-top: 4px; padding-bottom: 4px; } /* ── Werger / Bi zaravayên din groups: one per gloss, shared spacing ── */ #wiktku-start-trans .wiktku-trans-group, #wiktku-start-zarava .wiktku-zarava-group { margin-bottom: 0.6em; } #wiktku-start-trans .wiktku-trans-group:last-child, #wiktku-start-zarava .wiktku-zarava-group:last-child { margin-bottom: 0; } #wiktku-start-trans .wiktku-trans-group-label, #wiktku-start-zarava .wiktku-zarava-group-label { font-weight: 600; font-size: 0.88em; margin-bottom: 3px; } .wiktku-dfn-jeder-group { margin-top: 3px; } .wiktku-dfn-quote-src-sel { font-size: 0.88em; margin-top: 3px; display: block; } .wiktku-dfn-quote-src-fields { display: flex; flex-direction: column; gap: 3px; margin-top: 3px; } /* Stacked layout: textarea gets its own full-width row, button + status sit below it on their own row. */ .wiktku-dfn-quote-citoid { display: flex; flex-direction: column; align-items: stretch; gap: 0.4em; margin-top: 3px; margin-bottom: 3px; } .wiktku-dfn-quote-citoid-input { width: 100%; max-width: 100%; box-sizing: border-box; } /* Column flex + align-items:stretch (above) makes the textarea's .wiktku-resize-wrap reach full width automatically; button and status text opt back out via align-self so they keep their natural size. */ .wiktku-dfn-quote-citoid-btn, .wiktku-dfn-quote-citoid-status { align-self: flex-start; } .wiktku-dfn-quote-src-cat-status { display: block; font-size: 0.82em; color: var(--wikt-palette-lightgrey, #767676); margin-top: 2px; } .wiktku-dfn-quote-src-row { display: flex; align-items: baseline; gap: 4px; flex-wrap: wrap; } .wiktku-dfn-quote-src-row label { font-size: 0.82em; white-space: nowrap; min-width: 8em; } textarea.wiktku-dfn-quote-src-input { flex: 1 1 12em; max-width: 100%; box-sizing: border-box; } @media (max-width: 720px) { .wiktku-lang-row { flex-direction: column; } /* Re-asserts against the skin's own mobile-breakpoint heading styles, which load after ours in the cascade. */ #wiktku-start-form .wiktku-start-step-name { font-size: 1.05em !important; margin: 0 0 0.2em !important; line-height: 1.2 !important; border: 0 !important; padding: 0 !important; } /* Single column: search box, list, and narrow textareas (Etîket, Hevmane, Dûnde/Jê/Têkildar/Binêre herwiha word boxes, citation source fields, …) all use the full width. */ .wiktku-native-select-wrap, input.wiktku-ac-input, ul.wiktku-ac-results, #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield.wiktku-start-narrow { width: 100%; max-width: 100%; } .wiktku-mod-val-input { flex: 1 1 auto; max-width: 100%; } #wiktku-start-form textarea.wiktku-dfn-mane, #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text { --wiktku-ta-rows: 3; font-size: 1em; } #wiktku-start-form .wiktku-tewandin-wrap textarea.wiktku-tewandin-text, #wiktku-start-form textarea.wiktku-cavkani-text { --wiktku-ta-rows: 4; font-size: 1em; } /* Nimûne + Jêgirtin and their tr/t sub-fields: keep at least 4 rows on mobile too, rather than shrinking further than the desktop size. */ #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t { --wiktku-ta-rows: 4; font-size: 1em; } /* Citoid URL/DOI/ISBN box: taller tap target (~2 lines) on mobile, and now that this field is a <textarea> (see start.js) its placeholder can actually wrap into that space — a plain <input>'s placeholder can never wrap, no matter its height. */ .wiktku-dfn-quote-citoid-input { min-height: calc(2 * 1.35em + 10px); font-size: 1em; } .wiktku-dfn-nimune-sub, .wiktku-dfn-quote-sub { margin-left: 0.5em; padding-left: 0.4em; } .wiktku-pron-wrap .wiktku-native-select-wrap input.wiktku-ac-input, .wiktku-etym-wrap .wiktku-native-select-wrap input.wiktku-ac-input { font-size: 1em; min-height: 2.2em; } .wiktku-dfn-quote-src-row label { min-width: 6em; } #wiktku-start-form textarea.wiktku-dfn-quote-src-input { width: 100%; flex: 1 1 100%; } .wiktku-start-step { padding: 0.5em 0.6em; } } /* =================================================================== Night mode Palette.css already flips --wikt-palette-* vars for night mode; this hook only covers real colours (panel border) that aren't a palette var, since a drop shadow is invisible against an equally dark page. =================================================================== */ @media screen { html.skin-theme-clientpref-night .wiktku-ac-results { /* Border stands in for the shadow, invisible on a dark page. */ border-color: var(--wikt-palette-grey-5); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.6); } html.skin-theme-clientpref-night .wiktku-start-step, html.skin-theme-clientpref-night .wiktku-start-step:hover, html.skin-theme-clientpref-night .wiktku-start-step:focus-within { box-shadow: none; } } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os .wiktku-ac-results { border-color: var(--wikt-palette-grey-5); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.6); } html.skin-theme-clientpref-os .wiktku-start-step, html.skin-theme-clientpref-os .wiktku-start-step:hover, html.skin-theme-clientpref-os .wiktku-start-step:focus-within { box-shadow: none; } } /* "Zimanek lê zêde bike" portlet icon (Minerva/mobile) — Feather-core-edit.svg via CSS mask, matching Minerva's own icon pattern. */ .minerva-icon-portletlink-ca-wiktku-addlang { -webkit-mask-image: url("https://upload.wikimedia.org/wikipedia/commons/d/d7/Feather-core-edit.svg"); mask-image: url("https://upload.wikimedia.org/wikipedia/commons/d/d7/Feather-core-edit.svg"); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-position: center; mask-position: center; -webkit-mask-size: 20px; mask-size: 20px; background-color: currentColor; background-image: none; } /* ── posparams step (live wikitext + helper widgets) ── */ .wiktku-posparams-wrap { display: flex; flex-direction: column; gap: 6px; } .wiktku-posparams-helpers { display: flex; flex-direction: column; gap: 4px; } .wiktku-posparams-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; } .wiktku-posparams-row label { font-size: 1em; min-width: 10em; padding-right: 0; } .wiktku-posparams-text { width: 100%; box-sizing: border-box; font-family: monospace; font-size: 0.9em; } .wiktku-posparams-opt-toggle { font-size: 0.85em; margin-top: 2px; display: inline-block; } .wiktku-posparams-opt-panel { display: flex; flex-direction: column; gap: 2px; padding: 4px 0 2px 1em; } .wiktku-posparams-opt-row { display: flex; align-items: center; gap: 4px; font-size: 0.85em; } /* ── resim step (one or more images) ── */ .wiktku-resim-list { display: flex; flex-direction: column; gap: 6px; } .wiktku-resim-item { display: flex; flex-direction: column; gap: 4px; } .wiktku-resim-item .wiktku-posparams-row { flex-direction: column; align-items: flex-start; gap: 2px; } .wiktku-resim-item .wiktku-posparams-row label { min-width: 0; font-size: 0.9em; } /* ── dfn: "hide/show all subsections" link ── Toggles a class on the whole dfn stepDiv so one click hides the etîket/kategorî/hevmane/dijmane/nimûne/jêgirtin/etc. subgroups across every sense block at once. */ .wiktku-dfn-subs-toggle { font-size: 0.85em; font-weight: 500; display: inline-block; margin: 2px 0 8px; color: var(--wikt-palette-blue-9, #3366cc); text-decoration: none; } .wiktku-dfn-subs-toggle:hover { text-decoration: underline; } /* Only the ADVANCED subgroups collapse: Nimûne, Jêgirtin, Hevmane and Dijmane stay open because they are what people come here to fill in. */ #wiktku-start-form li.wiktku-sense-adv-hidden .wiktku-dfn-subgroup-adv { display: none !important; } /* The toggle sits between the primary groups and the advanced ones, so it needs no rule of its own beyond a little breathing room. */ #wiktku-start-form .wiktku-sense-adv-row { margin-top: 14px; } /* =================================================================== Desktop text bump Modifier pills/buttons and posparams helper text read fine at their small mobile sizes but look too small on desktop, so bump them up past the 720px breakpoint only. =================================================================== */ @media (min-width: 721px) { .wiktku-mod-btn, .wiktku-mod-confirm, .wiktku-mod-cancel { width: 1.8em; height: 1.8em; font-size: 1.1em; } .wiktku-mod-pill { font-size: 0.95em; padding: 3px 10px; } .wiktku-mod-val-input { font-size: 0.95em; } .wiktku-posparams-row label { font-size: 1em; } .wiktku-posparams-text { font-size: 1em; } .wiktku-posparams-opt-toggle { font-size: 0.95em; } .wiktku-posparams-opt-row { font-size: 0.95em; } .wiktku-dfn-subs-toggle { font-size: 0.95em; } /* Multi-column card layout for posparams helper fields (transliteration, gendered forms, comparative/superlative, hanja, verb-tense roots, …), desktop-only. Rows are shown/hidden via jQuery inline display; the grid only rearranges visible rows, not which ones are visible. */ .wiktku-posparams-helpers { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px 16px; align-items: start; } .wiktku-posparams-helpers > .wiktku-posparams-row { flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 3px; } .wiktku-posparams-helpers > .wiktku-posparams-row label { min-width: 0; } .wiktku-posparams-helpers > .wiktku-posparams-row .wiktku-posparams-field, .wiktku-posparams-helpers > .wiktku-posparams-row select.wiktku-posparams-cinsiyet-sel, .wiktku-posparams-helpers > .wiktku-posparams-row select.wiktku-posparams-lektur-sel { width: 100%; max-width: 100%; box-sizing: border-box; } /* The "Jimar" row lives here too — just another .wiktku-posparams-row, no extra CSS needed. */ /* These two aren't per-field rows — span the full card width so the collapsed toggle and its checkbox list don't get squeezed into one narrow column. */ .wiktku-posparams-helpers > .wiktku-posparams-opt-toggle, .wiktku-posparams-helpers > .wiktku-posparams-opt-panel { grid-column: 1 / -1; } } /* =================================================================== SÊWIRANA NÛ — design system layer =================================================================== Purely the visual skin (colour, type, weight, radius, spacing), layered after the layout rules above so it wins the cascade. No @import of Spectral / IBM Plex from Google Fonts: Wikimedia's CSP blocks third-party font hosts, so the stacks below name the spec's faces first (used if the wiki installs them locally) and fall back to faces with the same feel. Accent colour is reserved for actionable elements (focus, links, the active tab, the primary button, chips); section headings are near-black. =================================================================== */ #wiktku-start-form { /* Surfaces */ --wikt-page: #f4efe5; --wikt-card: #fffdf8; --wikt-card-sunken: #fbf8f1; --wikt-rule: #ded6c8; /* structural hairline */ --wikt-rule-soft: #efe8db; /* inside a card */ --wikt-field-edge: #cfc7b8; --wikt-field-bg: #fff; --wikt-code-bg: #f7f4ec; --wikt-card-edge: #e6dfd2; /* Ink */ --wikt-ink: #1c1a17; --wikt-ink-2: #3d3830; --wikt-ink-3: #57514a; --wikt-muted: #8a8378; --wikt-placeholder: #b3ab9e; /* Accent + status */ --wikt-accent: #2a5db0; --wikt-accent-deep: #22406f; --wikt-accent-tint: #eef2fa; --wikt-accent-edge: #d5def0; --wikt-danger: #9c3a28; --wikt-on-accent: #fff; /* text on a filled accent button */ --wikt-link-under: rgba(42, 93, 176, 0.35); /* Shape */ --wikt-r-field: 10px; --wikt-r-card: 14px; --wikt-r-pill: 999px; --wikt-tap: 44px; /* minimum field height */ --wikt-serif: Spectral, "Iowan Old Style", Georgia, "Times New Roman", serif; --wikt-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif; --wikt-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-family: var(--wikt-sans); font-size: 15px; line-height: 1.55; color: var(--wikt-ink); background: var(--wikt-page); padding: 24px; border-radius: var(--wikt-r-card); } /* ── Cards ─────────────────────────────────────────────────────────── Flat cream panel held by a single hairline border, no shadow. */ #wiktku-start-form .wiktku-start-step { background: var(--wikt-card); border: 1px solid var(--wikt-card-edge); border-left: 1px solid var(--wikt-card-edge); border-radius: var(--wikt-r-card); box-shadow: none; padding: 24px 24px 20px; margin-bottom: 16px; transition: border-color 0.12s ease; } #wiktku-start-form .wiktku-start-step:hover, #wiktku-start-form .wiktku-start-step:focus-within { box-shadow: none; border-color: var(--wikt-rule); } /* The fused pos + posparams pair keeps reading as one card. */ #wiktku-start-form #wiktku-start-pos { border-radius: var(--wikt-r-card) var(--wikt-r-card) 0 0; border-bottom: none; padding-bottom: 8px; } #wiktku-start-form #wiktku-start-posparams { border-radius: 0 0 var(--wikt-r-card) var(--wikt-r-card); border-top: none; padding-top: 4px; } /* ── Type ──────────────────────────────────────────────────────────── Step headings: serif, regular weight, near-black. */ #wiktku-start-form .wiktku-start-step-name { font-family: var(--wikt-serif); font-size: 24px !important; font-weight: 400; letter-spacing: -0.01em; line-height: 1.15; color: var(--wikt-ink); margin: 0 0 12px; } /* display:block matters: this is a <label>, so it was sharing a line with the control it introduces wherever start.js didn't emit a <br>. */ #wiktku-start-form .wiktku-start-step-question { display: block; font-size: 15px; font-weight: 400; color: var(--wikt-ink-3); margin: 0 0 12px; line-height: 1.6; max-width: 62ch; } /* Collapses the label entirely when empty (posparams' "Cins/zayend" title can be blank) instead of leaving its margin behind as a gap; a no-op for every other step, whose question text is never empty. */ #wiktku-start-form .wiktku-start-step-question:empty { display: none; margin: 0; } /* Same reason — a field label belongs above its field, not beside it. */ #wiktku-start-form .wiktku-posparams-row label, #wiktku-start-form .wiktku-dfn-sublabel { display: block; margin-bottom: 6px; padding-right: 0; } /* Field labels: small, medium weight, full-strength ink — they label a control, so they should not read as body copy. */ #wiktku-start-form .wiktku-start-step label, #wiktku-start-form .wiktku-posparams-row label, #wiktku-start-form .wiktku-dfn-sublabel { font-size: 13px; font-weight: 500; color: var(--wikt-ink); letter-spacing: 0.01em; } /* The parenthetical/example half of a label is supporting text. */ #wiktku-start-form .wiktku-dfn-sublabel-hint, #wiktku-start-form .wiktku-step-hint { font-weight: 400; font-style: italic; color: var(--wikt-muted); font-size: 12.5px; } /* ── Fields ────────────────────────────────────────────────────────── One shape for every control: 1px edge, 10px radius, 44px tall. */ #wiktku-start-form input[type="text"], #wiktku-start-form input[type="search"], #wiktku-start-form input.wiktku-ac-input, #wiktku-start-form textarea, #wiktku-start-form select { font-family: var(--wikt-sans); font-size: 15px; color: var(--wikt-ink); background: var(--wikt-field-bg); border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-field); padding: 10px 14px; box-shadow: none; transition: border-color 0.12s ease, box-shadow 0.12s ease; } #wiktku-start-form input[type="text"], #wiktku-start-form input[type="search"], #wiktku-start-form select { min-height: var(--wikt-tap); } #wiktku-start-form textarea { line-height: 1.6; } /* Wikitext and anything template-shaped reads as code. */ #wiktku-start-form .wiktku-posparams-text, #wiktku-start-form .wiktku-pron-text, #wiktku-start-form .wiktku-etym-text, #wiktku-start-form .wiktku-cavkani-text, #wiktku-start-form .wiktku-tewandin-text, #wiktku-start-form .wiktku-pron-preview-body { font-family: var(--wikt-mono); font-size: 13.5px; background: var(--wikt-code-bg); border-color: var(--wikt-card-edge); } #wiktku-start-form ::placeholder { color: var(--wikt-placeholder); opacity: 1; } /* Focus: accent edge + 3px tint halo. The only "elevation" in the design. */ #wiktku-start-form input[type="text"]:focus, #wiktku-start-form input[type="search"]:focus, #wiktku-start-form textarea:focus, #wiktku-start-form select:focus, #wiktku-start-form input.wiktku-ac-input:focus { border-color: var(--wikt-accent); box-shadow: 0 0 0 3px var(--wikt-accent-tint); outline: 0; } /* The searchable picker's visible input is the field, so it takes the field shape too (it otherwise inherits an older, boxier rule). */ #wiktku-start-form input.wiktku-ac-input { min-height: var(--wikt-tap); border-radius: var(--wikt-r-field); border-color: var(--wikt-field-edge); font-size: 15px; } #wiktku-start-form .wiktku-ac-results { border: 1px solid var(--wikt-rule); border-radius: var(--wikt-r-field); background: var(--wikt-card); box-shadow: none; } #wiktku-start-form .wiktku-ac-results li.wiktku-ac-active, #wiktku-start-form .wiktku-ac-results li:hover { background: var(--wikt-accent-tint); color: var(--wikt-accent-deep); } /* ── Tabs → the accent's main job ──────────────────────────────────── Active tab: tint fill + 3px accent underline, per the spec's "xala hûrgulî" note. Inactive tabs are plain text. */ #wiktku-start-form #wiktku-group-tabs, #wiktku-start-form #wiktku-section-tabs { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; border-bottom: 1px solid var(--wikt-rule); margin-bottom: 16px; padding-bottom: 0; } /* Both bars are direct children of #wiktku-start-form, so a sticky child stays stuck for as long as any part of the form is in view. Background is opaque so content scrolling underneath doesn't show through. Section-tabs pins below --wiktku-siteheader-h — an offset for Vector 2022's own sticky header, which otherwise sits on top of it at top:0 (Minerva has no such header, so mobile needs no offset); group-tabs pins below that plus --wiktku-stabs-h (section-tabs' own height). Both custom properties are set by syncStickyTabsOffset() in start.js and fall back to 0 on skins without a Vector sticky header. */ #wiktku-start-form #wiktku-section-tabs { position: sticky; top: var(--wiktku-siteheader-h, 0px); z-index: 20; background: var(--wikt-card); } #wiktku-start-form #wiktku-group-tabs { position: sticky; top: calc(var(--wiktku-siteheader-h, 0px) + var(--wiktku-stabs-h, 0px)); z-index: 19; background: var(--wikt-card); } #wiktku-start-form .wiktku-group-tab, #wiktku-start-form .wiktku-section-tab { font-size: 13.5px; font-weight: 500; color: var(--wikt-ink-3); background: transparent; border: 0; border-bottom: 3px solid transparent; border-radius: var(--wikt-r-pill) var(--wikt-r-pill) 0 0; padding: 9px 14px 11px; cursor: pointer; transition: background 0.12s ease, color 0.12s ease; } #wiktku-start-form .wiktku-group-tab:hover, #wiktku-start-form .wiktku-section-tab:hover { background: var(--wikt-card-sunken); color: var(--wikt-ink); } #wiktku-start-form .wiktku-group-tab.wiktku-tab-active, #wiktku-start-form .wiktku-section-tab.wiktku-tab-active { background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom-color: var(--wikt-accent); } /* ── Progressive-disclosure toggles ────────────────────────────────── Shared by "Tercîhên pêşketî" (posparams) and "Malûmatên pêşketî" (Mane): a rotating chevron plus a count of what's hidden. */ #wiktku-start-form .wiktku-adv-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin: 4px 0 12px; padding-top: 16px; border-top: 1px solid var(--wikt-rule-soft); } #wiktku-start-form .wiktku-adv-toggle { display: inline-flex; align-items: center; gap: 10px; font-size: 14px; font-weight: 500; color: var(--wikt-accent); text-decoration: none; cursor: pointer; } #wiktku-start-form .wiktku-adv-toggle:hover .wiktku-adv-toggle-text { text-decoration: underline; } #wiktku-start-form .wiktku-adv-toggle-chevron { width: 22px; height: 22px; flex: 0 0 22px; display: grid; place-items: center; font-size: 11px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); border-radius: 6px; transform: rotate(-90deg); transition: transform 0.15s ease; } /* Open state: dfn flips the class on the step, posparams on the link. */ #wiktku-start-form .wiktku-adv-toggle.wiktku-adv-open .wiktku-adv-toggle-chevron, #wiktku-start-dfn:not(.wiktku-dfn-subs-hidden) .wiktku-adv-toggle-chevron { transform: rotate(0deg); } #wiktku-start-form .wiktku-posparams-adv-panel { border: 1px solid var(--wikt-rule-soft); border-radius: 12px; background: var(--wikt-card-sunken); padding: 20px 18px; margin-bottom: 4px; } /* ── posparams grid ────────────────────────────────────────────────── "Tor, ne rêz" — two columns, nothing narrower than 220px, so the six gender/number fields stop being a six-across scanline. */ @media (min-width: 721px) { #wiktku-start-form .wiktku-posparams-helpers, #wiktku-start-form .wiktku-posparams-adv-panel { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 18px 22px; align-items: start; } #wiktku-start-form .wiktku-posparams-adv-panel > .wiktku-posparams-row, #wiktku-start-form .wiktku-posparams-helpers > .wiktku-posparams-row { flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 7px; } #wiktku-start-form .wiktku-posparams-helpers > .wiktku-adv-toggle-row, #wiktku-start-form .wiktku-posparams-helpers > .wiktku-posparams-adv-panel, #wiktku-start-form .wiktku-posparams-adv-panel > .wiktku-posparams-opt-panel { grid-column: 1 / -1; } } #wiktku-start-form .wiktku-posparams-opt-panel { border-top: 1px solid var(--wikt-rule-soft); padding-top: 14px; margin-top: 4px; } #wiktku-start-form .wiktku-posparams-opt-row { font-size: 13px; color: var(--wikt-ink-3); } /* ── Sense blocks ──────────────────────────────────────────────────── Each sense is a sunken panel inside the Mane card, with its number as an accent counter — so "how many meanings am I writing" is legible at a glance. */ #wiktku-start-form .wiktku-dfn-subgroup { margin: 14px 0 0; padding-top: 14px; border-top: 1px solid var(--wikt-rule-soft); } /* No divider above the first item — it would be a rule against the sense's own text. Needed explicitly: the earlier :first-of-type rule is a class selector and loses to this id-scoped one. */ #wiktku-start-form .wiktku-dfn-subgroup:first-of-type { margin-top: 8px; padding-top: 0; border-top: none; } #wiktku-start-form .wiktku-dfn-sublabel-term { color: var(--wikt-ink); } /* Plain white field like any other, not a tinted fill — a tint would read as "disabled" next to the white Mane box above it. */ #wiktku-start-form .wiktku-dfn-subfield, #wiktku-start-form textarea.wiktku-dfn-mane { background: var(--wikt-field-bg); border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-field); } /* No "1." "2." markers on the sub-lists: numbered rows would read as a form to fill top-down, when each row is really "another one if you have one" — and the marker would land on its own line above the block-level textarea, looking like a stray character. */ #wiktku-start-form .wiktku-dfn-sublist { margin: 0; padding-left: 0; list-style: none; } #wiktku-start-form .wiktku-dfn-sublist > li { margin-bottom: 6px; } /* ── Chips: tags, modifiers, template pills ──────────────────────────── */ #wiktku-start-form .wiktku-mod-pill, #wiktku-start-form .wiktku-besendin-select + .wiktku-chip { background: var(--wikt-accent-tint); color: var(--wikt-accent-deep); border: 1px solid var(--wikt-accent-edge); border-radius: var(--wikt-r-pill); font-size: 13px; padding: 6px 12px; } #wiktku-start-form .wiktku-mod-btn, #wiktku-start-form .wiktku-mod-confirm, #wiktku-start-form .wiktku-mod-cancel { border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); border-radius: 8px; } /* ── Footer + buttons ──────────────────────────────────────────────── One primary filled pill; destructive actions are outline-only in the danger colour so they stay quiet next to it. */ #wiktku-start-form #wiktku-start-footer { background: var(--wikt-card-sunken); border-top: 1px solid var(--wikt-rule); border-radius: 0 0 var(--wikt-r-card) var(--wikt-r-card); padding: 16px 20px; gap: 10px; } #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement-button { border-radius: var(--wikt-r-pill) !important; font-family: var(--wikt-sans); font-size: 14px; font-weight: 500; padding: 11px 22px; box-shadow: none !important; min-height: var(--wikt-tap); } #wiktku-start-form #wiktku-unhide-editform .oo-ui-buttonElement-button { background: var(--wikt-accent) !important; border-color: var(--wikt-accent) !important; color: var(--wikt-on-accent) !important; } /* Destructive actions: outline, not fill. */ #wiktku-start-form #wiktku-start-footer .oo-ui-flaggedElement-destructive .oo-ui-buttonElement-button { background: var(--wikt-card) !important; border-color: var(--wikt-danger) !important; color: var(--wikt-danger) !important; } #wiktku-start-form #wiktku-last-saved { font-family: var(--wikt-mono); font-size: 12px; color: var(--wikt-muted); } /* ── Beşên din picker ──────────────────────────────────────────────── This dropdown is now the entry point to eighteen sections, so it gets room and a label rather than sitting flush under the tab bar. */ #wiktku-start-form .wiktku-besendin-picker { margin: 0 0 20px; padding: 16px 18px; background: var(--wikt-card); border: 1px solid var(--wikt-card-edge); border-radius: 12px; } #wiktku-start-form .wiktku-besendin-picker .wiktku-native-select-wrap, #wiktku-start-form .wiktku-besendin-picker input.wiktku-ac-input { width: 100%; max-width: 28em; } /* ── Notices ─────────────────────────────────────────────────────────── */ #wiktku-start-form .wiktku-addlang-notice { background: var(--wikt-accent-tint); border: 1px solid var(--wikt-accent-edge); border-radius: var(--wikt-r-field); color: var(--wikt-ink-2); padding: 12px 16px; margin-bottom: 16px; } #wiktku-start-form .wiktku-pron-preview { background: var(--wikt-accent-tint); border-color: var(--wikt-accent-edge); border-radius: 12px; } #wiktku-start-form .wiktku-pron-preview-confirm, #wiktku-start-form .wiktku-pron-preview-cancel { border-radius: var(--wikt-r-pill); padding: 8px 16px; min-height: 36px; } /* Links carry the accent and a soft underline, per the spec's `a` rule. */ #wiktku-start-form a { color: var(--wikt-accent); text-decoration: none; border-bottom: 1px solid var(--wikt-link-under); } #wiktku-start-form a:hover { color: var(--wikt-accent-deep); } #wiktku-start-form .wiktku-adv-toggle, #wiktku-start-form .wiktku-group-tab, #wiktku-start-form .wiktku-section-tab { border-bottom-style: solid; } #wiktku-start-form .wiktku-adv-toggle { border-bottom: 0; } /* =================================================================== Dark mode =================================================================== Every colour above is a token on #wiktku-start-form, so this is a swap of that one block. Only applies given an explicit dark signal (skin-theme-clientpref-night / skin-nightmode, or skin-theme-clientpref-os plus prefers-color-scheme: dark) — no bare prefers-color-scheme fallback, since legacy Vector sets no theme class either and would otherwise go dark with nothing else on the page to match. Palette is warm, not neutral grey, to keep the cream design's character. Accent lightens to #7ba7e8 since #2a5db0 on a dark card is ~2.4:1 contrast and reads as near-black. =================================================================== */ html.skin-theme-clientpref-night #wiktku-start-form, html.skin-nightmode #wiktku-start-form { --wikt-page: #171613; --wikt-card: #201e1a; --wikt-card-sunken: #1a1916; --wikt-card-edge: #322e28; --wikt-rule: #3a3630; --wikt-rule-soft: #2c2924; --wikt-field-edge: #4a453d; --wikt-field-bg: #191815; --wikt-code-bg: #14130f; --wikt-ink: #ece7dd; --wikt-ink-2: #d5cfc4; --wikt-ink-3: #b3aca1; --wikt-muted: #8f887c; --wikt-placeholder: #6d675e; --wikt-accent: #7ba7e8; --wikt-accent-deep: #cfe0f8; --wikt-accent-tint: #1c2839; --wikt-accent-edge: #35496b; --wikt-danger: #e5907c; --wikt-on-accent: #14213a; --wikt-link-under: rgba(123, 167, 232, 0.4); } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os #wiktku-start-form { --wikt-page: #171613; --wikt-card: #201e1a; --wikt-card-sunken: #1a1916; --wikt-card-edge: #322e28; --wikt-rule: #3a3630; --wikt-rule-soft: #2c2924; --wikt-field-edge: #4a453d; --wikt-field-bg: #191815; --wikt-code-bg: #14130f; --wikt-ink: #ece7dd; --wikt-ink-2: #d5cfc4; --wikt-ink-3: #b3aca1; --wikt-muted: #8f887c; --wikt-placeholder: #6d675e; --wikt-accent: #7ba7e8; --wikt-accent-deep: #cfe0f8; --wikt-accent-tint: #1c2839; --wikt-accent-edge: #35496b; --wikt-danger: #e5907c; --wikt-on-accent: #14213a; --wikt-link-under: rgba(123, 167, 232, 0.4); } } /* A handful of rules still name literal light colours instead of tokens; neutralise the ones that actually show through in night mode. */ html.skin-theme-clientpref-night #wiktku-start-form .wiktku-ac-results, html.skin-nightmode #wiktku-start-form .wiktku-ac-results { background: var(--wikt-card); border-color: var(--wikt-rule); color: var(--wikt-ink); } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os #wiktku-start-form .wiktku-ac-results { background: var(--wikt-card); border-color: var(--wikt-rule); color: var(--wikt-ink); } } /* =================================================================== Autocomplete list: stop it escaping its card =================================================================== A fixed width would run past the card's border on full-width pickers, since the list is absolutely positioned at the wrapper's left edge. width:100% ties it to the (shrink-to-fit) wrapper's input width instead; min/max-width keep short pickers readable and stop viewport overflow. */ #wiktku-start-form ul.wiktku-ac-results { width: 100%; min-width: min(18em, 100%); max-width: min(92vw, 34em); box-sizing: border-box; border-radius: var(--wikt-r-field); box-shadow: none; } /* And the wrapper itself must not exceed the card it sits in. */ #wiktku-start-form .wiktku-native-select-wrap { max-width: 100%; } #wiktku-start-form .wiktku-cavkani-wrap .wiktku-native-select-wrap, #wiktku-start-form .wiktku-cavkani-wrap input.wiktku-ac-input, #wiktku-start-form .wiktku-pron-wrap .wiktku-native-select-wrap, #wiktku-start-form .wiktku-etym-wrap .wiktku-native-select-wrap { width: 100%; max-width: 100%; box-sizing: border-box; } /* =================================================================== Mobile footer =================================================================== Below 720px the primary button keeps its full size and everything else shrinks to a secondary scale, so the sticky footer doesn't dominate a phone viewport. =================================================================== */ @media (max-width: 720px) { #wiktku-start-form { padding: 12px; font-size: 14px; } #wiktku-start-form .wiktku-start-step { padding: 16px 14px 14px; border-radius: 12px; } #wiktku-start-form .wiktku-start-step-name { font-size: 20px !important; } #wiktku-start-form #wiktku-start-footer { padding: 10px 12px; gap: 6px; row-gap: 8px; } #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement-button { font-size: 13px; padding: 8px 14px; min-height: 38px; } /* The one you actually press stays thumb-sized. */ #wiktku-start-form #wiktku-unhide-editform .oo-ui-buttonElement-button { font-size: 14px; padding: 10px 20px; min-height: var(--wikt-tap); } /* Secondary actions share a row instead of each claiming a full one. */ #wiktku-start-form #wiktku-start-footer .oo-ui-buttonElement { flex: 0 1 auto; } #wiktku-start-form #wiktku-last-saved { flex: 1 0 100%; order: 10; font-size: 11px; white-space: normal; } #wiktku-start-form .wiktku-adv-toggle-row { gap: 8px; } } /* =================================================================== IPA character palette (v3 spec) =================================================================== Click-to-insert chart under Bilêvkirin, after fr.wiktionary's. Two sub-tabs — a short Kurmancî set that opens by default, and the full chart — because ~20 of the ~180 IPA symbols ever occur in Kurmancî and showing all of them first is the same "wall of fields" problem this redesign exists to fix. =================================================================== */ #wiktku-start-form .wiktku-ipa-panel { border: 1px solid var(--wikt-card-edge); border-radius: 12px; background: var(--wikt-card-sunken); padding: 0 0 12px; margin-bottom: 8px; overflow: hidden; } #wiktku-start-form .wiktku-ipa-subtabs { display: flex; align-items: center; gap: 4px; padding: 8px 12px 0; border-bottom: 1px solid var(--wikt-rule-soft); margin-bottom: 12px; flex-wrap: wrap; } #wiktku-start-form .wiktku-ipa-subtab { font-size: 13px; font-weight: 500; color: var(--wikt-ink-3); padding: 7px 12px 9px; border-bottom: 3px solid transparent; border-radius: 8px 8px 0 0; cursor: pointer; } #wiktku-start-form .wiktku-ipa-subtab:hover { background: var(--wikt-card); color: var(--wikt-ink); } #wiktku-start-form .wiktku-ipa-subtab.wiktku-tab-active { background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom-color: var(--wikt-accent); } /* Templates are not characters, so they sit apart from the chart — pinned to the right of the sub-tab row. */ #wiktku-start-form .wiktku-ipa-tplbtns { margin-left: auto; display: flex; gap: 6px; padding-bottom: 6px; } #wiktku-start-form .wiktku-ipa-tplbtn { font-family: var(--wikt-mono); font-size: 12px; padding: 6px 10px; border-radius: 7px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); cursor: pointer; white-space: nowrap; } #wiktku-start-form .wiktku-ipa-tplbtn:hover { border-color: var(--wikt-accent); } #wiktku-start-form .wiktku-ipa-grid { display: flex; flex-direction: column; gap: 8px; padding: 0 12px; } #wiktku-start-form .wiktku-ipa-row { display: flex; align-items: flex-start; gap: 10px; } #wiktku-start-form .wiktku-ipa-rowlabel { flex: 0 0 74px; font-size: 11.5px; color: var(--wikt-muted); padding-top: 8px; line-height: 1.3; } #wiktku-start-form .wiktku-ipa-keys { display: flex; flex-wrap: wrap; gap: 4px; flex: 1 1 auto; } #wiktku-start-form .wiktku-ipa-key { width: 30px; height: 30px; padding: 0; border-radius: 8px; border: 1px solid var(--wikt-field-edge); background: var(--wikt-field-bg); color: var(--wikt-ink); font-family: var(--wikt-mono); font-size: 14px; line-height: 1; cursor: pointer; display: grid; place-items: center; transition: background 0.1s ease, border-color 0.1s ease; } #wiktku-start-form .wiktku-ipa-key:hover { background: var(--wikt-accent-tint); border-color: var(--wikt-accent); color: var(--wikt-accent-deep); } #wiktku-start-form .wiktku-ipa-key:active { transform: translateY(1px); } /* Ligatures like d͡ʒ and long vowels need a little more room than one glyph; let those keys grow instead of clipping. */ #wiktku-start-form .wiktku-ipa-key { width: auto; min-width: 30px; padding: 0 5px; } /* A combining mark is shown on a dotted circle so it has something to attach to; only the mark itself is inserted. */ #wiktku-start-form .wiktku-ipa-key-combining { color: var(--wikt-ink-2); } @media (max-width: 720px) { #wiktku-start-form .wiktku-ipa-row { flex-direction: column; gap: 3px; } #wiktku-start-form .wiktku-ipa-rowlabel { flex: 0 0 auto; padding-top: 0; } #wiktku-start-form .wiktku-ipa-key { min-width: 34px; height: 34px; } } /* ── "+ Beş zêde bike" menu ────────────────────────────────────────── Adding a part of speech and adding Bilêvkirin are different actions, so the button opens a small menu instead of doing one of them. */ #wiktku-start-form .wiktku-addsection-menu { position: absolute; z-index: 60; margin-top: 6px; min-width: 15em; background: var(--wikt-card); border: 1px solid var(--wikt-rule); border-radius: 10px; padding: 4px; display: flex; flex-direction: column; } #wiktku-start-form .wiktku-addsection-item { display: flex; flex-direction: column; gap: 1px; padding: 8px 10px; border-radius: 7px; border-bottom: 0; text-decoration: none; color: var(--wikt-ink); } #wiktku-start-form .wiktku-addsection-item:hover { background: var(--wikt-accent-tint); } #wiktku-start-form .wiktku-addsection-item-label { font-size: 13.5px; font-weight: 500; } #wiktku-start-form .wiktku-addsection-item-hint { font-size: 11.5px; color: var(--wikt-muted); } #wiktku-start-form #wiktku-section-tabs .oo-ui-buttonElement { position: relative; } /* Bilêvkirin is a peer of the POS sections but not a part of speech — a hairline before it marks the boundary. */ #wiktku-start-form .wiktku-section-tab-pron { margin-left: 6px; border-left: 1px solid var(--wikt-rule); padding-left: 14px; border-radius: 0; } /* =================================================================== Per-sense tabs =================================================================== "Mane 1 / Mane 2 / + Mane zêde bike" switches which sense is shown; only the active one is in the flow, so a multi-sense entry doesn't turn into a long scroll. */ #wiktku-start-form .wiktku-dfn-sense-tabs { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; border-bottom: 1px solid var(--wikt-rule); margin-bottom: 14px; } #wiktku-start-form .wiktku-dfn-sense-tab { font-size: 13px; font-weight: 500; color: var(--wikt-ink-3); background: transparent; border: 0; border-bottom: 3px solid transparent; border-radius: var(--wikt-r-pill) var(--wikt-r-pill) 0 0; padding: 7px 12px 9px; cursor: pointer; user-select: none; transition: background 0.12s ease, color 0.12s ease; } #wiktku-start-form .wiktku-dfn-sense-tab:hover { background: var(--wikt-card-sunken); color: var(--wikt-ink); } #wiktku-start-form .wiktku-dfn-sense-tab.wiktku-tab-active { background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom-color: var(--wikt-accent); } /* Delete button on the Mane / Beş tab bars — a real OOUI ButtonWidget (icon: "trash", flags: ["destructive"], framed: false), so its glyph, red destructive tint and hover/focus states all come from OOUI's own WikimediaUI theme rather than being reimplemented here. This class only places it: a little breathing room from the tab before it, and vertically centered in the flex tab bar (OOUI's own icon-button box is already close to the tabs' height, so no extra sizing is needed). */ #wiktku-start-form .wiktku-trash-btn { margin-left: 4px; } #wiktku-start-form li.wiktku-dfn-sense { border: 1px solid var(--wikt-card-edge); border-radius: 12px; background: var(--wikt-card); margin-bottom: 10px; padding: 14px; list-style: none; overflow: visible; } #wiktku-start-form li.wiktku-dfn-sense.wiktku-sense-collapsed { display: none; } /* =================================================================== Template rows in the pickers (v3 spec) =================================================================== One row shape everywhere a template is chosen: the ⓘ explains terms like "guharto/kevnbûyî/ku-Latn/şaşnivîs" without leaving the form, and the 🔗 links out for when it doesn't. =================================================================== */ #wiktku-start-form ul.wiktku-ac-results li.wiktku-ac-tplrow { display: flex; align-items: center; gap: 8px; min-height: 44px; white-space: normal; padding: 6px 10px; } #wiktku-start-form .wiktku-ac-tpltext { flex: 1 1 auto; min-width: 0; font-family: var(--wikt-mono); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* Status, not category: green is the one to reach for, yellow means "only if you specifically need it" (kevnbûyî, şaşnivîs, kêmpeyda). */ #wiktku-start-form .wiktku-tpl-dot { flex: 0 0 8px; width: 8px; height: 8px; border-radius: 999px; } #wiktku-start-form .wiktku-tpl-dot-ok { background: #3d8a55; } #wiktku-start-form .wiktku-tpl-dot-special { background: #c9971f; } #wiktku-start-form .wiktku-tpl-icons { flex: 0 0 auto; display: flex; gap: 5px; align-items: center; } #wiktku-start-form .wiktku-tpl-icon { width: 26px; height: 26px; display: grid; place-items: center; font-size: 12px; line-height: 1; cursor: pointer; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); color: var(--wikt-accent); border-bottom: 1px solid var(--wikt-accent-edge); text-decoration: none; padding: 0; } #wiktku-start-form .wiktku-tpl-icon-link { border-radius: 7px; } #wiktku-start-form .wiktku-tpl-icon-info { border-radius: 999px; font-family: var(--wikt-serif); font-style: italic; font-weight: 600; background: transparent; border-color: var(--wikt-field-edge); color: var(--wikt-muted); } #wiktku-start-form .wiktku-tpl-icon:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); background: var(--wikt-accent-tint); } /* ── The ⓘ panel ───────────────────────────────────────────────────── Three parts, in the spec's order: what it does, its parameters, and a way out to the template page. */ #wiktku-start-form .wiktku-tpl-info { position: relative; margin: 8px 0 4px; padding: 14px 16px; border: 1px solid var(--wikt-accent-edge); background: var(--wikt-accent-tint); border-radius: 12px; font-size: 13.5px; line-height: 1.6; color: var(--wikt-ink-2); } #wiktku-start-form .wiktku-tpl-info-name { font-family: var(--wikt-mono); font-size: 13px; color: var(--wikt-accent-deep); margin-bottom: 6px; } #wiktku-start-form .wiktku-tpl-info-params { margin-top: 8px; } #wiktku-start-form .wiktku-tpl-info-params-title { font-size: 12px; color: var(--wikt-muted); margin-bottom: 2px; } #wiktku-start-form .wiktku-tpl-info-params ul { margin: 0; padding-left: 18px; font-family: var(--wikt-mono); font-size: 12.5px; } #wiktku-start-form .wiktku-tpl-info-link { display: inline-block; margin-top: 10px; font-size: 13px; } #wiktku-start-form .wiktku-tpl-info-close { position: absolute; top: 8px; right: 8px; width: 24px; height: 24px; border-radius: 999px; border: 0; background: transparent; color: var(--wikt-muted); cursor: pointer; font-size: 13px; line-height: 1; } #wiktku-start-form .wiktku-tpl-info-close:hover { background: var(--wikt-card); color: var(--wikt-ink); } /* =================================================================== Footer overflow "⋯" (v3 spec) =================================================================== Bişîne and "Edîtora çavkaniyê veke" stay on the bar; the cache actions, saved-at note and Tercîh move in here so the destructive buttons don't compete for attention and the sticky footer stays to one row on a phone. =================================================================== */ #wiktku-start-form .wiktku-more-wrap { position: relative; margin-left: auto; flex: 0 0 auto; } #wiktku-start-form .wiktku-more-btn { width: 36px; height: 36px; border-radius: 999px; border: 1px solid var(--wikt-field-edge); background: var(--wikt-card); color: var(--wikt-muted); font-size: 16px; line-height: 1; cursor: pointer; display: grid; place-items: center; } #wiktku-start-form .wiktku-more-btn:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); } #wiktku-start-form .wiktku-more-menu { position: absolute; right: 0; bottom: calc(100% + 8px); z-index: 70; min-width: 17em; background: var(--wikt-card); border: 1px solid var(--wikt-rule); border-radius: 12px; padding: 6px; display: flex; flex-direction: column; gap: 2px; } #wiktku-start-form .wiktku-more-item { display: flex; align-items: center; gap: 8px; } /* The buttons inside the menu are menu rows, not buttons on a bar. */ #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement { flex: 1 1 auto; } #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement-button { display: block; width: 100%; text-align: left; border: 0 !important; background: transparent !important; border-radius: 7px !important; padding: 9px 10px; min-height: 0; font-weight: 400; color: var(--wikt-ink) !important; } #wiktku-start-form .wiktku-more-item .oo-ui-buttonElement-button:hover { background: var(--wikt-accent-tint) !important; } #wiktku-start-form .wiktku-more-item-danger .oo-ui-buttonElement-button { color: var(--wikt-danger) !important; } #wiktku-start-form .wiktku-more-item-prefs .wiktku-prefs-btn { width: 26px; height: 26px; flex: 0 0 26px; border: 0; background-color: transparent; } #wiktku-start-form .wiktku-more-item-label { font-size: 13.5px; } #wiktku-start-form .wiktku-more-sep { height: 1px; background: var(--wikt-rule-soft); margin: 4px 2px; } #wiktku-start-form .wiktku-more-note { padding: 4px 10px 2px; } #wiktku-start-form .wiktku-more-note #wiktku-last-saved { white-space: normal; } /* "+ Mane zêde bike" sits as the last item in .wiktku-dfn-sense-tabs. */ #wiktku-start-form .wiktku-add-sense { display: inline-flex; align-items: center; gap: 6px; margin: 3px 0; padding: 6px 14px; border: 1px solid var(--wikt-field-edge); border-radius: var(--wikt-r-pill); background: var(--wikt-card); color: var(--wikt-ink-2); font-family: var(--wikt-sans); font-size: 13px; cursor: pointer; min-height: 34px; } #wiktku-start-form .wiktku-add-sense:hover { border-color: var(--wikt-accent); color: var(--wikt-accent); background: var(--wikt-accent-tint); } #wiktku-start-form .wiktku-add-sense-plus { color: var(--wikt-accent); font-size: 15px; line-height: 1; } /* ── Şablon picker, demoted to a link ──────────────────────────────── Picking a template replaces the definition rather than adding to it, so it is an alternative route, not the first control in the sense. Hidden behind one line of text until it is actually wanted. */ #wiktku-start-form .wiktku-dfn-tpl-link { display: inline-block; margin-top: 8px; font-size: 12.5px; color: var(--wikt-muted); border-bottom: 1px solid transparent; } #wiktku-start-form .wiktku-dfn-tpl-link:hover { color: var(--wikt-accent); border-bottom-color: var(--wikt-link-under); } #wiktku-start-form .wiktku-dfn-tpl-row { margin-top: 10px; padding-top: 12px; border-top: 1px solid var(--wikt-rule-soft); } /* ── Template-row icons on touch screens ───────────────────────────── 26px is fine for a mouse and too small for a thumb, and these two sit right next to each other at the end of a row you can also tap to select. Give them real targets and some separation on small screens. */ @media (max-width: 720px), (pointer: coarse) { #wiktku-start-form .wiktku-tpl-icon { width: 34px; height: 34px; font-size: 14px; } #wiktku-start-form .wiktku-tpl-icons { gap: 8px; padding-left: 4px; } #wiktku-start-form ul.wiktku-ac-results li.wiktku-ac-tplrow { min-height: 50px; } } /* The rendered pronunciation preview is real parser output, so it needs to sit as content rather than in the monospace wikitext treatment the panel inherits. */ #wiktku-start-form .wiktku-pron-preview-body { font-family: var(--wikt-sans); font-size: 15px; background: var(--wikt-card); border: 1px solid var(--wikt-accent-edge); border-radius: 8px; padding: 10px 12px; white-space: normal; } #wiktku-start-form .wiktku-pron-preview-body .IPA, #wiktku-start-form .wiktku-pron-preview-body code, #wiktku-start-form .wiktku-pron-preview-body tt { font-family: var(--wikt-mono); } /* Parser output brings its own margins; strip the outer ones so the preview box doesn't gain a blank first line. */ #wiktku-start-form .wiktku-pron-preview-body > *:first-child { margin-top: 0; } #wiktku-start-form .wiktku-pron-preview-body > *:last-child { margin-bottom: 0; } 2nnd7s2qu171out1s132zhlotya7gz6 Bikarhêner:Wikihez/Gadget-test.js 2 1358395 6333811 6333778 2026-08-15T14:02:34Z Wikihez 7344 6333811 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. // implicit dependencies: StorageUtils (ObjectStorage) //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var addLangMode = mw.util.getParamValue("wiktkuaddlang") === "1"; // ── Tercîh (user settings) panel stored via mw.storage (localStorage), globally var WIKTKU_PREFS_KEY = "wiktku_start_prefs"; var WIKTKU_PREFS_DEFAULTS = { // [] = show the full language list in the "ziman" step; otherwise // only these codes are shown there (data.json codes, not names). langCodes: [], // true = never auto-open on a new/empty page — only via the // "+Ziman/beşeke din" portlet link. onlyOnClick: false, // "auto" | "p-cactions" | "p-tb" | "p-views" — where the // "+Ziman/beşeke din" portlet link is added. portlet: "auto", // true = suppress routine/informational mw.notify toasts (page // loading, cache auto-restored, cache saved/cleared, "tê şandin…"). // Errors and direct results of an explicit action (like saving // Tercîh itself) always show regardless of this setting. quiet: false }; function wiktkuLoadPrefs() { if (!(window.mw && mw.storage)) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var raw; try { raw = mw.storage.get(WIKTKU_PREFS_KEY); } catch (e) { raw = null; } if (!raw) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var parsed; try { parsed = JSON.parse(raw); } catch (e) { parsed = {}; } return $.extend({}, WIKTKU_PREFS_DEFAULTS, parsed); } function wiktkuSavePrefs(prefs) { if (!(window.mw && mw.storage)) return false; try { mw.storage.set(WIKTKU_PREFS_KEY, JSON.stringify(prefs)); return true; } catch (e) { return false; } } var wiktkuPrefs = wiktkuLoadPrefs(); // Routine/informational notices go through here so "quiet mode" can // suppress them; errors and explicit-action confirmations (like the // Tercîh save toast) call mw.notify directly instead, and always show. function wiktkuNotify(message, options) { if (wiktkuPrefs.quiet) return; mw.notify(message, options); } // Lazily built the first time it's opened; reused after that (see // wiktkuOpenPrefsDialog below, defined once we know OOUI is available). var wiktkuPrefsWindowManager = null; var wiktkuPrefsDialog = null; function wiktkuOpenPrefsDialog() { mw.loader.using(["oojs-ui-core", "oojs-ui-windows"], function () { function WiktkuPrefsDialog(config) { WiktkuPrefsDialog.super.call(this, config); } if (!wiktkuPrefsDialog) { OO.inheritClass(WiktkuPrefsDialog, OO.ui.ProcessDialog); WiktkuPrefsDialog.static.name = "wiktkuPrefsDialog"; WiktkuPrefsDialog.static.title = "Tercîhên min"; WiktkuPrefsDialog.static.actions = [ { action: "save", label: "Qeyd bike", flags: ["primary", "progressive"] }, { action: "cancel", label: "Betal bike", flags: "safe" } ]; WiktkuPrefsDialog.prototype.initialize = function () { WiktkuPrefsDialog.super.prototype.initialize.call(this); this.langCodesInput = new OO.ui.TextInputWidget({ placeholder: "ku, zza, ckb (vala bihêle ji bo hemû zimanan)" }); this.onlyOnClickCheckbox = new OO.ui.CheckboxInputWidget({}); this.quietCheckbox = new OO.ui.CheckboxInputWidget({}); this.portletDropdown = new OO.ui.DropdownInputWidget({ options: [ { data: "auto", label: "Otomatîk (li gorî rûyê wîkiyê)" }, { data: "p-cactions", label: "p-cactions - Li qismê Amûran" }, { data: "left-navigation", label: "left-navigation - Li qismê Gotar-Gotûbêj" }, { data: "p-tb", label: "p-tb - Li qismê Giştî" }, { data: "p-views", label: "p-views - Li qismê Bixwîne" } ] }); var fieldset = new OO.ui.FieldsetLayout({ label: "Eyar" }); fieldset.addItems([ new OO.ui.FieldLayout(this.langCodesInput, { label: "Kodên zimanan ku tê xuyakirin li qismê \"ziman\"", align: "top", help: "Kodan bi virgulê (,) ji hev veqetîne. Vala bihêle da ku hemû ziman were nîşandan.", helpInline: true }), new OO.ui.FieldLayout(this.onlyOnClickCheckbox, { label: "Tenê veke wextê \"+Ziman/beşeke din\" were tikandin", align: "inline", help: "Eger were hilbijartin, ev amûr êdî otomatîk li ser rûpelên nû/vala dest pê nake — divê meriv her carê pêl \"+Ziman/beşeke din\" bike.", helpInline: true }), new OO.ui.FieldLayout(this.portletDropdown, { label: "Cihê lînka \"+Ziman/beşeke din\"", align: "top", help: "\"Otomatîk\" li gorî rûyê wîkiyê hildibijêre.", helpInline: true }), new OO.ui.FieldLayout(this.quietCheckbox, { label: "Moda bêdeng (kêmtir agahdarî nîşan bide)", align: "inline", help: "Agahdariyên normal nîşan nede. Xeta her tim tên xuyakirin.", helpInline: true }) ]); this.$body.addClass("wiktku-prefs-dialog-body").append(fieldset.$element); }; WiktkuPrefsDialog.prototype.getSetupProcess = function (data) { return WiktkuPrefsDialog.super.prototype.getSetupProcess.call(this, data) .next(function () { this.langCodesInput.setValue(wiktkuPrefs.langCodes.join(", ")); this.onlyOnClickCheckbox.setSelected(!!wiktkuPrefs.onlyOnClick); this.portletDropdown.setValue(wiktkuPrefs.portlet || "auto"); this.quietCheckbox.setSelected(!!wiktkuPrefs.quiet); }, this); }; WiktkuPrefsDialog.prototype.getActionProcess = function (action) { var dialog = this; if (action === "save") { return new OO.ui.Process(function () { var codes = dialog.langCodesInput.getValue() .split(/[,\s]+/) .map(function (c) { return c.trim().toLowerCase(); }) .filter(function (c) { return !!c; }); wiktkuPrefs = { langCodes: codes, onlyOnClick: dialog.onlyOnClickCheckbox.isSelected(), portlet: dialog.portletDropdown.getValue() || "auto", quiet: dialog.quietCheckbox.isSelected() }; wiktkuSavePrefs(wiktkuPrefs); mw.notify( "Tercîh hatin qeydkirin. Rûpelê ji nû ve bar bike (F5).", { type: "success", tag: "wiktku-prefs-save" } ); dialog.close({ action: "save" }); }); } if (action === "cancel") { return new OO.ui.Process(function () { dialog.close({ action: "cancel" }); }); } return WiktkuPrefsDialog.super.prototype.getActionProcess.call(this, action); }; wiktkuPrefsWindowManager = new OO.ui.WindowManager(); $(document.body).append(wiktkuPrefsWindowManager.$element); wiktkuPrefsDialog = new WiktkuPrefsDialog(); wiktkuPrefsWindowManager.addWindows([wiktkuPrefsDialog]); } wiktkuPrefsWindowManager.openWindow(wiktkuPrefsDialog); }); } var targetContainer; var skin = mw.config.get('skin'); if (wiktkuPrefs.portlet && wiktkuPrefs.portlet !== "auto") { targetContainer = wiktkuPrefs.portlet; } else if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Li vê rûpelê, ziman an jî beşeke nû zêde bike"); // If "onlyOnClick" is set, the wizard should ONLY ever open via the // "+Ziman/beşeke din" link — never automatically var wiktkuNewPageDetected = $(".mw-newarticletext, .mw-newarticletextanon").length > 0; if (wiktkuPrefs.onlyOnClick ? !addLangMode : (!addLangMode && !wiktkuNewPageDetected)) { return; } // ── Shared helpers ─────────────────────────────────────────────────── // Generic text/UI utilities live in their own package file now — see the // header of util.js for why. Aliased to bare names here so the ~400 call // sites below read exactly as they did when these were local functions. var wiktkuUtil = require("./start/util.js"); var capitalize = wiktkuUtil.capitalize; var decapitalize = wiktkuUtil.decapitalize; var escapeRegExp = wiktkuUtil.escapeRegExp; var stripWikilinks = wiktkuUtil.stripWikilinks; var splitTercimeIzah = wiktkuUtil.splitTercimeIzah; var insertAtCursor = wiktkuUtil.insertAtCursor; var foldDiacritics = wiktkuUtil.foldDiacritics; var wrapNativeSelect = wiktkuUtil.wrapNativeSelect; var initSelects = wiktkuUtil.initSelects; var wiktkuInitManualResize = wiktkuUtil.initManualResize; function langHeaderSource(codePattern) { return "\n?==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } var catSrcTemplates = null; var catSrcTemplatesPromise = null; function fetchCatSrcTemplates() { if (catSrcTemplatesPromise) return catSrcTemplatesPromise; catSrcTemplatesPromise = new mw.Api().get({ action: "query", list: "categorymembers", cmtitle: "Kategorî:Çavkanî", cmnamespace: 10, cmlimit: "max", formatversion: 2 }).then(function (data) { var members = (data.query && data.query.categorymembers) || []; catSrcTemplates = $.map(members, function (m) { // Pêşgira navî ya "Şablon:" rake. return m.title.replace(/^[^:]+:/, ""); }); catSrcTemplates.sort(function (a, b) { return a.localeCompare(b, userLang); }); return catSrcTemplates; }, function () { catSrcTemplates = []; return catSrcTemplates; }); return catSrcTemplatesPromise; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var formCache = new ObjectStorage("wiktku_start_draft_" + mw.config.get("wgPageName"), 1); var langsByCode = {}; // Looks up the display label for a language code, falling back to the // code itself if it isn't known yet (e.g. langsByCode not loaded). function getLangLabel(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; // Converts a {code: label} object (langChoices/posChoices in data.json) // into the {code, label[, sortKey]} array the rest of the script uses. // isLang: true adds a sortKey and shows "(code)" after the label — // language choices only. function choicesFromObject(obj, isLang) { var result = []; $.each(obj || {}, function (code, label) { var choice = { code: code, label: label }; if (isLang) choice.sortKey = label; result.push(choice); }); return result; } function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c.code] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Item 1 (Wikihez, 14 Tebax 2026): kodên jimarê (y, s, d, p, p+, tp, j, j+, // j/nj, nj, nj+, hj!, hj?) — ji data.json's "numberLabels" tê dagirtin. // Same {code: {cat, display[, req]}} shape as the wiki's own Lua // number-type table; "display" can contain HTML (<abbr>) or wikilinks // ([[...]]), so it's only used as-is inside the wikitext output — never // dropped straight into an <option>, which can't render either (see // stripMarkupForOption below). var NUMBER_LABELS = {}; // metadata[lang].g used to list gender AND number codes together (see // cinsiyet/posparams below) — this tells the two dropdowns apart: any // code that's a key in NUMBER_LABELS is a number code (goes in the new // Jimar dropdown / j= param), everything else is a gender code (stays // in the existing Cîns dropdown / c= param). Compound codes like "m-p" // or "n-p" are gender+plural pairs, not plain "p" — they don't match a // NUMBER_LABELS key, so they correctly stay on the gender side. function isNumberCode(code) { return Object.prototype.hasOwnProperty.call(NUMBER_LABELS, code); } // Strips the bit of markup "display" is allowed to contain so it's safe // to use as plain <option> text (options can't render HTML or wikilinks): // <abbr title="X">Y</abbr> -> "Y (X)", [[a|b]] -> "b", [[a]] -> "a". function stripMarkupForOption(html) { if (!html) return ""; return $.trim( String(html) .replace(/<abbr[^>]*title="([^"]*)"[^>]*>([\s\S]*?)<\/abbr>/gi, "$2 ($1)") .replace(/\[\[[^\]|]*\|([^\]]*)\]\]/g, "$1") .replace(/\[\[([^\]]*)\]\]/g, "$1") .replace(/<[^>]+>/g, "") ); } // Builds the Jimar dropdown's <option> text for one code: "j — jimarbar". function numberOptionLabel(code) { var def = NUMBER_LABELS[code]; if (!def) return code; var text = stripMarkupForOption(def.display); return text ? (code + " — " + text) : code; } // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } // ── Template explanations (v3 spec) ────────────────────────────────── // Every place a template can be picked shows the same row: a status // dot, the name, a link to the template page, and an ⓘ. This is the ⓘ. // // Text comes from the template's own TemplateData where it has any, so // the explanation stays right without anyone maintaining a second copy // by hand — with the desc already in data.json as the fallback for // templates that have none. var wiktkuTplDataCache = {}; // name -> {desc, params[]} or null when absent /** Fetches TemplateData for one template. Resolves to null if the * template has none (a plain, undocumented template — very common). */ function fetchTemplateData(name) { if (Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, name)) { return $.Deferred().resolve(wiktkuTplDataCache[name]).promise(); } return new mw.Api().get({ action: "templatedata", titles: "Şablon:" + name, redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; var first = null; $.each(pages, function (_, p) { if (!first) first = p; }); var out = null; if (first) { var desc = first.description; // TemplateData descriptions are language maps when the // template is documented in more than one language. if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(first.params || {}, function (key, p) { var label = p && p.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(p && p.required) }); }); out = { desc: desc || "", params: params }; } wiktkuTplDataCache[name] = out; return out; }, function () { // No TemplateData, or the API is unhappy — cache the miss so a // repeated ⓘ click doesn't re-request it every time. wiktkuTplDataCache[name] = null; return null; }); } /** Fetches TemplateData for many templates in one request and fills the * cache. This is what lets a picker show a real description per row * without anyone maintaining a second copy of it in data.json — the v3 * spec's "Nivîsên ravekirinê ji rûpela şablonê tên girtin * (TemplateData), ne bi destan têne nivîsandin." * Resolves either way; a template with no TemplateData caches as null. */ function prefetchTemplateData(names) { var missing = $.grep(names || [], function (n) { return n && !Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n); }); if (!missing.length) return $.Deferred().resolve().promise(); // The API caps a titles list at 50 for normal users. missing = missing.slice(0, 50); return new mw.Api().get({ action: "templatedata", titles: $.map(missing, function (n) { return "Şablon:" + n; }).join("|"), redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; $.each(pages, function (_, page) { if (!page || !page.title) return; var name = String(page.title).replace(/^[^:]+:/, ""); var desc = page.description; if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(page.params || {}, function (key, prm) { var label = prm && prm.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(prm && prm.required) }); }); wiktkuTplDataCache[name] = { desc: desc || "", params: params }; }); // Anything the API didn't answer for simply has none — cache the // miss so the per-row ⓘ doesn't re-request it one at a time. $.each(missing, function (_, n) { if (!Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n)) wiktkuTplDataCache[n] = null; }); }, function () { $.each(missing, function (_, n) { wiktkuTplDataCache[n] = null; }); }); } /** Rewrites each tagged <option> in `sel` as "name — description", using * TemplateData. Only fills rows that have no description yet, so the * hand-written ones in data.json (which carry usage examples the API * does not) are left exactly as they are. */ function applyTplDescriptions(sel) { if (!sel || !sel.length) return; var changed = false; sel.find("option[data-tpl]").each(function () { var opt = $(this); var name = opt.attr("data-tpl"); if (opt.text().indexOf(" — ") !== -1) return; // already described var td = wiktkuTplDataCache[name]; var desc = (td && td.desc) || localTplDesc(name); if (!desc) return; // One line: TemplateData descriptions can run to a paragraph. desc = $.trim(String(desc).split("\n")[0]); if (desc.length > 90) desc = desc.slice(0, 90) + "…"; opt.text(name + " — " + desc); changed = true; }); // The picker caches option text for searching, so it has to re-read. if (changed) sel.trigger("wiktku:refresh"); } /** Hand-written fallback description, from data.json. * * This is the escape hatch for templates with no TemplateData on the * wiki: add a "desc" to the entry in data.json and it shows up in the * dropdown and in the ⓘ immediately, no code change. TemplateData is * still the better place — VisualEditor and every other tool reads it * too — but this keeps the picker useful in the meantime. * * Works for any pool: pronTpls, etymTpls, tplDefs, jederDefs. */ function localTplDesc(name) { var pools = [steps.pron.pronTpls, steps.etym.etymTpls, steps.dfn.tplDefs, steps.dfn.jederDefs]; var found = ""; $.each(pools, function (_, pool) { if (pool && pool[name] && pool[name].desc) { found = pool[name].desc; return false; } }); return found; } /** Opens the inline explanation panel for `name`, anchored under the * picker it was opened from. */ function showTemplateInfo(name, anchorWrap) { $(".wiktku-tpl-info").remove(); var panel = $("<div class='wiktku-tpl-info'></div>"); panel.append($("<div class='wiktku-tpl-info-name'></div>").text("{{" + name + "}}")); var body = $("<div class='wiktku-tpl-info-desc'></div>").text("Tê barkirin…"); panel.append(body); var params = $("<div class='wiktku-tpl-info-params'></div>"); panel.append(params); panel.append($("<a class='wiktku-tpl-info-link' target='_blank' rel='noopener'></a>") .attr("href", wiktkuUtil.tplPageUrl(name)) .text("Rûpela şablonê veke →")); var close = $("<button type='button' class='wiktku-tpl-info-close' title='Bigire'>✕</button>"); close.on("click", function () { panel.remove(); }); panel.prepend(close); $(anchorWrap).after(panel); fetchTemplateData(name).then(function (td) { var desc = (td && td.desc) || localTplDesc(name); body.text(desc || "Ji bo vê şablonê ravek nehatiye nivîsandin."); if (td && td.params && td.params.length) { params.append($("<div class='wiktku-tpl-info-params-title'></div>").text("Parametre:")); var listEl = $("<ul></ul>"); $.each(td.params, function (_, p) { var line = p.name + (p.label ? " — " + p.label : "") + (p.required ? " (pêwîst)" : ""); listEl.append($("<li></li>").text(line)); }); params.append(listEl); } }); } /** Marks a picker's <option>s as template rows so the searchable widget * renders them with the dot / 🔗 / ⓘ affordances, and wires the ⓘ * handler for that picker. `nameOf` maps an <option> to a template * name — the pickers store different things in value= (a snippet for * the insert dropdowns, the bare name for the sense selector). */ function markTemplateOptions(sel, nameOf) { if (!sel || !sel.length) return; var names = []; sel.find("option").each(function () { var opt = $(this); var name = nameOf(opt); if (!name) return; opt.attr("data-tpl", name); // Deprecated/typo templates are the "special cases only" ones. opt.attr("data-tpl-status", /kevnbûyî|şaşnivîs|kêmpeyda/i.test(opt.text()) ? "yellow" : "green"); names.push(name); }); sel.data("wiktkuTplInfo", showTemplateInfo); // Fill in the descriptions. Matters most for the Mane picker, whose // entries in data.json are names with no desc at all — "rastnivîs", // "ku-Latn", "guharto" on their own, which is precisely Rewiye tine's // "famkirina van zehmet e". One request covers every template in the // picker, and the result is cached for the per-row ⓘ as well. prefetchTemplateData(names).always(function () { applyTplDescriptions(sel); }); } /** Pulls the template name out of a snippet like "* {{ku-IPA}}" or * "{{ji|SOURCELANG|CODE|…}}". */ function tplNameFromSnippet(snippet) { var m = /\{\{\s*([^|}\n]+)/.exec(snippet || ""); return m ? $.trim(m[1]) : ""; } // True if a sense has content beyond mane worth keeping (etîket, word // lists, nimûne, jêder) — so it's still emitted with {{mane?}} if empty. function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } // Wikihez, 14 Tebax 2026 (item 7): the real submit-blocking requirement // (Ziman + Cureyê rêzimanî, via step.required/canContinue) is already // obvious since Bişîne stays visibly disabled until it's met. What // wasn't obvious is that a technically-"complete" entry with nothing // in Mane, Bi zaravayên din or Werger is still empty in any meaningful // sense — so this is checked separately, at click time, with its own // message, instead of another star/legend marker on the page. function hasMinRequiredContent(values) { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasMane = dfnSenses.some(function (s) { return (s.tpl && s.tplTitle) || (!s.tpl && (s.mane !== "" || senseHasExtraContent(s))); }); if (hasMane) return true; if (values.lang === "ku") { var hasWerger = false; $("#wiktku-start-trans .wiktku-trans-group").each(function () { if (steps.trans.getGroupTranslations($(this)).length) hasWerger = true; }); if (hasWerger) return true; var hasZarava = false; $("#wiktku-start-zarava .wiktku-zarava-group").each(function () { if (steps.zarava.getGroupTranslations($(this)).length) hasZarava = true; }); if (hasZarava) return true; } return false; } // Bolds the *first* occurrence of the page name function boldPageNameOnce(text) { if (!text || !pageNameRe) return text; var re = new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "i"); return text.replace(re, "'''$1'''"); } // Converts literal line breaks typed into a nimûne/jêgirtin box into // wikitext <br> tags, function nlToBr(text) { return text ? text.replace(/\r\n|\r|\n/g, "<br>") : text; } function escapeHtmlForBackdrop(str) { return String(str) .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;"); } // Mirrors a textarea's text, with a small highlighted marker placed // right after each line that's followed by an actual typed/pasted // linebreak. Rendered into a transparent backdrop layer behind the // textarea (see ensureLinebreakBackdrop()), so only the point of the // break is marked instead of the whole box. function buildLinebreakBackdropHtml(text) { var lines = text.split(/\r\n|\r|\n/); return $.map(lines, function (line, i) { var isLast = i === lines.length - 1; return escapeHtmlForBackdrop(line) + (isLast ? "" : "<mark class='wiktku-linebreak-mark'>↵</mark>\n"); }).join(""); } // Copies the metrics that affect where text wraps/lands (font, line // height, padding, border) from the real textarea onto its backdrop, // via computed style rather than shared CSS classes — most of the // box's own rules are written as "textarea.foo", which a <div> with // the same class wouldn't match. Re-run on every update in case a // responsive breakpoint changed the textarea's own font-size. function syncLinebreakBackdropMetrics(textarea, backdrop) { var cs = window.getComputedStyle(textarea[0]); backdrop.css({ "box-sizing": cs.boxSizing, "padding-top": cs.paddingTop, "padding-right": cs.paddingRight, "padding-bottom": cs.paddingBottom, "padding-left": cs.paddingLeft, "border-width": cs.borderWidth, "border-style": "solid", "font-family": cs.fontFamily, "font-size": cs.fontSize, "font-weight": cs.fontWeight, "line-height": cs.lineHeight, "letter-spacing": cs.letterSpacing }); } // Lazily wraps a textarea in its own positioning anchor (independent // of .wiktku-resize-wrap, so this doesn't depend on load order versus // wiktkuMakeManualResizable) and inserts the transparent backdrop // layer used to mark the exact point of a linebreak. Safe to call // more than once on the same textarea — the backdrop is cached. function ensureLinebreakBackdrop(textarea) { var existing = textarea.data("wiktkuLinebreakBackdrop"); if (existing) return existing; textarea.wrap("<div class='wiktku-linebreak-wrap'></div>"); var backdrop = $("<div aria-hidden='true'></div>").addClass("wiktku-linebreak-backdrop"); textarea.before(backdrop); textarea.data("wiktkuLinebreakBackdrop", backdrop); textarea.on("scroll.wiktkuLinebreak", function () { backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); }); return backdrop; } // Flags a nimûne/jêgirtin textarea (via CSS class, for the border // tint + tooltip) while it contains a typed/pasted linebreak, so the // user notices before it's silently turned into <br> on output. // Marks only the exact point of the break via a mirrored backdrop, // rather than tinting the whole box. function highlightLinebreak(el) { var textarea = $(el); var text = textarea.val(); var hasBreak = /\r|\n/.test(text); textarea .toggleClass("wiktku-has-linebreak", hasBreak) .attr("title", hasBreak ? "Xeta nû dê wek <br> bê nivîsandin" : ""); if (!hasBreak) { var cached = textarea.data("wiktkuLinebreakBackdrop"); if (cached) cached.hide(); textarea.removeClass("wiktku-has-linebreak-source"); return; } var backdrop = ensureLinebreakBackdrop(textarea); textarea.addClass("wiktku-has-linebreak-source"); syncLinebreakBackdropMetrics(textarea, backdrop); backdrop.html(buildLinebreakBackdropHtml(text)).show(); backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); } // Each nimûne item can be { text, tr, t }: text, transliteration, translation. function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{nimûne?|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = nlToBr(boldPageNameOnce(text)); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + nlToBr(n.tr); // Translation as third positional param (no key needed). if (n.t) tpl += "|" + nlToBr(n.t); } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 60 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } // Formats jêder (citation) entries into "#* {{jêder…|…}}" lines; skips // entries with no quote text. Falls back to the generic {{jêder}} // template when no specific template was chosen. function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; var quote = nlToBr(boldPageNameOnce(jeder.quote)); var quoteTr = nlToBr(jeder.quoteTr); var quoteT = nlToBr(jeder.quoteT); if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + quote; if (quoteTr) cite += "|tr=" + quoteTr; if (quoteT) cite += "|tercime=" + quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + quote; if (quoteTr) out += "|tr=" + quoteTr; if (quoteT) out += "|tercime=" + quoteT; // A şablon picked from Kategorî:Çavkanî is transcluded as the // source param (e.g. |{{Kovara X}}); manual text is used as-is. var srcParam = jeder.jederCatTpl ? ("{{" + jeder.jederCatTpl + "}}") : (jeder.jederManual ? jeder.jederManual : "çavkanî?"); // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } // True if a sense has at least one jêder entry with quote text. function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } // Builds "{{tplName|lang|part1|part2|…}}" from a sense field (kategori, // etiket), wrapped inline (" {{…}} ") or on its own line ("\n#: {{…}}"). function buildSenseTpl(sense, field, lang, tplName) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return call } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } // ── Inline modifier system ─────────────────────────────────────────────── // Appends a ⊕ button to a word input <li>. Clicking it shows a compact // modifier picker; selecting one prompts for the value and appends // <modifier:value> to the textarea's current content. 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îf" }, { 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: qualifier (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" }, { key: "qq", label: "qq: qualifier (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î" } ]; // Sub-groups (inside a sense/definition block) that get the same ⊕ // modifier button as makeWordListStep fields. var MODIFIER_SUBGROUPS = { "wiktku-dfn-alternativ": true, "wiktku-dfn-hevmane": true, "wiktku-dfn-dijmane": true, "wiktku-dfn-koordine": true, "wiktku-dfn-jornav": true, "wiktku-dfn-jernav": true }; /** * Wraps a freshly-created textarea in a <li> with a ⊕ modifier button. * `ta` — the jQuery textarea element. * Returns the <li>. */ function makeModifierLi(ta) { var li = $("<li class='wiktku-word-li'></li>"); var btn = $("<button type='button' class='wiktku-mod-btn' title='Modifiyerê lê zêde bike'>⊕</button>"); var picker = $("<div class='wiktku-mod-picker'></div>").hide(); // Which modifier keys are already present in the textarea's current // text — e.g. "<t:...>" → "t" used. Each modifier can only be // applied once per word, so its pill gets disabled once used. function usedKeys() { var used = {}; var re = /<([a-zA-Z]+):/g; var val = ta.val() || ""; var m; while ((m = re.exec(val)) !== null) used[m[1]] = true; return used; } $.each(WORD_MODIFIERS, function (_, mod) { var pill = $("<button type='button' class='wiktku-mod-pill'></button>").text(mod.label); pill.attr("title", mod.hint); pill.data("mod-key", mod.key); pill.on("click", function (e) { e.preventDefault(); if (pill.prop("disabled")) return; // already used on this word picker.hide(); // Show a tiny inline input for the modifier value. var valWrap = $("<span class='wiktku-mod-val-wrap'></span>"); var valInp = $("<input type='text' class='wiktku-mod-val-input'>") .attr("placeholder", mod.hint + "…") .attr("size", 20); var confirm = $("<button type='button' class='wiktku-mod-confirm'>✓</button>"); var cancel = $("<button type='button' class='wiktku-mod-cancel'>✕</button>"); function applyModifier() { var v = $.trim(valInp.val()); if (v) { ta.val(ta.val() + "<" + mod.key + ":" + v + ">"); ta.trigger("input"); } valWrap.remove(); ta.focus(); } confirm.on("click", applyModifier); cancel.on("click", function () { valWrap.remove(); ta.focus(); }); valInp.on("keydown", function (e) { if (e.which === 13) { e.preventDefault(); applyModifier(); } if (e.which === 27) { valWrap.remove(); ta.focus(); } }); valWrap.append(valInp).append(confirm).append(cancel); li.append(valWrap); valInp.focus(); }); picker.append(pill); }); btn.on("click", function (e) { e.preventDefault(); // Close any other open pickers in the same list. li.closest("ol, ul").find(".wiktku-mod-picker").not(picker).hide(); // Grey out modifiers already used on this word — refreshed on // every open since the text (and thus what's "used") can change. var used = usedKeys(); picker.find(".wiktku-mod-pill").each(function () { var isUsed = !!used[$(this).data("mod-key")]; $(this).prop("disabled", isUsed).toggleClass("wiktku-mod-pill-used", isUsed); }); picker.toggle(); }); // Close picker when focus leaves the li entirely. li.on("focusout", function () { setTimeout(function () { if (!$.contains(li[0], document.activeElement)) picker.hide(); }, 150); }); li.append(ta).append(btn).append(picker); return li; } function makeWordListStep(id, name, question_fmt) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, modifiers: true, // Function instead of a plain string so it can name the current // language — computed fresh at build time and re-applied by // refresh() whenever the language changes. placeholder: function () { var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return "Kelîme" + (langLabel ? " bi " + langLabel : "") + "…"; }, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); var header = capitalize(name); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: {}, visible: function (values) { if (!values.lang) return false; // addLangMode: skip pron only if this lang already has a section. if (addLangMode) { // Clearing the page makes existing content irrelevant. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, // Fills the insert-dropdown from pronTpls, filtered by language. refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); // Rewiye tine, 14 Tebax 2026: "berê bilêvkirin otomatîk // çêdibû, niha zehmettir e ji bo yekî nezan — gelek şablon // hene, kîjan were hilbijartin?" A one-line reassurance: // this field is optional, and the dropdown below writes the // template for you — no need to know the syntax up front. wrap.append( $("<p class='wiktku-step-hint'></p>").text( "Ev qad ne mecbûrî ye. Heke tu nizanî kîjan şablonî hilbijêrî, vale bihêle — an ji pêşkêşkariya jêrîn şablonekî hilbijêre, ew ê bixweber li vir were nivîsandin." ) ); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike "); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); // Clear the picker's search box sel.trigger("wiktku:refresh"); ta.focus(); return; } // Item 5 (Wikihez, 14 Tebax 2026): the noLang templates // (ku-IPA, ku-kîte, zza-IPA, zza-kîte) auto-generate // their actual content from a Lua module reading the // page title — "{{ku-IPA}}" alone gives no hint what // that'll render as, so show a live preview and require // confirmation before inserting, instead of an inline // prompt()/confirm() dialog. var tplLabel = selectedOption.text(); $(this).val(""); sel.trigger("wiktku:refresh"); steps.pron.showTplPreview(stepDiv, ta, snippet, tplLabel); }); wrap.append(sel).append(ta); stepDiv.append(wrap); steps.pron.buildIpaPalette(wrap, ta); initSelects(wrap); return ta; }, // ── IPA character palette (v3 spec, 15 Tebax 2026) ─────────── // Modelled on fr.wiktionary's: every character is a button that // drops itself in at the cursor. Two sub-tabs, because the full // IPA chart is ~180 symbols and roughly twenty of them ever // appear in Kurmancî — "IPA (kurdî)" opens by default and the // full chart is one click away for loanwords and other // languages. Grouped with a label down the left so it reads as // a chart rather than one long line of glyphs. IPA_KU: [ { label: "Kît/stres", chars: ["ˈ", "ˌ", "ː"] }, { label: "Bêdeng", chars: ["d͡ʒ", "t͡ʃ", "ʒ", "ʃ", "ɫ", "ŋ", "ɾ", "r", "ʋ", "ħ", "ʕ", "ɣ", "χ", "ʔ"] }, { label: "Dengdêr", chars: ["ɑː", "eː", "ɛ", "ɪ", "iː", "ɯ", "ʊ", "uː", "yː", "ø", "œ"] } ], IPA_FULL: [ { label: "Bêdeng 1", chars: ["m", "ɱ", "n", "ɳ", "ɲ", "ŋ", "ɴ", "p", "b", "t", "d", "t̪", "d̪", "ʈ", "ɖ", "c", "ɟ", "k", "ɡ", "q", "ɢ", "ʡ", "ʔ"] }, { label: "Bêdeng 2", chars: ["ɸ", "β", "f", "v", "θ", "ð", "s", "z", "ʃ", "ʒ", "ʂ", "ʐ", "ɕ", "ʑ", "ç", "ʝ", "x", "ɣ", "χ", "ʁ", "ħ", "ʕ", "h", "ɦ", "ʜ", "ʢ", "ɧ"] }, { label: "Bêdeng 3", chars: ["ʋ", "ɹ", "ɻ", "j", "ɥ", "ɰ", "ʍ", "w", "ʙ", "ⱱ", "ɾ", "ɽ", "r", "ʀ", "ɺ", "l", "ɫ", "ɬ", "ɮ", "ɭ", "ʎ", "ʟ"] }, { label: "Bêdeng 4", chars: ["ɓ", "ɗ", "ᶑ", "ʄ", "ɠ", "ʛ", "ʘ", "ǀ", "ǃ", "ǂ", "ǁ"] }, { label: "Dengdêr", chars: ["i", "y", "ɪ", "ʏ", "ɨ", "ʉ", "ɯ", "u", "ʊ", "e", "ø", "ɘ", "ɵ", "ɤ", "o", "ə", "ɚ", "ɛ", "œ", "ɜ", "ɝ", "ɞ", "ʌ", "ɔ", "æ", "ɶ", "ɐ", "a", "ɑ", "ɒ"] }, { label: "Suprasegmental", chars: ["ˈ", "ˌ", "ː", "ˑ", "ʼ", "ˀ", "ˤ", "ᵝ", "ᵊ", "ˠ", "ʰ", "ʱ", "ʲ", "ˡ", "ⁿ", "ᵑ", "ʷ", "ᶣ", "˞", "‿"] }, { label: "Dîakrîtîk", chars: ["̚", "̪", "̺", "̻", "̼", "̬", "̊", "̥", "̞", "̝", "̘", "̙", "̽", "̟", "̠", "̈", "̤", "̹", "̜", "̍", "̩", "̆", "̯", "̃", "̰", "͡", "͜"] }, { label: "Ton", chars: ["̋", "́", "̄", "̀", "̏", "̌", "̂", "˥", "˦", "˧", "˨", "˩", "ꜛ", "ꜜ", "↗", "↘", "‖"] } ], /** Builds the two-sub-tab character palette under the textarea. */ buildIpaPalette: function (wrap, ta) { if (wrap.find(".wiktku-ipa-palette").length) return; var panel = $("<div class='wiktku-ipa-panel'></div>").hide(); var toggle = $("<a href='#' class='wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tîpên bilêvkirinê</span>")); toggle.on("click", function (e) { e.preventDefault(); var open = panel.is(":visible"); panel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); wrap.append($("<div class='wiktku-adv-toggle-row'></div>").append(toggle)); // Sub-tab bar, with the two template buttons pinned right. var subTabs = $("<div class='wiktku-ipa-subtabs'></div>"); var kuTab = $("<span class='wiktku-ipa-subtab wiktku-tab-active'>IPA (kurdî)</span>"); var fullTab = $("<span class='wiktku-ipa-subtab'>IPA</span>"); subTabs.append(kuTab).append(fullTab); var tplBtns = $("<span class='wiktku-ipa-tplbtns'></span>"); $.each([ { label: "{{ku-IPA|+}}", snippet: "{{ku-IPA|}}", back: 2 }, { label: "{{IPA|+}}", snippet: "{{IPA|ku|}}", back: 2 } ], function (_, t) { var b = $("<button type='button' class='wiktku-ipa-tplbtn'></button>").text(t.label); b.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], t.snippet); // Park the cursor inside the braces, where the value goes. var pos = ta[0].selectionStart - t.back; ta[0].selectionStart = ta[0].selectionEnd = pos; ta.focus(); }); tplBtns.append(b); }); subTabs.append(tplBtns); panel.append(subTabs); function buildGrid(groups) { var grid = $("<div class='wiktku-ipa-grid'></div>"); $.each(groups, function (_, g) { var row = $("<div class='wiktku-ipa-row'></div>"); row.append($("<span class='wiktku-ipa-rowlabel'></span>").text(g.label)); var keys = $("<span class='wiktku-ipa-keys'></span>"); $.each(g.chars, function (_, ch) { var btn = $("<button type='button' class='wiktku-ipa-key'></button>"); // A combining mark on its own renders as a stray // accent floating over whatever precedes it, so // show it on a dotted circle — but insert only // the mark itself. var combining = /^[̀-ͯ҃-҉]$/.test(ch); btn.text(combining ? "◌" + ch : ch); if (combining) btn.addClass("wiktku-ipa-key-combining"); btn.attr("title", ch); btn.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], ch); ta.focus(); }); keys.append(btn); }); row.append(keys); grid.append(row); }); return grid; } var kuGrid = buildGrid(steps.pron.IPA_KU); var fullGrid = buildGrid(steps.pron.IPA_FULL).hide(); panel.append(kuGrid).append(fullGrid); kuTab.on("click", function () { kuTab.addClass("wiktku-tab-active"); fullTab.removeClass("wiktku-tab-active"); kuGrid.show(); fullGrid.hide(); }); fullTab.on("click", function () { fullTab.addClass("wiktku-tab-active"); kuTab.removeClass("wiktku-tab-active"); fullGrid.show(); kuGrid.hide(); }); panel.addClass("wiktku-ipa-palette"); wrap.append(panel); }, /** Item 5: inline preview + confirm panel for a "noLang" (auto- * content) pronunciation template — fetches what the snippet * actually expands to for this page (via action=expandtemplates, * so the preview is exactly what {{ku-IPA}} etc. would produce) * and only inserts it into the textarea if the user confirms. */ showTplPreview: function (stepDiv, ta, snippet, tplLabel) { // Only one preview panel open at a time. stepDiv.find(".wiktku-pron-preview").remove(); var panel = $("<div class='wiktku-pron-preview'></div>"); panel.append($("<div class='wiktku-pron-preview-label'></div>") .text("Pêşdîtina " + tplLabel + ":")); var body = $("<div class='wiktku-pron-preview-body'></div>").text("Tê barkirin…"); panel.append(body); var actions = $("<div class='wiktku-pron-preview-actions'></div>"); var confirmBtn = $("<button type='button' class='wiktku-pron-preview-confirm'>✓ Tevlî bike</button>") .prop("disabled", true); var cancelBtn = $("<button type='button' class='wiktku-pron-preview-cancel'>✕ Betal bike</button>"); actions.append(confirmBtn).append(cancelBtn); panel.append(actions); ta.before(panel); confirmBtn.on("click", function () { insertAtCursor(ta[0], snippet); panel.remove(); ta.focus(); }); cancelBtn.on("click", function () { panel.remove(); }); // action=parse, not action=expandtemplates. expandtemplates // returns *expanded wikitext*, so the preview read as // [[IPA]]<sup>([[Wîkîferheng:IPA kurmancî|kilîd]])</sup>: // <span class="IPA">/-{kshhe}-/</span>[[Kategorî:…]] — which // is exactly what the person is trying to avoid having to // read. parse hands back the rendered HTML the page will // actually show. // // Drop the leading "* " first: it is wikitext list syntax // wrapping the template, and keeping it would render the // preview as a bulleted list rather than the line itself. new mw.Api().post({ action: "parse", title: pageName, text: snippet.replace(/^\*\s*/, ""), prop: "text", wrapoutputclass: "", disablelimitreport: 1, disableeditsection: 1, contentmodel: "wikitext", formatversion: 2 }).done(function (data) { var html = (data && data.parse && data.parse.text) || ""; if ($.trim($("<div>").html(html).text())) { body.html(html); // Category links render as nothing but still exist; // and any real link inside a preview should not // navigate away from a half-filled form. body.find("a").attr("target", "_blank").attr("rel", "noopener"); } else { body.text("(vala — ji bo vê rûpelê tiştek nehate afirandin)"); } confirmBtn.prop("disabled", false); }).fail(function () { body.text("Pêşdîtin nehate barkirin — tu dikarî hîn jî wê tevlî bikî."); confirmBtn.prop("disabled", false); }); }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line; }).join("\n"); // Back to "===", under Ziman and above the POS sections // (v3 spec, 15 Tebax 2026). It had been nested at "====" // inside each POS section per Ghybu's earlier note, but the // field is shared across sections, so a two-POS entry // printed the identical pronunciation twice — once under // Navdêr and once under Lêker. Emitted once by getWikitext() // now, not by getWikitextForCurrentSection(). return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var capitalizedPos = capitalize(pos); // "form" opt-param (checked in posparams) marks this as a // form-of/inflected entry — the section title becomes // "Formeke <pos>ê" instead of the plain pos name. The // template call itself still uses the unchanged pos name. var isForm = $("#wiktku-posparams-opt-form").is(":checked"); var header = isForm ? "\n=== Formeke " + pos + "ê ===\n" : "\n=== " + capitalizedPos + " ===\n"; // Image line (between header and template call) var imageLine = steps.resim.output(values); // Read the live wikitext from the posparams textarea. // Fall back to a plain {{pos|lang}} if the step hasn't been built yet. var tplLine = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); if (!tplLine) { tplLine = "{{" + pos + "|" + (values.lang || "") + "}}"; } return header + imageLine + tplLine + "\n"; } }, // cinsiyet (gender) — shown for navdêr/serenav only, with choices built // from metadata[lang].g since not every language has grammatical gender. cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams // Single source of truth for the selected gender code. The visible // dropdown lives inside the posparams step (see steps.posparams), // but it must always read/write THIS hidden field — not a field of // its own — since getValuesForStep("cinsiyet") reads from here. build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-cinsiyet-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // Item 1 (Wikihez, 14 Tebax 2026): jimar (grammatical number) — same // hidden-field pattern as cinsiyet just above, but writes into its // own j= template parameter instead of sharing c=. Shown for // navdêr/serenav only, with choices built from whichever of // metadata[lang].g are number codes (see isNumberCode) — mirrors // cinsiyet exactly, just filtered to the other half of that list. jimar: { id: "jimar", name: "jimar", question_fmt: 'Jimara "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-jimar-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // Lêker transitivity — hidden step, handled inside posparams lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function () { return false; }, choices: [ { code: "gh", label: "gerguhêz" }, { code: "x-gh", label: "xwerû-gerguhêz" }, { code: "p-gh", label: "pêkhatî-gerguhêz" }, { code: "h-gh", label: "hevedudanî-gerguhêz" }, { code: "b-gh", label: "biwêjî-gerguhêz" }, { code: "ngh", label: "negerguhêz" }, { code: "x-ngh", label: "xwerû-negerguhêz" }, { code: "p-ngh", label: "pêkhatî-negerguhêz" }, { code: "h-ngh", label: "hevedudanî-negerguhêz" }, { code: "b-ngh", label: "biwêjî-negerguhêz" } ], output: function () { return ""; } }, // tr — hidden step, handled inside posparams tr: { id: "tr", name: "transliterasyon", question_fmt: "Transliterasyona vê kelîmeyê", multiple: false, narrow: true, visible: function () { return false; } }, posparams: { id: "posparams", // Fused onto the "pos" card visually (see #wiktku-start-posparams // in styles.css) so the two read as ONE question, per Ghybu's // 14 Tebax 2026 feedback — this name is only a no-CSS/no-JS // fallback, since the h3 that would show it is hidden by CSS. name: "taybetmendî", // The old static "Parametreyên cureyê rêzimanî" label named the // mechanism, not the content. Show what's actually being asked // for instead: gender for nouns, verb type for verbs, a generic // fallback (transliteration/forms etc. still apply) otherwise. question_fmt: function (values) { var pos = values.pos || ""; if (pos === "navdêr" || pos === "serenav") return "Cins/zayend"; if (/^lêker/.test(pos)) return "Cureyê lêkerê"; return "Taybetmendî"; }, visible: function (values) { return !!(values.lang && values.pos); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-posparams-wrap").length) return null; var wrap = $("<div class='wiktku-posparams-wrap'></div>"); var helpers = $("<div class='wiktku-posparams-helpers'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-posparams-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-posparams-text") .attr("rows", 2); var _rebuilding = false; function safeRebuild() { if (_rebuilding) return; _rebuilding = true; steps.posparams.rebuildTa(stepDiv); _rebuilding = false; refresh(); } // Generic text-input row factory function makeTextRow(key, labelText, placeholder) { var row = $("<div class='wiktku-posparams-row'></div>") .attr("id", "wiktku-posparams-row-" + key).hide(); var inp = $("<input type='text'>") .addClass("wiktku-start-narrow wiktku-posparams-field") .attr("data-pp-key", key) .attr("placeholder", placeholder || ""); inp.on("input", safeRebuild); row.append($("<label></label>").text(labelText + ": ")).append(inp); return row; } // cinsiyet var cinsiyetRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-c'></div>") .append($("<label></label>").text("Cinsiyet: ")).hide(); var cinsiyetSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-cinsiyet-sel") .append($("<option value=''>— hilbijêre —</option>")); // Writes into the real, shared #wiktku-start-cinsiyet-field (owned by // steps.cinsiyet) rather than a field of its own — see the comment // on steps.cinsiyet.build for why that matters. cinsiyetSel.on("change", function () { $("#wiktku-start-cinsiyet-field").val($(this).val()).trigger("change"); safeRebuild(); }); cinsiyetRow.append(cinsiyetSel); // Item 1 (Wikihez, 14 Tebax 2026): jimar (number) — a second // dropdown next to Cinsiyet, same pattern (writes into the // shared hidden #wiktku-start-jimar-field), but into its own // j= param instead of sharing c=. Options + the title // tooltip (explanation) are built in syncHelpers, once the // language's number codes are known. var jimarRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-jimar'></div>") .append($("<label></label>").text("Jimar: ")).hide(); var jimarSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-jimar-sel") .append($("<option value=''>— hilbijêre —</option>")); jimarSel.on("change", function () { $("#wiktku-start-jimar-field").val($(this).val()).trigger("change"); safeRebuild(); }); jimarRow.append(jimarSel); // lektur — Ghybu, 14 Tebax 2026: "'Cureyê lêkerê' nayê fêm // kirin, bi min pêşta 'gerguhez/negerguhêz' were hilbijartin, // paşê jî form 'hevdudanî/pêkatî/…' ji ber ku her kes vana // nizanî." So the one 10-option dropdown ("xwerû-gerguhêz", // "biwêjî-negerguhêz", …) becomes two plain questions. The // emitted code is unchanged: base alone ("gh"), or prefix + // "-" + base ("x-gh") — exactly the codes steps.lektur.choices // already listed, just assembled from two answers instead of // asked as one. var lekturRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lektur'></div>") .append($("<label></label>").text("Lêker derbasdar e? ")).hide(); var lekturSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lektur-sel") .append($("<option value=''>— hilbijêre —</option>")) .append($("<option value='gh'>gerguhêz (bireser digire)</option>")) .append($("<option value='ngh'>negerguhêz (bireser nagire)</option>")); lekturSel.on("change", safeRebuild); lekturRow.append(lekturSel); // Second half of the same question — the structural form. // Blank = xwerû/sade, which is the common case. var lekturFormRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lekturform'></div>") .append($("<label></label>").text("Şiklê lêkerê: ")).hide(); var lekturFormSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lekturform-sel") .append($("<option value=''>sade (asayî)</option>")) .append($("<option value='x'>xwerû</option>")) .append($("<option value='p'>pêkhatî</option>")) .append($("<option value='h'>hevedudanî</option>")) .append($("<option value='b'>biwêjî</option>")); lekturFormSel.on("change", safeRebuild); lekturFormRow.append(lekturFormSel); helpers.append(cinsiyetRow).append(jimarRow).append(lekturRow).append(lekturFormRow); // ── Everything below here is "Tercîhên pêşketî" ────────────── // Ghybu, 14 Tebax 2026: "Tenê 'cîns' û 'jimar' bes e. 'Forma // mê', 'Forma nêr', … nayê fêm kirin. Bi min wekî 'Tercîhên // pêşketî' bi navkî din veşartî çêke." The rows themselves are // unchanged and syncHelpers still shows/hides each one by id // exactly as before — they just live inside a collapsed panel // now, so the default view of this card is two dropdowns // instead of twenty-odd fields. // Transliteration is a primary field, not an advanced one, for // any language not written in Latin script: for those, an // entry without it is incomplete. syncHelpers already gates // the row on needsTransliteration(lang), so for Kurmancî and // other Latin-script languages it simply never appears. helpers.append(makeTextRow("tr", "Transliterasyon (tr)", "Transliterasyon…")); var advPanel = $("<div class='wiktku-posparams-adv-panel'></div>").hide(); advPanel .append(makeTextRow("cuda", "nîşankirina alternatîv", "cuda…")) .append(makeTextRow("ts", "Transkrîpsiyon (ts)", "Transkrîpsiyon…")) .append(makeTextRow("m", "Forma mê (m)", "Forma mê…")) .append(makeTextRow("mtr", "Translit. mê (mtr)", "Transliterasyona mê…")) .append(makeTextRow("n", "Forma nêr (n)", "Forma nêr…")) .append(makeTextRow("ntr", "Translit. nêr (ntr)", "Transliterasyona nêr…")) .append(makeTextRow("p", "Forma pirjimar (p)", "Forma pirjimar…")) .append(makeTextRow("ptr", "Translit. pirjimar", "Transliterasyona pirjimar…")) .append(makeTextRow("y", "Forma yekjimar (y)", "Forma yekjimar…")) .append(makeTextRow("ytr", "Translit. yekjimar", "Transliterasyona yekjimar…")) .append(makeTextRow("sûp", "Forma sûperlatîv (sûp)", "Forma sûperlatîv…")) .append(makeTextRow("sûptr", "Translit. sûperlatîv", "Transliterasyona sûperlatîv…")) .append(makeTextRow("komp", "Forma komparatîv (komp)", "Forma komparatîv…")) .append(makeTextRow("komptr", "Translit. komparatîv", "Transliterasyona komparatîv…")) .append(makeTextRow("gir", "Forma girdêk (gir)", "gir=…")) .append(makeTextRow("girtr", "Translit. gir", "girtr=…")) .append(makeTextRow("hûr", "Forma hûrek (hûr)", "hûr=…")) .append(makeTextRow("hûrtr", "Translit. hûr", "hûrtr=…")) .append(makeTextRow("hanja", "Forma hanja", "hanja=…")) .append(makeTextRow("hanjaTr","Translit. hanja", "hanjaTr=…")) // Lêker rehên demê (only shown when pos is lêker — see syncHelpers) .append(makeTextRow("niha", "Rehê dema niha (niha)", "Rehê dema niha…")) .append(makeTextRow("nihatr", "Translit. rehê dema niha", "Transliterasyona rehê dema niha…")) .append(makeTextRow("borî", "Rehê dema borî (borî)", "Rehê dema borî…")) .append(makeTextRow("borîtr", "Translit. rehê dema borî", "Transliterasyona rehê dema borî…")) .append(makeTextRow("subj", "Rehê dema bilanî (subj)", "Rehê dema bilanî…")) .append(makeTextRow("subjtr", "Translit. rehê dema bilanî", "Transliterasyona rehê dema bilanî…")); // Optional boolean params — nested inside the advanced panel // (they were already the most niche thing on the card). var optPanel = $("<div class='wiktku-posparams-opt-panel'></div>"); $.each([ { key: "form", label: "form — ev made forma tewandî ye" }, { key: "formaalt", label: "formaalt — vê madeyê bike forma alternatîv" }, { key: "nekatcure", label: "nekatcure — sinifa rêzimanî kategorîze neke" }, { key: "nekatcins", label: "nekatcins — kategoriya cinsiyetê neyîne" }, { key: "nekatçendterm", label: "nekatçendterm — kategoriya çend-term neyîne" }, { key: "serlînkneke", label: "serlînkneke — sernavê madeyê lînk neke" }, { key: "nekatpalîndrom", label: "nekatpalîndrom — kategoriya palîndromê neyîne" }, { key: "neformtr", label: "neformtr — transliterasyona forman neyîne" } ], function (_, p) { var cb = $("<input type='checkbox'>") .attr("id", "wiktku-posparams-opt-" + p.key).val(p.key).on("change", safeRebuild); var lbl = $("<label></label>").attr("for", "wiktku-posparams-opt-" + p.key).text(" " + p.label); optPanel.append($("<div class='wiktku-posparams-opt-row'></div>").append(cb).append(lbl)); }); advPanel.append(optPanel); var optToggle = $("<a href='#' class='wiktku-posparams-opt-toggle wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tercîhên pêşketî</span>")); var optCount = $("<span class='wiktku-adv-toggle-count'></span>"); /** "N zevî · M tije" for whatever the advanced panel is * currently showing — the row set changes with pos/lang (see * syncHelpers), so this counts visible rows, not all of them. */ function syncAdvCount() { var rows = advPanel.find(".wiktku-posparams-row").filter(function () { return $(this).css("display") !== "none"; }); var filled = rows.filter(function () { return $.trim($(this).find("input").val() || "") !== ""; }).length; var checked = advPanel.find(".wiktku-posparams-opt-panel input:checked").length; optCount.text(rows.length + " zevî · " + (filled + checked) + " tije"); } stepDiv.data("syncAdvCount", syncAdvCount); optToggle.on("click", function (e) { e.preventDefault(); var open = advPanel.is(":visible"); advPanel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); syncAdvCount(); }); advPanel.on("input change", "input", syncAdvCount); helpers.append($("<div class='wiktku-adv-toggle-row'></div>") .append(optToggle).append(optCount)); helpers.append(advPanel); wrap.append(helpers).append(ta); // Typing directly in textarea keeps cinsiyet/jimar hidden // fields in sync, but does NOT call refresh() — preserves // manual edits. ta.on("input", function () { var text = $(this).val(); var cMatch = text.match(/\|c=([^|}\s]+)/); $("#wiktku-start-cinsiyet-field").val(cMatch ? cMatch[1] : ""); var jMatch = text.match(/\|j=([^|}\s]+)/); $("#wiktku-start-jimar-field").val(jMatch ? jMatch[1] : ""); }); stepDiv.append(wrap); return null; }, /** Reads all helper widget values and rewrites the textarea. * Called only by safeRebuild (user interaction) — never by syncHelpers, * so manual textarea edits are never overwritten by a refresh cycle. */ rebuildTa: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; if (!pos || !lang) return; var cinsiyet = stepDiv.find(".wiktku-posparams-cinsiyet-sel").val() || ""; var jimar = stepDiv.find(".wiktku-posparams-jimar-sel").val() || ""; // Two dropdowns, one code: "gh" / "ngh" on their own, or // prefixed with the structural form ("x-gh", "b-ngh", …). var lekturBase = stepDiv.find(".wiktku-posparams-lektur-sel").val() || ""; var lekturForm = stepDiv.find(".wiktku-posparams-lekturform-sel").val() || ""; var lektur = lekturBase ? (lekturForm ? lekturForm + "-" + lekturBase : lekturBase) : ""; function v(key) { return $.trim(stepDiv.find(".wiktku-posparams-field[data-pp-key='" + key + "']").val()); } var out = "{{" + pos + "|" + lang; if (pos === "navdêr" || pos === "serenav") { out += cinsiyet ? "|c=" + cinsiyet : (lang === "ku" ? "|c=?" : ""); // Item 1: number is its own j= param now, separate from // c= — c= keeps holding gender (and gender+plural // compounds like m-p/n-p, unaffected by this change). if (jimar) out += "|j=" + jimar; } else if (/^lêker/.test(pos) && lektur) { out += "|c=" + lektur; } if (v("cuda")) out += "|" + v("cuda"); if (v("tr")) out += "|tr=" + v("tr"); if (v("ts")) out += "|ts=" + v("ts"); $.each(["m","n","p","y"], function (_, k) { if (v(k)) out += "|" + k + "=" + v(k); if (v(k+"tr")) out += "|" + k + "tr=" + v(k+"tr"); }); if (v("sûp")) out += "|sûp=" + v("sûp"); if (v("sûptr")) out += "|sûptr=" + v("sûptr"); if (v("komp")) out += "|komp=" + v("komp"); if (v("komptr")) out += "|komptr=" + v("komptr"); if (v("gir")) out += "|gir=" + v("gir"); if (v("girtr")) out += "|girtr=" + v("girtr"); if (v("hûr")) out += "|hûr=" + v("hûr"); if (v("hûrtr")) out += "|hûrtr=" + v("hûrtr"); if (v("hanja")) out += "|hanja=" + v("hanja"); if (v("hanjaTr")) out += "|hanjaTr=" + v("hanjaTr"); if (v("niha")) out += "|niha=" + v("niha"); if (v("nihatr")) out += "|nihatr=" + v("nihatr"); if (v("borî")) out += "|borî=" + v("borî"); if (v("borîtr")) out += "|borîtr=" + v("borîtr"); if (v("subj")) out += "|subj=" + v("subj"); if (v("subjtr")) out += "|subjtr=" + v("subjtr"); stepDiv.find(".wiktku-posparams-opt-panel input:checked").each(function () { var key = $(this).val(); // "form" marks this entry as a form-of/inflected entry — it // takes "erê" rather than the plain "1" the other boolean // opt params use. out += "|" + key + "=" + (key === "form" ? "erê" : "1"); }); out += "}}"; stepDiv.find(".wiktku-posparams-text").val(out); $("#wiktku-start-cinsiyet-field").val(cinsiyet); $("#wiktku-start-jimar-field").val(jimar); }, /** Called from refresh() — controls row visibility only. * Does NOT rewrite textarea so user edits are preserved. * Rebuilds only when textarea is empty (first pos selection). */ syncHelpers: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; var needsTr = needsTransliteration(lang); var isNom = pos === "navdêr" || pos === "serenav" || pos === "rengdêr"; var isAdj = pos === "rengdêr"; var isTîp = pos === "tîp"; var isJa = lang === "ja"; var isLeker = /^lêker/.test(pos); // Item 1: metadata[lang].g used to list gender AND number // codes together — split them here (see isNumberCode) so // Cîns only ever offers gender codes (and gender+plural // compounds like m-p/n-p, which aren't NUMBER_LABELS keys) // and the new Jimar dropdown only offers number codes. var meta = metadata[lang]; var allCodes = (meta && meta.g) || []; var genderCodes = $.grep(allCodes, function (c) { return !isNumberCode(c); }); var jimarCodes = $.grep(allCodes, function (c) { return isNumberCode(c); }); var showC = (pos === "navdêr" || pos === "serenav") && genderCodes.length > 0; var cRow = stepDiv.find("#wiktku-posparams-row-c"); cRow.toggle(showC); if (showC) { var sel = cRow.find(".wiktku-posparams-cinsiyet-sel"); // Prefer the select's own current value (normal in-session // use); fall back to the shared hidden field, which is how // a cache/section restore communicates a saved gender // before this select has any <option>s to hold it. var prev = sel.val() || $("#wiktku-start-cinsiyet-field").val() || ""; sel.find("option[value!='']").remove(); $.each(genderCodes, function (_, code) { sel.append($("<option></option>").val(code).text(genderLabel(code))); }); if (prev) sel.val(prev); } var showJimar = (pos === "navdêr" || pos === "serenav") && jimarCodes.length > 0; var jimarRowEl = stepDiv.find("#wiktku-posparams-row-jimar"); jimarRowEl.toggle(showJimar); if (showJimar) { var jimarSelEl = jimarRowEl.find(".wiktku-posparams-jimar-sel"); var prevJimar = jimarSelEl.val() || $("#wiktku-start-jimar-field").val() || ""; jimarSelEl.find("option[value!='']").remove(); $.each(jimarCodes, function (_, code) { var def = NUMBER_LABELS[code] || {}; var opt = $("<option></option>").val(code).text(numberOptionLabel(code)); // The explanation (cat, e.g. "dualia tantum") shows as a // hover tooltip — <option> can't hold richer markup. if (def.cat) opt.attr("title", def.cat); jimarSelEl.append(opt); }); if (prevJimar) jimarSelEl.val(prevJimar); } stepDiv.find("#wiktku-posparams-row-lektur").toggle(isLeker); // Only ask for the structural form once the person has said // gerguhêz/negerguhêz — "paşê jî form", per Ghybu. stepDiv.find("#wiktku-posparams-row-lekturform") .toggle(isLeker && !!stepDiv.find(".wiktku-posparams-lektur-sel").val()); stepDiv.find("#wiktku-posparams-row-tr").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-ts").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-m").toggle(isNom); stepDiv.find("#wiktku-posparams-row-mtr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-n").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ntr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-p").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ptr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-y").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ytr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-sûp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-sûptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-komp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-komptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-gir").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-girtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hûr").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-hûrtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hanja").toggle(isJa); stepDiv.find("#wiktku-posparams-row-hanjaTr").toggle(isJa); stepDiv.find("#wiktku-posparams-row-niha").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-nihatr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-borî").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-borîtr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-subj").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-subjtr").toggle(isLeker && needsTr); // Row visibility just changed, so the "N zevî" half of the // advanced toggle's badge is stale — recount. var syncAdvCount = stepDiv.data("syncAdvCount"); if (typeof syncAdvCount === "function") syncAdvCount(); if (!$.trim(stepDiv.find(".wiktku-posparams-text").val())) { steps.posparams.rebuildTa(stepDiv); } }, output: function () { return ""; } // pos.output reads the textarea directly }, dfn: { id: "dfn", name: "Mane", // Field types that live behind "Malûmatên pêşketî". Kept as one // list so the collapse CSS, the count badge and the allGroups // adv: flags below can't drift apart. ADV_SUBGROUPS: [ "wiktku-dfn-etiket", "wiktku-dfn-kategori", "wiktku-dfn-alternativ", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ], question_fmt: function (values) { var base = "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin!"; if (values.lang === "ku") { return base + " Ji bo tercimeyan beşa 'Werger' bi kar bîne!"; } return base; }, multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, // Builds one sense block (<li>): mane textarea, nimûne list, and // sub-lists for alternatîv/hevmane/dijmane/etc. buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Tercime + Îzah boxes (non-ku alternative to the plain mane box) — // Non-ku entries get a direct translation plus a {{îzah|…}}-wrapped // gloss instead of a Kurdish-style gloss. Rather than teach every // consumer (getSenses/getOutput/linkify) a second data shape, these // boxes just write their combined text into dfnArea and re-fire its // "input" event, so dfnArea stays the single source of truth. var tercimeArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-tercime-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-tercime") .attr("rows", 2) .attr("placeholder", "Tercimeyên rasterast ên kurmancî… Ji bo school-a îngilîzî li vir 'mekteb, medrese' binivîse"); var izahArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-izah-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-izah") .attr("rows", 3) .attr("placeholder", "Îzaha kurmancî… Ji bo school-a îngilîzî li vir 'cihê tehsîlgirtinê' binivîse"); var nonKuWrap = $("<div class='wiktku-dfn-nonku-wrap'></div>") .append(tercimeArea).append(izahArea) .hide(); function syncNonKuToMane() { var t = $.trim(tercimeArea.val()); var iz = $.trim(izahArea.val()); // if tercime is blank, use îzah as definition var combined = t ? (iz ? t + " {{îzah|" + iz + "}}" : t) : iz; dfnArea.val(combined); // Re-fires onDfnInput so the sense list still grows and // refresh() still runs, exactly as if this were typed // directly into the mane textarea. dfnArea.trigger("input"); } tercimeArea.on("input", syncNonKuToMane); izahArea.on("input", syncNonKuToMane); // Switches between the plain mane box and the tercime+îzah pair — // only for non-ku entries with no tplSelect selected. function updateManeMode() { var lang = getValues().lang || ""; var isTpl = !!tplSelect.val(); if (lang && lang !== "ku" && !isTpl) { dfnArea.hide(); nonKuWrap.show(); } else { nonKuWrap.hide(); if (!isTpl) dfnArea.show(); } } // Store on the block so refresh() can re-sync every block when // lang changes, and restoreDfn() can re-sync after restoring. block.data("updateManeMode", updateManeMode); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || {}; // Cache of all non-placeholder option elements, so updateTplOptions // can detach/re-attach them without losing the full list. var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.attr("data-placeholder", "Li şablonekê bigere"); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (name, tpl) { // Rewiye tine, 14 Tebax 2026: "guharto? kevnbûyî? ku-Latn? // şaşnivîs? famkirina van zehmet e" — these 13 names had // zero explanation in the dropdown (unlike steps.pron's // template picker, which already shows "name — tpl.desc"). // Mirrors that same pattern here: if tpl.desc is ever // added to a tplDefs entry in data.json, it'll show up // automatically. It's optional per-entry, not required, // since data.json doesn't have desc text for these yet — // writing accurate one-line explanations for each needs // someone who actually knows what each template does. var opt = $("<option></option>") .val(name) .text(tpl.desc ? name + " — " + tpl.desc : name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); // v3: the same status-dot / 🔗 / ⓘ row treatment as every // other template picker. This one carries the bare name in // value=, so the name mapper is the identity rather than a // snippet parse. It also answers Rewiye tine's "famkirina // van zehmet e" about these thirteen names properly — the // explanation now comes from each template's own // TemplateData instead of waiting for someone to hand-write // thirteen desc strings into data.json. markTemplateOptions(tplSelect, function (opt) { return opt.val(); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible // ones — native <select> won't reliably hide options any other way. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); // Options that were detached when the descriptions arrived // missed that pass, so describe whatever is attached now. // The cache is warm by this point, so this is synchronous. applyTplDescriptions(tplSelect); tplSelect.trigger("wiktku:refresh"); if (currentVal && !currentStillValid) { tplSelect.val(""); tplTitleInput.hide().val(""); updateManeMode(); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpela hedefê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // Şablon senses have no plain gloss, so hide alternatîv/hevmane/ // dijmane/etc. Etîket, Nimûne and Jêgirtin stay visible either way. function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); nonKuWrap.hide(); tplTitleInput.show().focus(); } else { tplTitleInput.hide().val(""); updateManeMode(); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); // The template picker is an alternative to writing a // definition, not a step before it — so the box comes first // and this sits under it as a quiet link. It only expands // for the minority of senses that are a pointer at another // word (guharto, şaşnivîs, kevnbûyî) rather than a meaning. var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput) .hide(); var tplLink = $("<a href='#' class='wiktku-dfn-tpl-link'></a>") .text("Ev ne pênase ye — şablonek bi kar bîne"); tplLink.on("click", function (e) { e.preventDefault(); tplRow.show(); $(this).hide(); tplRow.find("input.wiktku-ac-input").first().focus(); }); /** Opens the picker without a click — used on restore, when a * sense already has a template and hiding it would make the * chosen value invisible. */ function revealTplRow() { tplRow.show(); tplLink.hide(); } block.data("revealTplRow", revealTplRow); block.append(dfnArea); block.append(nonKuWrap); block.append(tplLink); block.append(tplRow); // Apply lang filter on initial build. updateTplOptions(); updateManeMode(); // — Sub-field groups. — // Ghybu, 14 Tebax 2026: "Bi min beşên 'Hevmane' û dijmane jî // bike de nav beşa Mane ji ber ku pirr tên xwestin" — and, // separately, that showing all nine at once is what makes this // form read as long and tevlihev. So the four people actually // reach for (Nimûne, Jêgirtin, Hevmane, Dijmane) stay open, in // that order, and the other five sit behind the "Malûmatên // pêşketî" toggle (adv: true → .wiktku-dfn-subgroup-adv, which // is what the collapse CSS keys off now). // Jêgirtin isn't in this array — it's a compound widget built // after the loop — but it's inserted right after Nimûne so the // visible order matches the list above. var allGroups = [ { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "wekî etîket lê xuya nabe tenê kategorîze dike", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê", adv: true }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in", adv: true }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e", adv: true }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e", adv: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); if (g.adv) groupDiv.addClass("wiktku-dfn-subgroup-adv"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } // The placeholder names the current language, but that's // often not chosen yet when this block is first built — // so keep a function around that refresh() (and onSubInput, // for newly-grown fields) can call again once lang is set // or changes. function subPlaceholder() { if (g.noLangSuffix) return g.label + "…"; var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return g.label + (langLabel ? " bi " + langLabel : "") + "…"; } function updateSubPlaceholders() { list.find("> li > textarea.wiktku-dfn-subfield").attr("placeholder", subPlaceholder()); } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": ") .append($("<span></span>").addClass("wiktku-dfn-sublabel-hint").text(g.izah)); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var useModifiers = !!MODIFIER_SUBGROUPS[g.cls]; list.data("updatePlaceholders", updateSubPlaceholders); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", subPlaceholder()); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow, useModifiers); }); list.append(useModifiers ? makeModifierLi(firstInput) : $("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder group — growing list, same structure as Nimûne. — (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text("Jêgirtin")) .append(": "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<textarea></textarea>") .addClass("wiktku-dfn-subfield wiktku-dfn-quote-citoid-input") .attr("rows", 1) .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi otomatîk tijî bike", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); // Fetches citation data from Citoid and fills this citation's // şablon + fields — only rebuilds fields on template change, // and never overwrites values the user already typed. function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoid.fetchJederFields(query).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only rebuild if switching şablon, so a repeat fetch // doesn't clear fields already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel wiktku-plain-select"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); srcSel.append($("<option></option>").val("__category__").text("Ji Kategorî:Çavkanî şablonekê hilbijêre")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); // Citoid is only useful before a source is chosen — // hide it once a selection is made, restore on reset. if (chosen) { citoidWrap.hide(); } else { citoidWrap.show(); return; } if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } if (chosen === "__category__") { // Search widget over the members of [[Kategorî:Çavkanî]]. // Picking a şablon here immediately switches the row to // "Bi destê xwe binivîsim" mode with {{Şablon}} pre-filled, var catWrap = $("<span></span>").addClass("wiktku-native-select-wrap wiktku-dfn-quote-src-cat"); var catInput = $("<input type='search' autocomplete='off'>") .addClass("wiktku-start-narrow wiktku-dfn-quote-src-cat-input") .attr("placeholder", "Li navê şablonê bigere…"); var catResults = $("<ul></ul>").addClass("wiktku-ac-results wiktku-dfn-quote-src-cat-results").hide(); var catStatus = $("<span></span>").addClass("wiktku-dfn-quote-src-cat-status").text("Şablon tên barkirin…"); var showCatResults = function (query) { var q = $.trim(query).toLowerCase(); catResults.empty(); var list = catSrcTemplates || []; var matched = q ? $.grep(list, function (name) { return name.toLowerCase().indexOf(q) !== -1; }) : list; if (!matched.length) { catResults.hide(); return; } $.each(matched.slice(0, 50), function (_, name) { var li = $("<li></li>").text(name).attr("data-value", name); var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; e.preventDefault(); selectCatTpl(name); }); li.on("mousedown", function (e) { e.preventDefault(); selectCatTpl(name); }); catResults.append(li); }); catResults.show(); }; // Wraps the chosen şablon as {{Name}}, drops it into the // manual textarea, and switches the row into manual mode // so the user can keep editing it (add params, etc.). var selectCatTpl = function (name) { catResults.hide(); srcSel.val("__manual__"); srcSel.trigger("change"); srcFields.find(".wiktku-dfn-quote-src-manual") .val("{{" + name + "}}") .trigger("focus"); }; catInput.on("input", function () { showCatResults($(this).val()); }); catInput.on("focus", function () { showCatResults($(this).val()); }); catInput.on("blur", function () { setTimeout(function () { catResults.hide(); }, 200); }); catWrap.append(catInput).append(catResults).append(catStatus); srcFields.append(catWrap); fetchCatSrcTemplates().then(function () { catStatus.text(""); }, function () { catStatus.text("Şablon nehatin barkirin."); }); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (key, label) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", key) .attr("placeholder", label + "…"); // "Sernav" / "Sernavê orjînal" (title fields, e.g. for // kitêb/kovar/malper) get a taller, draggable box; every // other field in the template stays as-is. Field labels // come from the on-wiki jederDefs data, so match on the // (diacritic-folded) label text rather than a fixed key. var foldedLabel = foldDiacritics(label); if (/^sernav$/.test(foldedLabel) || /orjin/.test(foldedLabel)) { inp.addClass("wiktku-dfn-quote-src-input--title"); } row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); jederGroupDiv.append(jederLbl).append(jederList); // Straight after Nimûne rather than last: Jêgirtin is the // same kind of thing (an attested use of the word) and the // two belong together — see the allGroups comment above. var nimuneGroup = block.find(".wiktku-dfn-nimune-group"); if (nimuneGroup.length) jederGroupDiv.insertAfter(nimuneGroup); else block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); // ── "Malûmatên pêşketî" — per sense, after Dijmane ─────── // One toggle per sense rather than one for the whole step: // the fields behind it (Etîket, Kategorî, Jornav…) belong to // a single meaning, so a global switch flipped them for every // sense at once and gave a count that answered "across all // senses" — not a question anybody was asking. (function () { block.addClass("wiktku-sense-adv-hidden"); var advRow = $("<div class='wiktku-adv-toggle-row wiktku-sense-adv-row'></div>"); var advToggle = $("<a href='#' class='wiktku-adv-toggle'></a>").attr("aria-expanded", "false"); var advLabel = $("<span class='wiktku-adv-toggle-text'></span>"); advToggle.append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")).append(advLabel); var advCount = $("<span class='wiktku-adv-toggle-count'></span>"); function syncAdv() { var hidden = block.hasClass("wiktku-sense-adv-hidden"); advLabel.text(hidden ? "Malûmatên pêşketî nîşan bide" : "Malûmatên pêşketî veşêre"); advToggle.attr("aria-expanded", hidden ? "false" : "true") .toggleClass("wiktku-adv-open", !hidden); var total = 0, filled = 0; $.each(steps.dfn.ADV_SUBGROUPS, function (_, cls) { total++; var any = false; block.find("." + cls + "-group textarea").each(function () { if ($.trim($(this).val())) { any = true; return false; } }); if (any) filled++; }); advCount.text(total + " zevî · " + filled + " tije"); } advToggle.on("click", function (e) { e.preventDefault(); block.toggleClass("wiktku-sense-adv-hidden"); syncAdv(); }); block.on("input", "textarea", syncAdv); block.data("syncSenseAdv", syncAdv); advRow.append(advToggle).append(advCount); // After the last always-visible group (Dijmane) and before // the advanced ones, which sit below it in DOM order. var lastPrimary = block.find(".wiktku-dfn-dijmane-group"); if (lastPrimary.length) advRow.insertAfter(lastPrimary); else block.append(advRow); syncAdv(); }()); // ── Accordion wrapper (v3 spec) ────────────────────────── // Everything built above becomes the collapsible body, and a // header row goes in front of it. Done here, at the end, // rather than by threading a container through the ~500 lines // of field-building above — every one of those appends to // `block`, and getSenses/restoreDfn reach fields with .find(), // which doesn't care how deep they sit. var body = $("<div class='wiktku-dfn-sense-body'></div>").append(block.children()); var header = $("<div class='wiktku-dfn-sense-header'></div>"); header .append($("<span class='wiktku-dfn-sense-num'></span>")) .append($("<span class='wiktku-dfn-sense-title'></span>")) .append($("<span class='wiktku-dfn-sense-summary'></span>")) .append($("<span class='wiktku-dfn-sense-chevron'>▾</span>")); header.on("click", function () { // Collapsed → open it (and close whichever was open). // Open → collapse it, unless it's the only one. if (block.hasClass("wiktku-sense-collapsed")) steps.dfn.setOpenSense(stepDiv, block); else block.addClass("wiktku-sense-collapsed"); steps.dfn.syncSenseHeaders(stepDiv); }); block.append(header).append(body); // Typing (or clicking) anywhere in a sense makes it the open // one — "tenê maneya ku tê nivîsandin vekirî ye". body.on("focusin", function () { if (!block.hasClass("wiktku-sense-collapsed")) { steps.dfn.setOpenSense(stepDiv, block); } }); return block; }, /** True if a sense block has anything worth summarising. */ senseBlockHasContent: function (block) { var found = false; block.find("textarea, input[type='text']").each(function () { if ($.trim($(this).val() || "")) { found = true; return false; } }); if (found) return true; return !!block.find(".wiktku-dfn-tpl-select").val(); }, /** Opens `block` and collapses every other sense that has content. * A sense with nothing in it is never collapsed — the trailing * empty one is how you add the next meaning, so hiding it would * hide the only way forward. */ setOpenSense: function (stepDiv, block) { stepDiv.find("li.wiktku-dfn-sense").each(function () { var li = $(this); var collapse = !li.is(block) && steps.dfn.senseBlockHasContent(li); li.toggleClass("wiktku-sense-collapsed", collapse); }); steps.dfn.syncSenseHeaders(stepDiv); }, /** Renumbers the sense badges and refreshes each collapsed row's * one-line summary. Cheap enough to just re-run on any change. */ syncSenseHeaders: function (stepDiv) { stepDiv.find("li.wiktku-dfn-sense").each(function (i) { var li = $(this); li.find("> .wiktku-dfn-sense-header .wiktku-dfn-sense-num").text(i + 1); li.find("> .wiktku-dfn-sense-header .wiktku-dfn-sense-title").text("Mane " + (i + 1)); var summary = $.trim(li.find("textarea.wiktku-dfn-mane").first().val() || ""); if (!summary) { // A template sense has no prose — show the call itself. var tpl = li.find(".wiktku-dfn-tpl-select").val(); var title = $.trim(li.find(".wiktku-dfn-tpl-title").val() || ""); if (tpl) summary = "{{" + tpl + (title ? "|" + title : "") + "}}"; } summary = summary.split("\n")[0]; if (summary.length > 70) summary = summary.slice(0, 70) + "…"; li.find("> .wiktku-dfn-sense-header .wiktku-dfn-sense-summary").text(summary); }); }, /** Keeps the header summary in step with what is being typed. * No longer grows the list: a second sense appears only when * "+ Mane zêde bike" is clicked. Auto-growing meant every entry * with one meaning still showed an empty second one, which reads * as an unfinished form. */ onDfnInput: function (stepDiv, block, textarea) { steps.dfn.syncSenseHeaders(stepDiv); refresh(); }, /** Appends a sense, opens it, and collapses the others. */ addSense: function (stepDiv) { var list = stepDiv.find("ol.wiktku-dfn-list"); var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); initSelects(newBlock); steps.dfn.setOpenSense(stepDiv, newBlock); newBlock.find("textarea.wiktku-dfn-mane").first().focus(); refresh(); return newBlock; }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow, modifiers) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow, modifiers); }); list.append(modifiers ? makeModifierLi(next) : $("<li></li>").append(next)); // New field starts with no placeholder — give it (and any // others in the list) the current one. var updatePlaceholders = list.data("updatePlaceholders"); if (typeof updatePlaceholders === "function") updatePlaceholders(); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: {}, posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; // Rewiye tine, 14 Tebax 2026: "şablonên mana jî dikare serê // yekî tevlîhev bike... famkirina van zehmet e" — the "an jî // şablonek hilbijêre" dropdown inside each sense (guharto, // kevnbûyî, ku-Latn, şaşnivîs, …) had no explanation at all. // One reassurance, shown once for the whole Mane step rather // than repeated per sense: it's optional, plain text is the // normal path. if (!stepDiv.find(".wiktku-dfn-tpl-hint").length) { stepDiv.append( $("<p class='wiktku-step-hint wiktku-dfn-tpl-hint'></p>").text( "Ji bo her maneyekê, dropdown-a \"an jî şablonek hilbijêre\" ne mecbûrî ye — bi gelemperî tu tenê maneyê bi tîpên asayî dinivîsî. Ew şablon tenê ji bo rewşên taybet in (mînak: guherto, kevnbûyî, şaşnivîs); heke tu nizanî kîjan divê, vale bihêle." ) ); } var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); var addSenseBtn = $("<button type='button' class='wiktku-add-sense'></button>") .append($("<span class='wiktku-add-sense-plus'>+</span>")) .append(document.createTextNode("Mane zêde bike")); addSenseBtn.on("click", function (e) { e.preventDefault(); steps.dfn.addSense(stepDiv); }); stepDiv.append(addSenseBtn); steps.dfn.syncSenseHeaders(stepDiv); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName === "__category__") { // Reachable only if the user opened the category search but // never picked a şablon — picking one switches the row to // __manual__ (see selectCatTpl above), so there's nothing // meaningful to save here. } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: readList("wiktku-dfn-etiket"), kategori: readList("wiktku-dfn-kategori"), nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense var izahLines = []; // parallel — raw îzah gloss for that same sense // True only once some sense's *actual* dfn text (post tercime/îzah // split) is non-empty. var hasLinkableMane = false; $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("# " + (tplKatTpl ? tplKatTpl + " " : "") + (tplLabelTpl ? tplLabelTpl + " " : "") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(""); // template senses have no îzah return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty // Pull the îzah gloss (if any) out of the combined tercime+îzah // string — it's spliced back in separately below, after its // own linkify pass (see izahLines / the second linkifyText call). var izahRaw = null; var tercimeIzah = splitTercimeIzah(dfn); if (tercimeIzah) { dfn = tercimeIzah.tercime; izahRaw = stripWikilinks(tercimeIzah.izah); } if (dfn) { dfn = stripWikilinks(dfn); // Sentence-case + trailing period are for ku definitions, // which are written as full glosses. if (lang === "ku") { if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } // Real prose — this is what makes the sense worth running // through the main linkify pass. hasLinkableMane = true; } else if (izahRaw === null) { // No mane at all — this is just the "{{mane?|lang}}" // placeholder, a bare template call with no plain words // in it. Do NOT count it as linkable: sending nothing but // bracketed templates through the main linkify pass hangs // the linkify gadget (see the hasLinkableMane/hasIzah // check below). dfn = lang === "ku" ? "{{mane?|" + lang + "}}" : ""; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var out = "# " + (katTpl ? katTpl + " " : "") + (labelTpl ? labelTpl + " " : "") + dfn; var idx = defLines.length; var hasThisIzah = izahRaw !== null && $.trim(izahRaw) !== ""; // Bare {{...}} token — like {{wiktku-cite-N}}, this survives // linkify's first pass untouched (it treats template calls as // opaque), then gets swapped for {{îzah|…}} once the actual // gloss text has been linkified in its own separate pass. if (hasThisIzah) { out += (dfn ? " " : "") + "{{wiktku-izah-" + idx + "}}"; } function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(hasThisIzah ? izahRaw : ""); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } // Runs text through the linkify gadget if it's loaded, otherwise // just passes it through unchanged. Shared by both linkify passes // below (main mane text, and — separately — îzah glosses). function linkifyText(t, cb) { if (typeof $.kuLinkify === "function") { $.kuLinkify(t, cb); } else { cb(t); } } var hasIzah = izahLines.some(function (t) { return t && $.trim(t) !== ""; }); var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with nimûne?. text = "# {{mane?|" + lang + "}}\n#* {{nimûne?|" + lang + "}}\n"; callback(text); return; } // Runs the îzah-only linkify pass against `base` (either the raw // text, when there's no linkable mane to run the main pass on // first, or the already-linkified main text). Shared by both // branches below so the token-splice logic only lives once. function runIzahPass(base) { var izahJoined = $.map(izahLines, function (raw, idx) { if (!raw) return undefined; return "{{wiktku-izah-open-" + idx + "}}" + raw + "{{wiktku-izah-close-" + idx + "}}"; }).join("\n"); linkifyText(izahJoined, function (izahLinked) { var izahByIdx = {}; var re = /\{\{wiktku-izah-open-(\d+)\}\}([\s\S]*?)\{\{wiktku-izah-close-\1\}\}/g; var m; while ((m = re.exec(izahLinked)) !== null) { izahByIdx[parseInt(m[1], 10)] = m[2]; } var withIzah = base.replace(/\{\{wiktku-izah-(\d+)\}\}/g, function (_, n) { var linked = izahByIdx[parseInt(n, 10)]; return linked !== undefined ? "{{îzah|" + linked + "}}" : ""; }); callback(restoreCites(withIzah)); }); } if (!hasLinkableMane) { if (!hasIzah) { // All filled senses are template senses (or otherwise have // no plain text at all) — nothing here needs linkify. callback(restoreCites(text)); return; } // There's no plain mane text anywhere (e.g. tercime left blank // with only îzah filled in), so every defLine is just a bare // template call with nothing to word-link. Sending a line // like "# {{wiktku-izah-0}}" through the main linkify pass // gives it no plain words to work with, makes the linkify // gadget hang — so skip that pass entirely and run only // the îzah pass, splicing straight into the unlinkified text. var loadIzahOnly = function () { runIzahPass(text); }; mw.loader.using("ext.gadget.linkify", loadIzahOnly, loadIzahOnly); return; } var didTryToLoad = function () { // First pass: the main definition text (mane), same as before. linkifyText(text, function (mainLinked) { if (!hasIzah) { callback(restoreCites(mainLinked)); return; } // Second pass: îzah glosses, linkified via their own // separate call. Each gloss is wrapped in its own // {{wiktku-izah-open/close-N}} pair; like the existing // {{wiktku-cite-N}} tokens, these sit inside double // braces so linkify leaves the tokens themselves alone — // only the raw gloss text between each pair gets linked. runIzahPass(mainLinked); }); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, tewandin: { id: "tewandin", name: "tewandin", question_fmt: 'Tewandina "' + pageName + '" binivîse', visible: function (values) { return values.lang && values.pos; }, build: function (stepDiv) { if (stepDiv.find(".wiktku-tewandin-wrap").length) return null; var wrap = $("<div class='wiktku-tewandin-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-tewandin-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-tewandin-text") .attr("rows", 4) .attr("placeholder", "{{ku-tewîn-nav|nêr}}"); wrap.append(ta); stepDiv.append(wrap); function autoPopulate() { if (!ta.length) return; var vals = getValues(); var c = vals.cinsiyet || ""; var p = vals.pos || ""; if (!pageName.includes(" ") && c && GENDER_BASE_LABELS[c] && (p === "navdêr" || p === "serenav") && vals.lang === "ku" && c !== "mndudil") { var label = (c === "mnmane") ? "mê û nêr" : GENDER_BASE_LABELS[c]; var out = "{{ku-tewîn-nav|" + label; if (p === "serenav") out += "|y"; out += "}}"; if (!$.trim(ta.val())) ta.val(out); } } setTimeout(function () { autoPopulate(); $("#wiktku-start-form").on("change.tewandin", "#wiktku-start-lang-field, #wiktku-start-cinsiyet-field, #wiktku-start-pos-field", autoPopulate); }, 0); return ta; }, output: function () { var manualText = $.trim($("#wiktku-start-tewandin .wiktku-tewandin-text").val()); if (manualText) { return "\n==== Tewandin ====\n" + manualText + "\n"; } return ""; } }, // resim — one or more images resim: { id: "resim", name: "resim", question_fmt: "Resmekê lê zêde bike", visible: function (values) { return !!(values.lang && values.pos); }, /** Builds one image row: filename + caption + alt text. */ buildItem: function (stepDiv) { var item = $("<li class='wiktku-resim-item'></li>"); var fileRow = $("<div class='wiktku-posparams-row'></div>"); var fileInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-file") .attr("placeholder", "navê_dosyayê.jpg"); fileRow.append($("<label></label>").text("Navê dosyayê: ")).append(fileInp); var capRow = $("<div class='wiktku-posparams-row'></div>"); var capInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-caption") .attr("placeholder", "Danasîna resimê…"); capRow.append($("<label></label>").text("Danasîn: ")).append(capInp); // Alt text: what a screen reader announces for this image var altRow = $("<div class='wiktku-posparams-row'></div>"); var altInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-alt") .attr("placeholder", "Ji bo kesên nabînin, çi tê dîtin? (ne mecbûrî)"); altRow.append($("<label></label>").text("Nivîsa alternatîf: ")).append(altInp); // Auto-fill the caption with the plain page name when a filename // is typed fileInp.on("input", function () { var file = $.trim($(this).val()); var curCap = $.trim(capInp.val()); var isDefault = !curCap || curCap === pageName; if (file && isDefault) { capInp.val(pageName); } else if (!file && isDefault) { capInp.val(""); } steps.resim.onFileInput(stepDiv, item, this); }); item.append(fileRow).append(capRow).append(altRow); return item; }, /** Grows the image list when the last row's filename gets content. */ onFileInput: function (stepDiv, item, input) { var val = $.trim($(input).val()); var list = stepDiv.find("ol.wiktku-resim-list"); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { list.append(steps.resim.buildItem(stepDiv)); } }, build: function (stepDiv) { if (stepDiv.find(".wiktku-resim-wrap").length) return null; var wrap = $("<div class='wiktku-resim-wrap'></div>"); var list = $("<ol class='wiktku-resim-list'></ol>"); list.append(steps.resim.buildItem(stepDiv)); wrap.append(list); stepDiv.append(wrap); return null; }, /** Reads every filled row from the DOM into an array of {file, caption, alt} * objects — blank rows (missing filename or caption) are skipped. * Non-Kurdish captions get wrapped in {{zim|lang|…}} here, unless * the user already typed their own {{zim|…}} template. Alt text is * optional and left as plain text either way. */ getImages: function (values) { var lang = (values && values.lang) || getValues().lang || ""; var images = []; $("#wiktku-start-resim li.wiktku-resim-item").each(function () { var file = $.trim($(this).find(".wiktku-resim-file").val()); var caption = $.trim($(this).find(".wiktku-resim-caption").val()); var alt = $.trim($(this).find(".wiktku-resim-alt").val()); if (!file || !caption) return; // Strip leading "Wêne:" or "File:" if the user typed it — we add it ourselves. file = file.replace(/^(wêne|file|image)\s*:\s*/i, ""); if (lang && lang !== "ku" && !/^\{\{zim\s*\|/i.test(caption)) { caption = "{{zim|" + lang + "|" + caption + "}}"; } images.push({ file: file, caption: caption, alt: alt }); }); return images; }, output: function (values) { var images = steps.resim.getImages(values); if (!images.length) return ""; return images.map(function (img) { var altPart = img.alt ? "|alt=" + img.alt : ""; return "[[Wêne:" + img.file + "|thumb" + altPart + "|" + img.caption + "]]"; }).join("\n") + "\n"; } }, // bnr-h — {{bnr-h|Page1|Page2|…}} prepended before the lang section (shared, not per-section) bnrh: { id: "bnrh", name: "binêre herwiha (bnr-h)", question_fmt: "Şablona bnr-h li qismê herî jor a rûpelê", //visible: function (values) { return !!values.lang; }, multiple: true, narrow: true, placeholder: "Ji bo 'test' bnr 'Test', 'teşt'", output: function (values) { var pages = $.grep(values.bnrh || [], function (p) { return !!$.trim(p); }); if (!pages.length) return ""; return "{{bnr-h|" + pages.map(function (p) { return $.trim(p); }).join("|") + "}}\n"; } }, bikaranin: { id: "bikaranin", name: "Notên bikaranînê", question_fmt: "Notên bikaranînê yên li ser vê kelîmeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, output: function (values) { var text = $.trim(values.bikaranin || ""); if (!text) return ""; return "\n==== Notên bikaranînê ====\n" + text + "\n"; }, }, xwendin: { id: "xwendin", name: "Bêhtir bixwîne", question_fmt: "Lînkên derveyî eleqedarî vê madeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: function (values) { if (!values || !values.lang) { return `* {{wpedî}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; } const ziman = values.lang === "ku" ? "" : `|ziman=${values.lang}`; return `* {{wpedî${ziman}}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; }, output: function (values) { var text = $.trim(values.xwendin || ""); if (!text) return ""; return "\n==== Bêhtir bixwîne ====\n" + text + "\n"; }, }, alfabeyendin: { id: "alfabeyendin", name: "Bi alfabeyên din", question_fmt: function (values) { var base = "Nivîsîna vê kelîmeyê bi alfabeyên din" var langLabel = values.lang ? getLangLabel(values.lang) : ""; if (langLabel) { return base + " ên " + langLabel; } return base; }, visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: "Ji bo kurmancî: * {{ku-ar|şiklê alfaba erebî}}", output: function (values) { var text = $.trim(values.alfabeyendin || ""); if (!text) return ""; return "\n==== Bi alfabeyên din ====\n" + text + "\n"; }, }, formalt: makeWordListStep("formalt", "formên alternatîv", "Formên alternatîv ên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), hevmane: makeWordListStep("hevmane", "hevmane", "Hevmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), dijmane: makeWordListStep("dijmane", "dijmane", "Dijmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jornav: makeWordListStep("jornav", "jornav", "Jornavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jernav: makeWordListStep("jernav", "jêrnav", "Jêrnavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse"), binereherwiha: makeWordListStep("binereherwiha", "herwiha binêre", "Kelîmeyên din ên eleqedar binivîse"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: {}, visible: function (values) { return values.lang && values.pos; }, // Fills the insert-dropdown from the current etymTpls object. refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(ta); stepDiv.append(wrap); initSelects(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder. // Skip it only when every filled sense is a şablon sense // a completely empty entry with no şablon chosen still gets the placeholder var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasFilledTplSense = dfnSenses.some(function (s) { return !!s.tpl && !!s.tplTitle; }); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (hasFilledTplSense && !hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: function (values) { return {"navz": true, [values.lang]: true} }, // Language dropdown + growing word-input list; a new row appends // when the dropdown gets a value. Mirrors steps.trans, but flat. buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/build below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Attach the searchable picker now the select is in the DOM. initSelects(list); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", question_fmt: "'"+ pageName + "' di zaravayên din de çawa tê gotin?", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: {}, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zaravayekî bigere"); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; // Item 6 (Wikihez, 14 Tebax 2026): "Bi zaravayên din" now // auto-appears empty for lang=ku exactly like Werger // already does (steps.trans.output, same rule below) — // a completely empty entry still gets a placeholder // section to fill in later; an individual placeholder // gloss is only skipped once some other sense already has // real content, making that particular one redundant. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", question_fmt: "Tercimeyên vê maneyê bi zimanên din binivîse", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide only when every sense is a filled template sense (no plain // gloss to attach translations to). A mix, or nothing filled in // yet, still shows Werger. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, // Language dropdown + growing word-input list, scoped to one gloss's // group (each gloss has its own group and row list). buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/buildGroup below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, // Builds (or fetches) the .wiktku-trans-group for one gloss. buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, // Syncs one .wiktku-trans-group per current gloss, keyed by // data-gloss-pos so groups stay matched across rebuilds. build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, // Reads all translation rows, grouped by gloss position. getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, // Builds the numbered "{ index, gloss }" list, one per dfn sense // with a real mane (skips template senses). index is 1-based and // matches the sense's position in the "#" definition list. // When nothing's filled in, returns one placeholder entry so // Werger still has a group to attach to; when every sense is a // filled template sense, stays empty (matches trans.visible()). glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane, but other fields are filled — still gets a // gloss group since dfn.getOutput() emits {{mane?}} for it. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // A completely empty entry (nothing filled in dfn at all, no // şablon chosen either) still gets a placeholder Werger section // to fill in later. Only // skip an individual placeholder gloss below when some other // sense actually has real content, making that particular // placeholder redundant. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it. If some other sense already has real // content, this placeholder is redundant — skip it. If the // whole entry is empty, keep it so Werger still gets a // section to fill in. if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, cavkani: { id: "cavkani", name: "çavkanî", question_fmt: "Çavkaniyên din (ne jêgirtin) lê zêde bike", visible: function (values) { return !!values.pos; }, // Fills the insert-dropdown from the members of [[Kategorî:Çavkanî]]. refreshTplSelect: function () { var sel = $("#wiktku-start-cavkani .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(catSrcTemplates || [], function (_, name) { sel.append($("<option></option>").val(name).text(name)); }); markTemplateOptions(sel, function (opt) { return opt.val(); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-cavkani-wrap").length) return null; var wrap = $("<div class='wiktku-cavkani-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-cavkani-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-cavkani-text") .attr("rows", 4) .attr("placeholder", "Şablonekî ji lîsteyê hilbijêre an rasterast binivîse…"); // Template insert dropdown, populated from [[Kategorî:Çavkanî]] — // options refreshed once the category members are fetched. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var status = $("<span class='wiktku-cavkani-status'></span>"); sel.on("change", function () { var name = $(this).val(); if (!name) return; insertAtCursor(ta[0], "\n* {{" + name + "}}"); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(status).append(ta); stepDiv.append(wrap); // build() runs again for every new beş (see the "+ Beş zêde bike" // handler), after the initial page-wide pass — so this select needs // its own init or it stays a plain, unsearchable native <select>. initSelects(wrap); if (catSrcTemplates) { steps.cavkani.refreshTplSelect(); } else { status.text("Şablon tên barkirin…"); fetchCatSrcTemplates().then(function () { steps.cavkani.refreshTplSelect(); status.text(""); }, function () { status.text("Şablon nehatin barkirin."); }); } return ta; }, output: function () { var text = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); if (!text) return ""; return "\n==== Çavkanî ====\n" + text + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); // Ghybu, 14 Tebax 2026: bnrh/resim/pron used to sit here, always visible, // well above the tab bar (which starts right before "dfn"). They're now // tab-gated (see STEP_GROUPS below), so their DOM position moves down to // sit right next to it instead of rendering as always-open fields between // Ziman and Cureyê rêzimanî. This array only controls DOM build order — // nothing else keys off it (see the comment above stepIdToGroup). // Wikihez, 14 Tebax 2026: Mane tab's internal order is now Mane → malûmatên // pêşketî (nested inside dfn's own div, see steps.dfn.build) → Wêne → // Bi zaravayên din → Werger, so dfn/resim/zarava/trans need to sit // adjacent to each other, in that order, in the DOM. zarava/trans moved // out of the "Beşên din" cluster entirely — see STEP_GROUPS below. var ordered_steps = [ steps.lang, steps.pos, steps.posparams, steps.cinsiyet, steps.jimar, steps.lektur, steps.tr, // Mane tab, in reading order: the senses, then the two things that // belong to the entry as a whole rather than to one sense. steps.dfn, steps.tewandin, steps.alfabeyendin, steps.zarava, steps.trans, // Etîmolojî tab. steps.etym, steps.dunde, // Eleqedar tab — three lists of the same shape. steps.je, steps.tekildar, steps.binereherwiha, // Bilêvkirin: no longer in a tab at all (see PRON_SECTION_ID) — it // still needs a slot here because this array is what builds the DOM. steps.pron, // Beşên din, behind the picker. steps.resim, steps.bnrh, steps.bikaranin, steps.formalt, steps.hevmane, steps.dijmane, steps.jornav, steps.jernav, steps.cavkani, steps.xwendin]; // ── Step-group tabs ────────────────────────────────────────────────────── // Ghybu, 14 Tebax 2026 (revised): originally 5 tabs (Bingehîn/Bilêvkirin/ // Lînkkirin/Bikaranîn/Din), split by topic. Ghybu's follow-up flattened // that to exactly 3: "Mane", "Bilêvkirin", "Beşên din" ("other // sections") — with Wêne and Nimûne folded INTO "Mane" specifically // (not left in a misc tab), and everything that isn't Mane/Bilêvkirin // dumped into one single "Beşên din" catch-all rather than split across // topic tabs. Nimûne doesn't appear below as its own entry because it's // not a separate step — it's already rendered inside each dfn/Mane // sense block (see buildSenseBlock's allGroups), so it's under "Mane" // automatically. "mane" stays first (and so the default-active tab) // since required content — Mane itself — has to be what's seen by // default. // Wikihez, 14 Tebax 2026: zarava/trans moved from "besendin" into "mane" — // both are already gated to lang===ku (zarava.visible just delegates to // trans.visible), so they show/hide automatically with no picker // involvement, same as before; they just render inside the Mane tab // now instead of behind the Beşên din picker (see openedOtherSections // below, which only applies to "besendin" members). // Wikihez, 15 Tebax 2026: pared back again after Ghybu's "Tu jî dizanî ku // kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > // Dijmane". That path is now what the form shows by default and nothing // else: Mane holds the senses (whose own blocks carry Nimûne, Jêgirtin, // Hevmane and Dijmane — see steps.dfn.allGroups) plus Werger. Wêne and // "Bi zaravayên din" moved out to the Beşên din picker with everything // else; they aren't gone, they're one dropdown pick away. // v3 spec (15 Tebax 2026): four tabs instead of three, and Bilêvkirin // leaves the tab bar entirely. // // The Beşên din picker had grown to eighteen entries, which is its own // kind of "where do I find anything" problem — splitting the two // obvious clusters out as their own tabs is what fixes that: // Etîmolojî — where the word came from, and what came from it // Eleqedar — the three "related words" lists, which are the same // shape as each other and nothing like the rest // Tewandin moves into Mane and out from behind the picker: it is // commonly wanted and it belongs with the senses it inflects. Note this // is a PLACEMENT change only — Tewandin keeps its own free-text // {{ku-tewîn-nav}} field and does NOT absorb the Cins/zayend form // parameters (m=/n=/p=), which stay on the headword template where // they belong. The v3 mock merged the two; Wikihez rejected that. var STEP_GROUPS = [ { id: "mane", label: "Mane", steps: ["dfn", "tewandin", "alfabeyendin", "zarava", "trans"] }, { id: "etimoloji", label: "Etîmolojî", steps: ["etym", "dunde"] }, { id: "eleqedar", label: "Eleqedar", steps: ["je", "tekildar", "binereherwiha"] }, { id: "besendin", label: "Beşên din", steps: ["resim", "formalt", "hevmane", "dijmane", "jornav", "jernav", "bikaranin", "cavkani", "xwendin", "bnrh"] }, ]; // Steps that live behind the "Beşên din" picker — only these need an // explicit "open" before they're shown, even when their tab is active. // Derived from the group above so it can't drift out of sync. var BESENDIN_STEP_IDS = STEP_GROUPS[3].steps; // Reverse lookup: step id -> index into STEP_GROUPS (undefined for // ungrouped steps — now only lang/pos/posparams/cinsiyet/lektur/tr, // which stay always-visible since they're required to get to everything // else). var stepIdToGroup = {}; $.each(STEP_GROUPS, function (gi, g) { $.each(g.steps, function (_, sid) { stepIdToGroup[sid] = gi; }); }); // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "posparams", "cinsiyet", "jimar", "lektur", "tr", "resim", "dfn", "tewandin", "formalt", "bikaranin", "alfabeyendin", "hevmane", "dijmane", "jornav", "jernav", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans", "cavkani", "xwendin" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; // ── Bilêvkirin as a standalone section (v3 spec) ───────────────────── // Pronunciation belongs to the word, not to one part of speech, so it // sits beside Navdêr/Lêker in the section tab bar rather than inside // any of them, and is added once from "+ Beş zêde bike". // // Modelled as a flag rather than an entry in `sections`: activeSection // is used as an array index in a dozen places (saveCurrentSection, // restoreSection, sections[activeSection]…), and making it sometimes a // string would mean auditing all of them. Viewing Bilêvkirin instead // leaves activeSection pointing at the POS section you were on, so // coming back is free and nothing else has to change. // Always in the tab bar, and first — pronunciation applies to the whole // word, so it reads as the thing that comes before any part of speech // rather than an optional extra you have to know to add. Its content // only appears once you click it, like any other tab. var viewingPron = false; // is it the tab currently on screen // Which STEP_GROUPS tab is currently shown. Lives out here (like // activeSection above) so refresh() — which is not nested inside build() // — can read it and so renderGroupTabs()/updateGroupTabIndicators() below // can be called from refresh() too. Both operate on the tab bar via its // #wiktku-group-tabs id rather than a closured element reference, for the // same reason. var activeGroup = 0; // Unsaved-changes / autosave state. Lives out here (same reason as // activeGroup above) so destroy() — which runs on final submit and on // switching to the source editor, and is not nested inside build() — // can clear the timers and the beforeunload warning. build() assigns // into these; it doesn't re-declare them. var formDirty = false; var autosaveDebounceTimer = null; var autosaveInterval = null; /** Re-renders the step-group tab bar to reflect the current activeGroup. */ function renderGroupTabs() { var groupTabsDiv = $("#wiktku-group-tabs"); if (!groupTabsDiv.length) return; groupTabsDiv.empty(); $.each(STEP_GROUPS, function (i, g) { var tab = $("<span></span>") .addClass("wiktku-group-tab") .attr("data-group-idx", i) .text(g.label) .toggleClass("wiktku-tab-active", i === activeGroup); (function (idx) { tab.on("click", function () { if (idx === activeGroup) return; activeGroup = idx; renderGroupTabs(); if (idx === BESENDIN_GROUP_IDX) renderBesenDinPicker(); refresh(); }); }(i)); groupTabsDiv.append(tab); }); } /** * Toggles a "needs attention" dot on any group tab that still has a * required, unfilled field hidden inside it — so switching tabs doesn't * leave the person wondering why "Bişîne" stays disabled. */ function updateGroupTabIndicators(values) { var tabs = $("#wiktku-group-tabs .wiktku-group-tab"); if (!tabs.length) return; $.each(STEP_GROUPS, function (i, g) { var missing = false; $.each(g.steps, function (_, sid) { var step = steps[sid]; if (!step || !step.required) return; var val = values[sid]; if (val === "" || (step.multiple && $.isArray(val) && val.join("") === "")) { missing = true; } }); tabs.eq(i).toggleClass("wiktku-tab-missing", missing && i !== activeGroup); }); } // Wikihez, 14 Tebax 2026: "Beşên din" no longer shows all 16 fields // stacked at once — a picker reveals one at a time instead. This is // per-section state (like the field values themselves), snapshotted in // saveCurrentSection() and restored in restoreSection() below, and // auto-seeded from any field that already has content (so a returning // draft, or an older cache saved before this existed, doesn't hide // something the person already filled in). var openedOtherSections = {}; var BESENDIN_SET = {}; $.each(BESENDIN_STEP_IDS, function (_, sid) { BESENDIN_SET[sid] = true; }); // "besendin"'s index in STEP_GROUPS. Derived rather than hardcoded — // this was a literal 2 and silently pointed at the wrong tab the moment // Etîmolojî and Eleqedar were inserted ahead of it. var BESENDIN_GROUP_IDX = (function () { for (var i = 0; i < STEP_GROUPS.length; i++) { if (STEP_GROUPS[i].id === "besendin") return i; } return STEP_GROUPS.length - 1; }()); /** Re-renders the "Beşên din" picker to list only the not-yet-opened sections. */ function renderBesenDinPicker() { var wrap = $("#wiktku-besendin-picker"); if (!wrap.length) return; wrap.empty(); var pickerValues = getValues(); var unopened = $.grep(BESENDIN_STEP_IDS, function (sid) { if (openedOtherSections[sid]) return false; // Don't offer a section that would open onto nothing: several of // these are gated (Bi zaravayên din / Werger need lang=ku, most // need a pos). refresh() would hide it again straight away, so // picking it would read as a broken dropdown. var step = steps[sid]; if (step && typeof step.visible === "function") { try { if (!step.visible(pickerValues)) return false; } catch (e) { /* a step whose visible() needs DOM we lack yet — offer it */ } } return true; }); if (!unopened.length) return; // everything's open — nothing left to pick var sel = $("<select class='wiktku-besendin-select'></select>"); sel.attr("data-placeholder", "— beşek hilbijêre —"); sel.append($("<option value=''>— beşek hilbijêre —</option>")); $.each(unopened, function (_, sid) { var step = steps[sid]; if (!step) return; sel.append($("<option></option>").val(sid).text(capitalize(step.name))); }); sel.on("change", function () { var sid = $(this).val(); if (!sid) return; openedOtherSections[sid] = true; renderBesenDinPicker(); refresh(); }); wrap.append(sel); initSelects(wrap); } /** Marks any BESENDIN_STEP_IDS field that already has real content as * "opened", so restoring a draft doesn't bury filled-in sections behind * the picker. Reuses each step's own output() as the emptiness check — * it already knows what "empty" means per field, and it reads the DOM * the restore just populated. Call this AFTER the DOM has the restored * values in it. */ function seedOpenedFromContent() { var values = getValues(); $.each(BESENDIN_STEP_IDS, function (_, sid) { if (openedOtherSections[sid]) return; var step = steps[sid]; if (!step || typeof step.output !== "function") return; try { if (step.output(values)) openedOtherSections[sid] = true; } catch (e) { /* a step whose output() needs more state than we have yet — skip it */ } }); } function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } // Rebuilds the dfn DOM from a previously snapshotted senses array. function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. The // "+ Mane zêde bike" button goes with it — build() re-appends both, // and leaving the old one behind would both duplicate it and put it // above the rebuilt list. stepDiv.find("ol.wiktku-dfn-list").remove(); stepDiv.find(".wiktku-add-sense").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); // The picker is collapsed behind a link by default; a restored // sense that already uses a template has to show it, or the // chosen template is invisible and looks lost. var reveal = block.data("revealTplRow"); if (typeof reveal === "function") reveal(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // dfnArea is the only thing actually saved, so split it back into // tercime/îzah for editing (mirrors syncNonKuToMane's join format). var maneParts = splitTercimeIzah(sense.mane); block.find(".wiktku-dfn-tercime").val(maneParts ? maneParts.tercime : (sense.mane || "")); block.find(".wiktku-dfn-izah").val(maneParts ? maneParts.izah : ""); // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Same for the mane-box mode (plain vs tercime+îzah), since this // also depends on tplSelect's (and lang's) value. var updateMane = block.data("updateManeMode"); if (updateMane) updateMane(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found var useModifiers = !!MODIFIER_SUBGROUPS[cls]; // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true, useModifiers); }); subList.append(useModifiers ? makeModifierLi(ta) : $("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text).each(function () { highlightLinebreak(this); }); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder entries — accepts current array shape or a legacy // single object (older saved sections) for backwards compat. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote).each(function () { highlightLinebreak(this); }); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederCatTpl) { // Legacy format from before the şablon search switched rows to // manual mode directly — convert it the same way now, so it's // editable like any other free-form source. var catSelEl = li.find(".wiktku-dfn-quote-src-sel"); catSelEl.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val("{{" + j.jederCatTpl + "}}"); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); // Numbers and one-line summaries for the freshly rebuilt blocks, and // collapse everything that has content — on a restored draft nothing // is "the sense being edited" yet, so a five-sense entry would // otherwise come back fully expanded, which is the state this // accordion exists to avoid. steps.dfn.syncSenseHeaders(stepDiv); stepDiv.find("li.wiktku-dfn-sense").each(function () { var li = $(this); li.toggleClass("wiktku-sense-collapsed", steps.dfn.senseBlockHasContent(li)); }); } // Snapshots simple (non-dfn) per-section steps from the DOM into obj. function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } if (id === "cavkani") { snap.cavkani = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); return; } if (id === "posparams") { snap.posparams = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); return; } if (id === "resim") { // One entry per row, including blank ones, so a mid-edit draft // (e.g. a filename typed but no caption yet) survives a cache // restore instead of being silently dropped. snap.resim = $("#wiktku-start-resim li.wiktku-resim-item").map(function () { return { file: $.trim($(this).find(".wiktku-resim-file").val()), caption: $.trim($(this).find(".wiktku-resim-caption").val()), alt: $.trim($(this).find(".wiktku-resim-alt").val()) }; }).get(); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); // Item 3: which "Beşên din" sub-sections this section has already // opened via the picker — per-section, like everything else here. snap.openedOtherSections = $.extend({}, openedOtherSections); sections[activeSection] = snap; } // Restores a previously saved snapshot into the form DOM. function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); $("#wiktku-start-cavkani .wiktku-cavkani-text").val(snap.cavkani || ""); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); steps.posparams.build(ppDiv); var savedTa = snap.posparams || ""; ppDiv.find(".wiktku-posparams-text").val(savedTa); // Re-parse saved textarea to restore helper widget states. if (savedTa) { var cMatch = savedTa.match(/\|c=([^|}\s]+)/); var jMatch = savedTa.match(/\|j=([^|}\s]+)/); var trMatch = savedTa.match(/\|tr=([^|}\s]+)/); // Write into the shared hidden field (not the visible // select, which has no <option>s yet) — syncHelpers() // below reads it back to restore the dropdown once the // gender/number options for this language are populated. if (cMatch) $("#wiktku-start-cinsiyet-field").val(cMatch[1]); if (jMatch) $("#wiktku-start-jimar-field").val(jMatch[1]); if (trMatch) ppDiv.find(".wiktku-posparams-field[data-pp-key='tr']").val(trMatch[1]); // For lêker, c= holds the verb-type code instead of a // gender — split it back across the two dropdowns it is // now assembled from ("x-gh" → form "x" + base "gh"). if (cMatch && /^lêker/.test(snap.pos || "")) { var lekturParts = /^(?:([xphb])-)?(n?gh)$/.exec(cMatch[1]); if (lekturParts) { ppDiv.find(".wiktku-posparams-lektur-sel").val(lekturParts[2]); ppDiv.find(".wiktku-posparams-lekturform-sel").val(lekturParts[1] || ""); } } // Restore checked optional params. "form" is stored as // "erê" rather than "1" (see rebuildTa), so it needs its // own check here. ppDiv.find(".wiktku-posparams-opt-panel input[type='checkbox']").each(function () { var key = $(this).val(); var expected = key === "form" ? "erê" : "1"; $(this).prop("checked", savedTa.indexOf("|" + key + "=" + expected) !== -1); }); } steps.posparams.syncHelpers(ppDiv); return; } if (id === "resim") { var resimDiv = $("#wiktku-start-resim"); resimDiv.find(".wiktku-resim-wrap").remove(); steps.resim.build(resimDiv); // Accept both the new array-of-rows format and the older // single {file, caption} object saved before multi-image // support existed. var resimSnap = snap.resim; var rows = $.isArray(resimSnap) ? resimSnap : (resimSnap ? [resimSnap] : []); if (rows.length) { var list = resimDiv.find("ol.wiktku-resim-list"); list.empty(); $.each(rows, function (_, r) { var item = steps.resim.buildItem(resimDiv); item.find(".wiktku-resim-file").val(r.file || ""); item.find(".wiktku-resim-caption").val(r.caption || ""); item.find(".wiktku-resim-alt").val(r.alt || ""); list.append(item); }); // Always keep a blank trailing row, same as Nimûne/Dûnde. var lastItem = list.children("li.wiktku-resim-item").last(); if ($.trim(lastItem.find(".wiktku-resim-file").val())) { list.append(steps.resim.buildItem(resimDiv)); } } return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Tell the pickers about the programmatic value change. fields.filter("select").trigger("wiktku:refresh"); }); // Item 3: restore which "Beşên din" sub-sections were already opened // for this section, then seed in anything the DOM restore above just // filled in but that wasn't marked opened yet (e.g. an older cache // saved before this existed). openedOtherSections = $.extend({}, snap.openedOtherSections || {}); seedOpenedFromContent(); renderBesenDinPicker(); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); // Bilêvkirin is NOT emitted here — it is one shared field for the // whole word, so emitting it per section duplicated it. getWikitext() // prints it once, above the POS sections. steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.tewandin.output(values); entry += steps.bikaranin.output(values); entry += steps.alfabeyendin.output(values); entry += steps.formalt.output(values); entry += steps.hevmane.output(values); entry += steps.dijmane.output(values); entry += steps.jornav.output(values); entry += steps.jernav.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); entry += steps.cavkani.output(values); entry += steps.xwendin.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { // Each hop through here can be reached asynchronously: the dfn // step waits on mw.loader.using("ext.gadget.linkify") before // calling back, so from that point on the submit handler's own // try/catch is no longer on the stack. Guard every hop instead, // or a throw after linkify loads vanishes into an unhandled // rejection and the form just sits there looking busy. try { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } catch (e) { if (typeof onSubmitError === "function") onSubmitError(e); else throw e; } } processSection(0); } // Assembles wikitext for all sections plus the shared lang header. // pron used to be prepended here too (shared, above every section) — // it now nests inside each section instead, via getWikitextForCurrentSection. function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var bnrh = steps.bnrh.output(sharedValues); var entry = steps.lang.output(sharedValues); // One pronunciation per word, printed once between the language // header and the POS sections — see steps.pron.output. entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // bnr-h goes before the language section — only prepended when // generating fresh wikitext (not addLangMode, which handles it separately). if (!addLangMode && bnrh) entry = bnrh + entry; // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { if (s.mane) return s.mane; // Template sense (e.g. {{guharto|ku|somepage}}) — same // construction as the tplCall built in getOutput, so the // summary shows what actually gets written to the entry // instead of going blank. if (s.tpl && s.tplTitle) { return s.tplNoLang ? "{{" + s.tpl + "|" + s.tplTitle + "}}" : "{{" + s.tpl + "|" + sharedValues.lang + "|" + s.tplTitle + "}}"; } return ""; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; // Set by build() to its submitFailed(). Lives out here because the // wikitext-assembly functions below are outside build()'s closure but // still need a way to report a failure to the person rather than dying // silently in the console. var onSubmitError = null; // Item 7: whether Mane/Bi zaravayên din/Werger has anything in it — // kept outside refresh() so the click handler (defined separately, // where continueBtn is built) can read the latest value. var wiktkuContentGateOk = true; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues, placeholderText) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>").text(placeholderText || "")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice.label); if (choice.sortKey !== undefined) { // This is a language choice {code, label, sortKey} — show code. displayText = capitalize(choice.label) + " (" + choice.code + ")"; } var option = $(mw.html.element("option", { value: choice.code }, displayText)); if (disabledValues[choice.code]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } // Keys to disable for a key menu: already-taken or explicitly disabled. function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); populateMenus(input, step.keys, getDisabledKeys(step)); // Keep the key menus mutually exclusive: whatever one row selects is // disabled in every other row. Recomputed from the DOM on each change. input.on("change", function () { var all = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield"); var taken = {}; all.each(function () { var v = $(this).val(); if (v) taken[v] = true; }); all.not(this).each(function () { var self = $(this), own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (code) $(this).prop("disabled", !!taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }); // Return the wrapper; the select lives inside it and still fires change. return wrapNativeSelect(input); } // Adds another text field to the list if the last one now has text. function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); if (step.placeholder) { nextInput.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = step.modifiers ? makeModifierLi(nextInput).prepend(nextKeyInput || "") : $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) initSelects(nextItem); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } // Shows/hides steps based on whether their prerequisites are met, and // updates placeholders where applicable. function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); steps.cavkani.refreshTplSelect(); // Re-render any step's question label that depends on current values // (e.g. dfn's Werger-section reminder, which only applies to ku). $.each(steps, function (stepId, step) { if (typeof step.question_fmt === "function") { $("#wiktku-start-" + stepId + " .wiktku-start-step-question") .text(step.question_fmt(values)); } }); // Sync every sense block's mane-box mode (plain mane vs tercime+îzah) // to the current language, in case lang changes after blocks exist. $("#wiktku-start-dfn li.wiktku-dfn-sense").each(function () { var updateMane = $(this).data("updateManeMode"); if (updateMane) updateMane(); }); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Re-sync the "<label> bi <ziman>…" placeholder on every always-visible // sub-field list (etîket, kategorî, hevmane, …), since the language may // not have been chosen yet when these lists were first built, or may // have changed since. $("#wiktku-start-dfn .wiktku-dfn-sublist").each(function () { var upd = $(this).data("updatePlaceholders"); if (typeof upd === "function") upd(); }); // Same idea for word-list steps (jê, têkildar, binêre herwiha, …) // whose placeholder is a function of the current language. $.each(steps, function (stepId, step) { if (typeof step.placeholder === "function") { $("#wiktku-start-" + stepId + " textarea.wiktku-start-step-field") .attr("placeholder", step.placeholder()); } }); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // Insert after the quote textarea's resize-wrap (if the manual // resize handle has already been attached to it), not after the // bare textarea -- otherwise this lands *inside* that wrap, // between the textarea and its own grip, breaking jêgirtin's // handle and nesting the tr/t boxes inside it. var quoteTa = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap = quoteTa.closest(".wiktku-resize-wrap"); (quoteResizeWrap.length ? quoteResizeWrap : quoteTa).after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // See the tr-field branch above for why this targets the // resize-wrap instead of the bare textarea. var quoteTa2 = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap2 = quoteTa2.closest(".wiktku-resize-wrap"); (quoteResizeWrap2.length ? quoteResizeWrap2 : quoteTa2).after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { var groupIdx = stepIdToGroup[stepId]; var hiddenByTab = (groupIdx !== undefined && groupIdx !== activeGroup) || // Beşên din picker (point 3): stays hidden even while its tab // is active until explicitly opened from the dropdown. (BESENDIN_SET[stepId] && !openedOtherSections[stepId]); // Bilêvkirin is its own section now, so the two views are // mutually exclusive: on it, only pron shows (plus Ziman, which // is shared and stays above every section); off it, pron is // hidden no matter which tab is active. pron is deliberately // ungrouped — stepIdToGroup has no entry for it — so without // this branch it would show on all four tabs at once. if (stepId === "pron") { hiddenByTab = hiddenByTab || !viewingPron; } else if (viewingPron && stepId !== "lang") { hiddenByTab = true; } if (hiddenByTab || (typeof(step.visible) === "function" && !step.visible(values))) { $("#wiktku-start-" + stepId).hide(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } // After build, sync the posparams helper widgets whenever pos or lang changes. if (step.id === "posparams" && typeof step.syncHelpers === "function") { step.syncHelpers(stepDiv); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } stepDiv.slideDown(); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); // The four content tabs belong to a POS section — Bilêvkirin has no // sub-tabs of its own, so the bar goes away while it's on screen. $("#wiktku-group-tabs").toggle(!!values.pos && !viewingPron); var besenDinActive = activeGroup === BESENDIN_GROUP_IDX && !viewingPron; $("#wiktku-besendin-picker").toggle(besenDinActive); // The option list is filtered by each step's visible(), which depends // on lang/pos — so it has to be rebuilt when those change, not just // when a section is opened. Safe to call from here: rendering the // picker doesn't itself call refresh(), only picking an option does. if (besenDinActive) renderBesenDinPicker(); updateGroupTabIndicators(values); continueBtn.setDisabled(!canContinue); // Soft gate (item 7): stays a real, clickable OOUI button — a hard // setDisabled(true) here would swallow the click entirely, and then // there'd be no way to tell the person *why* nothing happened. The // CSS-only "looks disabled" class lets the click handler still run // and show wiktkuNotify's explanation. wiktkuContentGateOk = !canContinue || hasMinRequiredContent(values); continueBtn.$element.toggleClass("wiktku-btn-soft-disabled", !wiktkuContentGateOk); } function destroy() { if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); if (autosaveInterval) clearInterval(autosaveInterval); formDirty = false; $(window).off("beforeunload.wiktkuUnsaved"); $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard").slideDown(); // #editform was kept laid-out but off-screen (see build()) instead of // display:none, precisely so the editor never had to size itself // against a zero-width/height box. Just bring it back on-screen — // no slideDown needed since it was never actually collapsed. $("#editform").removeClass("wiktku-offscreen"); // Belt-and-braces: if WikiEditor/CodeMirror/mobile's auto-grow still // cached a stale size from some earlier point, nudge them to // recalculate now that the box is genuinely visible. $(window).trigger("resize"); if (window.CodeMirror) { var cm = $("#wpTextbox1").data("CodeMirror") || $("#wpTextbox1").data("cmInstance"); if (cm && typeof cm.refresh === "function") cm.refresh(); } $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and navz. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; // Inserts a new "== {{ziman|code}} ==" section at the correct sorted // position: navz, then ku/hac/sdh/lki/ckb/zza, then alphabetical by name. function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections — just write the new section. // Add \n\n only when there is real non-whitespace content above. var trimmed = existing.replace(/\s+$/, ""); return trimmed ? trimmed + "\n\n" + wikitext : wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // (?![\s\S]) matches only true end-of-string, since a bare "$" with // /m would stop at the section's first line break instead. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections, each separated by exactly \n\n. // Trim trailing whitespace off each section's content first so we // control the spacing precisely. var joined = sections.map(function (s) { return s.content.replace(/\s+$/, ""); }).join("\n\n"); // Only add a separator after the preamble when it has real content. var preambleTrimmed = preamble.replace(/\s+$/, ""); var prefix = preambleTrimmed ? preambleTrimmed + "\n\n" : ""; return prefix + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê zimanekî nû li rûpelê îlawe bikî. Eger ev ziman jixwe hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bike, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Muhtewaya rûpelê paqij bike (her tiştî jê bibe û rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); // Tab bar for switching between step-groups (topics) within a section. // renderGroupTabs()/updateGroupTabIndicators() (which populate and // maintain it) live outside build() — see near "var activeSection". var groupTabsDiv = $("<div id='wiktku-group-tabs'></div>"); // Wikihez, 14 Tebax 2026 (item 3): "Beşên din" picker — sits right under // the group tab bar, only shown while that tab is active (toggled in // refresh(), see BESENDIN_GROUP_IDX); renderBesenDinPicker() fills it. var besenDinPickerDiv = $("<div id='wiktku-besendin-picker' class='wiktku-besendin-picker'></div>"); /** Puts the form back in a usable state after a failed submit and * says what happened. Without this the button stays disabled and * the spinner spins forever on any exception — the person is left * staring at a form that looks busy but is dead, with the reason * visible only in the browser console. */ function submitFailed(err) { spinner.hide(); continueBtn.setDisabled(false); continueBtn.$element.removeClass("wiktku-btn-sending"); var detail = (err && (err.message || err.toString())) || "sedem nediyar"; mw.notify( "Şandin bi ser neket: " + detail + " — tiştê ku te nivîsî winda nebûye. Heke ev dubare bibe, " + "bi 'Edîtora çavkaniyê veke' berdewam bike.", { type: "error", tag: "wiktku-submit", autoHide: false } ); // Deliberately console.error as well: the notification is for the // person, this is for whoever they report the bug to. if (window.console && console.error) console.error("[wiktku] submit failed", err); } onSubmitError = submitFailed; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); continueBtn.$element.addClass("wiktku-btn-sending"); spinner.show(); try { getWikitext(function (wikitext) { try { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page — write fresh content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // ── bnr-h merge ────────────────────────────────────────── // If the user filled bnr-h inputs, either merge into the // existing {{bnr-h|…}} call or prepend a new one. var bnrhOut = steps.bnrh.output(getValues()); if (bnrhOut) { var newPages = bnrhOut.replace(/^\{\{bnr-h\|/, "").replace(/\}\}\n?$/, "").split("|"); var bnrhRe = /\{\{bnr-h\|([^}]*)\}\}/i; if (bnrhRe.test(existing)) { existing = existing.replace(bnrhRe, function (_, inner) { var existingPages = inner.split("|").map(function (p) { return p.trim(); }); $.each(newPages, function (_, p) { p = p.trim(); if (p && existingPages.indexOf(p) === -1) existingPages.push(p); }); return "{{bnr-h|" + existingPages.join("|") + "}}"; }); } else { existing = bnrhOut + existing; } } // If this language's section already exists (whitespace // differences aside), merge into it; otherwise insert new. var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); } catch (e) { // Thrown while writing the result into #wpTextbox1. submitFailed(e); } }); } catch (e) { // Thrown synchronously inside getWikitext — this is where the // splitTercimeIzah ReferenceError surfaced, and it produced no // message at all before this guard existed. submitFailed(e); } }); // Tracks whether groupTabsDiv has been inserted yet — see the // step.id-driven check below, replaced because it silently broke // when bnrh/resim/pron moved ahead of "dfn" in ordered_steps. var groupTabsInserted = false; $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); var nameH3 = $("<h3></h3>").addClass("wiktku-start-step-name"); var nameLabel = $("<label></label>") .attr("for", "wiktku-start-" + step.id + "-field") .text(name); nameH3.append(nameLabel); stepDiv.append(nameH3); if (step.question_fmt) { // question_fmt can be a plain string, or a function of the // current values (used by steps whose question text depends // on e.g. the chosen language) — refresh() keeps it in sync // afterwards via the .wiktku-start-step-question class. var questionText = typeof step.question_fmt === "function" ? step.question_fmt(getValues()) : step.question_fmt; stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, questionText))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); // initSelects() runs over the whole form once it is in the DOM. stepDiv.append(input); } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.placeholder) { input.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append(step.modifiers ? makeModifierLi(input) : $("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Section tabs (switch between POS sections) sit above the // per-section fields, starting at "pos". if (step.id === "pos") { startForm.append(sectionTabsDiv); } // Step-group tabs sit just before the first grouped step in // ordered_steps — whichever one that is. This USED to be a // hardcoded "dfn" check, back when dfn was the first grouped // step. Once bnrh/resim/pron moved into STEP_GROUPS too (and // earlier in ordered_steps than dfn, so they render near // pos/posparams), that check stopped matching anything: dfn was // no longer first, so groupTabsDiv never got appended at all, // and every grouped step's div — bnrh/resim/pron included — sat // there with no tab bar above it to reveal them. Deriving the // insertion point from stepIdToGroup instead means this keeps // working no matter how STEP_GROUPS/ordered_steps get reordered // later. if (!groupTabsInserted && stepIdToGroup[step.id] !== undefined) { startForm.append(groupTabsDiv); startForm.append(besenDinPickerDiv); groupTabsInserted = true; } startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); /** Adds a new, empty POS section and switches to it. */ function addPosSection() { saveCurrentSection(); viewingPron = false; sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); stepDiv.find(".wiktku-add-sense").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); return; } if (id === "resim") { $("#wiktku-start-resim .wiktku-resim-wrap").remove(); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); stepDiv.find("select.wiktku-start-step-field").trigger("wiktku:refresh"); }); // Fresh section — no "Beşên din" sub-section has been opened yet. openedOtherSections = {}; renderBesenDinPicker(); renderSectionTabs(); refresh(); } // One action again: Bilêvkirin is always in the bar now, so the menu // that used to offer both would have had a single entry. addSectionBtn.on("click", addPosSection); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); // Bilêvkirin leads the bar, ahead of the POS sections. var pronTab = $("<span></span>") .addClass("wiktku-section-tab wiktku-section-tab-pron") .text("Bilêvkirin") .toggleClass("wiktku-tab-active", viewingPron); pronTab.on("click", function () { if (viewingPron) return; saveCurrentSection(); viewingPron = true; refresh(); renderSectionTabs(); }); sectionTabsDiv.append(pronTab); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection && !viewingPron); (function (idx) { tab.on("click", function () { if (idx === activeSection && !viewingPron) return; // Leaving Bilêvkirin doesn't need a save — its field // is shared and never part of a section snapshot. if (!viewingPron) saveCurrentSection(); viewingPron = false; activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); /** * Re-populates a dynamically-growing "multiple" field list (bnrh, je, * tekildar, …) from a saved array of strings. Sets each value via * .val() + a triggered "input" event rather than touching the DOM * structure directly, so the normal refreshForTextField() growth * logic adds exactly as many rows as needed — the same thing that * happens when a person types into the last (empty) row. */ function restoreMultiField(id, values) { var container = $("#wiktku-start-" + id); $.each(values || [], function (i, v) { var field = container.find(".wiktku-start-step-field").eq(i); if (!field.length || !v) return; field.val(v).trigger("input"); }); } /** * Restores a full cached draft: shared lang/pron/bnrh fields, then * every section (via the same restoreSection()/refresh()/ * renderSectionTabs() sequence already used when switching tabs). * @param cached {{lang: string, pron: string, bnrh: Array, sections: Array, activeSection: number}} */ function restoreFromCache(cached) { if (cached.lang) { $("#wiktku-start-lang-field").val(cached.lang); $("#wiktku-start-lang-field").trigger("wiktku:refresh"); } // Rebuild dependent steps (pos, pron wrap, etc.) now that lang is set. refresh(); if (cached.pron !== undefined) { $("#wiktku-start-pron .wiktku-pron-text").val(cached.pron); } if (cached.bnrh) { restoreMultiField("bnrh", cached.bnrh); } sections = (cached.sections && cached.sections.length) ? cached.sections : [{}]; activeSection = (typeof cached.activeSection === "number" && cached.activeSection >= 0 && cached.activeSection < sections.length) ? cached.activeSection : 0; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); updateLastSavedIndicator(cached.savedAt || null); formDirty = false; wiktkuNotify("Danûstandina berê ya qeydkirî ji cache hate barkirin.", { type: "info", tag: "wiktku-cache-restore" }); } // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); // A new cureyê rêzimanî means any previously chosen cinsiyet/ // cureyê lêkerê no longer applies — clear both selections (and // the shared hidden cinsiyet field, since rebuildTa()/syncHelpers() // fall back to it) before wiping the textarea, so nothing stale // gets carried over into the rebuilt template. var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-cinsiyet-sel").val(""); ppDiv.find(".wiktku-posparams-jimar-sel").val(""); ppDiv.find(".wiktku-posparams-lektur-sel").prop("selectedIndex", 0); ppDiv.find(".wiktku-posparams-lekturform-sel").prop("selectedIndex", 0); $("#wiktku-start-cinsiyet-field").val(""); $("#wiktku-start-jimar-field").val(""); ppDiv.find(".wiktku-posparams-text").val(""); // refresh() runs steps.posparams.syncHelpers(), which toggles the // param rows for the new pos and — since the textarea is now // empty — calls rebuildTa() to repopulate it. Just clearing the // textarea (as before) never triggered this, so the params // section was left stale until some other field's change event // happened to fire a refresh(). refresh(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { // Immediate feedback that the click registered continueBtn.$element.addClass("wiktku-btn-flash"); setTimeout(function () { continueBtn.$element.removeClass("wiktku-btn-flash"); }, 500); // Item 7: Ziman/Cureyê rêzimanî already block submission via the // real OOUI setDisabled (see canContinue in refresh()) — this is // a second, softer check that still lets the click through so we // can explain *why*, instead of the button just silently doing // nothing. if (!wiktkuContentGateOk) { wiktkuNotify( "Berî şandinê, tiştekî binivîse: Mane, Bi zaravayên din, an jî Werger — kêmasî yek ji van sê beşan divê tijî be.", { type: "warn", tag: "wiktku-mincontent" } ); return; } wiktkuNotify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", flags: [ "destructive" ], }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Cache save/clear buttons ───────────────────────────────────────── // Manual, page-scoped save of the entire wizard (all sections, not // just the active one) via [[MediaWiki:Gadget-StorageUtils.js]]'s // ObjectStorage. Restoring happens silently on load at the end of // build(), once the full language list is available. // // Saving also happens automatically (debounced while typing, plus a // periodic fallback) — see "Autosave" below — since relying on the // person to remember to click "Li cache qeyd bike" before an // accidental tab close/reload defeats the point of having a cache // at all. function buildCacheSnapshot() { return { lang: getValues().lang || "", pron: $("#wiktku-start-pron .wiktku-pron-text").val() || "", // bnrh is shared (page-level), same as lang/pron above — not // per-section, so it doesn't live in sections[]. bnrh: getValuesForStep("bnrh"), sections: sections, activeSection: activeSection, savedAt: Date.now() }; } // ── Last-saved indicator ───────────────────────────────────────────── var lastSavedEl = $("<span id='wiktku-last-saved'></span>"); function formatSavedTime(ts) { try { return new Date(ts).toLocaleTimeString(mw.config.get("wgUserLanguage"), { hour: "2-digit", minute: "2-digit" }); } catch (e) { return new Date(ts).toLocaleTimeString(); } } function updateLastSavedIndicator(ts) { lastSavedEl.text(ts ? ("Cache: qeydkirî di saet " + formatSavedTime(ts) + " de") : ""); } // ── Dirty-state tracking + autosave ────────────────────────────────── // formDirty mirrors "does the live form differ from what's in cache". // Anything the person types/selects sets it; a successful save (auto // or manual) clears it; destroy() (final submit, or switching to the // source editor) also clears it since the wizard's job is over at // that point either way. formDirty/autosaveDebounceTimer/autosaveInterval // are declared in the outer scope (near activeGroup) — assigned here, // not re-declared — so destroy() can reach them too. var AUTOSAVE_DEBOUNCE_MS = 8000; // save shortly after typing pauses var AUTOSAVE_INTERVAL_MS = 60000; // …and at least this often regardless function performAutosave() { if (!formDirty) return; saveCurrentSection(); try { formCache.Set(buildCacheSnapshot()); formDirty = false; updateLastSavedIndicator(Date.now()); } catch (e) { // Silent on autosave failure (storage blocked/full, etc.) — the // manual button still surfaces a proper error if the person // tries it directly, no need to interrupt typing with a toast. } } function scheduleAutosave() { formDirty = true; if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = setTimeout(performAutosave, AUTOSAVE_DEBOUNCE_MS); } startForm.on("input change", "input, textarea, select", scheduleAutosave); autosaveInterval = setInterval(performAutosave, AUTOSAVE_INTERVAL_MS); // Warn on accidental tab close/reload while there's anything unsaved. $(window).on("beforeunload.wiktkuUnsaved", function (e) { if (!formDirty) return undefined; e.preventDefault(); e.returnValue = ""; return ""; }); var saveCacheBtn = new OO.ui.ButtonWidget({ label: "Li cache qeyd bike", title: "Halê vê formê yê niha (ziman, bilêvkirin û hemû beş) li cache (localStorage) qeyd bike, da ku eger rûpel bêyî xwestin were girtin an ji nû ve were barkirin, tu karibî berdewam bikî." }); saveCacheBtn.on("click", function () { saveCurrentSection(); // ObjectStorage.Set() doesn't return a success/failure value, so // the only way to detect a real failure (storage blocked, quota // exceeded, JSON.stringify choking on something unexpected) is to // catch it here rather than inspect a (nonexistent) return value. try { var snapshot = buildCacheSnapshot(); formCache.Set(snapshot); formDirty = false; updateLastSavedIndicator(snapshot.savedAt); wiktkuNotify("Halê formê li cache hate qeydkirin.", { type: "success", tag: "wiktku-cache-save" }); } catch (e) { mw.notify("Qeydkirina li cache bi ser neket.", { type: "error", tag: "wiktku-cache-save" }); } }); var clearCacheBtn = new OO.ui.ButtonWidget({ label: "Cache paqij bike", flags: [ "destructive" ], title: "Datayên qeydkirî yên vê rûpelê ji cache jê bibe (forma ku niha xuya dike naguherîne)." }); clearCacheBtn.on("click", function () { formCache.Set({}); // The live form still has whatever the person typed — it's just no // longer backed up anywhere, so treat this like a fresh unsaved edit. formDirty = true; updateLastSavedIndicator(null); wiktkuNotify("Cache hate paqijkirin.", { type: "success", tag: "wiktku-cache-clear" }); }); // ── "⋯" overflow ───────────────────────────────────────────── // v3: one primary action and one secondary stay on the bar; // everything else moves in here. Four same-weight buttons — two of // them red — was the loudest thing on the screen, and on a phone it // wrapped to three rows of a sticky footer. var moreBtn = $("<button type='button' class='wiktku-more-btn' title='Vebijarkên din'>⋯</button>"); var moreMenu = $("<div class='wiktku-more-menu'></div>").hide(); /** Moves an existing OOUI button into the overflow menu, keeping its * handlers — the widgets already carry the behaviour, so this is * purely about where they are shown. */ function intoMenu(btn, extraClass) { var row = $("<div class='wiktku-more-item'></div>"); if (extraClass) row.addClass(extraClass); btn.$element.on("click", function () { moreMenu.hide(); }); row.append(btn.$element); moreMenu.append(row); } intoMenu(saveCacheBtn); intoMenu(clearCacheBtn, "wiktku-more-item-danger"); moreMenu.append($("<div class='wiktku-more-sep'></div>")); moreMenu.append($("<div class='wiktku-more-item wiktku-more-note'></div>").append(lastSavedEl)); moreBtn.on("click", function (e) { e.preventDefault(); e.stopPropagation(); var open = moreMenu.is(":visible"); moreMenu.toggle(!open); if (!open) { setTimeout(function () { $(document).one("click.wiktkuMore", function () { moreMenu.hide(); }); }, 0); } }); var moreWrap = $("<span class='wiktku-more-wrap'></span>").append(moreBtn).append(moreMenu); footer.append(moreWrap); // Icon-only settings button — opens the Tercîh dialog. Plain OOUI // icon names depend on which icon-pack module happens to be loaded, // so this uses the actual Codex "settings" (color-subtle) SVG from // Commons directly, the same way the spinner above hotlinks its gif. var prefsBtn = $("<button></button>", { type: "button", "class": "wiktku-prefs-btn", title: "Tercîh — sazkariyên vê amûrê biguherîne" }); prefsBtn.on("click", function (e) { e.preventDefault(); wiktkuOpenPrefsDialog(); }); // The gear is icon-only on the bar; inside a text menu it needs a // label like everything else around it. prefsBtn.on("click", function () { moreMenu.hide(); }); moreMenu.prepend($("<div class='wiktku-more-sep'></div>")); moreMenu.prepend($("<div class='wiktku-more-item wiktku-more-item-prefs'></div>") .append(prefsBtn) .append($("<span class='wiktku-more-item-label'></span>").text("Tercîh"))); startForm.append(footer); // NOTE: deliberately NOT .hide() (display:none). WikiEditor/CodeMirror/ // the mobile editor's auto-grow logic measure #wpTextbox1's real // dimensions during their own init, which happens while the wizard is // up. A display:none ancestor reports 0 for offsetWidth/offsetHeight/ // scrollHeight, so those scripts bake in a near-zero height that never // gets recalculated later — slideDown() in destroy() only animates the // outer box, it doesn't re-trigger their sizing. Pushing #editform // off-screen instead keeps it laid out (real width/height available to // measure) without being visible, so the editbox opens at full size. $("#editform").addClass("wiktku-offscreen").before(startForm); // renderGroupTabs() looks up #wiktku-group-tabs via a live DOM // selector, so it must run after startForm is actually in the // document — calling it back in the build loop (while startForm was // still detached) silently no-op'd and left the tab bar empty. renderGroupTabs(); renderBesenDinPicker(); // One pass over the whole form: every select that hasn't already been // initialised, and isn't opted out with .wiktku-plain-select, gets // the searchable picker. initSelects(startForm); refresh(); // Give every draggable textarea a custom resize grip (works // consistently on Safari/iOS, unlike the native corner grip — see // the "Manual drag-to-resize handle" comment in styles.css), and // keep applying it to textareas added later on (new sense blocks, // quote-source fields, nimûne rows, …). wiktkuInitManualResize(startForm); new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { $(mutation.addedNodes).each(function () { if (this.nodeType !== 1) return; wiktkuInitManualResize(this); }); }); }).observe(startForm[0], { childList: true, subtree: true }); // Now that the full language list is loaded, silently restore any // draft the editor previously saved for this page. var cachedDraft = formCache.Get(); if (cachedDraft && cachedDraft.sections && cachedDraft.sections.length) { restoreFromCache(cachedDraft); } } mw.loader.using(["oojs-ui-core"], function () { function wiktkuProceedWithData(wiktkuData) { var d = wiktkuData || {}; // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Item 1: Jimar (number) code definitions — same shape as the wiki's // own Lua number-type table (code -> {cat, display[, req]}). if (d.numberLabels) $.extend(NUMBER_LABELS, d.numberLabels); // Populate lang choices (pinned list). if (d.langChoices) steps.lang.choices = choicesFromObject(d.langChoices, true); // Populate langsByCode and merge full language list from d.ziman. // d.ziman is a {code: name} object with all known languages. $.each(steps.lang.choices, function (i, choice) { if (choice.sortKey === undefined) choice.sortKey = choice.label; langsByCode[choice.code] = choice; }); if (d.ziman) { var pinnedCodes = {}; $.each(steps.lang.choices, function (i, c) { pinnedCodes[c.code] = true; }); var extraChoices = []; $.each(d.ziman, function (code, name) { if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; if (pinnedCodes[code]) return; var choice = { code: code, label: name, sortKey: name }; extraChoices.push(choice); langsByCode[code] = choice; }); extraChoices.sort(function (a, b) { return a.sortKey.localeCompare(b.sortKey, userLang); }); steps.lang.choices = steps.lang.choices.concat(extraChoices); } // Keep the full merged list around for trans/dunde/zarava — those // should still be able to reference any language even when the // Tercîh panel restricts the main "ziman" step below — then, if // the user set a restriction there, narrow steps.lang.choices // itself to just those codes. var wiktkuFullLangChoices = steps.lang.choices; if (wiktkuPrefs.langCodes && wiktkuPrefs.langCodes.length) { var wiktkuAllowedLangSet = {}; $.each(wiktkuPrefs.langCodes, function (i, code) { wiktkuAllowedLangSet[code] = true; }); var wiktkuRestrictedChoices = $.grep(wiktkuFullLangChoices, function (c) { return !!wiktkuAllowedLangSet[c.code]; }); // Fall back to the full list instead of showing an empty // dropdown if none of the saved codes matched anything // (typo'd code, data.json changed since, …). steps.lang.choices = wiktkuRestrictedChoices.length ? wiktkuRestrictedChoices : wiktkuFullLangChoices; } // Populate POS choices — also a plain {code: label} object in data.json. if (d.posChoices) steps.pos.choices = choicesFromObject(d.posChoices, false); // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the full language list // (not the possibly Tercîh-restricted steps.lang.choices). steps.trans.keys = wiktkuFullLangChoices; steps.dunde.keys = wiktkuFullLangChoices; steps.zarava.keys = getZaravaKeys(wiktkuFullLangChoices); build(); } // data.json ships inside this package module, so it is already parsed // and in memory — no action=raw round trip, and no Testing switch to // forget to flip back before deploying. wiktkuProceedWithData(require("./start/data.json")); }); }); //</nowiki> 6f1xjehku3gtr3spcw9kzto81tg6j5u 6333816 6333811 2026-08-15T14:28:57Z Wikihez 7344 6333816 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. // implicit dependencies: StorageUtils (ObjectStorage) //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var addLangMode = mw.util.getParamValue("wiktkuaddlang") === "1"; // ── Tercîh (user settings) panel stored via mw.storage (localStorage), globally var WIKTKU_PREFS_KEY = "wiktku_start_prefs"; var WIKTKU_PREFS_DEFAULTS = { // [] = show the full language list in the "ziman" step; otherwise // only these codes are shown there (data.json codes, not names). langCodes: [], // true = never auto-open on a new/empty page — only via the // "+Ziman/beşeke din" portlet link. onlyOnClick: false, // "auto" | "p-cactions" | "p-tb" | "p-views" — where the // "+Ziman/beşeke din" portlet link is added. portlet: "auto", // true = suppress routine/informational mw.notify toasts (page // loading, cache auto-restored, cache saved/cleared, "tê şandin…"). // Errors and direct results of an explicit action (like saving // Tercîh itself) always show regardless of this setting. quiet: false }; function wiktkuLoadPrefs() { if (!(window.mw && mw.storage)) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var raw; try { raw = mw.storage.get(WIKTKU_PREFS_KEY); } catch (e) { raw = null; } if (!raw) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var parsed; try { parsed = JSON.parse(raw); } catch (e) { parsed = {}; } return $.extend({}, WIKTKU_PREFS_DEFAULTS, parsed); } function wiktkuSavePrefs(prefs) { if (!(window.mw && mw.storage)) return false; try { mw.storage.set(WIKTKU_PREFS_KEY, JSON.stringify(prefs)); return true; } catch (e) { return false; } } var wiktkuPrefs = wiktkuLoadPrefs(); // Routine/informational notices go through here so "quiet mode" can // suppress them; errors and explicit-action confirmations (like the // Tercîh save toast) call mw.notify directly instead, and always show. function wiktkuNotify(message, options) { if (wiktkuPrefs.quiet) return; mw.notify(message, options); } // Lazily built the first time it's opened; reused after that (see // wiktkuOpenPrefsDialog below, defined once we know OOUI is available). var wiktkuPrefsWindowManager = null; var wiktkuPrefsDialog = null; function wiktkuOpenPrefsDialog() { mw.loader.using(["oojs-ui-core", "oojs-ui-windows"], function () { function WiktkuPrefsDialog(config) { WiktkuPrefsDialog.super.call(this, config); } if (!wiktkuPrefsDialog) { OO.inheritClass(WiktkuPrefsDialog, OO.ui.ProcessDialog); WiktkuPrefsDialog.static.name = "wiktkuPrefsDialog"; WiktkuPrefsDialog.static.title = "Tercîhên min"; WiktkuPrefsDialog.static.actions = [ { action: "save", label: "Qeyd bike", flags: ["primary", "progressive"] }, { action: "cancel", label: "Betal bike", flags: "safe" } ]; WiktkuPrefsDialog.prototype.initialize = function () { WiktkuPrefsDialog.super.prototype.initialize.call(this); this.langCodesInput = new OO.ui.TextInputWidget({ placeholder: "ku, zza, ckb (vala bihêle ji bo hemû zimanan)" }); this.onlyOnClickCheckbox = new OO.ui.CheckboxInputWidget({}); this.quietCheckbox = new OO.ui.CheckboxInputWidget({}); this.portletDropdown = new OO.ui.DropdownInputWidget({ options: [ { data: "auto", label: "Otomatîk (li gorî rûyê wîkiyê)" }, { data: "p-cactions", label: "p-cactions - Li qismê Amûran" }, { data: "left-navigation", label: "left-navigation - Li qismê Gotar-Gotûbêj" }, { data: "p-tb", label: "p-tb - Li qismê Giştî" }, { data: "p-views", label: "p-views - Li qismê Bixwîne" } ] }); var fieldset = new OO.ui.FieldsetLayout({ label: "Eyar" }); fieldset.addItems([ new OO.ui.FieldLayout(this.langCodesInput, { label: "Kodên zimanan ku tê xuyakirin li qismê \"ziman\"", align: "top", help: "Kodan bi virgulê (,) ji hev veqetîne. Vala bihêle da ku hemû ziman were nîşandan.", helpInline: true }), new OO.ui.FieldLayout(this.onlyOnClickCheckbox, { label: "Tenê veke wextê \"+Ziman/beşeke din\" were tikandin", align: "inline", help: "Eger were hilbijartin, ev amûr êdî otomatîk li ser rûpelên nû/vala dest pê nake — divê meriv her carê pêl \"+Ziman/beşeke din\" bike.", helpInline: true }), new OO.ui.FieldLayout(this.portletDropdown, { label: "Cihê lînka \"+Ziman/beşeke din\"", align: "top", help: "\"Otomatîk\" li gorî rûyê wîkiyê hildibijêre.", helpInline: true }), new OO.ui.FieldLayout(this.quietCheckbox, { label: "Moda bêdeng (kêmtir agahdarî nîşan bide)", align: "inline", help: "Agahdariyên normal nîşan nede. Xeta her tim tên xuyakirin.", helpInline: true }) ]); this.$body.addClass("wiktku-prefs-dialog-body").append(fieldset.$element); }; WiktkuPrefsDialog.prototype.getSetupProcess = function (data) { return WiktkuPrefsDialog.super.prototype.getSetupProcess.call(this, data) .next(function () { this.langCodesInput.setValue(wiktkuPrefs.langCodes.join(", ")); this.onlyOnClickCheckbox.setSelected(!!wiktkuPrefs.onlyOnClick); this.portletDropdown.setValue(wiktkuPrefs.portlet || "auto"); this.quietCheckbox.setSelected(!!wiktkuPrefs.quiet); }, this); }; WiktkuPrefsDialog.prototype.getActionProcess = function (action) { var dialog = this; if (action === "save") { return new OO.ui.Process(function () { var codes = dialog.langCodesInput.getValue() .split(/[,\s]+/) .map(function (c) { return c.trim().toLowerCase(); }) .filter(function (c) { return !!c; }); wiktkuPrefs = { langCodes: codes, onlyOnClick: dialog.onlyOnClickCheckbox.isSelected(), portlet: dialog.portletDropdown.getValue() || "auto", quiet: dialog.quietCheckbox.isSelected() }; wiktkuSavePrefs(wiktkuPrefs); mw.notify( "Tercîh hatin qeydkirin. Rûpelê ji nû ve bar bike (F5).", { type: "success", tag: "wiktku-prefs-save" } ); dialog.close({ action: "save" }); }); } if (action === "cancel") { return new OO.ui.Process(function () { dialog.close({ action: "cancel" }); }); } return WiktkuPrefsDialog.super.prototype.getActionProcess.call(this, action); }; wiktkuPrefsWindowManager = new OO.ui.WindowManager(); $(document.body).append(wiktkuPrefsWindowManager.$element); wiktkuPrefsDialog = new WiktkuPrefsDialog(); wiktkuPrefsWindowManager.addWindows([wiktkuPrefsDialog]); } wiktkuPrefsWindowManager.openWindow(wiktkuPrefsDialog); }); } var targetContainer; var skin = mw.config.get('skin'); if (wiktkuPrefs.portlet && wiktkuPrefs.portlet !== "auto") { targetContainer = wiktkuPrefs.portlet; } else if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Li vê rûpelê, ziman an jî beşeke nû zêde bike"); // If "onlyOnClick" is set, the wizard should ONLY ever open via the // "+Ziman/beşeke din" link — never automatically var wiktkuNewPageDetected = $(".mw-newarticletext, .mw-newarticletextanon").length > 0; if (wiktkuPrefs.onlyOnClick ? !addLangMode : (!addLangMode && !wiktkuNewPageDetected)) { return; } // ── Shared helpers ─────────────────────────────────────────────────── // Generic text/UI utilities live in their own package file now — see the // header of util.js for why. Aliased to bare names here so the ~400 call // sites below read exactly as they did when these were local functions. var wiktkuUtil = require("./start/util.js"); var capitalize = wiktkuUtil.capitalize; var decapitalize = wiktkuUtil.decapitalize; var escapeRegExp = wiktkuUtil.escapeRegExp; var stripWikilinks = wiktkuUtil.stripWikilinks; var splitTercimeIzah = wiktkuUtil.splitTercimeIzah; var insertAtCursor = wiktkuUtil.insertAtCursor; var foldDiacritics = wiktkuUtil.foldDiacritics; var wrapNativeSelect = wiktkuUtil.wrapNativeSelect; var initSelects = wiktkuUtil.initSelects; var wiktkuInitManualResize = wiktkuUtil.initManualResize; function langHeaderSource(codePattern) { return "\n?==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } var catSrcTemplates = null; var catSrcTemplatesPromise = null; function fetchCatSrcTemplates() { if (catSrcTemplatesPromise) return catSrcTemplatesPromise; catSrcTemplatesPromise = new mw.Api().get({ action: "query", list: "categorymembers", cmtitle: "Kategorî:Çavkanî", cmnamespace: 10, cmlimit: "max", formatversion: 2 }).then(function (data) { var members = (data.query && data.query.categorymembers) || []; catSrcTemplates = $.map(members, function (m) { // Pêşgira navî ya "Şablon:" rake. return m.title.replace(/^[^:]+:/, ""); }); catSrcTemplates.sort(function (a, b) { return a.localeCompare(b, userLang); }); return catSrcTemplates; }, function () { catSrcTemplates = []; return catSrcTemplates; }); return catSrcTemplatesPromise; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var formCache = new ObjectStorage("wiktku_start_draft_" + mw.config.get("wgPageName"), 1); var langsByCode = {}; // Looks up the display label for a language code, falling back to the // code itself if it isn't known yet (e.g. langsByCode not loaded). function getLangLabel(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; // Converts a {code: label} object (langChoices/posChoices in data.json) // into the {code, label[, sortKey]} array the rest of the script uses. // isLang: true adds a sortKey and shows "(code)" after the label — // language choices only. function choicesFromObject(obj, isLang) { var result = []; $.each(obj || {}, function (code, label) { var choice = { code: code, label: label }; if (isLang) choice.sortKey = label; result.push(choice); }); return result; } function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c.code] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Item 1 (Wikihez, 14 Tebax 2026): kodên jimarê (y, s, d, p, p+, tp, j, j+, // j/nj, nj, nj+, hj!, hj?) — ji data.json's "numberLabels" tê dagirtin. // Same {code: {cat, display[, req]}} shape as the wiki's own Lua // number-type table; "display" can contain HTML (<abbr>) or wikilinks // ([[...]]), so it's only used as-is inside the wikitext output — never // dropped straight into an <option>, which can't render either (see // stripMarkupForOption below). var NUMBER_LABELS = {}; // metadata[lang].g used to list gender AND number codes together (see // cinsiyet/posparams below) — this tells the two dropdowns apart: any // code that's a key in NUMBER_LABELS is a number code (goes in the new // Jimar dropdown / j= param), everything else is a gender code (stays // in the existing Cîns dropdown / c= param). Compound codes like "m-p" // or "n-p" are gender+plural pairs, not plain "p" — they don't match a // NUMBER_LABELS key, so they correctly stay on the gender side. function isNumberCode(code) { return Object.prototype.hasOwnProperty.call(NUMBER_LABELS, code); } // Strips the bit of markup "display" is allowed to contain so it's safe // to use as plain <option> text (options can't render HTML or wikilinks): // <abbr title="X">Y</abbr> -> "Y (X)", [[a|b]] -> "b", [[a]] -> "a". function stripMarkupForOption(html) { if (!html) return ""; return $.trim( String(html) .replace(/<abbr[^>]*title="([^"]*)"[^>]*>([\s\S]*?)<\/abbr>/gi, "$2 ($1)") .replace(/\[\[[^\]|]*\|([^\]]*)\]\]/g, "$1") .replace(/\[\[([^\]]*)\]\]/g, "$1") .replace(/<[^>]+>/g, "") ); } // Builds the Jimar dropdown's <option> text for one code: "j — jimarbar". function numberOptionLabel(code) { var def = NUMBER_LABELS[code]; if (!def) return code; var text = stripMarkupForOption(def.display); return text ? (code + " — " + text) : code; } // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } // ── Template explanations (v3 spec) ────────────────────────────────── // Every place a template can be picked shows the same row: a status // dot, the name, a link to the template page, and an ⓘ. This is the ⓘ. // // Text comes from the template's own TemplateData where it has any, so // the explanation stays right without anyone maintaining a second copy // by hand — with the desc already in data.json as the fallback for // templates that have none. var wiktkuTplDataCache = {}; // name -> {desc, params[]} or null when absent /** Fetches TemplateData for one template. Resolves to null if the * template has none (a plain, undocumented template — very common). */ function fetchTemplateData(name) { if (Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, name)) { return $.Deferred().resolve(wiktkuTplDataCache[name]).promise(); } return new mw.Api().get({ action: "templatedata", titles: "Şablon:" + name, redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; var first = null; $.each(pages, function (_, p) { if (!first) first = p; }); var out = null; if (first) { var desc = first.description; // TemplateData descriptions are language maps when the // template is documented in more than one language. if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(first.params || {}, function (key, p) { var label = p && p.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(p && p.required) }); }); out = { desc: desc || "", params: params }; } wiktkuTplDataCache[name] = out; return out; }, function () { // No TemplateData, or the API is unhappy — cache the miss so a // repeated ⓘ click doesn't re-request it every time. wiktkuTplDataCache[name] = null; return null; }); } /** Fetches TemplateData for many templates in one request and fills the * cache. This is what lets a picker show a real description per row * without anyone maintaining a second copy of it in data.json — the v3 * spec's "Nivîsên ravekirinê ji rûpela şablonê tên girtin * (TemplateData), ne bi destan têne nivîsandin." * Resolves either way; a template with no TemplateData caches as null. */ function prefetchTemplateData(names) { var missing = $.grep(names || [], function (n) { return n && !Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n); }); if (!missing.length) return $.Deferred().resolve().promise(); // The API caps a titles list at 50 for normal users. missing = missing.slice(0, 50); return new mw.Api().get({ action: "templatedata", titles: $.map(missing, function (n) { return "Şablon:" + n; }).join("|"), redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; $.each(pages, function (_, page) { if (!page || !page.title) return; var name = String(page.title).replace(/^[^:]+:/, ""); var desc = page.description; if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(page.params || {}, function (key, prm) { var label = prm && prm.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(prm && prm.required) }); }); wiktkuTplDataCache[name] = { desc: desc || "", params: params }; }); // Anything the API didn't answer for simply has none — cache the // miss so the per-row ⓘ doesn't re-request it one at a time. $.each(missing, function (_, n) { if (!Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n)) wiktkuTplDataCache[n] = null; }); }, function () { $.each(missing, function (_, n) { wiktkuTplDataCache[n] = null; }); }); } /** Rewrites each tagged <option> in `sel` as "name — description", using * TemplateData. Only fills rows that have no description yet, so the * hand-written ones in data.json (which carry usage examples the API * does not) are left exactly as they are. */ function applyTplDescriptions(sel) { if (!sel || !sel.length) return; var changed = false; sel.find("option[data-tpl]").each(function () { var opt = $(this); var name = opt.attr("data-tpl"); if (opt.text().indexOf(" — ") !== -1) return; // already described var td = wiktkuTplDataCache[name]; var desc = (td && td.desc) || localTplDesc(name); if (!desc) return; // One line: TemplateData descriptions can run to a paragraph. desc = $.trim(String(desc).split("\n")[0]); if (desc.length > 90) desc = desc.slice(0, 90) + "…"; opt.text(name + " — " + desc); changed = true; }); // The picker caches option text for searching, so it has to re-read. if (changed) sel.trigger("wiktku:refresh"); } /** Hand-written fallback description, from data.json. * * This is the escape hatch for templates with no TemplateData on the * wiki: add a "desc" to the entry in data.json and it shows up in the * dropdown and in the ⓘ immediately, no code change. TemplateData is * still the better place — VisualEditor and every other tool reads it * too — but this keeps the picker useful in the meantime. * * Works for any pool: pronTpls, etymTpls, tplDefs, jederDefs. */ function localTplDesc(name) { var pools = [steps.pron.pronTpls, steps.etym.etymTpls, steps.dfn.tplDefs, steps.dfn.jederDefs]; var found = ""; $.each(pools, function (_, pool) { if (pool && pool[name] && pool[name].desc) { found = pool[name].desc; return false; } }); return found; } /** Opens the inline explanation panel for `name`, anchored under the * picker it was opened from. */ function showTemplateInfo(name, anchorWrap) { $(".wiktku-tpl-info").remove(); var panel = $("<div class='wiktku-tpl-info'></div>"); panel.append($("<div class='wiktku-tpl-info-name'></div>").text("{{" + name + "}}")); var body = $("<div class='wiktku-tpl-info-desc'></div>").text("Tê barkirin…"); panel.append(body); var params = $("<div class='wiktku-tpl-info-params'></div>"); panel.append(params); panel.append($("<a class='wiktku-tpl-info-link' target='_blank' rel='noopener'></a>") .attr("href", wiktkuUtil.tplPageUrl(name)) .text("Rûpela şablonê veke →")); var close = $("<button type='button' class='wiktku-tpl-info-close' title='Bigire'>✕</button>"); close.on("click", function () { panel.remove(); }); panel.prepend(close); $(anchorWrap).after(panel); fetchTemplateData(name).then(function (td) { var desc = (td && td.desc) || localTplDesc(name); body.text(desc || "Ji bo vê şablonê ravek nehatiye nivîsandin."); if (td && td.params && td.params.length) { params.append($("<div class='wiktku-tpl-info-params-title'></div>").text("Parametre:")); var listEl = $("<ul></ul>"); $.each(td.params, function (_, p) { var line = p.name + (p.label ? " — " + p.label : "") + (p.required ? " (pêwîst)" : ""); listEl.append($("<li></li>").text(line)); }); params.append(listEl); } }); } /** Marks a picker's <option>s as template rows so the searchable widget * renders them with the dot / 🔗 / ⓘ affordances, and wires the ⓘ * handler for that picker. `nameOf` maps an <option> to a template * name — the pickers store different things in value= (a snippet for * the insert dropdowns, the bare name for the sense selector). */ function markTemplateOptions(sel, nameOf) { if (!sel || !sel.length) return; var names = []; sel.find("option").each(function () { var opt = $(this); var name = nameOf(opt); if (!name) return; opt.attr("data-tpl", name); // Deprecated/typo templates are the "special cases only" ones. opt.attr("data-tpl-status", /kevnbûyî|şaşnivîs|kêmpeyda/i.test(opt.text()) ? "yellow" : "green"); names.push(name); }); sel.data("wiktkuTplInfo", showTemplateInfo); // Fill in the descriptions. Matters most for the Mane picker, whose // entries in data.json are names with no desc at all — "rastnivîs", // "ku-Latn", "guharto" on their own, which is precisely Rewiye tine's // "famkirina van zehmet e". One request covers every template in the // picker, and the result is cached for the per-row ⓘ as well. prefetchTemplateData(names).always(function () { applyTplDescriptions(sel); }); } /** Pulls the template name out of a snippet like "* {{ku-IPA}}" or * "{{ji|SOURCELANG|CODE|…}}". */ function tplNameFromSnippet(snippet) { var m = /\{\{\s*([^|}\n]+)/.exec(snippet || ""); return m ? $.trim(m[1]) : ""; } // True if a sense has content beyond mane worth keeping (etîket, word // lists, nimûne, jêder) — so it's still emitted with {{mane?}} if empty. function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } // Wikihez, 14 Tebax 2026 (item 7): the real submit-blocking requirement // (Ziman + Cureyê rêzimanî, via step.required/canContinue) is already // obvious since Bişîne stays visibly disabled until it's met. What // wasn't obvious is that a technically-"complete" entry with nothing // in Mane, Bi zaravayên din or Werger is still empty in any meaningful // sense — so this is checked separately, at click time, with its own // message, instead of another star/legend marker on the page. function hasMinRequiredContent(values) { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasMane = dfnSenses.some(function (s) { return (s.tpl && s.tplTitle) || (!s.tpl && (s.mane !== "" || senseHasExtraContent(s))); }); if (hasMane) return true; if (values.lang === "ku") { var hasWerger = false; $("#wiktku-start-trans .wiktku-trans-group").each(function () { if (steps.trans.getGroupTranslations($(this)).length) hasWerger = true; }); if (hasWerger) return true; var hasZarava = false; $("#wiktku-start-zarava .wiktku-zarava-group").each(function () { if (steps.zarava.getGroupTranslations($(this)).length) hasZarava = true; }); if (hasZarava) return true; } return false; } // Bolds the *first* occurrence of the page name function boldPageNameOnce(text) { if (!text || !pageNameRe) return text; var re = new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "i"); return text.replace(re, "'''$1'''"); } // Converts literal line breaks typed into a nimûne/jêgirtin box into // wikitext <br> tags, function nlToBr(text) { return text ? text.replace(/\r\n|\r|\n/g, "<br>") : text; } function escapeHtmlForBackdrop(str) { return String(str) .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;"); } // Mirrors a textarea's text, with a small highlighted marker placed // right after each line that's followed by an actual typed/pasted // linebreak. Rendered into a transparent backdrop layer behind the // textarea (see ensureLinebreakBackdrop()), so only the point of the // break is marked instead of the whole box. function buildLinebreakBackdropHtml(text) { var lines = text.split(/\r\n|\r|\n/); return $.map(lines, function (line, i) { var isLast = i === lines.length - 1; return escapeHtmlForBackdrop(line) + (isLast ? "" : "<mark class='wiktku-linebreak-mark'>↵</mark>\n"); }).join(""); } // Copies the metrics that affect where text wraps/lands (font, line // height, padding, border) from the real textarea onto its backdrop, // via computed style rather than shared CSS classes — most of the // box's own rules are written as "textarea.foo", which a <div> with // the same class wouldn't match. Re-run on every update in case a // responsive breakpoint changed the textarea's own font-size. function syncLinebreakBackdropMetrics(textarea, backdrop) { var cs = window.getComputedStyle(textarea[0]); backdrop.css({ "box-sizing": cs.boxSizing, "padding-top": cs.paddingTop, "padding-right": cs.paddingRight, "padding-bottom": cs.paddingBottom, "padding-left": cs.paddingLeft, "border-width": cs.borderWidth, "border-style": "solid", "font-family": cs.fontFamily, "font-size": cs.fontSize, "font-weight": cs.fontWeight, "line-height": cs.lineHeight, "letter-spacing": cs.letterSpacing }); } // Lazily wraps a textarea in its own positioning anchor (independent // of .wiktku-resize-wrap, so this doesn't depend on load order versus // wiktkuMakeManualResizable) and inserts the transparent backdrop // layer used to mark the exact point of a linebreak. Safe to call // more than once on the same textarea — the backdrop is cached. function ensureLinebreakBackdrop(textarea) { var existing = textarea.data("wiktkuLinebreakBackdrop"); if (existing) return existing; textarea.wrap("<div class='wiktku-linebreak-wrap'></div>"); var backdrop = $("<div aria-hidden='true'></div>").addClass("wiktku-linebreak-backdrop"); textarea.before(backdrop); textarea.data("wiktkuLinebreakBackdrop", backdrop); textarea.on("scroll.wiktkuLinebreak", function () { backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); }); return backdrop; } // Flags a nimûne/jêgirtin textarea (via CSS class, for the border // tint + tooltip) while it contains a typed/pasted linebreak, so the // user notices before it's silently turned into <br> on output. // Marks only the exact point of the break via a mirrored backdrop, // rather than tinting the whole box. function highlightLinebreak(el) { var textarea = $(el); var text = textarea.val(); var hasBreak = /\r|\n/.test(text); textarea .toggleClass("wiktku-has-linebreak", hasBreak) .attr("title", hasBreak ? "Xeta nû dê wek <br> bê nivîsandin" : ""); if (!hasBreak) { var cached = textarea.data("wiktkuLinebreakBackdrop"); if (cached) cached.hide(); textarea.removeClass("wiktku-has-linebreak-source"); return; } var backdrop = ensureLinebreakBackdrop(textarea); textarea.addClass("wiktku-has-linebreak-source"); syncLinebreakBackdropMetrics(textarea, backdrop); backdrop.html(buildLinebreakBackdropHtml(text)).show(); backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); } // Each nimûne item can be { text, tr, t }: text, transliteration, translation. function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{nimûne?|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = nlToBr(boldPageNameOnce(text)); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + nlToBr(n.tr); // Translation as third positional param (no key needed). if (n.t) tpl += "|" + nlToBr(n.t); } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 60 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } // Formats jêder (citation) entries into "#* {{jêder…|…}}" lines; skips // entries with no quote text. Falls back to the generic {{jêder}} // template when no specific template was chosen. function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; var quote = nlToBr(boldPageNameOnce(jeder.quote)); var quoteTr = nlToBr(jeder.quoteTr); var quoteT = nlToBr(jeder.quoteT); if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + quote; if (quoteTr) cite += "|tr=" + quoteTr; if (quoteT) cite += "|tercime=" + quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + quote; if (quoteTr) out += "|tr=" + quoteTr; if (quoteT) out += "|tercime=" + quoteT; // A şablon picked from Kategorî:Çavkanî is transcluded as the // source param (e.g. |{{Kovara X}}); manual text is used as-is. var srcParam = jeder.jederCatTpl ? ("{{" + jeder.jederCatTpl + "}}") : (jeder.jederManual ? jeder.jederManual : "çavkanî?"); // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } // True if a sense has at least one jêder entry with quote text. function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } // Builds "{{tplName|lang|part1|part2|…}}" from a sense field (kategori, // etiket), wrapped inline (" {{…}} ") or on its own line ("\n#: {{…}}"). function buildSenseTpl(sense, field, lang, tplName) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return call } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } // ── Inline modifier system ─────────────────────────────────────────────── // Appends a ⊕ button to a word input <li>. Clicking it shows a compact // modifier picker; selecting one prompts for the value and appends // <modifier:value> to the textarea's current content. 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îf" }, { 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: qualifier (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" }, { key: "qq", label: "qq: qualifier (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î" } ]; // Sub-groups (inside a sense/definition block) that get the same ⊕ // modifier button as makeWordListStep fields. var MODIFIER_SUBGROUPS = { "wiktku-dfn-alternativ": true, "wiktku-dfn-hevmane": true, "wiktku-dfn-dijmane": true, "wiktku-dfn-koordine": true, "wiktku-dfn-jornav": true, "wiktku-dfn-jernav": true }; /** * Wraps a freshly-created textarea in a <li> with a ⊕ modifier button. * `ta` — the jQuery textarea element. * Returns the <li>. */ function makeModifierLi(ta) { var li = $("<li class='wiktku-word-li'></li>"); var btn = $("<button type='button' class='wiktku-mod-btn' title='Modifiyerê lê zêde bike'>⊕</button>"); var picker = $("<div class='wiktku-mod-picker'></div>").hide(); // Which modifier keys are already present in the textarea's current // text — e.g. "<t:...>" → "t" used. Each modifier can only be // applied once per word, so its pill gets disabled once used. function usedKeys() { var used = {}; var re = /<([a-zA-Z]+):/g; var val = ta.val() || ""; var m; while ((m = re.exec(val)) !== null) used[m[1]] = true; return used; } $.each(WORD_MODIFIERS, function (_, mod) { var pill = $("<button type='button' class='wiktku-mod-pill'></button>").text(mod.label); pill.attr("title", mod.hint); pill.data("mod-key", mod.key); pill.on("click", function (e) { e.preventDefault(); if (pill.prop("disabled")) return; // already used on this word picker.hide(); // Show a tiny inline input for the modifier value. var valWrap = $("<span class='wiktku-mod-val-wrap'></span>"); var valInp = $("<input type='text' class='wiktku-mod-val-input'>") .attr("placeholder", mod.hint + "…") .attr("size", 20); var confirm = $("<button type='button' class='wiktku-mod-confirm'>✓</button>"); var cancel = $("<button type='button' class='wiktku-mod-cancel'>✕</button>"); function applyModifier() { var v = $.trim(valInp.val()); if (v) { ta.val(ta.val() + "<" + mod.key + ":" + v + ">"); ta.trigger("input"); } valWrap.remove(); ta.focus(); } confirm.on("click", applyModifier); cancel.on("click", function () { valWrap.remove(); ta.focus(); }); valInp.on("keydown", function (e) { if (e.which === 13) { e.preventDefault(); applyModifier(); } if (e.which === 27) { valWrap.remove(); ta.focus(); } }); valWrap.append(valInp).append(confirm).append(cancel); li.append(valWrap); valInp.focus(); }); picker.append(pill); }); btn.on("click", function (e) { e.preventDefault(); // Close any other open pickers in the same list. li.closest("ol, ul").find(".wiktku-mod-picker").not(picker).hide(); // Grey out modifiers already used on this word — refreshed on // every open since the text (and thus what's "used") can change. var used = usedKeys(); picker.find(".wiktku-mod-pill").each(function () { var isUsed = !!used[$(this).data("mod-key")]; $(this).prop("disabled", isUsed).toggleClass("wiktku-mod-pill-used", isUsed); }); picker.toggle(); }); // Close picker when focus leaves the li entirely. li.on("focusout", function () { setTimeout(function () { if (!$.contains(li[0], document.activeElement)) picker.hide(); }, 150); }); li.append(ta).append(btn).append(picker); return li; } function makeWordListStep(id, name, question_fmt) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, modifiers: true, // Function instead of a plain string so it can name the current // language — computed fresh at build time and re-applied by // refresh() whenever the language changes. placeholder: function () { var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return "Kelîme" + (langLabel ? " bi " + langLabel : "") + "…"; }, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); var header = capitalize(name); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: {}, visible: function (values) { if (!values.lang) return false; // addLangMode: skip pron only if this lang already has a section. if (addLangMode) { // Clearing the page makes existing content irrelevant. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, // Fills the insert-dropdown from pronTpls, filtered by language. refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); // Rewiye tine, 14 Tebax 2026: "berê bilêvkirin otomatîk // çêdibû, niha zehmettir e ji bo yekî nezan — gelek şablon // hene, kîjan were hilbijartin?" A one-line reassurance: // this field is optional, and the dropdown below writes the // template for you — no need to know the syntax up front. wrap.append( $("<p class='wiktku-step-hint'></p>").text( "Ev qad ne mecbûrî ye. Heke tu nizanî kîjan şablonî hilbijêrî, vale bihêle — an ji pêşkêşkariya jêrîn şablonekî hilbijêre, ew ê bixweber li vir were nivîsandin." ) ); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike "); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); // Clear the picker's search box sel.trigger("wiktku:refresh"); ta.focus(); return; } // Item 5 (Wikihez, 14 Tebax 2026): the noLang templates // (ku-IPA, ku-kîte, zza-IPA, zza-kîte) auto-generate // their actual content from a Lua module reading the // page title — "{{ku-IPA}}" alone gives no hint what // that'll render as, so show a live preview and require // confirmation before inserting, instead of an inline // prompt()/confirm() dialog. var tplLabel = selectedOption.text(); $(this).val(""); sel.trigger("wiktku:refresh"); steps.pron.showTplPreview(stepDiv, ta, snippet, tplLabel); }); wrap.append(sel).append(ta); stepDiv.append(wrap); steps.pron.buildIpaPalette(wrap, ta); initSelects(wrap); return ta; }, // ── IPA character palette (v3 spec, 15 Tebax 2026) ─────────── // Modelled on fr.wiktionary's: every character is a button that // drops itself in at the cursor. Two sub-tabs, because the full // IPA chart is ~180 symbols and roughly twenty of them ever // appear in Kurmancî — "IPA (kurdî)" opens by default and the // full chart is one click away for loanwords and other // languages. Grouped with a label down the left so it reads as // a chart rather than one long line of glyphs. IPA_KU: [ { label: "Kît/stres", chars: ["ˈ", "ˌ", "ː"] }, { label: "Bêdeng", chars: ["d͡ʒ", "t͡ʃ", "ʒ", "ʃ", "ɫ", "ŋ", "ɾ", "r", "ʋ", "ħ", "ʕ", "ɣ", "χ", "ʔ"] }, { label: "Dengdêr", chars: ["ɑː", "eː", "ɛ", "ɪ", "iː", "ɯ", "ʊ", "uː", "yː", "ø", "œ"] } ], IPA_FULL: [ { label: "Bêdeng 1", chars: ["m", "ɱ", "n", "ɳ", "ɲ", "ŋ", "ɴ", "p", "b", "t", "d", "t̪", "d̪", "ʈ", "ɖ", "c", "ɟ", "k", "ɡ", "q", "ɢ", "ʡ", "ʔ"] }, { label: "Bêdeng 2", chars: ["ɸ", "β", "f", "v", "θ", "ð", "s", "z", "ʃ", "ʒ", "ʂ", "ʐ", "ɕ", "ʑ", "ç", "ʝ", "x", "ɣ", "χ", "ʁ", "ħ", "ʕ", "h", "ɦ", "ʜ", "ʢ", "ɧ"] }, { label: "Bêdeng 3", chars: ["ʋ", "ɹ", "ɻ", "j", "ɥ", "ɰ", "ʍ", "w", "ʙ", "ⱱ", "ɾ", "ɽ", "r", "ʀ", "ɺ", "l", "ɫ", "ɬ", "ɮ", "ɭ", "ʎ", "ʟ"] }, { label: "Bêdeng 4", chars: ["ɓ", "ɗ", "ᶑ", "ʄ", "ɠ", "ʛ", "ʘ", "ǀ", "ǃ", "ǂ", "ǁ"] }, { label: "Dengdêr", chars: ["i", "y", "ɪ", "ʏ", "ɨ", "ʉ", "ɯ", "u", "ʊ", "e", "ø", "ɘ", "ɵ", "ɤ", "o", "ə", "ɚ", "ɛ", "œ", "ɜ", "ɝ", "ɞ", "ʌ", "ɔ", "æ", "ɶ", "ɐ", "a", "ɑ", "ɒ"] }, { label: "Suprasegmental", chars: ["ˈ", "ˌ", "ː", "ˑ", "ʼ", "ˀ", "ˤ", "ᵝ", "ᵊ", "ˠ", "ʰ", "ʱ", "ʲ", "ˡ", "ⁿ", "ᵑ", "ʷ", "ᶣ", "˞", "‿"] }, { label: "Dîakrîtîk", chars: ["̚", "̪", "̺", "̻", "̼", "̬", "̊", "̥", "̞", "̝", "̘", "̙", "̽", "̟", "̠", "̈", "̤", "̹", "̜", "̍", "̩", "̆", "̯", "̃", "̰", "͡", "͜"] }, { label: "Ton", chars: ["̋", "́", "̄", "̀", "̏", "̌", "̂", "˥", "˦", "˧", "˨", "˩", "ꜛ", "ꜜ", "↗", "↘", "‖"] } ], /** Builds the two-sub-tab character palette under the textarea. */ buildIpaPalette: function (wrap, ta) { if (wrap.find(".wiktku-ipa-palette").length) return; var panel = $("<div class='wiktku-ipa-panel'></div>").hide(); var toggle = $("<a href='#' class='wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tîpên bilêvkirinê</span>")); toggle.on("click", function (e) { e.preventDefault(); var open = panel.is(":visible"); panel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); wrap.append($("<div class='wiktku-adv-toggle-row'></div>").append(toggle)); // Sub-tab bar, with the two template buttons pinned right. var subTabs = $("<div class='wiktku-ipa-subtabs'></div>"); var kuTab = $("<span class='wiktku-ipa-subtab wiktku-tab-active'>IPA (kurdî)</span>"); var fullTab = $("<span class='wiktku-ipa-subtab'>IPA</span>"); subTabs.append(kuTab).append(fullTab); var tplBtns = $("<span class='wiktku-ipa-tplbtns'></span>"); $.each([ { label: "{{ku-IPA|+}}", snippet: "{{ku-IPA|}}", back: 2 }, { label: "{{IPA|+}}", snippet: "{{IPA|ku|}}", back: 2 } ], function (_, t) { var b = $("<button type='button' class='wiktku-ipa-tplbtn'></button>").text(t.label); b.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], t.snippet); // Park the cursor inside the braces, where the value goes. var pos = ta[0].selectionStart - t.back; ta[0].selectionStart = ta[0].selectionEnd = pos; ta.focus(); }); tplBtns.append(b); }); subTabs.append(tplBtns); panel.append(subTabs); function buildGrid(groups) { var grid = $("<div class='wiktku-ipa-grid'></div>"); $.each(groups, function (_, g) { var row = $("<div class='wiktku-ipa-row'></div>"); row.append($("<span class='wiktku-ipa-rowlabel'></span>").text(g.label)); var keys = $("<span class='wiktku-ipa-keys'></span>"); $.each(g.chars, function (_, ch) { var btn = $("<button type='button' class='wiktku-ipa-key'></button>"); // A combining mark on its own renders as a stray // accent floating over whatever precedes it, so // show it on a dotted circle — but insert only // the mark itself. var combining = /^[̀-ͯ҃-҉]$/.test(ch); btn.text(combining ? "◌" + ch : ch); if (combining) btn.addClass("wiktku-ipa-key-combining"); btn.attr("title", ch); btn.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], ch); ta.focus(); }); keys.append(btn); }); row.append(keys); grid.append(row); }); return grid; } var kuGrid = buildGrid(steps.pron.IPA_KU); var fullGrid = buildGrid(steps.pron.IPA_FULL).hide(); panel.append(kuGrid).append(fullGrid); kuTab.on("click", function () { kuTab.addClass("wiktku-tab-active"); fullTab.removeClass("wiktku-tab-active"); kuGrid.show(); fullGrid.hide(); }); fullTab.on("click", function () { fullTab.addClass("wiktku-tab-active"); kuTab.removeClass("wiktku-tab-active"); fullGrid.show(); kuGrid.hide(); }); panel.addClass("wiktku-ipa-palette"); wrap.append(panel); }, /** Item 5: inline preview + confirm panel for a "noLang" (auto- * content) pronunciation template — fetches what the snippet * actually expands to for this page (via action=expandtemplates, * so the preview is exactly what {{ku-IPA}} etc. would produce) * and only inserts it into the textarea if the user confirms. */ showTplPreview: function (stepDiv, ta, snippet, tplLabel) { // Only one preview panel open at a time. stepDiv.find(".wiktku-pron-preview").remove(); var panel = $("<div class='wiktku-pron-preview'></div>"); panel.append($("<div class='wiktku-pron-preview-label'></div>") .text("Pêşdîtina " + tplLabel + ":")); var body = $("<div class='wiktku-pron-preview-body'></div>").text("Tê barkirin…"); panel.append(body); var actions = $("<div class='wiktku-pron-preview-actions'></div>"); var confirmBtn = $("<button type='button' class='wiktku-pron-preview-confirm'>✓ Tevlî bike</button>") .prop("disabled", true); var cancelBtn = $("<button type='button' class='wiktku-pron-preview-cancel'>✕ Betal bike</button>"); actions.append(confirmBtn).append(cancelBtn); panel.append(actions); ta.before(panel); confirmBtn.on("click", function () { insertAtCursor(ta[0], snippet); panel.remove(); ta.focus(); }); cancelBtn.on("click", function () { panel.remove(); }); // action=parse, not action=expandtemplates. expandtemplates // returns *expanded wikitext*, so the preview read as // [[IPA]]<sup>([[Wîkîferheng:IPA kurmancî|kilîd]])</sup>: // <span class="IPA">/-{kshhe}-/</span>[[Kategorî:…]] — which // is exactly what the person is trying to avoid having to // read. parse hands back the rendered HTML the page will // actually show. // // Drop the leading "* " first: it is wikitext list syntax // wrapping the template, and keeping it would render the // preview as a bulleted list rather than the line itself. new mw.Api().post({ action: "parse", title: pageName, text: snippet.replace(/^\*\s*/, ""), prop: "text", wrapoutputclass: "", disablelimitreport: 1, disableeditsection: 1, contentmodel: "wikitext", formatversion: 2 }).done(function (data) { var html = (data && data.parse && data.parse.text) || ""; if ($.trim($("<div>").html(html).text())) { body.html(html); // Category links render as nothing but still exist; // and any real link inside a preview should not // navigate away from a half-filled form. body.find("a").attr("target", "_blank").attr("rel", "noopener"); } else { body.text("(vala — ji bo vê rûpelê tiştek nehate afirandin)"); } confirmBtn.prop("disabled", false); }).fail(function () { body.text("Pêşdîtin nehate barkirin — tu dikarî hîn jî wê tevlî bikî."); confirmBtn.prop("disabled", false); }); }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line; }).join("\n"); // Back to "===", under Ziman and above the POS sections // (v3 spec, 15 Tebax 2026). It had been nested at "====" // inside each POS section per Ghybu's earlier note, but the // field is shared across sections, so a two-POS entry // printed the identical pronunciation twice — once under // Navdêr and once under Lêker. Emitted once by getWikitext() // now, not by getWikitextForCurrentSection(). return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var capitalizedPos = capitalize(pos); // "form" opt-param (checked in posparams) marks this as a // form-of/inflected entry — the section title becomes // "Formeke <pos>ê" instead of the plain pos name. The // template call itself still uses the unchanged pos name. var isForm = $("#wiktku-posparams-opt-form").is(":checked"); var header = isForm ? "\n=== Formeke " + pos + "ê ===\n" : "\n=== " + capitalizedPos + " ===\n"; // Image line (between header and template call) var imageLine = steps.resim.output(values); // Read the live wikitext from the posparams textarea. // Fall back to a plain {{pos|lang}} if the step hasn't been built yet. var tplLine = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); if (!tplLine) { tplLine = "{{" + pos + "|" + (values.lang || "") + "}}"; } return header + imageLine + tplLine + "\n"; } }, // cinsiyet (gender) — shown for navdêr/serenav only, with choices built // from metadata[lang].g since not every language has grammatical gender. cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams // Single source of truth for the selected gender code. The visible // dropdown lives inside the posparams step (see steps.posparams), // but it must always read/write THIS hidden field — not a field of // its own — since getValuesForStep("cinsiyet") reads from here. build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-cinsiyet-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // Item 1 (Wikihez, 14 Tebax 2026): jimar (grammatical number) — same // hidden-field pattern as cinsiyet just above, but writes into its // own j= template parameter instead of sharing c=. Shown for // navdêr/serenav only, with choices built from whichever of // metadata[lang].g are number codes (see isNumberCode) — mirrors // cinsiyet exactly, just filtered to the other half of that list. jimar: { id: "jimar", name: "jimar", question_fmt: 'Jimara "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-jimar-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // Lêker transitivity — hidden step, handled inside posparams lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function () { return false; }, choices: [ { code: "gh", label: "gerguhêz" }, { code: "x-gh", label: "xwerû-gerguhêz" }, { code: "p-gh", label: "pêkhatî-gerguhêz" }, { code: "h-gh", label: "hevedudanî-gerguhêz" }, { code: "b-gh", label: "biwêjî-gerguhêz" }, { code: "ngh", label: "negerguhêz" }, { code: "x-ngh", label: "xwerû-negerguhêz" }, { code: "p-ngh", label: "pêkhatî-negerguhêz" }, { code: "h-ngh", label: "hevedudanî-negerguhêz" }, { code: "b-ngh", label: "biwêjî-negerguhêz" } ], output: function () { return ""; } }, // tr — hidden step, handled inside posparams tr: { id: "tr", name: "transliterasyon", question_fmt: "Transliterasyona vê kelîmeyê", multiple: false, narrow: true, visible: function () { return false; } }, posparams: { id: "posparams", // Fused onto the "pos" card visually (see #wiktku-start-posparams // in styles.css) so the two read as ONE question, per Ghybu's // 14 Tebax 2026 feedback — this name is only a no-CSS/no-JS // fallback, since the h3 that would show it is hidden by CSS. name: "taybetmendî", // The old static "Parametreyên cureyê rêzimanî" label named the // mechanism, not the content. Show what's actually being asked // for instead: gender for nouns, verb type for verbs, a generic // fallback (transliteration/forms etc. still apply) otherwise. question_fmt: function (values) { var pos = values.pos || ""; // Wikihez, 15 Tebax 2026: the "Cins/zayend" title itself was // redundant with the fields right below it (Cinsiyet/Jimar are // self-labelled) and just added visual noise — dropped, but the // box/fields stay exactly as before. lêker/fallback titles are // unaffected since they weren't the ones flagged. if (pos === "navdêr" || pos === "serenav") return ""; if (/^lêker/.test(pos)) return "Cureyê lêkerê"; return "Taybetmendî"; }, visible: function (values) { return !!(values.lang && values.pos); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-posparams-wrap").length) return null; var wrap = $("<div class='wiktku-posparams-wrap'></div>"); var helpers = $("<div class='wiktku-posparams-helpers'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-posparams-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-posparams-text") .attr("rows", 2); var _rebuilding = false; function safeRebuild() { if (_rebuilding) return; _rebuilding = true; steps.posparams.rebuildTa(stepDiv); _rebuilding = false; refresh(); } // Generic text-input row factory function makeTextRow(key, labelText, placeholder) { var row = $("<div class='wiktku-posparams-row'></div>") .attr("id", "wiktku-posparams-row-" + key).hide(); var inp = $("<input type='text'>") .addClass("wiktku-start-narrow wiktku-posparams-field") .attr("data-pp-key", key) .attr("placeholder", placeholder || ""); inp.on("input", safeRebuild); row.append($("<label></label>").text(labelText + ": ")).append(inp); return row; } // cinsiyet var cinsiyetRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-c'></div>") .append($("<label></label>").text("Cinsiyet: ")).hide(); var cinsiyetSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-cinsiyet-sel") .append($("<option value=''>— hilbijêre —</option>")); // Writes into the real, shared #wiktku-start-cinsiyet-field (owned by // steps.cinsiyet) rather than a field of its own — see the comment // on steps.cinsiyet.build for why that matters. cinsiyetSel.on("change", function () { $("#wiktku-start-cinsiyet-field").val($(this).val()).trigger("change"); safeRebuild(); }); cinsiyetRow.append(cinsiyetSel); // Item 1 (Wikihez, 14 Tebax 2026): jimar (number) — a second // dropdown next to Cinsiyet, same pattern (writes into the // shared hidden #wiktku-start-jimar-field), but into its own // j= param instead of sharing c=. Options + the title // tooltip (explanation) are built in syncHelpers, once the // language's number codes are known. var jimarRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-jimar'></div>") .append($("<label></label>").text("Jimar: ")).hide(); var jimarSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-jimar-sel") .append($("<option value=''>— hilbijêre —</option>")); jimarSel.on("change", function () { $("#wiktku-start-jimar-field").val($(this).val()).trigger("change"); safeRebuild(); }); jimarRow.append(jimarSel); // lektur — Ghybu, 14 Tebax 2026: "'Cureyê lêkerê' nayê fêm // kirin, bi min pêşta 'gerguhez/negerguhêz' were hilbijartin, // paşê jî form 'hevdudanî/pêkatî/…' ji ber ku her kes vana // nizanî." So the one 10-option dropdown ("xwerû-gerguhêz", // "biwêjî-negerguhêz", …) becomes two plain questions. The // emitted code is unchanged: base alone ("gh"), or prefix + // "-" + base ("x-gh") — exactly the codes steps.lektur.choices // already listed, just assembled from two answers instead of // asked as one. var lekturRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lektur'></div>") .append($("<label></label>").text("Lêker derbasdar e? ")).hide(); var lekturSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lektur-sel") .append($("<option value=''>— hilbijêre —</option>")) .append($("<option value='gh'>gerguhêz (bireser digire)</option>")) .append($("<option value='ngh'>negerguhêz (bireser nagire)</option>")); lekturSel.on("change", safeRebuild); lekturRow.append(lekturSel); // Second half of the same question — the structural form. // Blank = xwerû/sade, which is the common case. var lekturFormRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lekturform'></div>") .append($("<label></label>").text("Şiklê lêkerê: ")).hide(); var lekturFormSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lekturform-sel") .append($("<option value=''>sade (asayî)</option>")) .append($("<option value='x'>xwerû</option>")) .append($("<option value='p'>pêkhatî</option>")) .append($("<option value='h'>hevedudanî</option>")) .append($("<option value='b'>biwêjî</option>")); lekturFormSel.on("change", safeRebuild); lekturFormRow.append(lekturFormSel); helpers.append(cinsiyetRow).append(jimarRow).append(lekturRow).append(lekturFormRow); // ── Everything below here is "Tercîhên pêşketî" ────────────── // Ghybu, 14 Tebax 2026: "Tenê 'cîns' û 'jimar' bes e. 'Forma // mê', 'Forma nêr', … nayê fêm kirin. Bi min wekî 'Tercîhên // pêşketî' bi navkî din veşartî çêke." The rows themselves are // unchanged and syncHelpers still shows/hides each one by id // exactly as before — they just live inside a collapsed panel // now, so the default view of this card is two dropdowns // instead of twenty-odd fields. // Transliteration is a primary field, not an advanced one, for // any language not written in Latin script: for those, an // entry without it is incomplete. syncHelpers already gates // the row on needsTransliteration(lang), so for Kurmancî and // other Latin-script languages it simply never appears. helpers.append(makeTextRow("tr", "Transliterasyon (tr)", "Transliterasyon…")); var advPanel = $("<div class='wiktku-posparams-adv-panel'></div>").hide(); advPanel .append(makeTextRow("cuda", "nîşankirina alternatîv", "cuda…")) .append(makeTextRow("ts", "Transkrîpsiyon (ts)", "Transkrîpsiyon…")) .append(makeTextRow("m", "Forma mê (m)", "Forma mê…")) .append(makeTextRow("mtr", "Translit. mê (mtr)", "Transliterasyona mê…")) .append(makeTextRow("n", "Forma nêr (n)", "Forma nêr…")) .append(makeTextRow("ntr", "Translit. nêr (ntr)", "Transliterasyona nêr…")) .append(makeTextRow("p", "Forma pirjimar (p)", "Forma pirjimar…")) .append(makeTextRow("ptr", "Translit. pirjimar", "Transliterasyona pirjimar…")) .append(makeTextRow("y", "Forma yekjimar (y)", "Forma yekjimar…")) .append(makeTextRow("ytr", "Translit. yekjimar", "Transliterasyona yekjimar…")) .append(makeTextRow("sûp", "Forma sûperlatîv (sûp)", "Forma sûperlatîv…")) .append(makeTextRow("sûptr", "Translit. sûperlatîv", "Transliterasyona sûperlatîv…")) .append(makeTextRow("komp", "Forma komparatîv (komp)", "Forma komparatîv…")) .append(makeTextRow("komptr", "Translit. komparatîv", "Transliterasyona komparatîv…")) .append(makeTextRow("gir", "Forma girdêk (gir)", "gir=…")) .append(makeTextRow("girtr", "Translit. gir", "girtr=…")) .append(makeTextRow("hûr", "Forma hûrek (hûr)", "hûr=…")) .append(makeTextRow("hûrtr", "Translit. hûr", "hûrtr=…")) .append(makeTextRow("hanja", "Forma hanja", "hanja=…")) .append(makeTextRow("hanjaTr","Translit. hanja", "hanjaTr=…")) // Lêker rehên demê (only shown when pos is lêker — see syncHelpers) .append(makeTextRow("niha", "Rehê dema niha (niha)", "Rehê dema niha…")) .append(makeTextRow("nihatr", "Translit. rehê dema niha", "Transliterasyona rehê dema niha…")) .append(makeTextRow("borî", "Rehê dema borî (borî)", "Rehê dema borî…")) .append(makeTextRow("borîtr", "Translit. rehê dema borî", "Transliterasyona rehê dema borî…")) .append(makeTextRow("subj", "Rehê dema bilanî (subj)", "Rehê dema bilanî…")) .append(makeTextRow("subjtr", "Translit. rehê dema bilanî", "Transliterasyona rehê dema bilanî…")); // Optional boolean params — nested inside the advanced panel // (they were already the most niche thing on the card). var optPanel = $("<div class='wiktku-posparams-opt-panel'></div>"); $.each([ { key: "form", label: "form — ev made forma tewandî ye" }, { key: "formaalt", label: "formaalt — vê madeyê bike forma alternatîv" }, { key: "nekatcure", label: "nekatcure — sinifa rêzimanî kategorîze neke" }, { key: "nekatcins", label: "nekatcins — kategoriya cinsiyetê neyîne" }, { key: "nekatçendterm", label: "nekatçendterm — kategoriya çend-term neyîne" }, { key: "serlînkneke", label: "serlînkneke — sernavê madeyê lînk neke" }, { key: "nekatpalîndrom", label: "nekatpalîndrom — kategoriya palîndromê neyîne" }, { key: "neformtr", label: "neformtr — transliterasyona forman neyîne" } ], function (_, p) { var cb = $("<input type='checkbox'>") .attr("id", "wiktku-posparams-opt-" + p.key).val(p.key).on("change", safeRebuild); var lbl = $("<label></label>").attr("for", "wiktku-posparams-opt-" + p.key).text(" " + p.label); optPanel.append($("<div class='wiktku-posparams-opt-row'></div>").append(cb).append(lbl)); }); advPanel.append(optPanel); var optToggle = $("<a href='#' class='wiktku-posparams-opt-toggle wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tercîhên pêşketî</span>")); // Wikihez, 15 Tebax 2026: the "N zevî · M tije" count badge // was removed (not needed) — the toggle itself still opens/ // closes the panel exactly as before. optToggle.on("click", function (e) { e.preventDefault(); var open = advPanel.is(":visible"); advPanel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); helpers.append($("<div class='wiktku-adv-toggle-row'></div>") .append(optToggle)); helpers.append(advPanel); wrap.append(helpers).append(ta); // Typing directly in textarea keeps cinsiyet/jimar hidden // fields in sync, but does NOT call refresh() — preserves // manual edits. ta.on("input", function () { var text = $(this).val(); var cMatch = text.match(/\|c=([^|}\s]+)/); $("#wiktku-start-cinsiyet-field").val(cMatch ? cMatch[1] : ""); var jMatch = text.match(/\|j=([^|}\s]+)/); $("#wiktku-start-jimar-field").val(jMatch ? jMatch[1] : ""); }); stepDiv.append(wrap); return null; }, /** Reads all helper widget values and rewrites the textarea. * Called only by safeRebuild (user interaction) — never by syncHelpers, * so manual textarea edits are never overwritten by a refresh cycle. */ rebuildTa: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; if (!pos || !lang) return; var cinsiyet = stepDiv.find(".wiktku-posparams-cinsiyet-sel").val() || ""; var jimar = stepDiv.find(".wiktku-posparams-jimar-sel").val() || ""; // Two dropdowns, one code: "gh" / "ngh" on their own, or // prefixed with the structural form ("x-gh", "b-ngh", …). var lekturBase = stepDiv.find(".wiktku-posparams-lektur-sel").val() || ""; var lekturForm = stepDiv.find(".wiktku-posparams-lekturform-sel").val() || ""; var lektur = lekturBase ? (lekturForm ? lekturForm + "-" + lekturBase : lekturBase) : ""; function v(key) { return $.trim(stepDiv.find(".wiktku-posparams-field[data-pp-key='" + key + "']").val()); } var out = "{{" + pos + "|" + lang; if (pos === "navdêr" || pos === "serenav") { out += cinsiyet ? "|c=" + cinsiyet : (lang === "ku" ? "|c=?" : ""); // Item 1: number is its own j= param now, separate from // c= — c= keeps holding gender (and gender+plural // compounds like m-p/n-p, unaffected by this change). if (jimar) out += "|j=" + jimar; } else if (/^lêker/.test(pos) && lektur) { out += "|c=" + lektur; } if (v("cuda")) out += "|" + v("cuda"); if (v("tr")) out += "|tr=" + v("tr"); if (v("ts")) out += "|ts=" + v("ts"); $.each(["m","n","p","y"], function (_, k) { if (v(k)) out += "|" + k + "=" + v(k); if (v(k+"tr")) out += "|" + k + "tr=" + v(k+"tr"); }); if (v("sûp")) out += "|sûp=" + v("sûp"); if (v("sûptr")) out += "|sûptr=" + v("sûptr"); if (v("komp")) out += "|komp=" + v("komp"); if (v("komptr")) out += "|komptr=" + v("komptr"); if (v("gir")) out += "|gir=" + v("gir"); if (v("girtr")) out += "|girtr=" + v("girtr"); if (v("hûr")) out += "|hûr=" + v("hûr"); if (v("hûrtr")) out += "|hûrtr=" + v("hûrtr"); if (v("hanja")) out += "|hanja=" + v("hanja"); if (v("hanjaTr")) out += "|hanjaTr=" + v("hanjaTr"); if (v("niha")) out += "|niha=" + v("niha"); if (v("nihatr")) out += "|nihatr=" + v("nihatr"); if (v("borî")) out += "|borî=" + v("borî"); if (v("borîtr")) out += "|borîtr=" + v("borîtr"); if (v("subj")) out += "|subj=" + v("subj"); if (v("subjtr")) out += "|subjtr=" + v("subjtr"); stepDiv.find(".wiktku-posparams-opt-panel input:checked").each(function () { var key = $(this).val(); // "form" marks this entry as a form-of/inflected entry — it // takes "erê" rather than the plain "1" the other boolean // opt params use. out += "|" + key + "=" + (key === "form" ? "erê" : "1"); }); out += "}}"; stepDiv.find(".wiktku-posparams-text").val(out); $("#wiktku-start-cinsiyet-field").val(cinsiyet); $("#wiktku-start-jimar-field").val(jimar); }, /** Called from refresh() — controls row visibility only. * Does NOT rewrite textarea so user edits are preserved. * Rebuilds only when textarea is empty (first pos selection). */ syncHelpers: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; var needsTr = needsTransliteration(lang); var isNom = pos === "navdêr" || pos === "serenav" || pos === "rengdêr"; var isAdj = pos === "rengdêr"; var isTîp = pos === "tîp"; var isJa = lang === "ja"; var isLeker = /^lêker/.test(pos); // Item 1: metadata[lang].g used to list gender AND number // codes together — split them here (see isNumberCode) so // Cîns only ever offers gender codes (and gender+plural // compounds like m-p/n-p, which aren't NUMBER_LABELS keys) // and the new Jimar dropdown only offers number codes. var meta = metadata[lang]; var allCodes = (meta && meta.g) || []; var genderCodes = $.grep(allCodes, function (c) { return !isNumberCode(c); }); var jimarCodes = $.grep(allCodes, function (c) { return isNumberCode(c); }); var showC = (pos === "navdêr" || pos === "serenav") && genderCodes.length > 0; var cRow = stepDiv.find("#wiktku-posparams-row-c"); cRow.toggle(showC); if (showC) { var sel = cRow.find(".wiktku-posparams-cinsiyet-sel"); // Prefer the select's own current value (normal in-session // use); fall back to the shared hidden field, which is how // a cache/section restore communicates a saved gender // before this select has any <option>s to hold it. var prev = sel.val() || $("#wiktku-start-cinsiyet-field").val() || ""; sel.find("option[value!='']").remove(); $.each(genderCodes, function (_, code) { sel.append($("<option></option>").val(code).text(genderLabel(code))); }); if (prev) sel.val(prev); } var showJimar = (pos === "navdêr" || pos === "serenav") && jimarCodes.length > 0; var jimarRowEl = stepDiv.find("#wiktku-posparams-row-jimar"); jimarRowEl.toggle(showJimar); if (showJimar) { var jimarSelEl = jimarRowEl.find(".wiktku-posparams-jimar-sel"); var prevJimar = jimarSelEl.val() || $("#wiktku-start-jimar-field").val() || ""; jimarSelEl.find("option[value!='']").remove(); $.each(jimarCodes, function (_, code) { var def = NUMBER_LABELS[code] || {}; var opt = $("<option></option>").val(code).text(numberOptionLabel(code)); // The explanation (cat, e.g. "dualia tantum") shows as a // hover tooltip — <option> can't hold richer markup. if (def.cat) opt.attr("title", def.cat); jimarSelEl.append(opt); }); if (prevJimar) jimarSelEl.val(prevJimar); } stepDiv.find("#wiktku-posparams-row-lektur").toggle(isLeker); // Only ask for the structural form once the person has said // gerguhêz/negerguhêz — "paşê jî form", per Ghybu. stepDiv.find("#wiktku-posparams-row-lekturform") .toggle(isLeker && !!stepDiv.find(".wiktku-posparams-lektur-sel").val()); stepDiv.find("#wiktku-posparams-row-tr").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-ts").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-m").toggle(isNom); stepDiv.find("#wiktku-posparams-row-mtr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-n").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ntr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-p").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ptr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-y").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ytr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-sûp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-sûptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-komp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-komptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-gir").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-girtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hûr").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-hûrtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hanja").toggle(isJa); stepDiv.find("#wiktku-posparams-row-hanjaTr").toggle(isJa); stepDiv.find("#wiktku-posparams-row-niha").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-nihatr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-borî").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-borîtr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-subj").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-subjtr").toggle(isLeker && needsTr); if (!$.trim(stepDiv.find(".wiktku-posparams-text").val())) { steps.posparams.rebuildTa(stepDiv); } }, output: function () { return ""; } // pos.output reads the textarea directly }, dfn: { id: "dfn", name: "Mane", // Field types that live behind "Malûmatên pêşketî". Kept as one // list so the collapse CSS, the count badge and the allGroups // adv: flags below can't drift apart. ADV_SUBGROUPS: [ "wiktku-dfn-etiket", "wiktku-dfn-kategori", "wiktku-dfn-alternativ", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ], question_fmt: function (values) { var base = "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin!"; if (values.lang === "ku") { return base + " Ji bo tercimeyan beşa 'Werger' bi kar bîne!"; } return base; }, multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, // Builds one sense block (<li>): mane textarea, nimûne list, and // sub-lists for alternatîv/hevmane/dijmane/etc. buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Tercime + Îzah boxes (non-ku alternative to the plain mane box) — // Non-ku entries get a direct translation plus a {{îzah|…}}-wrapped // gloss instead of a Kurdish-style gloss. Rather than teach every // consumer (getSenses/getOutput/linkify) a second data shape, these // boxes just write their combined text into dfnArea and re-fire its // "input" event, so dfnArea stays the single source of truth. var tercimeArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-tercime-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-tercime") .attr("rows", 2) .attr("placeholder", "Tercimeyên rasterast ên kurmancî… Ji bo school-a îngilîzî li vir 'mekteb, medrese' binivîse"); var izahArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-izah-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-izah") .attr("rows", 3) .attr("placeholder", "Îzaha kurmancî… Ji bo school-a îngilîzî li vir 'cihê tehsîlgirtinê' binivîse"); var nonKuWrap = $("<div class='wiktku-dfn-nonku-wrap'></div>") .append(tercimeArea).append(izahArea) .hide(); function syncNonKuToMane() { var t = $.trim(tercimeArea.val()); var iz = $.trim(izahArea.val()); // if tercime is blank, use îzah as definition var combined = t ? (iz ? t + " {{îzah|" + iz + "}}" : t) : iz; dfnArea.val(combined); // Re-fires onDfnInput so the sense list still grows and // refresh() still runs, exactly as if this were typed // directly into the mane textarea. dfnArea.trigger("input"); } tercimeArea.on("input", syncNonKuToMane); izahArea.on("input", syncNonKuToMane); // Switches between the plain mane box and the tercime+îzah pair — // only for non-ku entries with no tplSelect selected. function updateManeMode() { var lang = getValues().lang || ""; var isTpl = !!tplSelect.val(); if (lang && lang !== "ku" && !isTpl) { dfnArea.hide(); nonKuWrap.show(); } else { nonKuWrap.hide(); if (!isTpl) dfnArea.show(); } } // Store on the block so refresh() can re-sync every block when // lang changes, and restoreDfn() can re-sync after restoring. block.data("updateManeMode", updateManeMode); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || {}; // Cache of all non-placeholder option elements, so updateTplOptions // can detach/re-attach them without losing the full list. var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.attr("data-placeholder", "Li şablonekê bigere"); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (name, tpl) { // Rewiye tine, 14 Tebax 2026: "guharto? kevnbûyî? ku-Latn? // şaşnivîs? famkirina van zehmet e" — these 13 names had // zero explanation in the dropdown (unlike steps.pron's // template picker, which already shows "name — tpl.desc"). // Mirrors that same pattern here: if tpl.desc is ever // added to a tplDefs entry in data.json, it'll show up // automatically. It's optional per-entry, not required, // since data.json doesn't have desc text for these yet — // writing accurate one-line explanations for each needs // someone who actually knows what each template does. var opt = $("<option></option>") .val(name) .text(tpl.desc ? name + " — " + tpl.desc : name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); // v3: the same status-dot / 🔗 / ⓘ row treatment as every // other template picker. This one carries the bare name in // value=, so the name mapper is the identity rather than a // snippet parse. It also answers Rewiye tine's "famkirina // van zehmet e" about these thirteen names properly — the // explanation now comes from each template's own // TemplateData instead of waiting for someone to hand-write // thirteen desc strings into data.json. markTemplateOptions(tplSelect, function (opt) { return opt.val(); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible // ones — native <select> won't reliably hide options any other way. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); // Options that were detached when the descriptions arrived // missed that pass, so describe whatever is attached now. // The cache is warm by this point, so this is synchronous. applyTplDescriptions(tplSelect); tplSelect.trigger("wiktku:refresh"); if (currentVal && !currentStillValid) { tplSelect.val(""); tplTitleInput.hide().val(""); updateManeMode(); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpela hedefê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // Şablon senses have no plain gloss, so hide alternatîv/hevmane/ // dijmane/etc. Etîket, Nimûne and Jêgirtin stay visible either way. function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); nonKuWrap.hide(); tplTitleInput.show().focus(); } else { tplTitleInput.hide().val(""); updateManeMode(); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); // The template picker is an alternative to writing a // definition, not a step before it — so the box comes first // and this sits under it as a quiet link. It only expands // for the minority of senses that are a pointer at another // word (guharto, şaşnivîs, kevnbûyî) rather than a meaning. var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput) .hide(); var tplLink = $("<a href='#' class='wiktku-dfn-tpl-link'></a>") .text("Ev ne pênase ye — şablonek bi kar bîne"); tplLink.on("click", function (e) { e.preventDefault(); tplRow.show(); $(this).hide(); tplRow.find("input.wiktku-ac-input").first().focus(); }); /** Opens the picker without a click — used on restore, when a * sense already has a template and hiding it would make the * chosen value invisible. */ function revealTplRow() { tplRow.show(); tplLink.hide(); } block.data("revealTplRow", revealTplRow); block.append(dfnArea); block.append(nonKuWrap); block.append(tplLink); block.append(tplRow); // Apply lang filter on initial build. updateTplOptions(); updateManeMode(); // — Sub-field groups. — // Ghybu, 14 Tebax 2026: "Bi min beşên 'Hevmane' û dijmane jî // bike de nav beşa Mane ji ber ku pirr tên xwestin" — and, // separately, that showing all nine at once is what makes this // form read as long and tevlihev. So the four people actually // reach for (Nimûne, Jêgirtin, Hevmane, Dijmane) stay open, in // that order, and the other five sit behind the "Malûmatên // pêşketî" toggle (adv: true → .wiktku-dfn-subgroup-adv, which // is what the collapse CSS keys off now). // Jêgirtin isn't in this array — it's a compound widget built // after the loop — but it's inserted right after Nimûne so the // visible order matches the list above. var allGroups = [ { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "wekî etîket lê xuya nabe tenê kategorîze dike", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê", adv: true }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in", adv: true }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e", adv: true }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e", adv: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); if (g.adv) groupDiv.addClass("wiktku-dfn-subgroup-adv"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } // The placeholder names the current language, but that's // often not chosen yet when this block is first built — // so keep a function around that refresh() (and onSubInput, // for newly-grown fields) can call again once lang is set // or changes. function subPlaceholder() { if (g.noLangSuffix) return g.label + "…"; var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return g.label + (langLabel ? " bi " + langLabel : "") + "…"; } function updateSubPlaceholders() { list.find("> li > textarea.wiktku-dfn-subfield").attr("placeholder", subPlaceholder()); } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": ") .append($("<span></span>").addClass("wiktku-dfn-sublabel-hint").text(g.izah)); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var useModifiers = !!MODIFIER_SUBGROUPS[g.cls]; list.data("updatePlaceholders", updateSubPlaceholders); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", subPlaceholder()); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow, useModifiers); }); list.append(useModifiers ? makeModifierLi(firstInput) : $("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder group — growing list, same structure as Nimûne. — (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text("Jêgirtin")) .append(": "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<textarea></textarea>") .addClass("wiktku-dfn-subfield wiktku-dfn-quote-citoid-input") .attr("rows", 1) .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi otomatîk tijî bike", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); // Fetches citation data from Citoid and fills this citation's // şablon + fields — only rebuilds fields on template change, // and never overwrites values the user already typed. function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoid.fetchJederFields(query).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only rebuild if switching şablon, so a repeat fetch // doesn't clear fields already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel wiktku-plain-select"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); srcSel.append($("<option></option>").val("__category__").text("Ji Kategorî:Çavkanî şablonekê hilbijêre")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); // Citoid is only useful before a source is chosen — // hide it once a selection is made, restore on reset. if (chosen) { citoidWrap.hide(); } else { citoidWrap.show(); return; } if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } if (chosen === "__category__") { // Search widget over the members of [[Kategorî:Çavkanî]]. // Picking a şablon here immediately switches the row to // "Bi destê xwe binivîsim" mode with {{Şablon}} pre-filled, var catWrap = $("<span></span>").addClass("wiktku-native-select-wrap wiktku-dfn-quote-src-cat"); var catInput = $("<input type='search' autocomplete='off'>") .addClass("wiktku-start-narrow wiktku-dfn-quote-src-cat-input") .attr("placeholder", "Li navê şablonê bigere…"); var catResults = $("<ul></ul>").addClass("wiktku-ac-results wiktku-dfn-quote-src-cat-results").hide(); var catStatus = $("<span></span>").addClass("wiktku-dfn-quote-src-cat-status").text("Şablon tên barkirin…"); var showCatResults = function (query) { var q = $.trim(query).toLowerCase(); catResults.empty(); var list = catSrcTemplates || []; var matched = q ? $.grep(list, function (name) { return name.toLowerCase().indexOf(q) !== -1; }) : list; if (!matched.length) { catResults.hide(); return; } $.each(matched.slice(0, 50), function (_, name) { var li = $("<li></li>").text(name).attr("data-value", name); var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; e.preventDefault(); selectCatTpl(name); }); li.on("mousedown", function (e) { e.preventDefault(); selectCatTpl(name); }); catResults.append(li); }); catResults.show(); }; // Wraps the chosen şablon as {{Name}}, drops it into the // manual textarea, and switches the row into manual mode // so the user can keep editing it (add params, etc.). var selectCatTpl = function (name) { catResults.hide(); srcSel.val("__manual__"); srcSel.trigger("change"); srcFields.find(".wiktku-dfn-quote-src-manual") .val("{{" + name + "}}") .trigger("focus"); }; catInput.on("input", function () { showCatResults($(this).val()); }); catInput.on("focus", function () { showCatResults($(this).val()); }); catInput.on("blur", function () { setTimeout(function () { catResults.hide(); }, 200); }); catWrap.append(catInput).append(catResults).append(catStatus); srcFields.append(catWrap); fetchCatSrcTemplates().then(function () { catStatus.text(""); }, function () { catStatus.text("Şablon nehatin barkirin."); }); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (key, label) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", key) .attr("placeholder", label + "…"); // "Sernav" / "Sernavê orjînal" (title fields, e.g. for // kitêb/kovar/malper) get a taller, draggable box; every // other field in the template stays as-is. Field labels // come from the on-wiki jederDefs data, so match on the // (diacritic-folded) label text rather than a fixed key. var foldedLabel = foldDiacritics(label); if (/^sernav$/.test(foldedLabel) || /orjin/.test(foldedLabel)) { inp.addClass("wiktku-dfn-quote-src-input--title"); } row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); jederGroupDiv.append(jederLbl).append(jederList); // Straight after Nimûne rather than last: Jêgirtin is the // same kind of thing (an attested use of the word) and the // two belong together — see the allGroups comment above. var nimuneGroup = block.find(".wiktku-dfn-nimune-group"); if (nimuneGroup.length) jederGroupDiv.insertAfter(nimuneGroup); else block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); // ── "Malûmatên pêşketî" — per sense, after Dijmane ─────── // One toggle per sense rather than one for the whole step: // the fields behind it (Etîket, Kategorî, Jornav…) belong to // a single meaning, so a global switch flipped them for every // sense at once and gave a count that answered "across all // senses" — not a question anybody was asking. (function () { block.addClass("wiktku-sense-adv-hidden"); var advRow = $("<div class='wiktku-adv-toggle-row wiktku-sense-adv-row'></div>"); var advToggle = $("<a href='#' class='wiktku-adv-toggle'></a>").attr("aria-expanded", "false"); var advLabel = $("<span class='wiktku-adv-toggle-text'></span>"); advToggle.append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")).append(advLabel); // Wikihez, 15 Tebax 2026: the "N zevî · M tije" count badge // was removed (not needed) — syncAdv still keeps the // toggle's own label/chevron/aria-expanded in sync. function syncAdv() { var hidden = block.hasClass("wiktku-sense-adv-hidden"); advLabel.text(hidden ? "Malûmatên pêşketî nîşan bide" : "Malûmatên pêşketî veşêre"); advToggle.attr("aria-expanded", hidden ? "false" : "true") .toggleClass("wiktku-adv-open", !hidden); } advToggle.on("click", function (e) { e.preventDefault(); block.toggleClass("wiktku-sense-adv-hidden"); syncAdv(); }); block.data("syncSenseAdv", syncAdv); advRow.append(advToggle); // After the last always-visible group (Dijmane) and before // the advanced ones, which sit below it in DOM order. var lastPrimary = block.find(".wiktku-dfn-dijmane-group"); if (lastPrimary.length) advRow.insertAfter(lastPrimary); else block.append(advRow); syncAdv(); }()); // ── Accordion wrapper (v3 spec) ────────────────────────── // Everything built above becomes the collapsible body, and a // header row goes in front of it. Done here, at the end, // rather than by threading a container through the ~500 lines // of field-building above — every one of those appends to // `block`, and getSenses/restoreDfn reach fields with .find(), // which doesn't care how deep they sit. var body = $("<div class='wiktku-dfn-sense-body'></div>").append(block.children()); var header = $("<div class='wiktku-dfn-sense-header'></div>"); header .append($("<span class='wiktku-dfn-sense-num'></span>")) .append($("<span class='wiktku-dfn-sense-title'></span>")) .append($("<span class='wiktku-dfn-sense-summary'></span>")) .append($("<span class='wiktku-dfn-sense-chevron'>▾</span>")); header.on("click", function () { // Collapsed → open it (and close whichever was open). // Open → collapse it, unless it's the only one. if (block.hasClass("wiktku-sense-collapsed")) steps.dfn.setOpenSense(stepDiv, block); else block.addClass("wiktku-sense-collapsed"); steps.dfn.syncSenseHeaders(stepDiv); }); block.append(header).append(body); // Typing (or clicking) anywhere in a sense makes it the open // one — "tenê maneya ku tê nivîsandin vekirî ye". body.on("focusin", function () { if (!block.hasClass("wiktku-sense-collapsed")) { steps.dfn.setOpenSense(stepDiv, block); } }); return block; }, /** True if a sense block has anything worth summarising. */ senseBlockHasContent: function (block) { var found = false; block.find("textarea, input[type='text']").each(function () { if ($.trim($(this).val() || "")) { found = true; return false; } }); if (found) return true; return !!block.find(".wiktku-dfn-tpl-select").val(); }, /** Opens `block` and collapses every other sense that has content. * A sense with nothing in it is never collapsed — the trailing * empty one is how you add the next meaning, so hiding it would * hide the only way forward. */ setOpenSense: function (stepDiv, block) { stepDiv.find("li.wiktku-dfn-sense").each(function () { var li = $(this); var collapse = !li.is(block) && steps.dfn.senseBlockHasContent(li); li.toggleClass("wiktku-sense-collapsed", collapse); }); steps.dfn.syncSenseHeaders(stepDiv); }, /** Renumbers the sense badges and refreshes each collapsed row's * one-line summary. Cheap enough to just re-run on any change. */ syncSenseHeaders: function (stepDiv) { stepDiv.find("li.wiktku-dfn-sense").each(function (i) { var li = $(this); li.find("> .wiktku-dfn-sense-header .wiktku-dfn-sense-num").text(i + 1); li.find("> .wiktku-dfn-sense-header .wiktku-dfn-sense-title").text("Mane " + (i + 1)); var summary = $.trim(li.find("textarea.wiktku-dfn-mane").first().val() || ""); if (!summary) { // A template sense has no prose — show the call itself. var tpl = li.find(".wiktku-dfn-tpl-select").val(); var title = $.trim(li.find(".wiktku-dfn-tpl-title").val() || ""); if (tpl) summary = "{{" + tpl + (title ? "|" + title : "") + "}}"; } summary = summary.split("\n")[0]; if (summary.length > 70) summary = summary.slice(0, 70) + "…"; li.find("> .wiktku-dfn-sense-header .wiktku-dfn-sense-summary").text(summary); }); }, /** Keeps the header summary in step with what is being typed. * No longer grows the list: a second sense appears only when * "+ Mane zêde bike" is clicked. Auto-growing meant every entry * with one meaning still showed an empty second one, which reads * as an unfinished form. */ onDfnInput: function (stepDiv, block, textarea) { steps.dfn.syncSenseHeaders(stepDiv); refresh(); }, /** Appends a sense, opens it, and collapses the others. */ addSense: function (stepDiv) { var list = stepDiv.find("ol.wiktku-dfn-list"); var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); initSelects(newBlock); steps.dfn.setOpenSense(stepDiv, newBlock); newBlock.find("textarea.wiktku-dfn-mane").first().focus(); refresh(); return newBlock; }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow, modifiers) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow, modifiers); }); list.append(modifiers ? makeModifierLi(next) : $("<li></li>").append(next)); // New field starts with no placeholder — give it (and any // others in the list) the current one. var updatePlaceholders = list.data("updatePlaceholders"); if (typeof updatePlaceholders === "function") updatePlaceholders(); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: {}, posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; // Rewiye tine, 14 Tebax 2026: "şablonên mana jî dikare serê // yekî tevlîhev bike... famkirina van zehmet e" — the "an jî // şablonek hilbijêre" dropdown inside each sense (guharto, // kevnbûyî, ku-Latn, şaşnivîs, …) had no explanation at all. // One reassurance, shown once for the whole Mane step rather // than repeated per sense: it's optional, plain text is the // normal path. if (!stepDiv.find(".wiktku-dfn-tpl-hint").length) { stepDiv.append( $("<p class='wiktku-step-hint wiktku-dfn-tpl-hint'></p>").text( "Ji bo her maneyekê, dropdown-a \"an jî şablonek hilbijêre\" ne mecbûrî ye — bi gelemperî tu tenê maneyê bi tîpên asayî dinivîsî. Ew şablon tenê ji bo rewşên taybet in (mînak: guherto, kevnbûyî, şaşnivîs); heke tu nizanî kîjan divê, vale bihêle." ) ); } var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); var addSenseBtn = $("<button type='button' class='wiktku-add-sense'></button>") .append($("<span class='wiktku-add-sense-plus'>+</span>")) .append(document.createTextNode("Mane zêde bike")); addSenseBtn.on("click", function (e) { e.preventDefault(); steps.dfn.addSense(stepDiv); }); stepDiv.append(addSenseBtn); steps.dfn.syncSenseHeaders(stepDiv); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName === "__category__") { // Reachable only if the user opened the category search but // never picked a şablon — picking one switches the row to // __manual__ (see selectCatTpl above), so there's nothing // meaningful to save here. } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: readList("wiktku-dfn-etiket"), kategori: readList("wiktku-dfn-kategori"), nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense var izahLines = []; // parallel — raw îzah gloss for that same sense // True only once some sense's *actual* dfn text (post tercime/îzah // split) is non-empty. var hasLinkableMane = false; $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("# " + (tplKatTpl ? tplKatTpl + " " : "") + (tplLabelTpl ? tplLabelTpl + " " : "") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(""); // template senses have no îzah return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty // Pull the îzah gloss (if any) out of the combined tercime+îzah // string — it's spliced back in separately below, after its // own linkify pass (see izahLines / the second linkifyText call). var izahRaw = null; var tercimeIzah = splitTercimeIzah(dfn); if (tercimeIzah) { dfn = tercimeIzah.tercime; izahRaw = stripWikilinks(tercimeIzah.izah); } if (dfn) { dfn = stripWikilinks(dfn); // Sentence-case + trailing period are for ku definitions, // which are written as full glosses. if (lang === "ku") { if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } // Real prose — this is what makes the sense worth running // through the main linkify pass. hasLinkableMane = true; } else if (izahRaw === null) { // No mane at all — this is just the "{{mane?|lang}}" // placeholder, a bare template call with no plain words // in it. Do NOT count it as linkable: sending nothing but // bracketed templates through the main linkify pass hangs // the linkify gadget (see the hasLinkableMane/hasIzah // check below). dfn = lang === "ku" ? "{{mane?|" + lang + "}}" : ""; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var out = "# " + (katTpl ? katTpl + " " : "") + (labelTpl ? labelTpl + " " : "") + dfn; var idx = defLines.length; var hasThisIzah = izahRaw !== null && $.trim(izahRaw) !== ""; // Bare {{...}} token — like {{wiktku-cite-N}}, this survives // linkify's first pass untouched (it treats template calls as // opaque), then gets swapped for {{îzah|…}} once the actual // gloss text has been linkified in its own separate pass. if (hasThisIzah) { out += (dfn ? " " : "") + "{{wiktku-izah-" + idx + "}}"; } function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(hasThisIzah ? izahRaw : ""); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } // Runs text through the linkify gadget if it's loaded, otherwise // just passes it through unchanged. Shared by both linkify passes // below (main mane text, and — separately — îzah glosses). function linkifyText(t, cb) { if (typeof $.kuLinkify === "function") { $.kuLinkify(t, cb); } else { cb(t); } } var hasIzah = izahLines.some(function (t) { return t && $.trim(t) !== ""; }); var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with nimûne?. text = "# {{mane?|" + lang + "}}\n#* {{nimûne?|" + lang + "}}\n"; callback(text); return; } // Runs the îzah-only linkify pass against `base` (either the raw // text, when there's no linkable mane to run the main pass on // first, or the already-linkified main text). Shared by both // branches below so the token-splice logic only lives once. function runIzahPass(base) { var izahJoined = $.map(izahLines, function (raw, idx) { if (!raw) return undefined; return "{{wiktku-izah-open-" + idx + "}}" + raw + "{{wiktku-izah-close-" + idx + "}}"; }).join("\n"); linkifyText(izahJoined, function (izahLinked) { var izahByIdx = {}; var re = /\{\{wiktku-izah-open-(\d+)\}\}([\s\S]*?)\{\{wiktku-izah-close-\1\}\}/g; var m; while ((m = re.exec(izahLinked)) !== null) { izahByIdx[parseInt(m[1], 10)] = m[2]; } var withIzah = base.replace(/\{\{wiktku-izah-(\d+)\}\}/g, function (_, n) { var linked = izahByIdx[parseInt(n, 10)]; return linked !== undefined ? "{{îzah|" + linked + "}}" : ""; }); callback(restoreCites(withIzah)); }); } if (!hasLinkableMane) { if (!hasIzah) { // All filled senses are template senses (or otherwise have // no plain text at all) — nothing here needs linkify. callback(restoreCites(text)); return; } // There's no plain mane text anywhere (e.g. tercime left blank // with only îzah filled in), so every defLine is just a bare // template call with nothing to word-link. Sending a line // like "# {{wiktku-izah-0}}" through the main linkify pass // gives it no plain words to work with, makes the linkify // gadget hang — so skip that pass entirely and run only // the îzah pass, splicing straight into the unlinkified text. var loadIzahOnly = function () { runIzahPass(text); }; mw.loader.using("ext.gadget.linkify", loadIzahOnly, loadIzahOnly); return; } var didTryToLoad = function () { // First pass: the main definition text (mane), same as before. linkifyText(text, function (mainLinked) { if (!hasIzah) { callback(restoreCites(mainLinked)); return; } // Second pass: îzah glosses, linkified via their own // separate call. Each gloss is wrapped in its own // {{wiktku-izah-open/close-N}} pair; like the existing // {{wiktku-cite-N}} tokens, these sit inside double // braces so linkify leaves the tokens themselves alone — // only the raw gloss text between each pair gets linked. runIzahPass(mainLinked); }); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, tewandin: { id: "tewandin", name: "tewandin", question_fmt: 'Tewandina "' + pageName + '" binivîse', visible: function (values) { return values.lang && values.pos; }, build: function (stepDiv) { if (stepDiv.find(".wiktku-tewandin-wrap").length) return null; var wrap = $("<div class='wiktku-tewandin-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-tewandin-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-tewandin-text") .attr("rows", 4) .attr("placeholder", "{{ku-tewîn-nav|nêr}}"); wrap.append(ta); stepDiv.append(wrap); function autoPopulate() { if (!ta.length) return; var vals = getValues(); var c = vals.cinsiyet || ""; var p = vals.pos || ""; if (!pageName.includes(" ") && c && GENDER_BASE_LABELS[c] && (p === "navdêr" || p === "serenav") && vals.lang === "ku" && c !== "mndudil") { var label = (c === "mnmane") ? "mê û nêr" : GENDER_BASE_LABELS[c]; var out = "{{ku-tewîn-nav|" + label; if (p === "serenav") out += "|y"; out += "}}"; if (!$.trim(ta.val())) ta.val(out); } } setTimeout(function () { autoPopulate(); $("#wiktku-start-form").on("change.tewandin", "#wiktku-start-lang-field, #wiktku-start-cinsiyet-field, #wiktku-start-pos-field", autoPopulate); }, 0); return ta; }, output: function () { var manualText = $.trim($("#wiktku-start-tewandin .wiktku-tewandin-text").val()); if (manualText) { return "\n==== Tewandin ====\n" + manualText + "\n"; } return ""; } }, // resim — one or more images resim: { id: "resim", name: "resim", question_fmt: "Resmekê lê zêde bike", visible: function (values) { return !!(values.lang && values.pos); }, /** Builds one image row: filename + caption + alt text. */ buildItem: function (stepDiv) { var item = $("<li class='wiktku-resim-item'></li>"); var fileRow = $("<div class='wiktku-posparams-row'></div>"); var fileInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-file") .attr("placeholder", "navê_dosyayê.jpg"); fileRow.append($("<label></label>").text("Navê dosyayê: ")).append(fileInp); var capRow = $("<div class='wiktku-posparams-row'></div>"); var capInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-caption") .attr("placeholder", "Danasîna resimê…"); capRow.append($("<label></label>").text("Danasîn: ")).append(capInp); // Alt text: what a screen reader announces for this image var altRow = $("<div class='wiktku-posparams-row'></div>"); var altInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-alt") .attr("placeholder", "Ji bo kesên nabînin, çi tê dîtin? (ne mecbûrî)"); altRow.append($("<label></label>").text("Nivîsa alternatîf: ")).append(altInp); // Auto-fill the caption with the plain page name when a filename // is typed fileInp.on("input", function () { var file = $.trim($(this).val()); var curCap = $.trim(capInp.val()); var isDefault = !curCap || curCap === pageName; if (file && isDefault) { capInp.val(pageName); } else if (!file && isDefault) { capInp.val(""); } steps.resim.onFileInput(stepDiv, item, this); }); item.append(fileRow).append(capRow).append(altRow); return item; }, /** Grows the image list when the last row's filename gets content. */ onFileInput: function (stepDiv, item, input) { var val = $.trim($(input).val()); var list = stepDiv.find("ol.wiktku-resim-list"); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { list.append(steps.resim.buildItem(stepDiv)); } }, build: function (stepDiv) { if (stepDiv.find(".wiktku-resim-wrap").length) return null; var wrap = $("<div class='wiktku-resim-wrap'></div>"); var list = $("<ol class='wiktku-resim-list'></ol>"); list.append(steps.resim.buildItem(stepDiv)); wrap.append(list); stepDiv.append(wrap); return null; }, /** Reads every filled row from the DOM into an array of {file, caption, alt} * objects — blank rows (missing filename or caption) are skipped. * Non-Kurdish captions get wrapped in {{zim|lang|…}} here, unless * the user already typed their own {{zim|…}} template. Alt text is * optional and left as plain text either way. */ getImages: function (values) { var lang = (values && values.lang) || getValues().lang || ""; var images = []; $("#wiktku-start-resim li.wiktku-resim-item").each(function () { var file = $.trim($(this).find(".wiktku-resim-file").val()); var caption = $.trim($(this).find(".wiktku-resim-caption").val()); var alt = $.trim($(this).find(".wiktku-resim-alt").val()); if (!file || !caption) return; // Strip leading "Wêne:" or "File:" if the user typed it — we add it ourselves. file = file.replace(/^(wêne|file|image)\s*:\s*/i, ""); if (lang && lang !== "ku" && !/^\{\{zim\s*\|/i.test(caption)) { caption = "{{zim|" + lang + "|" + caption + "}}"; } images.push({ file: file, caption: caption, alt: alt }); }); return images; }, output: function (values) { var images = steps.resim.getImages(values); if (!images.length) return ""; return images.map(function (img) { var altPart = img.alt ? "|alt=" + img.alt : ""; return "[[Wêne:" + img.file + "|thumb" + altPart + "|" + img.caption + "]]"; }).join("\n") + "\n"; } }, // bnr-h — {{bnr-h|Page1|Page2|…}} prepended before the lang section (shared, not per-section) bnrh: { id: "bnrh", name: "binêre herwiha (bnr-h)", question_fmt: "Şablona bnr-h li qismê herî jor a rûpelê", //visible: function (values) { return !!values.lang; }, multiple: true, narrow: true, placeholder: "Ji bo 'test' bnr 'Test', 'teşt'", output: function (values) { var pages = $.grep(values.bnrh || [], function (p) { return !!$.trim(p); }); if (!pages.length) return ""; return "{{bnr-h|" + pages.map(function (p) { return $.trim(p); }).join("|") + "}}\n"; } }, bikaranin: { id: "bikaranin", name: "Notên bikaranînê", question_fmt: "Notên bikaranînê yên li ser vê kelîmeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, output: function (values) { var text = $.trim(values.bikaranin || ""); if (!text) return ""; return "\n==== Notên bikaranînê ====\n" + text + "\n"; }, }, xwendin: { id: "xwendin", name: "Bêhtir bixwîne", question_fmt: "Lînkên derveyî eleqedarî vê madeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: function (values) { if (!values || !values.lang) { return `* {{wpedî}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; } const ziman = values.lang === "ku" ? "" : `|ziman=${values.lang}`; return `* {{wpedî${ziman}}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; }, output: function (values) { var text = $.trim(values.xwendin || ""); if (!text) return ""; return "\n==== Bêhtir bixwîne ====\n" + text + "\n"; }, }, alfabeyendin: { id: "alfabeyendin", name: "Bi alfabeyên din", question_fmt: function (values) { var base = "Nivîsîna vê kelîmeyê bi alfabeyên din" var langLabel = values.lang ? getLangLabel(values.lang) : ""; if (langLabel) { return base + " ên " + langLabel; } return base; }, visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: "Ji bo kurmancî: * {{ku-ar|şiklê alfaba erebî}}", output: function (values) { var text = $.trim(values.alfabeyendin || ""); if (!text) return ""; return "\n==== Bi alfabeyên din ====\n" + text + "\n"; }, }, formalt: makeWordListStep("formalt", "formên alternatîv", "Formên alternatîv ên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), hevmane: makeWordListStep("hevmane", "hevmane", "Hevmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), dijmane: makeWordListStep("dijmane", "dijmane", "Dijmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jornav: makeWordListStep("jornav", "jornav", "Jornavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jernav: makeWordListStep("jernav", "jêrnav", "Jêrnavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse"), binereherwiha: makeWordListStep("binereherwiha", "herwiha binêre", "Kelîmeyên din ên eleqedar binivîse"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: {}, visible: function (values) { return values.lang && values.pos; }, // Fills the insert-dropdown from the current etymTpls object. refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(ta); stepDiv.append(wrap); initSelects(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder. // Skip it only when every filled sense is a şablon sense // a completely empty entry with no şablon chosen still gets the placeholder var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasFilledTplSense = dfnSenses.some(function (s) { return !!s.tpl && !!s.tplTitle; }); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (hasFilledTplSense && !hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: function (values) { return {"navz": true, [values.lang]: true} }, // Language dropdown + growing word-input list; a new row appends // when the dropdown gets a value. Mirrors steps.trans, but flat. buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/build below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Attach the searchable picker now the select is in the DOM. initSelects(list); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", question_fmt: "'"+ pageName + "' di zaravayên din de çawa tê gotin?", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: {}, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zaravayekî bigere"); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; // Item 6 (Wikihez, 14 Tebax 2026): "Bi zaravayên din" now // auto-appears empty for lang=ku exactly like Werger // already does (steps.trans.output, same rule below) — // a completely empty entry still gets a placeholder // section to fill in later; an individual placeholder // gloss is only skipped once some other sense already has // real content, making that particular one redundant. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", question_fmt: "Tercimeyên vê maneyê bi zimanên din binivîse", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide only when every sense is a filled template sense (no plain // gloss to attach translations to). A mix, or nothing filled in // yet, still shows Werger. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, // Language dropdown + growing word-input list, scoped to one gloss's // group (each gloss has its own group and row list). buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/buildGroup below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, // Builds (or fetches) the .wiktku-trans-group for one gloss. buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, // Syncs one .wiktku-trans-group per current gloss, keyed by // data-gloss-pos so groups stay matched across rebuilds. build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, // Reads all translation rows, grouped by gloss position. getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, // Builds the numbered "{ index, gloss }" list, one per dfn sense // with a real mane (skips template senses). index is 1-based and // matches the sense's position in the "#" definition list. // When nothing's filled in, returns one placeholder entry so // Werger still has a group to attach to; when every sense is a // filled template sense, stays empty (matches trans.visible()). glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane, but other fields are filled — still gets a // gloss group since dfn.getOutput() emits {{mane?}} for it. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // A completely empty entry (nothing filled in dfn at all, no // şablon chosen either) still gets a placeholder Werger section // to fill in later. Only // skip an individual placeholder gloss below when some other // sense actually has real content, making that particular // placeholder redundant. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it. If some other sense already has real // content, this placeholder is redundant — skip it. If the // whole entry is empty, keep it so Werger still gets a // section to fill in. if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, cavkani: { id: "cavkani", name: "çavkanî", question_fmt: "Çavkaniyên din (ne jêgirtin) lê zêde bike", visible: function (values) { return !!values.pos; }, // Fills the insert-dropdown from the members of [[Kategorî:Çavkanî]]. refreshTplSelect: function () { var sel = $("#wiktku-start-cavkani .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(catSrcTemplates || [], function (_, name) { sel.append($("<option></option>").val(name).text(name)); }); markTemplateOptions(sel, function (opt) { return opt.val(); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-cavkani-wrap").length) return null; var wrap = $("<div class='wiktku-cavkani-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-cavkani-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-cavkani-text") .attr("rows", 4) .attr("placeholder", "Şablonekî ji lîsteyê hilbijêre an rasterast binivîse…"); // Template insert dropdown, populated from [[Kategorî:Çavkanî]] — // options refreshed once the category members are fetched. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var status = $("<span class='wiktku-cavkani-status'></span>"); sel.on("change", function () { var name = $(this).val(); if (!name) return; insertAtCursor(ta[0], "\n* {{" + name + "}}"); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(status).append(ta); stepDiv.append(wrap); // build() runs again for every new beş (see the "+ Beş zêde bike" // handler), after the initial page-wide pass — so this select needs // its own init or it stays a plain, unsearchable native <select>. initSelects(wrap); if (catSrcTemplates) { steps.cavkani.refreshTplSelect(); } else { status.text("Şablon tên barkirin…"); fetchCatSrcTemplates().then(function () { steps.cavkani.refreshTplSelect(); status.text(""); }, function () { status.text("Şablon nehatin barkirin."); }); } return ta; }, output: function () { var text = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); if (!text) return ""; return "\n==== Çavkanî ====\n" + text + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); // Ghybu, 14 Tebax 2026: bnrh/resim/pron used to sit here, always visible, // well above the tab bar (which starts right before "dfn"). They're now // tab-gated (see STEP_GROUPS below), so their DOM position moves down to // sit right next to it instead of rendering as always-open fields between // Ziman and Cureyê rêzimanî. This array only controls DOM build order — // nothing else keys off it (see the comment above stepIdToGroup). // Wikihez, 14 Tebax 2026: Mane tab's internal order is now Mane → malûmatên // pêşketî (nested inside dfn's own div, see steps.dfn.build) → Wêne → // Bi zaravayên din → Werger, so dfn/resim/zarava/trans need to sit // adjacent to each other, in that order, in the DOM. zarava/trans moved // out of the "Beşên din" cluster entirely — see STEP_GROUPS below. var ordered_steps = [ steps.lang, steps.pos, steps.posparams, steps.cinsiyet, steps.jimar, steps.lektur, steps.tr, // Mane tab, in reading order: the senses, then the two things that // belong to the entry as a whole rather than to one sense. steps.dfn, steps.tewandin, steps.alfabeyendin, steps.zarava, steps.trans, // Etîmolojî tab. steps.etym, steps.dunde, // Eleqedar tab — three lists of the same shape. steps.je, steps.tekildar, steps.binereherwiha, // Bilêvkirin: no longer in a tab at all (see PRON_SECTION_ID) — it // still needs a slot here because this array is what builds the DOM. steps.pron, // Beşên din, behind the picker. steps.resim, steps.bnrh, steps.bikaranin, steps.formalt, steps.hevmane, steps.dijmane, steps.jornav, steps.jernav, steps.cavkani, steps.xwendin]; // ── Step-group tabs ────────────────────────────────────────────────────── // Ghybu, 14 Tebax 2026 (revised): originally 5 tabs (Bingehîn/Bilêvkirin/ // Lînkkirin/Bikaranîn/Din), split by topic. Ghybu's follow-up flattened // that to exactly 3: "Mane", "Bilêvkirin", "Beşên din" ("other // sections") — with Wêne and Nimûne folded INTO "Mane" specifically // (not left in a misc tab), and everything that isn't Mane/Bilêvkirin // dumped into one single "Beşên din" catch-all rather than split across // topic tabs. Nimûne doesn't appear below as its own entry because it's // not a separate step — it's already rendered inside each dfn/Mane // sense block (see buildSenseBlock's allGroups), so it's under "Mane" // automatically. "mane" stays first (and so the default-active tab) // since required content — Mane itself — has to be what's seen by // default. // Wikihez, 14 Tebax 2026: zarava/trans moved from "besendin" into "mane" — // both are already gated to lang===ku (zarava.visible just delegates to // trans.visible), so they show/hide automatically with no picker // involvement, same as before; they just render inside the Mane tab // now instead of behind the Beşên din picker (see openedOtherSections // below, which only applies to "besendin" members). // Wikihez, 15 Tebax 2026: pared back again after Ghybu's "Tu jî dizanî ku // kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > // Dijmane". That path is now what the form shows by default and nothing // else: Mane holds the senses (whose own blocks carry Nimûne, Jêgirtin, // Hevmane and Dijmane — see steps.dfn.allGroups) plus Werger. Wêne and // "Bi zaravayên din" moved out to the Beşên din picker with everything // else; they aren't gone, they're one dropdown pick away. // v3 spec (15 Tebax 2026): four tabs instead of three, and Bilêvkirin // leaves the tab bar entirely. // // The Beşên din picker had grown to eighteen entries, which is its own // kind of "where do I find anything" problem — splitting the two // obvious clusters out as their own tabs is what fixes that: // Etîmolojî — where the word came from, and what came from it // Eleqedar — the three "related words" lists, which are the same // shape as each other and nothing like the rest // Tewandin moves into Mane and out from behind the picker: it is // commonly wanted and it belongs with the senses it inflects. Note this // is a PLACEMENT change only — Tewandin keeps its own free-text // {{ku-tewîn-nav}} field and does NOT absorb the Cins/zayend form // parameters (m=/n=/p=), which stay on the headword template where // they belong. The v3 mock merged the two; Wikihez rejected that. var STEP_GROUPS = [ { id: "mane", label: "Mane", steps: ["dfn", "tewandin", "alfabeyendin", "zarava", "trans"] }, { id: "etimoloji", label: "Etîmolojî", steps: ["etym", "dunde"] }, { id: "eleqedar", label: "Eleqedar", steps: ["je", "tekildar", "binereherwiha"] }, { id: "besendin", label: "Beşên din", steps: ["resim", "formalt", "hevmane", "dijmane", "jornav", "jernav", "bikaranin", "cavkani", "xwendin", "bnrh"] }, ]; // Steps that live behind the "Beşên din" picker — only these need an // explicit "open" before they're shown, even when their tab is active. // Derived from the group above so it can't drift out of sync. var BESENDIN_STEP_IDS = STEP_GROUPS[3].steps; // Reverse lookup: step id -> index into STEP_GROUPS (undefined for // ungrouped steps — now only lang/pos/posparams/cinsiyet/lektur/tr, // which stay always-visible since they're required to get to everything // else). var stepIdToGroup = {}; $.each(STEP_GROUPS, function (gi, g) { $.each(g.steps, function (_, sid) { stepIdToGroup[sid] = gi; }); }); // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "posparams", "cinsiyet", "jimar", "lektur", "tr", "resim", "dfn", "tewandin", "formalt", "bikaranin", "alfabeyendin", "hevmane", "dijmane", "jornav", "jernav", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans", "cavkani", "xwendin" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; // ── Bilêvkirin as a standalone section (v3 spec) ───────────────────── // Pronunciation belongs to the word, not to one part of speech, so it // sits beside Navdêr/Lêker in the section tab bar rather than inside // any of them, and is added once from "+ Beş zêde bike". // // Modelled as a flag rather than an entry in `sections`: activeSection // is used as an array index in a dozen places (saveCurrentSection, // restoreSection, sections[activeSection]…), and making it sometimes a // string would mean auditing all of them. Viewing Bilêvkirin instead // leaves activeSection pointing at the POS section you were on, so // coming back is free and nothing else has to change. // Always in the tab bar, and first — pronunciation applies to the whole // word, so it reads as the thing that comes before any part of speech // rather than an optional extra you have to know to add. Its content // only appears once you click it, like any other tab. var viewingPron = false; // is it the tab currently on screen // Which STEP_GROUPS tab is currently shown. Lives out here (like // activeSection above) so refresh() — which is not nested inside build() // — can read it and so renderGroupTabs()/updateGroupTabIndicators() below // can be called from refresh() too. Both operate on the tab bar via its // #wiktku-group-tabs id rather than a closured element reference, for the // same reason. var activeGroup = 0; // Unsaved-changes / autosave state. Lives out here (same reason as // activeGroup above) so destroy() — which runs on final submit and on // switching to the source editor, and is not nested inside build() — // can clear the timers and the beforeunload warning. build() assigns // into these; it doesn't re-declare them. var formDirty = false; var autosaveDebounceTimer = null; var autosaveInterval = null; /** Re-renders the step-group tab bar to reflect the current activeGroup. */ function renderGroupTabs() { var groupTabsDiv = $("#wiktku-group-tabs"); if (!groupTabsDiv.length) return; groupTabsDiv.empty(); $.each(STEP_GROUPS, function (i, g) { var tab = $("<span></span>") .addClass("wiktku-group-tab") .attr("data-group-idx", i) .text(g.label) .toggleClass("wiktku-tab-active", i === activeGroup); (function (idx) { tab.on("click", function () { if (idx === activeGroup) return; activeGroup = idx; renderGroupTabs(); if (idx === BESENDIN_GROUP_IDX) renderBesenDinPicker(); refresh(); }); }(i)); groupTabsDiv.append(tab); }); } /** * Toggles a "needs attention" dot on any group tab that still has a * required, unfilled field hidden inside it — so switching tabs doesn't * leave the person wondering why "Bişîne" stays disabled. */ function updateGroupTabIndicators(values) { var tabs = $("#wiktku-group-tabs .wiktku-group-tab"); if (!tabs.length) return; $.each(STEP_GROUPS, function (i, g) { var missing = false; $.each(g.steps, function (_, sid) { var step = steps[sid]; if (!step || !step.required) return; var val = values[sid]; if (val === "" || (step.multiple && $.isArray(val) && val.join("") === "")) { missing = true; } }); tabs.eq(i).toggleClass("wiktku-tab-missing", missing && i !== activeGroup); }); } // Wikihez, 14 Tebax 2026: "Beşên din" no longer shows all 16 fields // stacked at once — a picker reveals one at a time instead. This is // per-section state (like the field values themselves), snapshotted in // saveCurrentSection() and restored in restoreSection() below, and // auto-seeded from any field that already has content (so a returning // draft, or an older cache saved before this existed, doesn't hide // something the person already filled in). var openedOtherSections = {}; var BESENDIN_SET = {}; $.each(BESENDIN_STEP_IDS, function (_, sid) { BESENDIN_SET[sid] = true; }); // "besendin"'s index in STEP_GROUPS. Derived rather than hardcoded — // this was a literal 2 and silently pointed at the wrong tab the moment // Etîmolojî and Eleqedar were inserted ahead of it. var BESENDIN_GROUP_IDX = (function () { for (var i = 0; i < STEP_GROUPS.length; i++) { if (STEP_GROUPS[i].id === "besendin") return i; } return STEP_GROUPS.length - 1; }()); /** Re-renders the "Beşên din" picker to list only the not-yet-opened sections. */ function renderBesenDinPicker() { var wrap = $("#wiktku-besendin-picker"); if (!wrap.length) return; wrap.empty(); var pickerValues = getValues(); var unopened = $.grep(BESENDIN_STEP_IDS, function (sid) { if (openedOtherSections[sid]) return false; // Don't offer a section that would open onto nothing: several of // these are gated (Bi zaravayên din / Werger need lang=ku, most // need a pos). refresh() would hide it again straight away, so // picking it would read as a broken dropdown. var step = steps[sid]; if (step && typeof step.visible === "function") { try { if (!step.visible(pickerValues)) return false; } catch (e) { /* a step whose visible() needs DOM we lack yet — offer it */ } } return true; }); if (!unopened.length) return; // everything's open — nothing left to pick var sel = $("<select class='wiktku-besendin-select'></select>"); sel.attr("data-placeholder", "— beşek hilbijêre —"); sel.append($("<option value=''>— beşek hilbijêre —</option>")); $.each(unopened, function (_, sid) { var step = steps[sid]; if (!step) return; sel.append($("<option></option>").val(sid).text(capitalize(step.name))); }); sel.on("change", function () { var sid = $(this).val(); if (!sid) return; openedOtherSections[sid] = true; renderBesenDinPicker(); refresh(); }); wrap.append(sel); initSelects(wrap); } /** Marks any BESENDIN_STEP_IDS field that already has real content as * "opened", so restoring a draft doesn't bury filled-in sections behind * the picker. Reuses each step's own output() as the emptiness check — * it already knows what "empty" means per field, and it reads the DOM * the restore just populated. Call this AFTER the DOM has the restored * values in it. */ function seedOpenedFromContent() { var values = getValues(); $.each(BESENDIN_STEP_IDS, function (_, sid) { if (openedOtherSections[sid]) return; var step = steps[sid]; if (!step || typeof step.output !== "function") return; try { if (step.output(values)) openedOtherSections[sid] = true; } catch (e) { /* a step whose output() needs more state than we have yet — skip it */ } }); } function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } // Rebuilds the dfn DOM from a previously snapshotted senses array. function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. The // "+ Mane zêde bike" button goes with it — build() re-appends both, // and leaving the old one behind would both duplicate it and put it // above the rebuilt list. stepDiv.find("ol.wiktku-dfn-list").remove(); stepDiv.find(".wiktku-add-sense").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); // The picker is collapsed behind a link by default; a restored // sense that already uses a template has to show it, or the // chosen template is invisible and looks lost. var reveal = block.data("revealTplRow"); if (typeof reveal === "function") reveal(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // dfnArea is the only thing actually saved, so split it back into // tercime/îzah for editing (mirrors syncNonKuToMane's join format). var maneParts = splitTercimeIzah(sense.mane); block.find(".wiktku-dfn-tercime").val(maneParts ? maneParts.tercime : (sense.mane || "")); block.find(".wiktku-dfn-izah").val(maneParts ? maneParts.izah : ""); // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Same for the mane-box mode (plain vs tercime+îzah), since this // also depends on tplSelect's (and lang's) value. var updateMane = block.data("updateManeMode"); if (updateMane) updateMane(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found var useModifiers = !!MODIFIER_SUBGROUPS[cls]; // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true, useModifiers); }); subList.append(useModifiers ? makeModifierLi(ta) : $("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text).each(function () { highlightLinebreak(this); }); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder entries — accepts current array shape or a legacy // single object (older saved sections) for backwards compat. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote).each(function () { highlightLinebreak(this); }); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederCatTpl) { // Legacy format from before the şablon search switched rows to // manual mode directly — convert it the same way now, so it's // editable like any other free-form source. var catSelEl = li.find(".wiktku-dfn-quote-src-sel"); catSelEl.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val("{{" + j.jederCatTpl + "}}"); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); // Numbers and one-line summaries for the freshly rebuilt blocks, and // collapse everything that has content — on a restored draft nothing // is "the sense being edited" yet, so a five-sense entry would // otherwise come back fully expanded, which is the state this // accordion exists to avoid. steps.dfn.syncSenseHeaders(stepDiv); stepDiv.find("li.wiktku-dfn-sense").each(function () { var li = $(this); li.toggleClass("wiktku-sense-collapsed", steps.dfn.senseBlockHasContent(li)); }); } // Snapshots simple (non-dfn) per-section steps from the DOM into obj. function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } if (id === "cavkani") { snap.cavkani = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); return; } if (id === "posparams") { snap.posparams = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); return; } if (id === "resim") { // One entry per row, including blank ones, so a mid-edit draft // (e.g. a filename typed but no caption yet) survives a cache // restore instead of being silently dropped. snap.resim = $("#wiktku-start-resim li.wiktku-resim-item").map(function () { return { file: $.trim($(this).find(".wiktku-resim-file").val()), caption: $.trim($(this).find(".wiktku-resim-caption").val()), alt: $.trim($(this).find(".wiktku-resim-alt").val()) }; }).get(); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); // Item 3: which "Beşên din" sub-sections this section has already // opened via the picker — per-section, like everything else here. snap.openedOtherSections = $.extend({}, openedOtherSections); sections[activeSection] = snap; } // Restores a previously saved snapshot into the form DOM. function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); $("#wiktku-start-cavkani .wiktku-cavkani-text").val(snap.cavkani || ""); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); steps.posparams.build(ppDiv); var savedTa = snap.posparams || ""; ppDiv.find(".wiktku-posparams-text").val(savedTa); // Re-parse saved textarea to restore helper widget states. if (savedTa) { var cMatch = savedTa.match(/\|c=([^|}\s]+)/); var jMatch = savedTa.match(/\|j=([^|}\s]+)/); var trMatch = savedTa.match(/\|tr=([^|}\s]+)/); // Write into the shared hidden field (not the visible // select, which has no <option>s yet) — syncHelpers() // below reads it back to restore the dropdown once the // gender/number options for this language are populated. if (cMatch) $("#wiktku-start-cinsiyet-field").val(cMatch[1]); if (jMatch) $("#wiktku-start-jimar-field").val(jMatch[1]); if (trMatch) ppDiv.find(".wiktku-posparams-field[data-pp-key='tr']").val(trMatch[1]); // For lêker, c= holds the verb-type code instead of a // gender — split it back across the two dropdowns it is // now assembled from ("x-gh" → form "x" + base "gh"). if (cMatch && /^lêker/.test(snap.pos || "")) { var lekturParts = /^(?:([xphb])-)?(n?gh)$/.exec(cMatch[1]); if (lekturParts) { ppDiv.find(".wiktku-posparams-lektur-sel").val(lekturParts[2]); ppDiv.find(".wiktku-posparams-lekturform-sel").val(lekturParts[1] || ""); } } // Restore checked optional params. "form" is stored as // "erê" rather than "1" (see rebuildTa), so it needs its // own check here. ppDiv.find(".wiktku-posparams-opt-panel input[type='checkbox']").each(function () { var key = $(this).val(); var expected = key === "form" ? "erê" : "1"; $(this).prop("checked", savedTa.indexOf("|" + key + "=" + expected) !== -1); }); } steps.posparams.syncHelpers(ppDiv); return; } if (id === "resim") { var resimDiv = $("#wiktku-start-resim"); resimDiv.find(".wiktku-resim-wrap").remove(); steps.resim.build(resimDiv); // Accept both the new array-of-rows format and the older // single {file, caption} object saved before multi-image // support existed. var resimSnap = snap.resim; var rows = $.isArray(resimSnap) ? resimSnap : (resimSnap ? [resimSnap] : []); if (rows.length) { var list = resimDiv.find("ol.wiktku-resim-list"); list.empty(); $.each(rows, function (_, r) { var item = steps.resim.buildItem(resimDiv); item.find(".wiktku-resim-file").val(r.file || ""); item.find(".wiktku-resim-caption").val(r.caption || ""); item.find(".wiktku-resim-alt").val(r.alt || ""); list.append(item); }); // Always keep a blank trailing row, same as Nimûne/Dûnde. var lastItem = list.children("li.wiktku-resim-item").last(); if ($.trim(lastItem.find(".wiktku-resim-file").val())) { list.append(steps.resim.buildItem(resimDiv)); } } return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Tell the pickers about the programmatic value change. fields.filter("select").trigger("wiktku:refresh"); }); // Item 3: restore which "Beşên din" sub-sections were already opened // for this section, then seed in anything the DOM restore above just // filled in but that wasn't marked opened yet (e.g. an older cache // saved before this existed). openedOtherSections = $.extend({}, snap.openedOtherSections || {}); seedOpenedFromContent(); renderBesenDinPicker(); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); // Bilêvkirin is NOT emitted here — it is one shared field for the // whole word, so emitting it per section duplicated it. getWikitext() // prints it once, above the POS sections. steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.tewandin.output(values); entry += steps.bikaranin.output(values); entry += steps.alfabeyendin.output(values); entry += steps.formalt.output(values); entry += steps.hevmane.output(values); entry += steps.dijmane.output(values); entry += steps.jornav.output(values); entry += steps.jernav.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); entry += steps.cavkani.output(values); entry += steps.xwendin.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { // Each hop through here can be reached asynchronously: the dfn // step waits on mw.loader.using("ext.gadget.linkify") before // calling back, so from that point on the submit handler's own // try/catch is no longer on the stack. Guard every hop instead, // or a throw after linkify loads vanishes into an unhandled // rejection and the form just sits there looking busy. try { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } catch (e) { if (typeof onSubmitError === "function") onSubmitError(e); else throw e; } } processSection(0); } // Assembles wikitext for all sections plus the shared lang header. // pron used to be prepended here too (shared, above every section) — // it now nests inside each section instead, via getWikitextForCurrentSection. function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var bnrh = steps.bnrh.output(sharedValues); var entry = steps.lang.output(sharedValues); // One pronunciation per word, printed once between the language // header and the POS sections — see steps.pron.output. entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // bnr-h goes before the language section — only prepended when // generating fresh wikitext (not addLangMode, which handles it separately). if (!addLangMode && bnrh) entry = bnrh + entry; // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { if (s.mane) return s.mane; // Template sense (e.g. {{guharto|ku|somepage}}) — same // construction as the tplCall built in getOutput, so the // summary shows what actually gets written to the entry // instead of going blank. if (s.tpl && s.tplTitle) { return s.tplNoLang ? "{{" + s.tpl + "|" + s.tplTitle + "}}" : "{{" + s.tpl + "|" + sharedValues.lang + "|" + s.tplTitle + "}}"; } return ""; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; // Set by build() to its submitFailed(). Lives out here because the // wikitext-assembly functions below are outside build()'s closure but // still need a way to report a failure to the person rather than dying // silently in the console. var onSubmitError = null; // Item 7: whether Mane/Bi zaravayên din/Werger has anything in it — // kept outside refresh() so the click handler (defined separately, // where continueBtn is built) can read the latest value. var wiktkuContentGateOk = true; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues, placeholderText) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>").text(placeholderText || "")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice.label); if (choice.sortKey !== undefined) { // This is a language choice {code, label, sortKey} — show code. displayText = capitalize(choice.label) + " (" + choice.code + ")"; } var option = $(mw.html.element("option", { value: choice.code }, displayText)); if (disabledValues[choice.code]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } // Keys to disable for a key menu: already-taken or explicitly disabled. function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); populateMenus(input, step.keys, getDisabledKeys(step)); // Keep the key menus mutually exclusive: whatever one row selects is // disabled in every other row. Recomputed from the DOM on each change. input.on("change", function () { var all = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield"); var taken = {}; all.each(function () { var v = $(this).val(); if (v) taken[v] = true; }); all.not(this).each(function () { var self = $(this), own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (code) $(this).prop("disabled", !!taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }); // Return the wrapper; the select lives inside it and still fires change. return wrapNativeSelect(input); } // Adds another text field to the list if the last one now has text. function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); if (step.placeholder) { nextInput.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = step.modifiers ? makeModifierLi(nextInput).prepend(nextKeyInput || "") : $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) initSelects(nextItem); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } // Shows/hides steps based on whether their prerequisites are met, and // updates placeholders where applicable. function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); steps.cavkani.refreshTplSelect(); // Re-render any step's question label that depends on current values // (e.g. dfn's Werger-section reminder, which only applies to ku). $.each(steps, function (stepId, step) { if (typeof step.question_fmt === "function") { $("#wiktku-start-" + stepId + " .wiktku-start-step-question") .text(step.question_fmt(values)); } }); // Sync every sense block's mane-box mode (plain mane vs tercime+îzah) // to the current language, in case lang changes after blocks exist. $("#wiktku-start-dfn li.wiktku-dfn-sense").each(function () { var updateMane = $(this).data("updateManeMode"); if (updateMane) updateMane(); }); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Re-sync the "<label> bi <ziman>…" placeholder on every always-visible // sub-field list (etîket, kategorî, hevmane, …), since the language may // not have been chosen yet when these lists were first built, or may // have changed since. $("#wiktku-start-dfn .wiktku-dfn-sublist").each(function () { var upd = $(this).data("updatePlaceholders"); if (typeof upd === "function") upd(); }); // Same idea for word-list steps (jê, têkildar, binêre herwiha, …) // whose placeholder is a function of the current language. $.each(steps, function (stepId, step) { if (typeof step.placeholder === "function") { $("#wiktku-start-" + stepId + " textarea.wiktku-start-step-field") .attr("placeholder", step.placeholder()); } }); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // Insert after the quote textarea's resize-wrap (if the manual // resize handle has already been attached to it), not after the // bare textarea -- otherwise this lands *inside* that wrap, // between the textarea and its own grip, breaking jêgirtin's // handle and nesting the tr/t boxes inside it. var quoteTa = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap = quoteTa.closest(".wiktku-resize-wrap"); (quoteResizeWrap.length ? quoteResizeWrap : quoteTa).after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // See the tr-field branch above for why this targets the // resize-wrap instead of the bare textarea. var quoteTa2 = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap2 = quoteTa2.closest(".wiktku-resize-wrap"); (quoteResizeWrap2.length ? quoteResizeWrap2 : quoteTa2).after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { var groupIdx = stepIdToGroup[stepId]; var hiddenByTab = (groupIdx !== undefined && groupIdx !== activeGroup) || // Beşên din picker (point 3): stays hidden even while its tab // is active until explicitly opened from the dropdown. (BESENDIN_SET[stepId] && !openedOtherSections[stepId]); // Bilêvkirin is its own section now, so the two views are // mutually exclusive: on it, only pron shows (plus Ziman, which // is shared and stays above every section); off it, pron is // hidden no matter which tab is active. pron is deliberately // ungrouped — stepIdToGroup has no entry for it — so without // this branch it would show on all four tabs at once. if (stepId === "pron") { hiddenByTab = hiddenByTab || !viewingPron; } else if (viewingPron && stepId !== "lang") { hiddenByTab = true; } if (hiddenByTab || (typeof(step.visible) === "function" && !step.visible(values))) { $("#wiktku-start-" + stepId).hide(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } // After build, sync the posparams helper widgets whenever pos or lang changes. if (step.id === "posparams" && typeof step.syncHelpers === "function") { step.syncHelpers(stepDiv); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } stepDiv.slideDown(); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); // The four content tabs belong to a POS section — Bilêvkirin has no // sub-tabs of its own, so the bar goes away while it's on screen. $("#wiktku-group-tabs").toggle(!!values.pos && !viewingPron); var besenDinActive = activeGroup === BESENDIN_GROUP_IDX && !viewingPron; $("#wiktku-besendin-picker").toggle(besenDinActive); // The option list is filtered by each step's visible(), which depends // on lang/pos — so it has to be rebuilt when those change, not just // when a section is opened. Safe to call from here: rendering the // picker doesn't itself call refresh(), only picking an option does. if (besenDinActive) renderBesenDinPicker(); updateGroupTabIndicators(values); continueBtn.setDisabled(!canContinue); // Soft gate (item 7): stays a real, clickable OOUI button — a hard // setDisabled(true) here would swallow the click entirely, and then // there'd be no way to tell the person *why* nothing happened. The // CSS-only "looks disabled" class lets the click handler still run // and show wiktkuNotify's explanation. wiktkuContentGateOk = !canContinue || hasMinRequiredContent(values); continueBtn.$element.toggleClass("wiktku-btn-soft-disabled", !wiktkuContentGateOk); } function destroy() { if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); if (autosaveInterval) clearInterval(autosaveInterval); formDirty = false; $(window).off("beforeunload.wiktkuUnsaved"); $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard").slideDown(); // #editform was kept laid-out but off-screen (see build()) instead of // display:none, precisely so the editor never had to size itself // against a zero-width/height box. Just bring it back on-screen — // no slideDown needed since it was never actually collapsed. $("#editform").removeClass("wiktku-offscreen"); // Belt-and-braces: if WikiEditor/CodeMirror/mobile's auto-grow still // cached a stale size from some earlier point, nudge them to // recalculate now that the box is genuinely visible. $(window).trigger("resize"); if (window.CodeMirror) { var cm = $("#wpTextbox1").data("CodeMirror") || $("#wpTextbox1").data("cmInstance"); if (cm && typeof cm.refresh === "function") cm.refresh(); } $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and navz. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; // Inserts a new "== {{ziman|code}} ==" section at the correct sorted // position: navz, then ku/hac/sdh/lki/ckb/zza, then alphabetical by name. function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections — just write the new section. // Add \n\n only when there is real non-whitespace content above. var trimmed = existing.replace(/\s+$/, ""); return trimmed ? trimmed + "\n\n" + wikitext : wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // (?![\s\S]) matches only true end-of-string, since a bare "$" with // /m would stop at the section's first line break instead. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections, each separated by exactly \n\n. // Trim trailing whitespace off each section's content first so we // control the spacing precisely. var joined = sections.map(function (s) { return s.content.replace(/\s+$/, ""); }).join("\n\n"); // Only add a separator after the preamble when it has real content. var preambleTrimmed = preamble.replace(/\s+$/, ""); var prefix = preambleTrimmed ? preambleTrimmed + "\n\n" : ""; return prefix + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê zimanekî nû li rûpelê îlawe bikî. Eger ev ziman jixwe hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bike, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Muhtewaya rûpelê paqij bike (her tiştî jê bibe û rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); // Tab bar for switching between step-groups (topics) within a section. // renderGroupTabs()/updateGroupTabIndicators() (which populate and // maintain it) live outside build() — see near "var activeSection". var groupTabsDiv = $("<div id='wiktku-group-tabs'></div>"); // Wikihez, 15 Tebax 2026: both tab bars are sticky (CSS) so they stay // clickable while scrolling. group-tabs' sticky "top" has to sit right // below section-tabs' actual rendered height — which isn't a fixed // number, since the section-tabs bar can wrap onto a second line // (many sections open, or a narrow/mobile viewport). Measured here // and published as a CSS custom property the stylesheet reads back; // recomputed whenever section-tabs' own content changes // (renderSectionTabs) and on window resize. var stickyOffsetResizeQueued = false; function syncStickyTabsOffset() { var h = sectionTabsDiv.is(":visible") ? (sectionTabsDiv.outerHeight() || 0) : 0; startForm.css("--wiktku-stabs-h", h + "px"); } $(window).on("resize.wiktkuStickyTabs", function () { if (stickyOffsetResizeQueued) return; stickyOffsetResizeQueued = true; window.requestAnimationFrame(function () { stickyOffsetResizeQueued = false; syncStickyTabsOffset(); }); }); // Wikihez, 14 Tebax 2026 (item 3): "Beşên din" picker — sits right under // the group tab bar, only shown while that tab is active (toggled in // refresh(), see BESENDIN_GROUP_IDX); renderBesenDinPicker() fills it. var besenDinPickerDiv = $("<div id='wiktku-besendin-picker' class='wiktku-besendin-picker'></div>"); /** Puts the form back in a usable state after a failed submit and * says what happened. Without this the button stays disabled and * the spinner spins forever on any exception — the person is left * staring at a form that looks busy but is dead, with the reason * visible only in the browser console. */ function submitFailed(err) { spinner.hide(); continueBtn.setDisabled(false); continueBtn.$element.removeClass("wiktku-btn-sending"); var detail = (err && (err.message || err.toString())) || "sedem nediyar"; mw.notify( "Şandin bi ser neket: " + detail + " — tiştê ku te nivîsî winda nebûye. Heke ev dubare bibe, " + "bi 'Edîtora çavkaniyê veke' berdewam bike.", { type: "error", tag: "wiktku-submit", autoHide: false } ); // Deliberately console.error as well: the notification is for the // person, this is for whoever they report the bug to. if (window.console && console.error) console.error("[wiktku] submit failed", err); } onSubmitError = submitFailed; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); continueBtn.$element.addClass("wiktku-btn-sending"); spinner.show(); try { getWikitext(function (wikitext) { try { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page — write fresh content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // ── bnr-h merge ────────────────────────────────────────── // If the user filled bnr-h inputs, either merge into the // existing {{bnr-h|…}} call or prepend a new one. var bnrhOut = steps.bnrh.output(getValues()); if (bnrhOut) { var newPages = bnrhOut.replace(/^\{\{bnr-h\|/, "").replace(/\}\}\n?$/, "").split("|"); var bnrhRe = /\{\{bnr-h\|([^}]*)\}\}/i; if (bnrhRe.test(existing)) { existing = existing.replace(bnrhRe, function (_, inner) { var existingPages = inner.split("|").map(function (p) { return p.trim(); }); $.each(newPages, function (_, p) { p = p.trim(); if (p && existingPages.indexOf(p) === -1) existingPages.push(p); }); return "{{bnr-h|" + existingPages.join("|") + "}}"; }); } else { existing = bnrhOut + existing; } } // If this language's section already exists (whitespace // differences aside), merge into it; otherwise insert new. var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); } catch (e) { // Thrown while writing the result into #wpTextbox1. submitFailed(e); } }); } catch (e) { // Thrown synchronously inside getWikitext — this is where the // splitTercimeIzah ReferenceError surfaced, and it produced no // message at all before this guard existed. submitFailed(e); } }); // Tracks whether groupTabsDiv has been inserted yet — see the // step.id-driven check below, replaced because it silently broke // when bnrh/resim/pron moved ahead of "dfn" in ordered_steps. var groupTabsInserted = false; $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); var nameH3 = $("<h3></h3>").addClass("wiktku-start-step-name"); var nameLabel = $("<label></label>") .attr("for", "wiktku-start-" + step.id + "-field") .text(name); nameH3.append(nameLabel); stepDiv.append(nameH3); if (step.question_fmt) { // question_fmt can be a plain string, or a function of the // current values (used by steps whose question text depends // on e.g. the chosen language) — refresh() keeps it in sync // afterwards via the .wiktku-start-step-question class. var questionText = typeof step.question_fmt === "function" ? step.question_fmt(getValues()) : step.question_fmt; stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, questionText))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); // initSelects() runs over the whole form once it is in the DOM. stepDiv.append(input); } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.placeholder) { input.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append(step.modifiers ? makeModifierLi(input) : $("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Section tabs (switch between POS sections) sit above the // per-section fields, starting at "pos". if (step.id === "pos") { startForm.append(sectionTabsDiv); } // Step-group tabs sit just before the first grouped step in // ordered_steps — whichever one that is. This USED to be a // hardcoded "dfn" check, back when dfn was the first grouped // step. Once bnrh/resim/pron moved into STEP_GROUPS too (and // earlier in ordered_steps than dfn, so they render near // pos/posparams), that check stopped matching anything: dfn was // no longer first, so groupTabsDiv never got appended at all, // and every grouped step's div — bnrh/resim/pron included — sat // there with no tab bar above it to reveal them. Deriving the // insertion point from stepIdToGroup instead means this keeps // working no matter how STEP_GROUPS/ordered_steps get reordered // later. if (!groupTabsInserted && stepIdToGroup[step.id] !== undefined) { startForm.append(groupTabsDiv); startForm.append(besenDinPickerDiv); groupTabsInserted = true; } startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); /** Adds a new, empty POS section and switches to it. */ function addPosSection() { saveCurrentSection(); viewingPron = false; sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); stepDiv.find(".wiktku-add-sense").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); return; } if (id === "resim") { $("#wiktku-start-resim .wiktku-resim-wrap").remove(); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); stepDiv.find("select.wiktku-start-step-field").trigger("wiktku:refresh"); }); // Fresh section — no "Beşên din" sub-section has been opened yet. openedOtherSections = {}; renderBesenDinPicker(); renderSectionTabs(); refresh(); } // One action again: Bilêvkirin is always in the bar now, so the menu // that used to offer both would have had a single entry. addSectionBtn.on("click", addPosSection); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); syncStickyTabsOffset(); return; } sectionTabsDiv.show(); // Bilêvkirin leads the bar, ahead of the POS sections. var pronTab = $("<span></span>") .addClass("wiktku-section-tab wiktku-section-tab-pron") .text("Bilêvkirin") .toggleClass("wiktku-tab-active", viewingPron); pronTab.on("click", function () { if (viewingPron) return; saveCurrentSection(); viewingPron = true; refresh(); renderSectionTabs(); }); sectionTabsDiv.append(pronTab); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection && !viewingPron); (function (idx) { tab.on("click", function () { if (idx === activeSection && !viewingPron) return; // Leaving Bilêvkirin doesn't need a save — its field // is shared and never part of a section snapshot. if (!viewingPron) saveCurrentSection(); viewingPron = false; activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); syncStickyTabsOffset(); } renderSectionTabs(); /** * Re-populates a dynamically-growing "multiple" field list (bnrh, je, * tekildar, …) from a saved array of strings. Sets each value via * .val() + a triggered "input" event rather than touching the DOM * structure directly, so the normal refreshForTextField() growth * logic adds exactly as many rows as needed — the same thing that * happens when a person types into the last (empty) row. */ function restoreMultiField(id, values) { var container = $("#wiktku-start-" + id); $.each(values || [], function (i, v) { var field = container.find(".wiktku-start-step-field").eq(i); if (!field.length || !v) return; field.val(v).trigger("input"); }); } /** * Restores a full cached draft: shared lang/pron/bnrh fields, then * every section (via the same restoreSection()/refresh()/ * renderSectionTabs() sequence already used when switching tabs). * @param cached {{lang: string, pron: string, bnrh: Array, sections: Array, activeSection: number}} */ function restoreFromCache(cached) { if (cached.lang) { $("#wiktku-start-lang-field").val(cached.lang); $("#wiktku-start-lang-field").trigger("wiktku:refresh"); } // Rebuild dependent steps (pos, pron wrap, etc.) now that lang is set. refresh(); if (cached.pron !== undefined) { $("#wiktku-start-pron .wiktku-pron-text").val(cached.pron); } if (cached.bnrh) { restoreMultiField("bnrh", cached.bnrh); } sections = (cached.sections && cached.sections.length) ? cached.sections : [{}]; activeSection = (typeof cached.activeSection === "number" && cached.activeSection >= 0 && cached.activeSection < sections.length) ? cached.activeSection : 0; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); updateLastSavedIndicator(cached.savedAt || null); formDirty = false; wiktkuNotify("Danûstandina berê ya qeydkirî ji cache hate barkirin.", { type: "info", tag: "wiktku-cache-restore" }); } // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); // A new cureyê rêzimanî means any previously chosen cinsiyet/ // cureyê lêkerê no longer applies — clear both selections (and // the shared hidden cinsiyet field, since rebuildTa()/syncHelpers() // fall back to it) before wiping the textarea, so nothing stale // gets carried over into the rebuilt template. var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-cinsiyet-sel").val(""); ppDiv.find(".wiktku-posparams-jimar-sel").val(""); ppDiv.find(".wiktku-posparams-lektur-sel").prop("selectedIndex", 0); ppDiv.find(".wiktku-posparams-lekturform-sel").prop("selectedIndex", 0); $("#wiktku-start-cinsiyet-field").val(""); $("#wiktku-start-jimar-field").val(""); ppDiv.find(".wiktku-posparams-text").val(""); // refresh() runs steps.posparams.syncHelpers(), which toggles the // param rows for the new pos and — since the textarea is now // empty — calls rebuildTa() to repopulate it. Just clearing the // textarea (as before) never triggered this, so the params // section was left stale until some other field's change event // happened to fire a refresh(). refresh(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { // Immediate feedback that the click registered continueBtn.$element.addClass("wiktku-btn-flash"); setTimeout(function () { continueBtn.$element.removeClass("wiktku-btn-flash"); }, 500); // Item 7: Ziman/Cureyê rêzimanî already block submission via the // real OOUI setDisabled (see canContinue in refresh()) — this is // a second, softer check that still lets the click through so we // can explain *why*, instead of the button just silently doing // nothing. if (!wiktkuContentGateOk) { wiktkuNotify( "Berî şandinê, tiştekî binivîse: Mane, Bi zaravayên din, an jî Werger — kêmasî yek ji van sê beşan divê tijî be.", { type: "warn", tag: "wiktku-mincontent" } ); return; } wiktkuNotify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", flags: [ "destructive" ], }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Cache save/clear buttons ───────────────────────────────────────── // Manual, page-scoped save of the entire wizard (all sections, not // just the active one) via [[MediaWiki:Gadget-StorageUtils.js]]'s // ObjectStorage. Restoring happens silently on load at the end of // build(), once the full language list is available. // // Saving also happens automatically (debounced while typing, plus a // periodic fallback) — see "Autosave" below — since relying on the // person to remember to click "Li cache qeyd bike" before an // accidental tab close/reload defeats the point of having a cache // at all. function buildCacheSnapshot() { return { lang: getValues().lang || "", pron: $("#wiktku-start-pron .wiktku-pron-text").val() || "", // bnrh is shared (page-level), same as lang/pron above — not // per-section, so it doesn't live in sections[]. bnrh: getValuesForStep("bnrh"), sections: sections, activeSection: activeSection, savedAt: Date.now() }; } // ── Last-saved indicator ───────────────────────────────────────────── var lastSavedEl = $("<span id='wiktku-last-saved'></span>"); function formatSavedTime(ts) { try { return new Date(ts).toLocaleTimeString(mw.config.get("wgUserLanguage"), { hour: "2-digit", minute: "2-digit" }); } catch (e) { return new Date(ts).toLocaleTimeString(); } } function updateLastSavedIndicator(ts) { lastSavedEl.text(ts ? ("Cache: qeydkirî di saet " + formatSavedTime(ts) + " de") : ""); } // ── Dirty-state tracking + autosave ────────────────────────────────── // formDirty mirrors "does the live form differ from what's in cache". // Anything the person types/selects sets it; a successful save (auto // or manual) clears it; destroy() (final submit, or switching to the // source editor) also clears it since the wizard's job is over at // that point either way. formDirty/autosaveDebounceTimer/autosaveInterval // are declared in the outer scope (near activeGroup) — assigned here, // not re-declared — so destroy() can reach them too. var AUTOSAVE_DEBOUNCE_MS = 8000; // save shortly after typing pauses var AUTOSAVE_INTERVAL_MS = 60000; // …and at least this often regardless function performAutosave() { if (!formDirty) return; saveCurrentSection(); try { formCache.Set(buildCacheSnapshot()); formDirty = false; updateLastSavedIndicator(Date.now()); } catch (e) { // Silent on autosave failure (storage blocked/full, etc.) — the // manual button still surfaces a proper error if the person // tries it directly, no need to interrupt typing with a toast. } } function scheduleAutosave() { formDirty = true; if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = setTimeout(performAutosave, AUTOSAVE_DEBOUNCE_MS); } startForm.on("input change", "input, textarea, select", scheduleAutosave); autosaveInterval = setInterval(performAutosave, AUTOSAVE_INTERVAL_MS); // Warn on accidental tab close/reload while there's anything unsaved. $(window).on("beforeunload.wiktkuUnsaved", function (e) { if (!formDirty) return undefined; e.preventDefault(); e.returnValue = ""; return ""; }); var saveCacheBtn = new OO.ui.ButtonWidget({ label: "Li cache qeyd bike", title: "Halê vê formê yê niha (ziman, bilêvkirin û hemû beş) li cache (localStorage) qeyd bike, da ku eger rûpel bêyî xwestin were girtin an ji nû ve were barkirin, tu karibî berdewam bikî." }); saveCacheBtn.on("click", function () { saveCurrentSection(); // ObjectStorage.Set() doesn't return a success/failure value, so // the only way to detect a real failure (storage blocked, quota // exceeded, JSON.stringify choking on something unexpected) is to // catch it here rather than inspect a (nonexistent) return value. try { var snapshot = buildCacheSnapshot(); formCache.Set(snapshot); formDirty = false; updateLastSavedIndicator(snapshot.savedAt); wiktkuNotify("Halê formê li cache hate qeydkirin.", { type: "success", tag: "wiktku-cache-save" }); } catch (e) { mw.notify("Qeydkirina li cache bi ser neket.", { type: "error", tag: "wiktku-cache-save" }); } }); var clearCacheBtn = new OO.ui.ButtonWidget({ label: "Cache paqij bike", flags: [ "destructive" ], title: "Datayên qeydkirî yên vê rûpelê ji cache jê bibe (forma ku niha xuya dike naguherîne)." }); clearCacheBtn.on("click", function () { formCache.Set({}); // The live form still has whatever the person typed — it's just no // longer backed up anywhere, so treat this like a fresh unsaved edit. formDirty = true; updateLastSavedIndicator(null); wiktkuNotify("Cache hate paqijkirin.", { type: "success", tag: "wiktku-cache-clear" }); }); // ── "⋯" overflow ───────────────────────────────────────────── // v3: one primary action and one secondary stay on the bar; // everything else moves in here. Four same-weight buttons — two of // them red — was the loudest thing on the screen, and on a phone it // wrapped to three rows of a sticky footer. var moreBtn = $("<button type='button' class='wiktku-more-btn' title='Vebijarkên din'>⋯</button>"); var moreMenu = $("<div class='wiktku-more-menu'></div>").hide(); /** Moves an existing OOUI button into the overflow menu, keeping its * handlers — the widgets already carry the behaviour, so this is * purely about where they are shown. */ function intoMenu(btn, extraClass) { var row = $("<div class='wiktku-more-item'></div>"); if (extraClass) row.addClass(extraClass); btn.$element.on("click", function () { moreMenu.hide(); }); row.append(btn.$element); moreMenu.append(row); } intoMenu(saveCacheBtn); intoMenu(clearCacheBtn, "wiktku-more-item-danger"); moreMenu.append($("<div class='wiktku-more-sep'></div>")); moreMenu.append($("<div class='wiktku-more-item wiktku-more-note'></div>").append(lastSavedEl)); moreBtn.on("click", function (e) { e.preventDefault(); e.stopPropagation(); var open = moreMenu.is(":visible"); moreMenu.toggle(!open); if (!open) { setTimeout(function () { $(document).one("click.wiktkuMore", function () { moreMenu.hide(); }); }, 0); } }); var moreWrap = $("<span class='wiktku-more-wrap'></span>").append(moreBtn).append(moreMenu); footer.append(moreWrap); // Icon-only settings button — opens the Tercîh dialog. Plain OOUI // icon names depend on which icon-pack module happens to be loaded, // so this uses the actual Codex "settings" (color-subtle) SVG from // Commons directly, the same way the spinner above hotlinks its gif. var prefsBtn = $("<button></button>", { type: "button", "class": "wiktku-prefs-btn", title: "Tercîh — sazkariyên vê amûrê biguherîne" }); prefsBtn.on("click", function (e) { e.preventDefault(); wiktkuOpenPrefsDialog(); }); // The gear is icon-only on the bar; inside a text menu it needs a // label like everything else around it. prefsBtn.on("click", function () { moreMenu.hide(); }); moreMenu.prepend($("<div class='wiktku-more-sep'></div>")); moreMenu.prepend($("<div class='wiktku-more-item wiktku-more-item-prefs'></div>") .append(prefsBtn) .append($("<span class='wiktku-more-item-label'></span>").text("Tercîh"))); startForm.append(footer); // NOTE: deliberately NOT .hide() (display:none). WikiEditor/CodeMirror/ // the mobile editor's auto-grow logic measure #wpTextbox1's real // dimensions during their own init, which happens while the wizard is // up. A display:none ancestor reports 0 for offsetWidth/offsetHeight/ // scrollHeight, so those scripts bake in a near-zero height that never // gets recalculated later — slideDown() in destroy() only animates the // outer box, it doesn't re-trigger their sizing. Pushing #editform // off-screen instead keeps it laid out (real width/height available to // measure) without being visible, so the editbox opens at full size. $("#editform").addClass("wiktku-offscreen").before(startForm); // renderGroupTabs() looks up #wiktku-group-tabs via a live DOM // selector, so it must run after startForm is actually in the // document — calling it back in the build loop (while startForm was // still detached) silently no-op'd and left the tab bar empty. renderGroupTabs(); renderBesenDinPicker(); // One pass over the whole form: every select that hasn't already been // initialised, and isn't opted out with .wiktku-plain-select, gets // the searchable picker. initSelects(startForm); refresh(); // Give every draggable textarea a custom resize grip (works // consistently on Safari/iOS, unlike the native corner grip — see // the "Manual drag-to-resize handle" comment in styles.css), and // keep applying it to textareas added later on (new sense blocks, // quote-source fields, nimûne rows, …). wiktkuInitManualResize(startForm); new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { $(mutation.addedNodes).each(function () { if (this.nodeType !== 1) return; wiktkuInitManualResize(this); }); }); }).observe(startForm[0], { childList: true, subtree: true }); // Now that the full language list is loaded, silently restore any // draft the editor previously saved for this page. var cachedDraft = formCache.Get(); if (cachedDraft && cachedDraft.sections && cachedDraft.sections.length) { restoreFromCache(cachedDraft); } } mw.loader.using(["oojs-ui-core"], function () { function wiktkuProceedWithData(wiktkuData) { var d = wiktkuData || {}; // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Item 1: Jimar (number) code definitions — same shape as the wiki's // own Lua number-type table (code -> {cat, display[, req]}). if (d.numberLabels) $.extend(NUMBER_LABELS, d.numberLabels); // Populate lang choices (pinned list). if (d.langChoices) steps.lang.choices = choicesFromObject(d.langChoices, true); // Populate langsByCode and merge full language list from d.ziman. // d.ziman is a {code: name} object with all known languages. $.each(steps.lang.choices, function (i, choice) { if (choice.sortKey === undefined) choice.sortKey = choice.label; langsByCode[choice.code] = choice; }); if (d.ziman) { var pinnedCodes = {}; $.each(steps.lang.choices, function (i, c) { pinnedCodes[c.code] = true; }); var extraChoices = []; $.each(d.ziman, function (code, name) { if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; if (pinnedCodes[code]) return; var choice = { code: code, label: name, sortKey: name }; extraChoices.push(choice); langsByCode[code] = choice; }); extraChoices.sort(function (a, b) { return a.sortKey.localeCompare(b.sortKey, userLang); }); steps.lang.choices = steps.lang.choices.concat(extraChoices); } // Keep the full merged list around for trans/dunde/zarava — those // should still be able to reference any language even when the // Tercîh panel restricts the main "ziman" step below — then, if // the user set a restriction there, narrow steps.lang.choices // itself to just those codes. var wiktkuFullLangChoices = steps.lang.choices; if (wiktkuPrefs.langCodes && wiktkuPrefs.langCodes.length) { var wiktkuAllowedLangSet = {}; $.each(wiktkuPrefs.langCodes, function (i, code) { wiktkuAllowedLangSet[code] = true; }); var wiktkuRestrictedChoices = $.grep(wiktkuFullLangChoices, function (c) { return !!wiktkuAllowedLangSet[c.code]; }); // Fall back to the full list instead of showing an empty // dropdown if none of the saved codes matched anything // (typo'd code, data.json changed since, …). steps.lang.choices = wiktkuRestrictedChoices.length ? wiktkuRestrictedChoices : wiktkuFullLangChoices; } // Populate POS choices — also a plain {code: label} object in data.json. if (d.posChoices) steps.pos.choices = choicesFromObject(d.posChoices, false); // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the full language list // (not the possibly Tercîh-restricted steps.lang.choices). steps.trans.keys = wiktkuFullLangChoices; steps.dunde.keys = wiktkuFullLangChoices; steps.zarava.keys = getZaravaKeys(wiktkuFullLangChoices); build(); } // data.json ships inside this package module, so it is already parsed // and in memory — no action=raw round trip, and no Testing switch to // forget to flip back before deploying. wiktkuProceedWithData(require("./start/data.json")); }); }); //</nowiki> cr6ryp03h7vjjfhzfdstcki4xjqm9ks 6333818 6333816 2026-08-15T14:37:18Z Wikihez 7344 6333818 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. // implicit dependencies: StorageUtils (ObjectStorage) //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var addLangMode = mw.util.getParamValue("wiktkuaddlang") === "1"; // ── Tercîh (user settings) panel stored via mw.storage (localStorage), globally var WIKTKU_PREFS_KEY = "wiktku_start_prefs"; var WIKTKU_PREFS_DEFAULTS = { // [] = show the full language list in the "ziman" step; otherwise // only these codes are shown there (data.json codes, not names). langCodes: [], // true = never auto-open on a new/empty page — only via the // "+Ziman/beşeke din" portlet link. onlyOnClick: false, // "auto" | "p-cactions" | "p-tb" | "p-views" — where the // "+Ziman/beşeke din" portlet link is added. portlet: "auto", // true = suppress routine/informational mw.notify toasts (page // loading, cache auto-restored, cache saved/cleared, "tê şandin…"). // Errors and direct results of an explicit action (like saving // Tercîh itself) always show regardless of this setting. quiet: false }; function wiktkuLoadPrefs() { if (!(window.mw && mw.storage)) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var raw; try { raw = mw.storage.get(WIKTKU_PREFS_KEY); } catch (e) { raw = null; } if (!raw) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var parsed; try { parsed = JSON.parse(raw); } catch (e) { parsed = {}; } return $.extend({}, WIKTKU_PREFS_DEFAULTS, parsed); } function wiktkuSavePrefs(prefs) { if (!(window.mw && mw.storage)) return false; try { mw.storage.set(WIKTKU_PREFS_KEY, JSON.stringify(prefs)); return true; } catch (e) { return false; } } var wiktkuPrefs = wiktkuLoadPrefs(); // Routine/informational notices go through here so "quiet mode" can // suppress them; errors and explicit-action confirmations (like the // Tercîh save toast) call mw.notify directly instead, and always show. function wiktkuNotify(message, options) { if (wiktkuPrefs.quiet) return; mw.notify(message, options); } // Lazily built the first time it's opened; reused after that (see // wiktkuOpenPrefsDialog below, defined once we know OOUI is available). var wiktkuPrefsWindowManager = null; var wiktkuPrefsDialog = null; function wiktkuOpenPrefsDialog() { mw.loader.using(["oojs-ui-core", "oojs-ui-windows"], function () { function WiktkuPrefsDialog(config) { WiktkuPrefsDialog.super.call(this, config); } if (!wiktkuPrefsDialog) { OO.inheritClass(WiktkuPrefsDialog, OO.ui.ProcessDialog); WiktkuPrefsDialog.static.name = "wiktkuPrefsDialog"; WiktkuPrefsDialog.static.title = "Tercîhên min"; WiktkuPrefsDialog.static.actions = [ { action: "save", label: "Qeyd bike", flags: ["primary", "progressive"] }, { action: "cancel", label: "Betal bike", flags: "safe" } ]; WiktkuPrefsDialog.prototype.initialize = function () { WiktkuPrefsDialog.super.prototype.initialize.call(this); this.langCodesInput = new OO.ui.TextInputWidget({ placeholder: "ku, zza, ckb (vala bihêle ji bo hemû zimanan)" }); this.onlyOnClickCheckbox = new OO.ui.CheckboxInputWidget({}); this.quietCheckbox = new OO.ui.CheckboxInputWidget({}); this.portletDropdown = new OO.ui.DropdownInputWidget({ options: [ { data: "auto", label: "Otomatîk (li gorî rûyê wîkiyê)" }, { data: "p-cactions", label: "p-cactions - Li qismê Amûran" }, { data: "left-navigation", label: "left-navigation - Li qismê Gotar-Gotûbêj" }, { data: "p-tb", label: "p-tb - Li qismê Giştî" }, { data: "p-views", label: "p-views - Li qismê Bixwîne" } ] }); var fieldset = new OO.ui.FieldsetLayout({ label: "Eyar" }); fieldset.addItems([ new OO.ui.FieldLayout(this.langCodesInput, { label: "Kodên zimanan ku tê xuyakirin li qismê \"ziman\"", align: "top", help: "Kodan bi virgulê (,) ji hev veqetîne. Vala bihêle da ku hemû ziman were nîşandan.", helpInline: true }), new OO.ui.FieldLayout(this.onlyOnClickCheckbox, { label: "Tenê veke wextê \"+Ziman/beşeke din\" were tikandin", align: "inline", help: "Eger were hilbijartin, ev amûr êdî otomatîk li ser rûpelên nû/vala dest pê nake — divê meriv her carê pêl \"+Ziman/beşeke din\" bike.", helpInline: true }), new OO.ui.FieldLayout(this.portletDropdown, { label: "Cihê lînka \"+Ziman/beşeke din\"", align: "top", help: "\"Otomatîk\" li gorî rûyê wîkiyê hildibijêre.", helpInline: true }), new OO.ui.FieldLayout(this.quietCheckbox, { label: "Moda bêdeng (kêmtir agahdarî nîşan bide)", align: "inline", help: "Agahdariyên normal nîşan nede. Xeta her tim tên xuyakirin.", helpInline: true }) ]); this.$body.addClass("wiktku-prefs-dialog-body").append(fieldset.$element); }; WiktkuPrefsDialog.prototype.getSetupProcess = function (data) { return WiktkuPrefsDialog.super.prototype.getSetupProcess.call(this, data) .next(function () { this.langCodesInput.setValue(wiktkuPrefs.langCodes.join(", ")); this.onlyOnClickCheckbox.setSelected(!!wiktkuPrefs.onlyOnClick); this.portletDropdown.setValue(wiktkuPrefs.portlet || "auto"); this.quietCheckbox.setSelected(!!wiktkuPrefs.quiet); }, this); }; WiktkuPrefsDialog.prototype.getActionProcess = function (action) { var dialog = this; if (action === "save") { return new OO.ui.Process(function () { var codes = dialog.langCodesInput.getValue() .split(/[,\s]+/) .map(function (c) { return c.trim().toLowerCase(); }) .filter(function (c) { return !!c; }); wiktkuPrefs = { langCodes: codes, onlyOnClick: dialog.onlyOnClickCheckbox.isSelected(), portlet: dialog.portletDropdown.getValue() || "auto", quiet: dialog.quietCheckbox.isSelected() }; wiktkuSavePrefs(wiktkuPrefs); mw.notify( "Tercîh hatin qeydkirin. Rûpelê ji nû ve bar bike (F5).", { type: "success", tag: "wiktku-prefs-save" } ); dialog.close({ action: "save" }); }); } if (action === "cancel") { return new OO.ui.Process(function () { dialog.close({ action: "cancel" }); }); } return WiktkuPrefsDialog.super.prototype.getActionProcess.call(this, action); }; wiktkuPrefsWindowManager = new OO.ui.WindowManager(); $(document.body).append(wiktkuPrefsWindowManager.$element); wiktkuPrefsDialog = new WiktkuPrefsDialog(); wiktkuPrefsWindowManager.addWindows([wiktkuPrefsDialog]); } wiktkuPrefsWindowManager.openWindow(wiktkuPrefsDialog); }); } var targetContainer; var skin = mw.config.get('skin'); if (wiktkuPrefs.portlet && wiktkuPrefs.portlet !== "auto") { targetContainer = wiktkuPrefs.portlet; } else if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Li vê rûpelê, ziman an jî beşeke nû zêde bike"); // If "onlyOnClick" is set, the wizard should ONLY ever open via the // "+Ziman/beşeke din" link — never automatically var wiktkuNewPageDetected = $(".mw-newarticletext, .mw-newarticletextanon").length > 0; if (wiktkuPrefs.onlyOnClick ? !addLangMode : (!addLangMode && !wiktkuNewPageDetected)) { return; } // ── Shared helpers ─────────────────────────────────────────────────── // Generic text/UI utilities live in their own package file now — see the // header of util.js for why. Aliased to bare names here so the ~400 call // sites below read exactly as they did when these were local functions. var wiktkuUtil = require("./start/util.js"); var capitalize = wiktkuUtil.capitalize; var decapitalize = wiktkuUtil.decapitalize; var escapeRegExp = wiktkuUtil.escapeRegExp; var stripWikilinks = wiktkuUtil.stripWikilinks; var splitTercimeIzah = wiktkuUtil.splitTercimeIzah; var insertAtCursor = wiktkuUtil.insertAtCursor; var foldDiacritics = wiktkuUtil.foldDiacritics; var wrapNativeSelect = wiktkuUtil.wrapNativeSelect; var initSelects = wiktkuUtil.initSelects; var wiktkuInitManualResize = wiktkuUtil.initManualResize; function langHeaderSource(codePattern) { return "\n?==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } var catSrcTemplates = null; var catSrcTemplatesPromise = null; function fetchCatSrcTemplates() { if (catSrcTemplatesPromise) return catSrcTemplatesPromise; catSrcTemplatesPromise = new mw.Api().get({ action: "query", list: "categorymembers", cmtitle: "Kategorî:Çavkanî", cmnamespace: 10, cmlimit: "max", formatversion: 2 }).then(function (data) { var members = (data.query && data.query.categorymembers) || []; catSrcTemplates = $.map(members, function (m) { // Pêşgira navî ya "Şablon:" rake. return m.title.replace(/^[^:]+:/, ""); }); catSrcTemplates.sort(function (a, b) { return a.localeCompare(b, userLang); }); return catSrcTemplates; }, function () { catSrcTemplates = []; return catSrcTemplates; }); return catSrcTemplatesPromise; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var formCache = new ObjectStorage("wiktku_start_draft_" + mw.config.get("wgPageName"), 1); var langsByCode = {}; // Looks up the display label for a language code, falling back to the // code itself if it isn't known yet (e.g. langsByCode not loaded). function getLangLabel(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; // Converts a {code: label} object (langChoices/posChoices in data.json) // into the {code, label[, sortKey]} array the rest of the script uses. // isLang: true adds a sortKey and shows "(code)" after the label — // language choices only. function choicesFromObject(obj, isLang) { var result = []; $.each(obj || {}, function (code, label) { var choice = { code: code, label: label }; if (isLang) choice.sortKey = label; result.push(choice); }); return result; } function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c.code] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Item 1 (Wikihez, 14 Tebax 2026): kodên jimarê (y, s, d, p, p+, tp, j, j+, // j/nj, nj, nj+, hj!, hj?) — ji data.json's "numberLabels" tê dagirtin. // Same {code: {cat, display[, req]}} shape as the wiki's own Lua // number-type table; "display" can contain HTML (<abbr>) or wikilinks // ([[...]]), so it's only used as-is inside the wikitext output — never // dropped straight into an <option>, which can't render either (see // stripMarkupForOption below). var NUMBER_LABELS = {}; // metadata[lang].g used to list gender AND number codes together (see // cinsiyet/posparams below) — this tells the two dropdowns apart: any // code that's a key in NUMBER_LABELS is a number code (goes in the new // Jimar dropdown / j= param), everything else is a gender code (stays // in the existing Cîns dropdown / c= param). Compound codes like "m-p" // or "n-p" are gender+plural pairs, not plain "p" — they don't match a // NUMBER_LABELS key, so they correctly stay on the gender side. function isNumberCode(code) { return Object.prototype.hasOwnProperty.call(NUMBER_LABELS, code); } // Strips the bit of markup "display" is allowed to contain so it's safe // to use as plain <option> text (options can't render HTML or wikilinks): // <abbr title="X">Y</abbr> -> "Y (X)", [[a|b]] -> "b", [[a]] -> "a". function stripMarkupForOption(html) { if (!html) return ""; return $.trim( String(html) .replace(/<abbr[^>]*title="([^"]*)"[^>]*>([\s\S]*?)<\/abbr>/gi, "$2 ($1)") .replace(/\[\[[^\]|]*\|([^\]]*)\]\]/g, "$1") .replace(/\[\[([^\]]*)\]\]/g, "$1") .replace(/<[^>]+>/g, "") ); } // Builds the Jimar dropdown's <option> text for one code: "j — jimarbar". function numberOptionLabel(code) { var def = NUMBER_LABELS[code]; if (!def) return code; var text = stripMarkupForOption(def.display); return text ? (code + " — " + text) : code; } // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } // ── Template explanations (v3 spec) ────────────────────────────────── // Every place a template can be picked shows the same row: a status // dot, the name, a link to the template page, and an ⓘ. This is the ⓘ. // // Text comes from the template's own TemplateData where it has any, so // the explanation stays right without anyone maintaining a second copy // by hand — with the desc already in data.json as the fallback for // templates that have none. var wiktkuTplDataCache = {}; // name -> {desc, params[]} or null when absent /** Fetches TemplateData for one template. Resolves to null if the * template has none (a plain, undocumented template — very common). */ function fetchTemplateData(name) { if (Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, name)) { return $.Deferred().resolve(wiktkuTplDataCache[name]).promise(); } return new mw.Api().get({ action: "templatedata", titles: "Şablon:" + name, redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; var first = null; $.each(pages, function (_, p) { if (!first) first = p; }); var out = null; if (first) { var desc = first.description; // TemplateData descriptions are language maps when the // template is documented in more than one language. if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(first.params || {}, function (key, p) { var label = p && p.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(p && p.required) }); }); out = { desc: desc || "", params: params }; } wiktkuTplDataCache[name] = out; return out; }, function () { // No TemplateData, or the API is unhappy — cache the miss so a // repeated ⓘ click doesn't re-request it every time. wiktkuTplDataCache[name] = null; return null; }); } /** Fetches TemplateData for many templates in one request and fills the * cache. This is what lets a picker show a real description per row * without anyone maintaining a second copy of it in data.json — the v3 * spec's "Nivîsên ravekirinê ji rûpela şablonê tên girtin * (TemplateData), ne bi destan têne nivîsandin." * Resolves either way; a template with no TemplateData caches as null. */ function prefetchTemplateData(names) { var missing = $.grep(names || [], function (n) { return n && !Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n); }); if (!missing.length) return $.Deferred().resolve().promise(); // The API caps a titles list at 50 for normal users. missing = missing.slice(0, 50); return new mw.Api().get({ action: "templatedata", titles: $.map(missing, function (n) { return "Şablon:" + n; }).join("|"), redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; $.each(pages, function (_, page) { if (!page || !page.title) return; var name = String(page.title).replace(/^[^:]+:/, ""); var desc = page.description; if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(page.params || {}, function (key, prm) { var label = prm && prm.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(prm && prm.required) }); }); wiktkuTplDataCache[name] = { desc: desc || "", params: params }; }); // Anything the API didn't answer for simply has none — cache the // miss so the per-row ⓘ doesn't re-request it one at a time. $.each(missing, function (_, n) { if (!Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n)) wiktkuTplDataCache[n] = null; }); }, function () { $.each(missing, function (_, n) { wiktkuTplDataCache[n] = null; }); }); } /** Rewrites each tagged <option> in `sel` as "name — description", using * TemplateData. Only fills rows that have no description yet, so the * hand-written ones in data.json (which carry usage examples the API * does not) are left exactly as they are. */ function applyTplDescriptions(sel) { if (!sel || !sel.length) return; var changed = false; sel.find("option[data-tpl]").each(function () { var opt = $(this); var name = opt.attr("data-tpl"); if (opt.text().indexOf(" — ") !== -1) return; // already described var td = wiktkuTplDataCache[name]; var desc = (td && td.desc) || localTplDesc(name); if (!desc) return; // One line: TemplateData descriptions can run to a paragraph. desc = $.trim(String(desc).split("\n")[0]); if (desc.length > 90) desc = desc.slice(0, 90) + "…"; opt.text(name + " — " + desc); changed = true; }); // The picker caches option text for searching, so it has to re-read. if (changed) sel.trigger("wiktku:refresh"); } /** Hand-written fallback description, from data.json. * * This is the escape hatch for templates with no TemplateData on the * wiki: add a "desc" to the entry in data.json and it shows up in the * dropdown and in the ⓘ immediately, no code change. TemplateData is * still the better place — VisualEditor and every other tool reads it * too — but this keeps the picker useful in the meantime. * * Works for any pool: pronTpls, etymTpls, tplDefs, jederDefs. */ function localTplDesc(name) { var pools = [steps.pron.pronTpls, steps.etym.etymTpls, steps.dfn.tplDefs, steps.dfn.jederDefs]; var found = ""; $.each(pools, function (_, pool) { if (pool && pool[name] && pool[name].desc) { found = pool[name].desc; return false; } }); return found; } /** Opens the inline explanation panel for `name`, anchored under the * picker it was opened from. */ function showTemplateInfo(name, anchorWrap) { $(".wiktku-tpl-info").remove(); var panel = $("<div class='wiktku-tpl-info'></div>"); panel.append($("<div class='wiktku-tpl-info-name'></div>").text("{{" + name + "}}")); var body = $("<div class='wiktku-tpl-info-desc'></div>").text("Tê barkirin…"); panel.append(body); var params = $("<div class='wiktku-tpl-info-params'></div>"); panel.append(params); panel.append($("<a class='wiktku-tpl-info-link' target='_blank' rel='noopener'></a>") .attr("href", wiktkuUtil.tplPageUrl(name)) .text("Rûpela şablonê veke →")); var close = $("<button type='button' class='wiktku-tpl-info-close' title='Bigire'>✕</button>"); close.on("click", function () { panel.remove(); }); panel.prepend(close); $(anchorWrap).after(panel); fetchTemplateData(name).then(function (td) { var desc = (td && td.desc) || localTplDesc(name); body.text(desc || "Ji bo vê şablonê ravek nehatiye nivîsandin."); if (td && td.params && td.params.length) { params.append($("<div class='wiktku-tpl-info-params-title'></div>").text("Parametre:")); var listEl = $("<ul></ul>"); $.each(td.params, function (_, p) { var line = p.name + (p.label ? " — " + p.label : "") + (p.required ? " (pêwîst)" : ""); listEl.append($("<li></li>").text(line)); }); params.append(listEl); } }); } /** Marks a picker's <option>s as template rows so the searchable widget * renders them with the dot / 🔗 / ⓘ affordances, and wires the ⓘ * handler for that picker. `nameOf` maps an <option> to a template * name — the pickers store different things in value= (a snippet for * the insert dropdowns, the bare name for the sense selector). */ function markTemplateOptions(sel, nameOf) { if (!sel || !sel.length) return; var names = []; sel.find("option").each(function () { var opt = $(this); var name = nameOf(opt); if (!name) return; opt.attr("data-tpl", name); // Deprecated/typo templates are the "special cases only" ones. opt.attr("data-tpl-status", /kevnbûyî|şaşnivîs|kêmpeyda/i.test(opt.text()) ? "yellow" : "green"); names.push(name); }); sel.data("wiktkuTplInfo", showTemplateInfo); // Fill in the descriptions. Matters most for the Mane picker, whose // entries in data.json are names with no desc at all — "rastnivîs", // "ku-Latn", "guharto" on their own, which is precisely Rewiye tine's // "famkirina van zehmet e". One request covers every template in the // picker, and the result is cached for the per-row ⓘ as well. prefetchTemplateData(names).always(function () { applyTplDescriptions(sel); }); } /** Pulls the template name out of a snippet like "* {{ku-IPA}}" or * "{{ji|SOURCELANG|CODE|…}}". */ function tplNameFromSnippet(snippet) { var m = /\{\{\s*([^|}\n]+)/.exec(snippet || ""); return m ? $.trim(m[1]) : ""; } // True if a sense has content beyond mane worth keeping (etîket, word // lists, nimûne, jêder) — so it's still emitted with {{mane?}} if empty. function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } // Wikihez, 14 Tebax 2026 (item 7): the real submit-blocking requirement // (Ziman + Cureyê rêzimanî, via step.required/canContinue) is already // obvious since Bişîne stays visibly disabled until it's met. What // wasn't obvious is that a technically-"complete" entry with nothing // in Mane, Bi zaravayên din or Werger is still empty in any meaningful // sense — so this is checked separately, at click time, with its own // message, instead of another star/legend marker on the page. function hasMinRequiredContent(values) { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasMane = dfnSenses.some(function (s) { return (s.tpl && s.tplTitle) || (!s.tpl && (s.mane !== "" || senseHasExtraContent(s))); }); if (hasMane) return true; if (values.lang === "ku") { var hasWerger = false; $("#wiktku-start-trans .wiktku-trans-group").each(function () { if (steps.trans.getGroupTranslations($(this)).length) hasWerger = true; }); if (hasWerger) return true; var hasZarava = false; $("#wiktku-start-zarava .wiktku-zarava-group").each(function () { if (steps.zarava.getGroupTranslations($(this)).length) hasZarava = true; }); if (hasZarava) return true; } return false; } // Bolds the *first* occurrence of the page name function boldPageNameOnce(text) { if (!text || !pageNameRe) return text; var re = new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "i"); return text.replace(re, "'''$1'''"); } // Converts literal line breaks typed into a nimûne/jêgirtin box into // wikitext <br> tags, function nlToBr(text) { return text ? text.replace(/\r\n|\r|\n/g, "<br>") : text; } function escapeHtmlForBackdrop(str) { return String(str) .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;"); } // Mirrors a textarea's text, with a small highlighted marker placed // right after each line that's followed by an actual typed/pasted // linebreak. Rendered into a transparent backdrop layer behind the // textarea (see ensureLinebreakBackdrop()), so only the point of the // break is marked instead of the whole box. function buildLinebreakBackdropHtml(text) { var lines = text.split(/\r\n|\r|\n/); return $.map(lines, function (line, i) { var isLast = i === lines.length - 1; return escapeHtmlForBackdrop(line) + (isLast ? "" : "<mark class='wiktku-linebreak-mark'>↵</mark>\n"); }).join(""); } // Copies the metrics that affect where text wraps/lands (font, line // height, padding, border) from the real textarea onto its backdrop, // via computed style rather than shared CSS classes — most of the // box's own rules are written as "textarea.foo", which a <div> with // the same class wouldn't match. Re-run on every update in case a // responsive breakpoint changed the textarea's own font-size. function syncLinebreakBackdropMetrics(textarea, backdrop) { var cs = window.getComputedStyle(textarea[0]); backdrop.css({ "box-sizing": cs.boxSizing, "padding-top": cs.paddingTop, "padding-right": cs.paddingRight, "padding-bottom": cs.paddingBottom, "padding-left": cs.paddingLeft, "border-width": cs.borderWidth, "border-style": "solid", "font-family": cs.fontFamily, "font-size": cs.fontSize, "font-weight": cs.fontWeight, "line-height": cs.lineHeight, "letter-spacing": cs.letterSpacing }); } // Lazily wraps a textarea in its own positioning anchor (independent // of .wiktku-resize-wrap, so this doesn't depend on load order versus // wiktkuMakeManualResizable) and inserts the transparent backdrop // layer used to mark the exact point of a linebreak. Safe to call // more than once on the same textarea — the backdrop is cached. function ensureLinebreakBackdrop(textarea) { var existing = textarea.data("wiktkuLinebreakBackdrop"); if (existing) return existing; textarea.wrap("<div class='wiktku-linebreak-wrap'></div>"); var backdrop = $("<div aria-hidden='true'></div>").addClass("wiktku-linebreak-backdrop"); textarea.before(backdrop); textarea.data("wiktkuLinebreakBackdrop", backdrop); textarea.on("scroll.wiktkuLinebreak", function () { backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); }); return backdrop; } // Flags a nimûne/jêgirtin textarea (via CSS class, for the border // tint + tooltip) while it contains a typed/pasted linebreak, so the // user notices before it's silently turned into <br> on output. // Marks only the exact point of the break via a mirrored backdrop, // rather than tinting the whole box. function highlightLinebreak(el) { var textarea = $(el); var text = textarea.val(); var hasBreak = /\r|\n/.test(text); textarea .toggleClass("wiktku-has-linebreak", hasBreak) .attr("title", hasBreak ? "Xeta nû dê wek <br> bê nivîsandin" : ""); if (!hasBreak) { var cached = textarea.data("wiktkuLinebreakBackdrop"); if (cached) cached.hide(); textarea.removeClass("wiktku-has-linebreak-source"); return; } var backdrop = ensureLinebreakBackdrop(textarea); textarea.addClass("wiktku-has-linebreak-source"); syncLinebreakBackdropMetrics(textarea, backdrop); backdrop.html(buildLinebreakBackdropHtml(text)).show(); backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); } // Each nimûne item can be { text, tr, t }: text, transliteration, translation. function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{nimûne?|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = nlToBr(boldPageNameOnce(text)); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + nlToBr(n.tr); // Translation as third positional param (no key needed). if (n.t) tpl += "|" + nlToBr(n.t); } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 60 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } // Formats jêder (citation) entries into "#* {{jêder…|…}}" lines; skips // entries with no quote text. Falls back to the generic {{jêder}} // template when no specific template was chosen. function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; var quote = nlToBr(boldPageNameOnce(jeder.quote)); var quoteTr = nlToBr(jeder.quoteTr); var quoteT = nlToBr(jeder.quoteT); if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + quote; if (quoteTr) cite += "|tr=" + quoteTr; if (quoteT) cite += "|tercime=" + quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + quote; if (quoteTr) out += "|tr=" + quoteTr; if (quoteT) out += "|tercime=" + quoteT; // A şablon picked from Kategorî:Çavkanî is transcluded as the // source param (e.g. |{{Kovara X}}); manual text is used as-is. var srcParam = jeder.jederCatTpl ? ("{{" + jeder.jederCatTpl + "}}") : (jeder.jederManual ? jeder.jederManual : "çavkanî?"); // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } // True if a sense has at least one jêder entry with quote text. function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } // Builds "{{tplName|lang|part1|part2|…}}" from a sense field (kategori, // etiket), wrapped inline (" {{…}} ") or on its own line ("\n#: {{…}}"). function buildSenseTpl(sense, field, lang, tplName) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return call } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } // ── Inline modifier system ─────────────────────────────────────────────── // Appends a ⊕ button to a word input <li>. Clicking it shows a compact // modifier picker; selecting one prompts for the value and appends // <modifier:value> to the textarea's current content. 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îf" }, { 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: qualifier (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" }, { key: "qq", label: "qq: qualifier (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î" } ]; // Sub-groups (inside a sense/definition block) that get the same ⊕ // modifier button as makeWordListStep fields. var MODIFIER_SUBGROUPS = { "wiktku-dfn-alternativ": true, "wiktku-dfn-hevmane": true, "wiktku-dfn-dijmane": true, "wiktku-dfn-koordine": true, "wiktku-dfn-jornav": true, "wiktku-dfn-jernav": true }; /** * Wraps a freshly-created textarea in a <li> with a ⊕ modifier button. * `ta` — the jQuery textarea element. * Returns the <li>. */ function makeModifierLi(ta) { var li = $("<li class='wiktku-word-li'></li>"); var btn = $("<button type='button' class='wiktku-mod-btn' title='Modifiyerê lê zêde bike'>⊕</button>"); var picker = $("<div class='wiktku-mod-picker'></div>").hide(); // Which modifier keys are already present in the textarea's current // text — e.g. "<t:...>" → "t" used. Each modifier can only be // applied once per word, so its pill gets disabled once used. function usedKeys() { var used = {}; var re = /<([a-zA-Z]+):/g; var val = ta.val() || ""; var m; while ((m = re.exec(val)) !== null) used[m[1]] = true; return used; } $.each(WORD_MODIFIERS, function (_, mod) { var pill = $("<button type='button' class='wiktku-mod-pill'></button>").text(mod.label); pill.attr("title", mod.hint); pill.data("mod-key", mod.key); pill.on("click", function (e) { e.preventDefault(); if (pill.prop("disabled")) return; // already used on this word picker.hide(); // Show a tiny inline input for the modifier value. var valWrap = $("<span class='wiktku-mod-val-wrap'></span>"); var valInp = $("<input type='text' class='wiktku-mod-val-input'>") .attr("placeholder", mod.hint + "…") .attr("size", 20); var confirm = $("<button type='button' class='wiktku-mod-confirm'>✓</button>"); var cancel = $("<button type='button' class='wiktku-mod-cancel'>✕</button>"); function applyModifier() { var v = $.trim(valInp.val()); if (v) { ta.val(ta.val() + "<" + mod.key + ":" + v + ">"); ta.trigger("input"); } valWrap.remove(); ta.focus(); } confirm.on("click", applyModifier); cancel.on("click", function () { valWrap.remove(); ta.focus(); }); valInp.on("keydown", function (e) { if (e.which === 13) { e.preventDefault(); applyModifier(); } if (e.which === 27) { valWrap.remove(); ta.focus(); } }); valWrap.append(valInp).append(confirm).append(cancel); li.append(valWrap); valInp.focus(); }); picker.append(pill); }); btn.on("click", function (e) { e.preventDefault(); // Close any other open pickers in the same list. li.closest("ol, ul").find(".wiktku-mod-picker").not(picker).hide(); // Grey out modifiers already used on this word — refreshed on // every open since the text (and thus what's "used") can change. var used = usedKeys(); picker.find(".wiktku-mod-pill").each(function () { var isUsed = !!used[$(this).data("mod-key")]; $(this).prop("disabled", isUsed).toggleClass("wiktku-mod-pill-used", isUsed); }); picker.toggle(); }); // Close picker when focus leaves the li entirely. li.on("focusout", function () { setTimeout(function () { if (!$.contains(li[0], document.activeElement)) picker.hide(); }, 150); }); li.append(ta).append(btn).append(picker); return li; } function makeWordListStep(id, name, question_fmt) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, modifiers: true, // Function instead of a plain string so it can name the current // language — computed fresh at build time and re-applied by // refresh() whenever the language changes. placeholder: function () { var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return "Kelîme" + (langLabel ? " bi " + langLabel : "") + "…"; }, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); var header = capitalize(name); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: {}, visible: function (values) { if (!values.lang) return false; // addLangMode: skip pron only if this lang already has a section. if (addLangMode) { // Clearing the page makes existing content irrelevant. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, // Fills the insert-dropdown from pronTpls, filtered by language. refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); // Rewiye tine, 14 Tebax 2026: "berê bilêvkirin otomatîk // çêdibû, niha zehmettir e ji bo yekî nezan — gelek şablon // hene, kîjan were hilbijartin?" A one-line reassurance: // this field is optional, and the dropdown below writes the // template for you — no need to know the syntax up front. wrap.append( $("<p class='wiktku-step-hint'></p>").text( "Ev qad ne mecbûrî ye. Heke tu nizanî kîjan şablonî hilbijêrî, vale bihêle — an ji pêşkêşkariya jêrîn şablonekî hilbijêre, ew ê bixweber li vir were nivîsandin." ) ); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike "); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); // Clear the picker's search box sel.trigger("wiktku:refresh"); ta.focus(); return; } // Item 5 (Wikihez, 14 Tebax 2026): the noLang templates // (ku-IPA, ku-kîte, zza-IPA, zza-kîte) auto-generate // their actual content from a Lua module reading the // page title — "{{ku-IPA}}" alone gives no hint what // that'll render as, so show a live preview and require // confirmation before inserting, instead of an inline // prompt()/confirm() dialog. var tplLabel = selectedOption.text(); $(this).val(""); sel.trigger("wiktku:refresh"); steps.pron.showTplPreview(stepDiv, ta, snippet, tplLabel); }); wrap.append(sel).append(ta); stepDiv.append(wrap); steps.pron.buildIpaPalette(wrap, ta); initSelects(wrap); return ta; }, // ── IPA character palette (v3 spec, 15 Tebax 2026) ─────────── // Modelled on fr.wiktionary's: every character is a button that // drops itself in at the cursor. Two sub-tabs, because the full // IPA chart is ~180 symbols and roughly twenty of them ever // appear in Kurmancî — "IPA (kurdî)" opens by default and the // full chart is one click away for loanwords and other // languages. Grouped with a label down the left so it reads as // a chart rather than one long line of glyphs. IPA_KU: [ { label: "Kît/stres", chars: ["ˈ", "ˌ", "ː"] }, { label: "Bêdeng", chars: ["d͡ʒ", "t͡ʃ", "ʒ", "ʃ", "ɫ", "ŋ", "ɾ", "r", "ʋ", "ħ", "ʕ", "ɣ", "χ", "ʔ"] }, { label: "Dengdêr", chars: ["ɑː", "eː", "ɛ", "ɪ", "iː", "ɯ", "ʊ", "uː", "yː", "ø", "œ"] } ], IPA_FULL: [ { label: "Bêdeng 1", chars: ["m", "ɱ", "n", "ɳ", "ɲ", "ŋ", "ɴ", "p", "b", "t", "d", "t̪", "d̪", "ʈ", "ɖ", "c", "ɟ", "k", "ɡ", "q", "ɢ", "ʡ", "ʔ"] }, { label: "Bêdeng 2", chars: ["ɸ", "β", "f", "v", "θ", "ð", "s", "z", "ʃ", "ʒ", "ʂ", "ʐ", "ɕ", "ʑ", "ç", "ʝ", "x", "ɣ", "χ", "ʁ", "ħ", "ʕ", "h", "ɦ", "ʜ", "ʢ", "ɧ"] }, { label: "Bêdeng 3", chars: ["ʋ", "ɹ", "ɻ", "j", "ɥ", "ɰ", "ʍ", "w", "ʙ", "ⱱ", "ɾ", "ɽ", "r", "ʀ", "ɺ", "l", "ɫ", "ɬ", "ɮ", "ɭ", "ʎ", "ʟ"] }, { label: "Bêdeng 4", chars: ["ɓ", "ɗ", "ᶑ", "ʄ", "ɠ", "ʛ", "ʘ", "ǀ", "ǃ", "ǂ", "ǁ"] }, { label: "Dengdêr", chars: ["i", "y", "ɪ", "ʏ", "ɨ", "ʉ", "ɯ", "u", "ʊ", "e", "ø", "ɘ", "ɵ", "ɤ", "o", "ə", "ɚ", "ɛ", "œ", "ɜ", "ɝ", "ɞ", "ʌ", "ɔ", "æ", "ɶ", "ɐ", "a", "ɑ", "ɒ"] }, { label: "Suprasegmental", chars: ["ˈ", "ˌ", "ː", "ˑ", "ʼ", "ˀ", "ˤ", "ᵝ", "ᵊ", "ˠ", "ʰ", "ʱ", "ʲ", "ˡ", "ⁿ", "ᵑ", "ʷ", "ᶣ", "˞", "‿"] }, { label: "Dîakrîtîk", chars: ["̚", "̪", "̺", "̻", "̼", "̬", "̊", "̥", "̞", "̝", "̘", "̙", "̽", "̟", "̠", "̈", "̤", "̹", "̜", "̍", "̩", "̆", "̯", "̃", "̰", "͡", "͜"] }, { label: "Ton", chars: ["̋", "́", "̄", "̀", "̏", "̌", "̂", "˥", "˦", "˧", "˨", "˩", "ꜛ", "ꜜ", "↗", "↘", "‖"] } ], /** Builds the two-sub-tab character palette under the textarea. */ buildIpaPalette: function (wrap, ta) { if (wrap.find(".wiktku-ipa-palette").length) return; var panel = $("<div class='wiktku-ipa-panel'></div>").hide(); var toggle = $("<a href='#' class='wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tîpên bilêvkirinê</span>")); toggle.on("click", function (e) { e.preventDefault(); var open = panel.is(":visible"); panel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); wrap.append($("<div class='wiktku-adv-toggle-row'></div>").append(toggle)); // Sub-tab bar, with the two template buttons pinned right. var subTabs = $("<div class='wiktku-ipa-subtabs'></div>"); var kuTab = $("<span class='wiktku-ipa-subtab wiktku-tab-active'>IPA (kurdî)</span>"); var fullTab = $("<span class='wiktku-ipa-subtab'>IPA</span>"); subTabs.append(kuTab).append(fullTab); var tplBtns = $("<span class='wiktku-ipa-tplbtns'></span>"); $.each([ { label: "{{ku-IPA|+}}", snippet: "{{ku-IPA|}}", back: 2 }, { label: "{{IPA|+}}", snippet: "{{IPA|ku|}}", back: 2 } ], function (_, t) { var b = $("<button type='button' class='wiktku-ipa-tplbtn'></button>").text(t.label); b.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], t.snippet); // Park the cursor inside the braces, where the value goes. var pos = ta[0].selectionStart - t.back; ta[0].selectionStart = ta[0].selectionEnd = pos; ta.focus(); }); tplBtns.append(b); }); subTabs.append(tplBtns); panel.append(subTabs); function buildGrid(groups) { var grid = $("<div class='wiktku-ipa-grid'></div>"); $.each(groups, function (_, g) { var row = $("<div class='wiktku-ipa-row'></div>"); row.append($("<span class='wiktku-ipa-rowlabel'></span>").text(g.label)); var keys = $("<span class='wiktku-ipa-keys'></span>"); $.each(g.chars, function (_, ch) { var btn = $("<button type='button' class='wiktku-ipa-key'></button>"); // A combining mark on its own renders as a stray // accent floating over whatever precedes it, so // show it on a dotted circle — but insert only // the mark itself. var combining = /^[̀-ͯ҃-҉]$/.test(ch); btn.text(combining ? "◌" + ch : ch); if (combining) btn.addClass("wiktku-ipa-key-combining"); btn.attr("title", ch); btn.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], ch); ta.focus(); }); keys.append(btn); }); row.append(keys); grid.append(row); }); return grid; } var kuGrid = buildGrid(steps.pron.IPA_KU); var fullGrid = buildGrid(steps.pron.IPA_FULL).hide(); panel.append(kuGrid).append(fullGrid); kuTab.on("click", function () { kuTab.addClass("wiktku-tab-active"); fullTab.removeClass("wiktku-tab-active"); kuGrid.show(); fullGrid.hide(); }); fullTab.on("click", function () { fullTab.addClass("wiktku-tab-active"); kuTab.removeClass("wiktku-tab-active"); fullGrid.show(); kuGrid.hide(); }); panel.addClass("wiktku-ipa-palette"); wrap.append(panel); }, /** Item 5: inline preview + confirm panel for a "noLang" (auto- * content) pronunciation template — fetches what the snippet * actually expands to for this page (via action=expandtemplates, * so the preview is exactly what {{ku-IPA}} etc. would produce) * and only inserts it into the textarea if the user confirms. */ showTplPreview: function (stepDiv, ta, snippet, tplLabel) { // Only one preview panel open at a time. stepDiv.find(".wiktku-pron-preview").remove(); var panel = $("<div class='wiktku-pron-preview'></div>"); panel.append($("<div class='wiktku-pron-preview-label'></div>") .text("Pêşdîtina " + tplLabel + ":")); var body = $("<div class='wiktku-pron-preview-body'></div>").text("Tê barkirin…"); panel.append(body); var actions = $("<div class='wiktku-pron-preview-actions'></div>"); var confirmBtn = $("<button type='button' class='wiktku-pron-preview-confirm'>✓ Tevlî bike</button>") .prop("disabled", true); var cancelBtn = $("<button type='button' class='wiktku-pron-preview-cancel'>✕ Betal bike</button>"); actions.append(confirmBtn).append(cancelBtn); panel.append(actions); ta.before(panel); confirmBtn.on("click", function () { insertAtCursor(ta[0], snippet); panel.remove(); ta.focus(); }); cancelBtn.on("click", function () { panel.remove(); }); // action=parse, not action=expandtemplates. expandtemplates // returns *expanded wikitext*, so the preview read as // [[IPA]]<sup>([[Wîkîferheng:IPA kurmancî|kilîd]])</sup>: // <span class="IPA">/-{kshhe}-/</span>[[Kategorî:…]] — which // is exactly what the person is trying to avoid having to // read. parse hands back the rendered HTML the page will // actually show. // // Drop the leading "* " first: it is wikitext list syntax // wrapping the template, and keeping it would render the // preview as a bulleted list rather than the line itself. new mw.Api().post({ action: "parse", title: pageName, text: snippet.replace(/^\*\s*/, ""), prop: "text", wrapoutputclass: "", disablelimitreport: 1, disableeditsection: 1, contentmodel: "wikitext", formatversion: 2 }).done(function (data) { var html = (data && data.parse && data.parse.text) || ""; if ($.trim($("<div>").html(html).text())) { body.html(html); // Category links render as nothing but still exist; // and any real link inside a preview should not // navigate away from a half-filled form. body.find("a").attr("target", "_blank").attr("rel", "noopener"); } else { body.text("(vala — ji bo vê rûpelê tiştek nehate afirandin)"); } confirmBtn.prop("disabled", false); }).fail(function () { body.text("Pêşdîtin nehate barkirin — tu dikarî hîn jî wê tevlî bikî."); confirmBtn.prop("disabled", false); }); }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line; }).join("\n"); // Back to "===", under Ziman and above the POS sections // (v3 spec, 15 Tebax 2026). It had been nested at "====" // inside each POS section per Ghybu's earlier note, but the // field is shared across sections, so a two-POS entry // printed the identical pronunciation twice — once under // Navdêr and once under Lêker. Emitted once by getWikitext() // now, not by getWikitextForCurrentSection(). return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var capitalizedPos = capitalize(pos); // "form" opt-param (checked in posparams) marks this as a // form-of/inflected entry — the section title becomes // "Formeke <pos>ê" instead of the plain pos name. The // template call itself still uses the unchanged pos name. var isForm = $("#wiktku-posparams-opt-form").is(":checked"); var header = isForm ? "\n=== Formeke " + pos + "ê ===\n" : "\n=== " + capitalizedPos + " ===\n"; // Image line (between header and template call) var imageLine = steps.resim.output(values); // Read the live wikitext from the posparams textarea. // Fall back to a plain {{pos|lang}} if the step hasn't been built yet. var tplLine = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); if (!tplLine) { tplLine = "{{" + pos + "|" + (values.lang || "") + "}}"; } return header + imageLine + tplLine + "\n"; } }, // cinsiyet (gender) — shown for navdêr/serenav only, with choices built // from metadata[lang].g since not every language has grammatical gender. cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams // Single source of truth for the selected gender code. The visible // dropdown lives inside the posparams step (see steps.posparams), // but it must always read/write THIS hidden field — not a field of // its own — since getValuesForStep("cinsiyet") reads from here. build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-cinsiyet-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // Item 1 (Wikihez, 14 Tebax 2026): jimar (grammatical number) — same // hidden-field pattern as cinsiyet just above, but writes into its // own j= template parameter instead of sharing c=. Shown for // navdêr/serenav only, with choices built from whichever of // metadata[lang].g are number codes (see isNumberCode) — mirrors // cinsiyet exactly, just filtered to the other half of that list. jimar: { id: "jimar", name: "jimar", question_fmt: 'Jimara "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-jimar-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // Lêker transitivity — hidden step, handled inside posparams lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function () { return false; }, choices: [ { code: "gh", label: "gerguhêz" }, { code: "x-gh", label: "xwerû-gerguhêz" }, { code: "p-gh", label: "pêkhatî-gerguhêz" }, { code: "h-gh", label: "hevedudanî-gerguhêz" }, { code: "b-gh", label: "biwêjî-gerguhêz" }, { code: "ngh", label: "negerguhêz" }, { code: "x-ngh", label: "xwerû-negerguhêz" }, { code: "p-ngh", label: "pêkhatî-negerguhêz" }, { code: "h-ngh", label: "hevedudanî-negerguhêz" }, { code: "b-ngh", label: "biwêjî-negerguhêz" } ], output: function () { return ""; } }, // tr — hidden step, handled inside posparams tr: { id: "tr", name: "transliterasyon", question_fmt: "Transliterasyona vê kelîmeyê", multiple: false, narrow: true, visible: function () { return false; } }, posparams: { id: "posparams", // Fused onto the "pos" card visually (see #wiktku-start-posparams // in styles.css) so the two read as ONE question, per Ghybu's // 14 Tebax 2026 feedback — this name is only a no-CSS/no-JS // fallback, since the h3 that would show it is hidden by CSS. name: "taybetmendî", // The old static "Parametreyên cureyê rêzimanî" label named the // mechanism, not the content. Show what's actually being asked // for instead: gender for nouns, verb type for verbs, a generic // fallback (transliteration/forms etc. still apply) otherwise. question_fmt: function (values) { var pos = values.pos || ""; // Wikihez, 15 Tebax 2026: the "Cins/zayend" title itself was // redundant with the fields right below it (Cinsiyet/Jimar are // self-labelled) and just added visual noise — dropped, but the // box/fields stay exactly as before. lêker/fallback titles are // unaffected since they weren't the ones flagged. if (pos === "navdêr" || pos === "serenav") return ""; if (/^lêker/.test(pos)) return "Cureyê lêkerê"; return "Taybetmendî"; }, visible: function (values) { return !!(values.lang && values.pos); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-posparams-wrap").length) return null; var wrap = $("<div class='wiktku-posparams-wrap'></div>"); var helpers = $("<div class='wiktku-posparams-helpers'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-posparams-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-posparams-text") .attr("rows", 2); var _rebuilding = false; function safeRebuild() { if (_rebuilding) return; _rebuilding = true; steps.posparams.rebuildTa(stepDiv); _rebuilding = false; refresh(); } // Generic text-input row factory function makeTextRow(key, labelText, placeholder) { var row = $("<div class='wiktku-posparams-row'></div>") .attr("id", "wiktku-posparams-row-" + key).hide(); var inp = $("<input type='text'>") .addClass("wiktku-start-narrow wiktku-posparams-field") .attr("data-pp-key", key) .attr("placeholder", placeholder || ""); inp.on("input", safeRebuild); row.append($("<label></label>").text(labelText + ": ")).append(inp); return row; } // cinsiyet var cinsiyetRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-c'></div>") .append($("<label></label>").text("Cinsiyet: ")).hide(); var cinsiyetSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-cinsiyet-sel") .append($("<option value=''>— hilbijêre —</option>")); // Writes into the real, shared #wiktku-start-cinsiyet-field (owned by // steps.cinsiyet) rather than a field of its own — see the comment // on steps.cinsiyet.build for why that matters. cinsiyetSel.on("change", function () { $("#wiktku-start-cinsiyet-field").val($(this).val()).trigger("change"); safeRebuild(); }); cinsiyetRow.append(cinsiyetSel); // Item 1 (Wikihez, 14 Tebax 2026): jimar (number) — a second // dropdown next to Cinsiyet, same pattern (writes into the // shared hidden #wiktku-start-jimar-field), but into its own // j= param instead of sharing c=. Options + the title // tooltip (explanation) are built in syncHelpers, once the // language's number codes are known. var jimarRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-jimar'></div>") .append($("<label></label>").text("Jimar: ")).hide(); var jimarSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-jimar-sel") .append($("<option value=''>— hilbijêre —</option>")); jimarSel.on("change", function () { $("#wiktku-start-jimar-field").val($(this).val()).trigger("change"); safeRebuild(); }); jimarRow.append(jimarSel); // lektur — Ghybu, 14 Tebax 2026: "'Cureyê lêkerê' nayê fêm // kirin, bi min pêşta 'gerguhez/negerguhêz' were hilbijartin, // paşê jî form 'hevdudanî/pêkatî/…' ji ber ku her kes vana // nizanî." So the one 10-option dropdown ("xwerû-gerguhêz", // "biwêjî-negerguhêz", …) becomes two plain questions. The // emitted code is unchanged: base alone ("gh"), or prefix + // "-" + base ("x-gh") — exactly the codes steps.lektur.choices // already listed, just assembled from two answers instead of // asked as one. var lekturRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lektur'></div>") .append($("<label></label>").text("Lêker derbasdar e? ")).hide(); var lekturSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lektur-sel") .append($("<option value=''>— hilbijêre —</option>")) .append($("<option value='gh'>gerguhêz (bireser digire)</option>")) .append($("<option value='ngh'>negerguhêz (bireser nagire)</option>")); lekturSel.on("change", safeRebuild); lekturRow.append(lekturSel); // Second half of the same question — the structural form. // Blank = xwerû/sade, which is the common case. var lekturFormRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lekturform'></div>") .append($("<label></label>").text("Şiklê lêkerê: ")).hide(); var lekturFormSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lekturform-sel") .append($("<option value=''>sade (asayî)</option>")) .append($("<option value='x'>xwerû</option>")) .append($("<option value='p'>pêkhatî</option>")) .append($("<option value='h'>hevedudanî</option>")) .append($("<option value='b'>biwêjî</option>")); lekturFormSel.on("change", safeRebuild); lekturFormRow.append(lekturFormSel); helpers.append(cinsiyetRow).append(jimarRow).append(lekturRow).append(lekturFormRow); // ── Everything below here is "Tercîhên pêşketî" ────────────── // Ghybu, 14 Tebax 2026: "Tenê 'cîns' û 'jimar' bes e. 'Forma // mê', 'Forma nêr', … nayê fêm kirin. Bi min wekî 'Tercîhên // pêşketî' bi navkî din veşartî çêke." The rows themselves are // unchanged and syncHelpers still shows/hides each one by id // exactly as before — they just live inside a collapsed panel // now, so the default view of this card is two dropdowns // instead of twenty-odd fields. // Transliteration is a primary field, not an advanced one, for // any language not written in Latin script: for those, an // entry without it is incomplete. syncHelpers already gates // the row on needsTransliteration(lang), so for Kurmancî and // other Latin-script languages it simply never appears. helpers.append(makeTextRow("tr", "Transliterasyon (tr)", "Transliterasyon…")); var advPanel = $("<div class='wiktku-posparams-adv-panel'></div>").hide(); advPanel .append(makeTextRow("cuda", "nîşankirina alternatîv", "cuda…")) .append(makeTextRow("ts", "Transkrîpsiyon (ts)", "Transkrîpsiyon…")) .append(makeTextRow("m", "Forma mê (m)", "Forma mê…")) .append(makeTextRow("mtr", "Translit. mê (mtr)", "Transliterasyona mê…")) .append(makeTextRow("n", "Forma nêr (n)", "Forma nêr…")) .append(makeTextRow("ntr", "Translit. nêr (ntr)", "Transliterasyona nêr…")) .append(makeTextRow("p", "Forma pirjimar (p)", "Forma pirjimar…")) .append(makeTextRow("ptr", "Translit. pirjimar", "Transliterasyona pirjimar…")) .append(makeTextRow("y", "Forma yekjimar (y)", "Forma yekjimar…")) .append(makeTextRow("ytr", "Translit. yekjimar", "Transliterasyona yekjimar…")) .append(makeTextRow("sûp", "Forma sûperlatîv (sûp)", "Forma sûperlatîv…")) .append(makeTextRow("sûptr", "Translit. sûperlatîv", "Transliterasyona sûperlatîv…")) .append(makeTextRow("komp", "Forma komparatîv (komp)", "Forma komparatîv…")) .append(makeTextRow("komptr", "Translit. komparatîv", "Transliterasyona komparatîv…")) .append(makeTextRow("gir", "Forma girdêk (gir)", "gir=…")) .append(makeTextRow("girtr", "Translit. gir", "girtr=…")) .append(makeTextRow("hûr", "Forma hûrek (hûr)", "hûr=…")) .append(makeTextRow("hûrtr", "Translit. hûr", "hûrtr=…")) .append(makeTextRow("hanja", "Forma hanja", "hanja=…")) .append(makeTextRow("hanjaTr","Translit. hanja", "hanjaTr=…")) // Lêker rehên demê (only shown when pos is lêker — see syncHelpers) .append(makeTextRow("niha", "Rehê dema niha (niha)", "Rehê dema niha…")) .append(makeTextRow("nihatr", "Translit. rehê dema niha", "Transliterasyona rehê dema niha…")) .append(makeTextRow("borî", "Rehê dema borî (borî)", "Rehê dema borî…")) .append(makeTextRow("borîtr", "Translit. rehê dema borî", "Transliterasyona rehê dema borî…")) .append(makeTextRow("subj", "Rehê dema bilanî (subj)", "Rehê dema bilanî…")) .append(makeTextRow("subjtr", "Translit. rehê dema bilanî", "Transliterasyona rehê dema bilanî…")); // Optional boolean params — nested inside the advanced panel // (they were already the most niche thing on the card). var optPanel = $("<div class='wiktku-posparams-opt-panel'></div>"); $.each([ { key: "form", label: "form — ev made forma tewandî ye" }, { key: "formaalt", label: "formaalt — vê madeyê bike forma alternatîv" }, { key: "nekatcure", label: "nekatcure — sinifa rêzimanî kategorîze neke" }, { key: "nekatcins", label: "nekatcins — kategoriya cinsiyetê neyîne" }, { key: "nekatçendterm", label: "nekatçendterm — kategoriya çend-term neyîne" }, { key: "serlînkneke", label: "serlînkneke — sernavê madeyê lînk neke" }, { key: "nekatpalîndrom", label: "nekatpalîndrom — kategoriya palîndromê neyîne" }, { key: "neformtr", label: "neformtr — transliterasyona forman neyîne" } ], function (_, p) { var cb = $("<input type='checkbox'>") .attr("id", "wiktku-posparams-opt-" + p.key).val(p.key).on("change", safeRebuild); var lbl = $("<label></label>").attr("for", "wiktku-posparams-opt-" + p.key).text(" " + p.label); optPanel.append($("<div class='wiktku-posparams-opt-row'></div>").append(cb).append(lbl)); }); advPanel.append(optPanel); var optToggle = $("<a href='#' class='wiktku-posparams-opt-toggle wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tercîhên pêşketî</span>")); // Wikihez, 15 Tebax 2026: the "N zevî · M tije" count badge // was removed (not needed) — the toggle itself still opens/ // closes the panel exactly as before. optToggle.on("click", function (e) { e.preventDefault(); var open = advPanel.is(":visible"); advPanel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); helpers.append($("<div class='wiktku-adv-toggle-row'></div>") .append(optToggle)); helpers.append(advPanel); wrap.append(helpers).append(ta); // Typing directly in textarea keeps cinsiyet/jimar hidden // fields in sync, but does NOT call refresh() — preserves // manual edits. ta.on("input", function () { var text = $(this).val(); var cMatch = text.match(/\|c=([^|}\s]+)/); $("#wiktku-start-cinsiyet-field").val(cMatch ? cMatch[1] : ""); var jMatch = text.match(/\|j=([^|}\s]+)/); $("#wiktku-start-jimar-field").val(jMatch ? jMatch[1] : ""); }); stepDiv.append(wrap); return null; }, /** Reads all helper widget values and rewrites the textarea. * Called only by safeRebuild (user interaction) — never by syncHelpers, * so manual textarea edits are never overwritten by a refresh cycle. */ rebuildTa: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; if (!pos || !lang) return; var cinsiyet = stepDiv.find(".wiktku-posparams-cinsiyet-sel").val() || ""; var jimar = stepDiv.find(".wiktku-posparams-jimar-sel").val() || ""; // Two dropdowns, one code: "gh" / "ngh" on their own, or // prefixed with the structural form ("x-gh", "b-ngh", …). var lekturBase = stepDiv.find(".wiktku-posparams-lektur-sel").val() || ""; var lekturForm = stepDiv.find(".wiktku-posparams-lekturform-sel").val() || ""; var lektur = lekturBase ? (lekturForm ? lekturForm + "-" + lekturBase : lekturBase) : ""; function v(key) { return $.trim(stepDiv.find(".wiktku-posparams-field[data-pp-key='" + key + "']").val()); } var out = "{{" + pos + "|" + lang; if (pos === "navdêr" || pos === "serenav") { out += cinsiyet ? "|c=" + cinsiyet : (lang === "ku" ? "|c=?" : ""); // Item 1: number is its own j= param now, separate from // c= — c= keeps holding gender (and gender+plural // compounds like m-p/n-p, unaffected by this change). if (jimar) out += "|j=" + jimar; } else if (/^lêker/.test(pos) && lektur) { out += "|c=" + lektur; } if (v("cuda")) out += "|" + v("cuda"); if (v("tr")) out += "|tr=" + v("tr"); if (v("ts")) out += "|ts=" + v("ts"); $.each(["m","n","p","y"], function (_, k) { if (v(k)) out += "|" + k + "=" + v(k); if (v(k+"tr")) out += "|" + k + "tr=" + v(k+"tr"); }); if (v("sûp")) out += "|sûp=" + v("sûp"); if (v("sûptr")) out += "|sûptr=" + v("sûptr"); if (v("komp")) out += "|komp=" + v("komp"); if (v("komptr")) out += "|komptr=" + v("komptr"); if (v("gir")) out += "|gir=" + v("gir"); if (v("girtr")) out += "|girtr=" + v("girtr"); if (v("hûr")) out += "|hûr=" + v("hûr"); if (v("hûrtr")) out += "|hûrtr=" + v("hûrtr"); if (v("hanja")) out += "|hanja=" + v("hanja"); if (v("hanjaTr")) out += "|hanjaTr=" + v("hanjaTr"); if (v("niha")) out += "|niha=" + v("niha"); if (v("nihatr")) out += "|nihatr=" + v("nihatr"); if (v("borî")) out += "|borî=" + v("borî"); if (v("borîtr")) out += "|borîtr=" + v("borîtr"); if (v("subj")) out += "|subj=" + v("subj"); if (v("subjtr")) out += "|subjtr=" + v("subjtr"); stepDiv.find(".wiktku-posparams-opt-panel input:checked").each(function () { var key = $(this).val(); // "form" marks this entry as a form-of/inflected entry — it // takes "erê" rather than the plain "1" the other boolean // opt params use. out += "|" + key + "=" + (key === "form" ? "erê" : "1"); }); out += "}}"; stepDiv.find(".wiktku-posparams-text").val(out); $("#wiktku-start-cinsiyet-field").val(cinsiyet); $("#wiktku-start-jimar-field").val(jimar); }, /** Called from refresh() — controls row visibility only. * Does NOT rewrite textarea so user edits are preserved. * Rebuilds only when textarea is empty (first pos selection). */ syncHelpers: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; var needsTr = needsTransliteration(lang); var isNom = pos === "navdêr" || pos === "serenav" || pos === "rengdêr"; var isAdj = pos === "rengdêr"; var isTîp = pos === "tîp"; var isJa = lang === "ja"; var isLeker = /^lêker/.test(pos); // Item 1: metadata[lang].g used to list gender AND number // codes together — split them here (see isNumberCode) so // Cîns only ever offers gender codes (and gender+plural // compounds like m-p/n-p, which aren't NUMBER_LABELS keys) // and the new Jimar dropdown only offers number codes. var meta = metadata[lang]; var allCodes = (meta && meta.g) || []; var genderCodes = $.grep(allCodes, function (c) { return !isNumberCode(c); }); var jimarCodes = $.grep(allCodes, function (c) { return isNumberCode(c); }); var showC = (pos === "navdêr" || pos === "serenav") && genderCodes.length > 0; var cRow = stepDiv.find("#wiktku-posparams-row-c"); cRow.toggle(showC); if (showC) { var sel = cRow.find(".wiktku-posparams-cinsiyet-sel"); // Prefer the select's own current value (normal in-session // use); fall back to the shared hidden field, which is how // a cache/section restore communicates a saved gender // before this select has any <option>s to hold it. var prev = sel.val() || $("#wiktku-start-cinsiyet-field").val() || ""; sel.find("option[value!='']").remove(); $.each(genderCodes, function (_, code) { sel.append($("<option></option>").val(code).text(genderLabel(code))); }); if (prev) sel.val(prev); } var showJimar = (pos === "navdêr" || pos === "serenav") && jimarCodes.length > 0; var jimarRowEl = stepDiv.find("#wiktku-posparams-row-jimar"); jimarRowEl.toggle(showJimar); if (showJimar) { var jimarSelEl = jimarRowEl.find(".wiktku-posparams-jimar-sel"); var prevJimar = jimarSelEl.val() || $("#wiktku-start-jimar-field").val() || ""; jimarSelEl.find("option[value!='']").remove(); $.each(jimarCodes, function (_, code) { var def = NUMBER_LABELS[code] || {}; var opt = $("<option></option>").val(code).text(numberOptionLabel(code)); // The explanation (cat, e.g. "dualia tantum") shows as a // hover tooltip — <option> can't hold richer markup. if (def.cat) opt.attr("title", def.cat); jimarSelEl.append(opt); }); if (prevJimar) jimarSelEl.val(prevJimar); } stepDiv.find("#wiktku-posparams-row-lektur").toggle(isLeker); // Only ask for the structural form once the person has said // gerguhêz/negerguhêz — "paşê jî form", per Ghybu. stepDiv.find("#wiktku-posparams-row-lekturform") .toggle(isLeker && !!stepDiv.find(".wiktku-posparams-lektur-sel").val()); stepDiv.find("#wiktku-posparams-row-tr").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-ts").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-m").toggle(isNom); stepDiv.find("#wiktku-posparams-row-mtr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-n").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ntr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-p").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ptr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-y").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ytr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-sûp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-sûptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-komp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-komptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-gir").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-girtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hûr").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-hûrtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hanja").toggle(isJa); stepDiv.find("#wiktku-posparams-row-hanjaTr").toggle(isJa); stepDiv.find("#wiktku-posparams-row-niha").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-nihatr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-borî").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-borîtr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-subj").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-subjtr").toggle(isLeker && needsTr); if (!$.trim(stepDiv.find(".wiktku-posparams-text").val())) { steps.posparams.rebuildTa(stepDiv); } }, output: function () { return ""; } // pos.output reads the textarea directly }, dfn: { id: "dfn", name: "Mane", // Field types that live behind "Malûmatên pêşketî". Kept as one // list so the collapse CSS, the count badge and the allGroups // adv: flags below can't drift apart. ADV_SUBGROUPS: [ "wiktku-dfn-etiket", "wiktku-dfn-kategori", "wiktku-dfn-alternativ", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ], question_fmt: function (values) { var base = "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin!"; if (values.lang === "ku") { return base + " Ji bo tercimeyan beşa 'Werger' bi kar bîne!"; } return base; }, multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, // Builds one sense block (<li>): mane textarea, nimûne list, and // sub-lists for alternatîv/hevmane/dijmane/etc. buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Tercime + Îzah boxes (non-ku alternative to the plain mane box) — // Non-ku entries get a direct translation plus a {{îzah|…}}-wrapped // gloss instead of a Kurdish-style gloss. Rather than teach every // consumer (getSenses/getOutput/linkify) a second data shape, these // boxes just write their combined text into dfnArea and re-fire its // "input" event, so dfnArea stays the single source of truth. var tercimeArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-tercime-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-tercime") .attr("rows", 2) .attr("placeholder", "Tercimeyên rasterast ên kurmancî… Ji bo school-a îngilîzî li vir 'mekteb, medrese' binivîse"); var izahArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-izah-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-izah") .attr("rows", 3) .attr("placeholder", "Îzaha kurmancî… Ji bo school-a îngilîzî li vir 'cihê tehsîlgirtinê' binivîse"); var nonKuWrap = $("<div class='wiktku-dfn-nonku-wrap'></div>") .append(tercimeArea).append(izahArea) .hide(); function syncNonKuToMane() { var t = $.trim(tercimeArea.val()); var iz = $.trim(izahArea.val()); // if tercime is blank, use îzah as definition var combined = t ? (iz ? t + " {{îzah|" + iz + "}}" : t) : iz; dfnArea.val(combined); // Re-fires onDfnInput so the sense list still grows and // refresh() still runs, exactly as if this were typed // directly into the mane textarea. dfnArea.trigger("input"); } tercimeArea.on("input", syncNonKuToMane); izahArea.on("input", syncNonKuToMane); // Switches between the plain mane box and the tercime+îzah pair — // only for non-ku entries with no tplSelect selected. function updateManeMode() { var lang = getValues().lang || ""; var isTpl = !!tplSelect.val(); if (lang && lang !== "ku" && !isTpl) { dfnArea.hide(); nonKuWrap.show(); } else { nonKuWrap.hide(); if (!isTpl) dfnArea.show(); } } // Store on the block so refresh() can re-sync every block when // lang changes, and restoreDfn() can re-sync after restoring. block.data("updateManeMode", updateManeMode); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || {}; // Cache of all non-placeholder option elements, so updateTplOptions // can detach/re-attach them without losing the full list. var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.attr("data-placeholder", "Li şablonekê bigere"); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (name, tpl) { // Rewiye tine, 14 Tebax 2026: "guharto? kevnbûyî? ku-Latn? // şaşnivîs? famkirina van zehmet e" — these 13 names had // zero explanation in the dropdown (unlike steps.pron's // template picker, which already shows "name — tpl.desc"). // Mirrors that same pattern here: if tpl.desc is ever // added to a tplDefs entry in data.json, it'll show up // automatically. It's optional per-entry, not required, // since data.json doesn't have desc text for these yet — // writing accurate one-line explanations for each needs // someone who actually knows what each template does. var opt = $("<option></option>") .val(name) .text(tpl.desc ? name + " — " + tpl.desc : name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); // v3: the same status-dot / 🔗 / ⓘ row treatment as every // other template picker. This one carries the bare name in // value=, so the name mapper is the identity rather than a // snippet parse. It also answers Rewiye tine's "famkirina // van zehmet e" about these thirteen names properly — the // explanation now comes from each template's own // TemplateData instead of waiting for someone to hand-write // thirteen desc strings into data.json. markTemplateOptions(tplSelect, function (opt) { return opt.val(); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible // ones — native <select> won't reliably hide options any other way. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); // Options that were detached when the descriptions arrived // missed that pass, so describe whatever is attached now. // The cache is warm by this point, so this is synchronous. applyTplDescriptions(tplSelect); tplSelect.trigger("wiktku:refresh"); if (currentVal && !currentStillValid) { tplSelect.val(""); tplTitleInput.hide().val(""); updateManeMode(); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpela hedefê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // Şablon senses have no plain gloss, so hide alternatîv/hevmane/ // dijmane/etc. Etîket, Nimûne and Jêgirtin stay visible either way. function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); nonKuWrap.hide(); tplTitleInput.show().focus(); } else { tplTitleInput.hide().val(""); updateManeMode(); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); // The template picker is an alternative to writing a // definition, not a step before it — so the box comes first // and this sits under it as a quiet link. It only expands // for the minority of senses that are a pointer at another // word (guharto, şaşnivîs, kevnbûyî) rather than a meaning. var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput) .hide(); var tplLink = $("<a href='#' class='wiktku-dfn-tpl-link'></a>") .text("Ev ne pênase ye — şablonek bi kar bîne"); tplLink.on("click", function (e) { e.preventDefault(); tplRow.show(); $(this).hide(); tplRow.find("input.wiktku-ac-input").first().focus(); }); /** Opens the picker without a click — used on restore, when a * sense already has a template and hiding it would make the * chosen value invisible. */ function revealTplRow() { tplRow.show(); tplLink.hide(); } block.data("revealTplRow", revealTplRow); block.append(dfnArea); block.append(nonKuWrap); block.append(tplLink); block.append(tplRow); // Apply lang filter on initial build. updateTplOptions(); updateManeMode(); // — Sub-field groups. — // Ghybu, 14 Tebax 2026: "Bi min beşên 'Hevmane' û dijmane jî // bike de nav beşa Mane ji ber ku pirr tên xwestin" — and, // separately, that showing all nine at once is what makes this // form read as long and tevlihev. So the four people actually // reach for (Nimûne, Jêgirtin, Hevmane, Dijmane) stay open, in // that order, and the other five sit behind the "Malûmatên // pêşketî" toggle (adv: true → .wiktku-dfn-subgroup-adv, which // is what the collapse CSS keys off now). // Jêgirtin isn't in this array — it's a compound widget built // after the loop — but it's inserted right after Nimûne so the // visible order matches the list above. var allGroups = [ { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "wekî etîket lê xuya nabe tenê kategorîze dike", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê", adv: true }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in", adv: true }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e", adv: true }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e", adv: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); if (g.adv) groupDiv.addClass("wiktku-dfn-subgroup-adv"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } // The placeholder names the current language, but that's // often not chosen yet when this block is first built — // so keep a function around that refresh() (and onSubInput, // for newly-grown fields) can call again once lang is set // or changes. function subPlaceholder() { if (g.noLangSuffix) return g.label + "…"; var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return g.label + (langLabel ? " bi " + langLabel : "") + "…"; } function updateSubPlaceholders() { list.find("> li > textarea.wiktku-dfn-subfield").attr("placeholder", subPlaceholder()); } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": ") .append($("<span></span>").addClass("wiktku-dfn-sublabel-hint").text(g.izah)); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var useModifiers = !!MODIFIER_SUBGROUPS[g.cls]; list.data("updatePlaceholders", updateSubPlaceholders); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", subPlaceholder()); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow, useModifiers); }); list.append(useModifiers ? makeModifierLi(firstInput) : $("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder group — growing list, same structure as Nimûne. — (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text("Jêgirtin")) .append(": "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<textarea></textarea>") .addClass("wiktku-dfn-subfield wiktku-dfn-quote-citoid-input") .attr("rows", 1) .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi otomatîk tijî bike", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); // Fetches citation data from Citoid and fills this citation's // şablon + fields — only rebuilds fields on template change, // and never overwrites values the user already typed. function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoid.fetchJederFields(query).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only rebuild if switching şablon, so a repeat fetch // doesn't clear fields already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel wiktku-plain-select"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); srcSel.append($("<option></option>").val("__category__").text("Ji Kategorî:Çavkanî şablonekê hilbijêre")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); // Citoid is only useful before a source is chosen — // hide it once a selection is made, restore on reset. if (chosen) { citoidWrap.hide(); } else { citoidWrap.show(); return; } if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } if (chosen === "__category__") { // Search widget over the members of [[Kategorî:Çavkanî]]. // Picking a şablon here immediately switches the row to // "Bi destê xwe binivîsim" mode with {{Şablon}} pre-filled, var catWrap = $("<span></span>").addClass("wiktku-native-select-wrap wiktku-dfn-quote-src-cat"); var catInput = $("<input type='search' autocomplete='off'>") .addClass("wiktku-start-narrow wiktku-dfn-quote-src-cat-input") .attr("placeholder", "Li navê şablonê bigere…"); var catResults = $("<ul></ul>").addClass("wiktku-ac-results wiktku-dfn-quote-src-cat-results").hide(); var catStatus = $("<span></span>").addClass("wiktku-dfn-quote-src-cat-status").text("Şablon tên barkirin…"); var showCatResults = function (query) { var q = $.trim(query).toLowerCase(); catResults.empty(); var list = catSrcTemplates || []; var matched = q ? $.grep(list, function (name) { return name.toLowerCase().indexOf(q) !== -1; }) : list; if (!matched.length) { catResults.hide(); return; } $.each(matched.slice(0, 50), function (_, name) { var li = $("<li></li>").text(name).attr("data-value", name); var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; e.preventDefault(); selectCatTpl(name); }); li.on("mousedown", function (e) { e.preventDefault(); selectCatTpl(name); }); catResults.append(li); }); catResults.show(); }; // Wraps the chosen şablon as {{Name}}, drops it into the // manual textarea, and switches the row into manual mode // so the user can keep editing it (add params, etc.). var selectCatTpl = function (name) { catResults.hide(); srcSel.val("__manual__"); srcSel.trigger("change"); srcFields.find(".wiktku-dfn-quote-src-manual") .val("{{" + name + "}}") .trigger("focus"); }; catInput.on("input", function () { showCatResults($(this).val()); }); catInput.on("focus", function () { showCatResults($(this).val()); }); catInput.on("blur", function () { setTimeout(function () { catResults.hide(); }, 200); }); catWrap.append(catInput).append(catResults).append(catStatus); srcFields.append(catWrap); fetchCatSrcTemplates().then(function () { catStatus.text(""); }, function () { catStatus.text("Şablon nehatin barkirin."); }); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (key, label) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", key) .attr("placeholder", label + "…"); // "Sernav" / "Sernavê orjînal" (title fields, e.g. for // kitêb/kovar/malper) get a taller, draggable box; every // other field in the template stays as-is. Field labels // come from the on-wiki jederDefs data, so match on the // (diacritic-folded) label text rather than a fixed key. var foldedLabel = foldDiacritics(label); if (/^sernav$/.test(foldedLabel) || /orjin/.test(foldedLabel)) { inp.addClass("wiktku-dfn-quote-src-input--title"); } row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); jederGroupDiv.append(jederLbl).append(jederList); // Straight after Nimûne rather than last: Jêgirtin is the // same kind of thing (an attested use of the word) and the // two belong together — see the allGroups comment above. var nimuneGroup = block.find(".wiktku-dfn-nimune-group"); if (nimuneGroup.length) jederGroupDiv.insertAfter(nimuneGroup); else block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); // ── "Malûmatên pêşketî" — per sense, after Dijmane ─────── // One toggle per sense rather than one for the whole step: // the fields behind it (Etîket, Kategorî, Jornav…) belong to // a single meaning, so a global switch flipped them for every // sense at once and gave a count that answered "across all // senses" — not a question anybody was asking. (function () { block.addClass("wiktku-sense-adv-hidden"); var advRow = $("<div class='wiktku-adv-toggle-row wiktku-sense-adv-row'></div>"); var advToggle = $("<a href='#' class='wiktku-adv-toggle'></a>").attr("aria-expanded", "false"); var advLabel = $("<span class='wiktku-adv-toggle-text'></span>"); advToggle.append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")).append(advLabel); // Wikihez, 15 Tebax 2026: the "N zevî · M tije" count badge // was removed (not needed) — syncAdv still keeps the // toggle's own label/chevron/aria-expanded in sync. function syncAdv() { var hidden = block.hasClass("wiktku-sense-adv-hidden"); advLabel.text(hidden ? "Malûmatên pêşketî nîşan bide" : "Malûmatên pêşketî veşêre"); advToggle.attr("aria-expanded", hidden ? "false" : "true") .toggleClass("wiktku-adv-open", !hidden); } advToggle.on("click", function (e) { e.preventDefault(); block.toggleClass("wiktku-sense-adv-hidden"); syncAdv(); }); block.data("syncSenseAdv", syncAdv); advRow.append(advToggle); // After the last always-visible group (Dijmane) and before // the advanced ones, which sit below it in DOM order. var lastPrimary = block.find(".wiktku-dfn-dijmane-group"); if (lastPrimary.length) advRow.insertAfter(lastPrimary); else block.append(advRow); syncAdv(); }()); // ── Accordion wrapper (v3 spec) ────────────────────────── // Everything built above becomes the collapsible body, and a // header row goes in front of it. Done here, at the end, // rather than by threading a container through the ~500 lines // of field-building above — every one of those appends to // `block`, and getSenses/restoreDfn reach fields with .find(), // which doesn't care how deep they sit. var body = $("<div class='wiktku-dfn-sense-body'></div>").append(block.children()); var header = $("<div class='wiktku-dfn-sense-header'></div>"); header .append($("<span class='wiktku-dfn-sense-num'></span>")) .append($("<span class='wiktku-dfn-sense-title'></span>")) .append($("<span class='wiktku-dfn-sense-summary'></span>")) .append($("<span class='wiktku-dfn-sense-chevron'>▾</span>")); header.on("click", function () { // Collapsed → open it (and close whichever was open). // Open → collapse it, unless it's the only one. if (block.hasClass("wiktku-sense-collapsed")) steps.dfn.setOpenSense(stepDiv, block); else block.addClass("wiktku-sense-collapsed"); steps.dfn.syncSenseHeaders(stepDiv); }); block.append(header).append(body); // Typing (or clicking) anywhere in a sense makes it the open // one — "tenê maneya ku tê nivîsandin vekirî ye". body.on("focusin", function () { if (!block.hasClass("wiktku-sense-collapsed")) { steps.dfn.setOpenSense(stepDiv, block); } }); return block; }, /** True if a sense block has anything worth summarising. */ senseBlockHasContent: function (block) { var found = false; block.find("textarea, input[type='text']").each(function () { if ($.trim($(this).val() || "")) { found = true; return false; } }); if (found) return true; return !!block.find(".wiktku-dfn-tpl-select").val(); }, /** Opens `block` and collapses every other sense that has content. * A sense with nothing in it is never collapsed — the trailing * empty one is how you add the next meaning, so hiding it would * hide the only way forward. */ setOpenSense: function (stepDiv, block) { stepDiv.find("li.wiktku-dfn-sense").each(function () { var li = $(this); var collapse = !li.is(block) && steps.dfn.senseBlockHasContent(li); li.toggleClass("wiktku-sense-collapsed", collapse); }); steps.dfn.syncSenseHeaders(stepDiv); }, /** Renumbers the sense badges and refreshes each collapsed row's * one-line summary. Cheap enough to just re-run on any change. */ syncSenseHeaders: function (stepDiv) { stepDiv.find("li.wiktku-dfn-sense").each(function (i) { var li = $(this); li.find("> .wiktku-dfn-sense-header .wiktku-dfn-sense-num").text(i + 1); li.find("> .wiktku-dfn-sense-header .wiktku-dfn-sense-title").text("Mane " + (i + 1)); var summary = $.trim(li.find("textarea.wiktku-dfn-mane").first().val() || ""); if (!summary) { // A template sense has no prose — show the call itself. var tpl = li.find(".wiktku-dfn-tpl-select").val(); var title = $.trim(li.find(".wiktku-dfn-tpl-title").val() || ""); if (tpl) summary = "{{" + tpl + (title ? "|" + title : "") + "}}"; } summary = summary.split("\n")[0]; if (summary.length > 70) summary = summary.slice(0, 70) + "…"; li.find("> .wiktku-dfn-sense-header .wiktku-dfn-sense-summary").text(summary); }); }, /** Keeps the header summary in step with what is being typed. * No longer grows the list: a second sense appears only when * "+ Mane zêde bike" is clicked. Auto-growing meant every entry * with one meaning still showed an empty second one, which reads * as an unfinished form. */ onDfnInput: function (stepDiv, block, textarea) { steps.dfn.syncSenseHeaders(stepDiv); refresh(); }, /** Appends a sense, opens it, and collapses the others. */ addSense: function (stepDiv) { var list = stepDiv.find("ol.wiktku-dfn-list"); var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); initSelects(newBlock); steps.dfn.setOpenSense(stepDiv, newBlock); newBlock.find("textarea.wiktku-dfn-mane").first().focus(); refresh(); return newBlock; }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow, modifiers) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow, modifiers); }); list.append(modifiers ? makeModifierLi(next) : $("<li></li>").append(next)); // New field starts with no placeholder — give it (and any // others in the list) the current one. var updatePlaceholders = list.data("updatePlaceholders"); if (typeof updatePlaceholders === "function") updatePlaceholders(); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: {}, posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; // Rewiye tine, 14 Tebax 2026: "şablonên mana jî dikare serê // yekî tevlîhev bike... famkirina van zehmet e" — the "an jî // şablonek hilbijêre" dropdown inside each sense (guharto, // kevnbûyî, ku-Latn, şaşnivîs, …) had no explanation at all. // One reassurance, shown once for the whole Mane step rather // than repeated per sense: it's optional, plain text is the // normal path. if (!stepDiv.find(".wiktku-dfn-tpl-hint").length) { stepDiv.append( $("<p class='wiktku-step-hint wiktku-dfn-tpl-hint'></p>").text( "Ji bo her maneyekê, dropdown-a \"an jî şablonek hilbijêre\" ne mecbûrî ye — bi gelemperî tu tenê maneyê bi tîpên asayî dinivîsî. Ew şablon tenê ji bo rewşên taybet in (mînak: guherto, kevnbûyî, şaşnivîs); heke tu nizanî kîjan divê, vale bihêle." ) ); } var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); var addSenseBtn = $("<button type='button' class='wiktku-add-sense'></button>") .append($("<span class='wiktku-add-sense-plus'>+</span>")) .append(document.createTextNode("Mane zêde bike")); addSenseBtn.on("click", function (e) { e.preventDefault(); steps.dfn.addSense(stepDiv); }); stepDiv.append(addSenseBtn); steps.dfn.syncSenseHeaders(stepDiv); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName === "__category__") { // Reachable only if the user opened the category search but // never picked a şablon — picking one switches the row to // __manual__ (see selectCatTpl above), so there's nothing // meaningful to save here. } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: readList("wiktku-dfn-etiket"), kategori: readList("wiktku-dfn-kategori"), nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense var izahLines = []; // parallel — raw îzah gloss for that same sense // True only once some sense's *actual* dfn text (post tercime/îzah // split) is non-empty. var hasLinkableMane = false; $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("# " + (tplKatTpl ? tplKatTpl + " " : "") + (tplLabelTpl ? tplLabelTpl + " " : "") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(""); // template senses have no îzah return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty // Pull the îzah gloss (if any) out of the combined tercime+îzah // string — it's spliced back in separately below, after its // own linkify pass (see izahLines / the second linkifyText call). var izahRaw = null; var tercimeIzah = splitTercimeIzah(dfn); if (tercimeIzah) { dfn = tercimeIzah.tercime; izahRaw = stripWikilinks(tercimeIzah.izah); } if (dfn) { dfn = stripWikilinks(dfn); // Sentence-case + trailing period are for ku definitions, // which are written as full glosses. if (lang === "ku") { if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } // Real prose — this is what makes the sense worth running // through the main linkify pass. hasLinkableMane = true; } else if (izahRaw === null) { // No mane at all — this is just the "{{mane?|lang}}" // placeholder, a bare template call with no plain words // in it. Do NOT count it as linkable: sending nothing but // bracketed templates through the main linkify pass hangs // the linkify gadget (see the hasLinkableMane/hasIzah // check below). dfn = lang === "ku" ? "{{mane?|" + lang + "}}" : ""; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var out = "# " + (katTpl ? katTpl + " " : "") + (labelTpl ? labelTpl + " " : "") + dfn; var idx = defLines.length; var hasThisIzah = izahRaw !== null && $.trim(izahRaw) !== ""; // Bare {{...}} token — like {{wiktku-cite-N}}, this survives // linkify's first pass untouched (it treats template calls as // opaque), then gets swapped for {{îzah|…}} once the actual // gloss text has been linkified in its own separate pass. if (hasThisIzah) { out += (dfn ? " " : "") + "{{wiktku-izah-" + idx + "}}"; } function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(hasThisIzah ? izahRaw : ""); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } // Runs text through the linkify gadget if it's loaded, otherwise // just passes it through unchanged. Shared by both linkify passes // below (main mane text, and — separately — îzah glosses). function linkifyText(t, cb) { if (typeof $.kuLinkify === "function") { $.kuLinkify(t, cb); } else { cb(t); } } var hasIzah = izahLines.some(function (t) { return t && $.trim(t) !== ""; }); var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with nimûne?. text = "# {{mane?|" + lang + "}}\n#* {{nimûne?|" + lang + "}}\n"; callback(text); return; } // Runs the îzah-only linkify pass against `base` (either the raw // text, when there's no linkable mane to run the main pass on // first, or the already-linkified main text). Shared by both // branches below so the token-splice logic only lives once. function runIzahPass(base) { var izahJoined = $.map(izahLines, function (raw, idx) { if (!raw) return undefined; return "{{wiktku-izah-open-" + idx + "}}" + raw + "{{wiktku-izah-close-" + idx + "}}"; }).join("\n"); linkifyText(izahJoined, function (izahLinked) { var izahByIdx = {}; var re = /\{\{wiktku-izah-open-(\d+)\}\}([\s\S]*?)\{\{wiktku-izah-close-\1\}\}/g; var m; while ((m = re.exec(izahLinked)) !== null) { izahByIdx[parseInt(m[1], 10)] = m[2]; } var withIzah = base.replace(/\{\{wiktku-izah-(\d+)\}\}/g, function (_, n) { var linked = izahByIdx[parseInt(n, 10)]; return linked !== undefined ? "{{îzah|" + linked + "}}" : ""; }); callback(restoreCites(withIzah)); }); } if (!hasLinkableMane) { if (!hasIzah) { // All filled senses are template senses (or otherwise have // no plain text at all) — nothing here needs linkify. callback(restoreCites(text)); return; } // There's no plain mane text anywhere (e.g. tercime left blank // with only îzah filled in), so every defLine is just a bare // template call with nothing to word-link. Sending a line // like "# {{wiktku-izah-0}}" through the main linkify pass // gives it no plain words to work with, makes the linkify // gadget hang — so skip that pass entirely and run only // the îzah pass, splicing straight into the unlinkified text. var loadIzahOnly = function () { runIzahPass(text); }; mw.loader.using("ext.gadget.linkify", loadIzahOnly, loadIzahOnly); return; } var didTryToLoad = function () { // First pass: the main definition text (mane), same as before. linkifyText(text, function (mainLinked) { if (!hasIzah) { callback(restoreCites(mainLinked)); return; } // Second pass: îzah glosses, linkified via their own // separate call. Each gloss is wrapped in its own // {{wiktku-izah-open/close-N}} pair; like the existing // {{wiktku-cite-N}} tokens, these sit inside double // braces so linkify leaves the tokens themselves alone — // only the raw gloss text between each pair gets linked. runIzahPass(mainLinked); }); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, tewandin: { id: "tewandin", name: "tewandin", question_fmt: 'Tewandina "' + pageName + '" binivîse', visible: function (values) { return values.lang && values.pos; }, build: function (stepDiv) { if (stepDiv.find(".wiktku-tewandin-wrap").length) return null; var wrap = $("<div class='wiktku-tewandin-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-tewandin-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-tewandin-text") .attr("rows", 4) .attr("placeholder", "{{ku-tewîn-nav|nêr}}"); wrap.append(ta); stepDiv.append(wrap); function autoPopulate() { if (!ta.length) return; var vals = getValues(); var c = vals.cinsiyet || ""; var p = vals.pos || ""; if (!pageName.includes(" ") && c && GENDER_BASE_LABELS[c] && (p === "navdêr" || p === "serenav") && vals.lang === "ku" && c !== "mndudil") { var label = (c === "mnmane") ? "mê û nêr" : GENDER_BASE_LABELS[c]; var out = "{{ku-tewîn-nav|" + label; if (p === "serenav") out += "|y"; out += "}}"; if (!$.trim(ta.val())) ta.val(out); } } setTimeout(function () { autoPopulate(); $("#wiktku-start-form").on("change.tewandin", "#wiktku-start-lang-field, #wiktku-start-cinsiyet-field, #wiktku-start-pos-field", autoPopulate); }, 0); return ta; }, output: function () { var manualText = $.trim($("#wiktku-start-tewandin .wiktku-tewandin-text").val()); if (manualText) { return "\n==== Tewandin ====\n" + manualText + "\n"; } return ""; } }, // resim — one or more images resim: { id: "resim", name: "resim", question_fmt: "Resmekê lê zêde bike", visible: function (values) { return !!(values.lang && values.pos); }, /** Builds one image row: filename + caption + alt text. */ buildItem: function (stepDiv) { var item = $("<li class='wiktku-resim-item'></li>"); var fileRow = $("<div class='wiktku-posparams-row'></div>"); var fileInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-file") .attr("placeholder", "navê_dosyayê.jpg"); fileRow.append($("<label></label>").text("Navê dosyayê: ")).append(fileInp); var capRow = $("<div class='wiktku-posparams-row'></div>"); var capInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-caption") .attr("placeholder", "Danasîna resimê…"); capRow.append($("<label></label>").text("Danasîn: ")).append(capInp); // Alt text: what a screen reader announces for this image var altRow = $("<div class='wiktku-posparams-row'></div>"); var altInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-alt") .attr("placeholder", "Ji bo kesên nabînin, çi tê dîtin? (ne mecbûrî)"); altRow.append($("<label></label>").text("Nivîsa alternatîf: ")).append(altInp); // Auto-fill the caption with the plain page name when a filename // is typed fileInp.on("input", function () { var file = $.trim($(this).val()); var curCap = $.trim(capInp.val()); var isDefault = !curCap || curCap === pageName; if (file && isDefault) { capInp.val(pageName); } else if (!file && isDefault) { capInp.val(""); } steps.resim.onFileInput(stepDiv, item, this); }); item.append(fileRow).append(capRow).append(altRow); return item; }, /** Grows the image list when the last row's filename gets content. */ onFileInput: function (stepDiv, item, input) { var val = $.trim($(input).val()); var list = stepDiv.find("ol.wiktku-resim-list"); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { list.append(steps.resim.buildItem(stepDiv)); } }, build: function (stepDiv) { if (stepDiv.find(".wiktku-resim-wrap").length) return null; var wrap = $("<div class='wiktku-resim-wrap'></div>"); var list = $("<ol class='wiktku-resim-list'></ol>"); list.append(steps.resim.buildItem(stepDiv)); wrap.append(list); stepDiv.append(wrap); return null; }, /** Reads every filled row from the DOM into an array of {file, caption, alt} * objects — blank rows (missing filename or caption) are skipped. * Non-Kurdish captions get wrapped in {{zim|lang|…}} here, unless * the user already typed their own {{zim|…}} template. Alt text is * optional and left as plain text either way. */ getImages: function (values) { var lang = (values && values.lang) || getValues().lang || ""; var images = []; $("#wiktku-start-resim li.wiktku-resim-item").each(function () { var file = $.trim($(this).find(".wiktku-resim-file").val()); var caption = $.trim($(this).find(".wiktku-resim-caption").val()); var alt = $.trim($(this).find(".wiktku-resim-alt").val()); if (!file || !caption) return; // Strip leading "Wêne:" or "File:" if the user typed it — we add it ourselves. file = file.replace(/^(wêne|file|image)\s*:\s*/i, ""); if (lang && lang !== "ku" && !/^\{\{zim\s*\|/i.test(caption)) { caption = "{{zim|" + lang + "|" + caption + "}}"; } images.push({ file: file, caption: caption, alt: alt }); }); return images; }, output: function (values) { var images = steps.resim.getImages(values); if (!images.length) return ""; return images.map(function (img) { var altPart = img.alt ? "|alt=" + img.alt : ""; return "[[Wêne:" + img.file + "|thumb" + altPart + "|" + img.caption + "]]"; }).join("\n") + "\n"; } }, // bnr-h — {{bnr-h|Page1|Page2|…}} prepended before the lang section (shared, not per-section) bnrh: { id: "bnrh", name: "binêre herwiha (bnr-h)", question_fmt: "Şablona bnr-h li qismê herî jor a rûpelê", //visible: function (values) { return !!values.lang; }, multiple: true, narrow: true, placeholder: "Ji bo 'test' bnr 'Test', 'teşt'", output: function (values) { var pages = $.grep(values.bnrh || [], function (p) { return !!$.trim(p); }); if (!pages.length) return ""; return "{{bnr-h|" + pages.map(function (p) { return $.trim(p); }).join("|") + "}}\n"; } }, bikaranin: { id: "bikaranin", name: "Notên bikaranînê", question_fmt: "Notên bikaranînê yên li ser vê kelîmeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, output: function (values) { var text = $.trim(values.bikaranin || ""); if (!text) return ""; return "\n==== Notên bikaranînê ====\n" + text + "\n"; }, }, xwendin: { id: "xwendin", name: "Bêhtir bixwîne", question_fmt: "Lînkên derveyî eleqedarî vê madeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: function (values) { if (!values || !values.lang) { return `* {{wpedî}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; } const ziman = values.lang === "ku" ? "" : `|ziman=${values.lang}`; return `* {{wpedî${ziman}}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; }, output: function (values) { var text = $.trim(values.xwendin || ""); if (!text) return ""; return "\n==== Bêhtir bixwîne ====\n" + text + "\n"; }, }, alfabeyendin: { id: "alfabeyendin", name: "Bi alfabeyên din", question_fmt: function (values) { var base = "Nivîsîna vê kelîmeyê bi alfabeyên din" var langLabel = values.lang ? getLangLabel(values.lang) : ""; if (langLabel) { return base + " ên " + langLabel; } return base; }, visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: "Ji bo kurmancî: * {{ku-ar|şiklê alfaba erebî}}", output: function (values) { var text = $.trim(values.alfabeyendin || ""); if (!text) return ""; return "\n==== Bi alfabeyên din ====\n" + text + "\n"; }, }, formalt: makeWordListStep("formalt", "formên alternatîv", "Formên alternatîv ên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), hevmane: makeWordListStep("hevmane", "hevmane", "Hevmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), dijmane: makeWordListStep("dijmane", "dijmane", "Dijmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jornav: makeWordListStep("jornav", "jornav", "Jornavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jernav: makeWordListStep("jernav", "jêrnav", "Jêrnavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse"), binereherwiha: makeWordListStep("binereherwiha", "herwiha binêre", "Kelîmeyên din ên eleqedar binivîse"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: {}, visible: function (values) { return values.lang && values.pos; }, // Fills the insert-dropdown from the current etymTpls object. refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(ta); stepDiv.append(wrap); initSelects(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder. // Skip it only when every filled sense is a şablon sense // a completely empty entry with no şablon chosen still gets the placeholder var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasFilledTplSense = dfnSenses.some(function (s) { return !!s.tpl && !!s.tplTitle; }); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (hasFilledTplSense && !hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: function (values) { return {"navz": true, [values.lang]: true} }, // Language dropdown + growing word-input list; a new row appends // when the dropdown gets a value. Mirrors steps.trans, but flat. buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/build below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Attach the searchable picker now the select is in the DOM. initSelects(list); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", question_fmt: "'"+ pageName + "' di zaravayên din de çawa tê gotin?", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: {}, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zaravayekî bigere"); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; // Item 6 (Wikihez, 14 Tebax 2026): "Bi zaravayên din" now // auto-appears empty for lang=ku exactly like Werger // already does (steps.trans.output, same rule below) — // a completely empty entry still gets a placeholder // section to fill in later; an individual placeholder // gloss is only skipped once some other sense already has // real content, making that particular one redundant. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", question_fmt: "Tercimeyên vê maneyê bi zimanên din binivîse", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide only when every sense is a filled template sense (no plain // gloss to attach translations to). A mix, or nothing filled in // yet, still shows Werger. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, // Language dropdown + growing word-input list, scoped to one gloss's // group (each gloss has its own group and row list). buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/buildGroup below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, // Builds (or fetches) the .wiktku-trans-group for one gloss. buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, // Syncs one .wiktku-trans-group per current gloss, keyed by // data-gloss-pos so groups stay matched across rebuilds. build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, // Reads all translation rows, grouped by gloss position. getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, // Builds the numbered "{ index, gloss }" list, one per dfn sense // with a real mane (skips template senses). index is 1-based and // matches the sense's position in the "#" definition list. // When nothing's filled in, returns one placeholder entry so // Werger still has a group to attach to; when every sense is a // filled template sense, stays empty (matches trans.visible()). glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane, but other fields are filled — still gets a // gloss group since dfn.getOutput() emits {{mane?}} for it. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // A completely empty entry (nothing filled in dfn at all, no // şablon chosen either) still gets a placeholder Werger section // to fill in later. Only // skip an individual placeholder gloss below when some other // sense actually has real content, making that particular // placeholder redundant. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it. If some other sense already has real // content, this placeholder is redundant — skip it. If the // whole entry is empty, keep it so Werger still gets a // section to fill in. if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, cavkani: { id: "cavkani", name: "çavkanî", question_fmt: "Çavkaniyên din (ne jêgirtin) lê zêde bike", visible: function (values) { return !!values.pos; }, // Fills the insert-dropdown from the members of [[Kategorî:Çavkanî]]. refreshTplSelect: function () { var sel = $("#wiktku-start-cavkani .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(catSrcTemplates || [], function (_, name) { sel.append($("<option></option>").val(name).text(name)); }); markTemplateOptions(sel, function (opt) { return opt.val(); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-cavkani-wrap").length) return null; var wrap = $("<div class='wiktku-cavkani-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-cavkani-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-cavkani-text") .attr("rows", 4) .attr("placeholder", "Şablonekî ji lîsteyê hilbijêre an rasterast binivîse…"); // Template insert dropdown, populated from [[Kategorî:Çavkanî]] — // options refreshed once the category members are fetched. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var status = $("<span class='wiktku-cavkani-status'></span>"); sel.on("change", function () { var name = $(this).val(); if (!name) return; insertAtCursor(ta[0], "\n* {{" + name + "}}"); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(status).append(ta); stepDiv.append(wrap); // build() runs again for every new beş (see the "+ Beş zêde bike" // handler), after the initial page-wide pass — so this select needs // its own init or it stays a plain, unsearchable native <select>. initSelects(wrap); if (catSrcTemplates) { steps.cavkani.refreshTplSelect(); } else { status.text("Şablon tên barkirin…"); fetchCatSrcTemplates().then(function () { steps.cavkani.refreshTplSelect(); status.text(""); }, function () { status.text("Şablon nehatin barkirin."); }); } return ta; }, output: function () { var text = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); if (!text) return ""; return "\n==== Çavkanî ====\n" + text + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); // Ghybu, 14 Tebax 2026: bnrh/resim/pron used to sit here, always visible, // well above the tab bar (which starts right before "dfn"). They're now // tab-gated (see STEP_GROUPS below), so their DOM position moves down to // sit right next to it instead of rendering as always-open fields between // Ziman and Cureyê rêzimanî. This array only controls DOM build order — // nothing else keys off it (see the comment above stepIdToGroup). // Wikihez, 14 Tebax 2026: Mane tab's internal order is now Mane → malûmatên // pêşketî (nested inside dfn's own div, see steps.dfn.build) → Wêne → // Bi zaravayên din → Werger, so dfn/resim/zarava/trans need to sit // adjacent to each other, in that order, in the DOM. zarava/trans moved // out of the "Beşên din" cluster entirely — see STEP_GROUPS below. var ordered_steps = [ steps.lang, steps.pos, steps.posparams, steps.cinsiyet, steps.jimar, steps.lektur, steps.tr, // Mane tab, in reading order: the senses, then the two things that // belong to the entry as a whole rather than to one sense. steps.dfn, steps.tewandin, steps.alfabeyendin, steps.zarava, steps.trans, // Etîmolojî tab. steps.etym, steps.dunde, // Eleqedar tab — three lists of the same shape. steps.je, steps.tekildar, steps.binereherwiha, // Bilêvkirin: no longer in a tab at all (see PRON_SECTION_ID) — it // still needs a slot here because this array is what builds the DOM. steps.pron, // Beşên din, behind the picker. steps.resim, steps.bnrh, steps.bikaranin, steps.formalt, steps.hevmane, steps.dijmane, steps.jornav, steps.jernav, steps.cavkani, steps.xwendin]; // ── Step-group tabs ────────────────────────────────────────────────────── // Ghybu, 14 Tebax 2026 (revised): originally 5 tabs (Bingehîn/Bilêvkirin/ // Lînkkirin/Bikaranîn/Din), split by topic. Ghybu's follow-up flattened // that to exactly 3: "Mane", "Bilêvkirin", "Beşên din" ("other // sections") — with Wêne and Nimûne folded INTO "Mane" specifically // (not left in a misc tab), and everything that isn't Mane/Bilêvkirin // dumped into one single "Beşên din" catch-all rather than split across // topic tabs. Nimûne doesn't appear below as its own entry because it's // not a separate step — it's already rendered inside each dfn/Mane // sense block (see buildSenseBlock's allGroups), so it's under "Mane" // automatically. "mane" stays first (and so the default-active tab) // since required content — Mane itself — has to be what's seen by // default. // Wikihez, 14 Tebax 2026: zarava/trans moved from "besendin" into "mane" — // both are already gated to lang===ku (zarava.visible just delegates to // trans.visible), so they show/hide automatically with no picker // involvement, same as before; they just render inside the Mane tab // now instead of behind the Beşên din picker (see openedOtherSections // below, which only applies to "besendin" members). // Wikihez, 15 Tebax 2026: pared back again after Ghybu's "Tu jî dizanî ku // kesên ku tên vira çito peyv çêdikin: Ziman > Mane > Mînak > Hevmane > // Dijmane". That path is now what the form shows by default and nothing // else: Mane holds the senses (whose own blocks carry Nimûne, Jêgirtin, // Hevmane and Dijmane — see steps.dfn.allGroups) plus Werger. Wêne and // "Bi zaravayên din" moved out to the Beşên din picker with everything // else; they aren't gone, they're one dropdown pick away. // v3 spec (15 Tebax 2026): four tabs instead of three, and Bilêvkirin // leaves the tab bar entirely. // // The Beşên din picker had grown to eighteen entries, which is its own // kind of "where do I find anything" problem — splitting the two // obvious clusters out as their own tabs is what fixes that: // Etîmolojî — where the word came from, and what came from it // Eleqedar — the three "related words" lists, which are the same // shape as each other and nothing like the rest // Tewandin moves into Mane and out from behind the picker: it is // commonly wanted and it belongs with the senses it inflects. Note this // is a PLACEMENT change only — Tewandin keeps its own free-text // {{ku-tewîn-nav}} field and does NOT absorb the Cins/zayend form // parameters (m=/n=/p=), which stay on the headword template where // they belong. The v3 mock merged the two; Wikihez rejected that. var STEP_GROUPS = [ { id: "mane", label: "Mane", steps: ["dfn", "tewandin", "alfabeyendin", "zarava", "trans"] }, { id: "etimoloji", label: "Etîmolojî", steps: ["etym", "dunde"] }, { id: "eleqedar", label: "Eleqedar", steps: ["je", "tekildar", "binereherwiha"] }, { id: "besendin", label: "Beşên din", steps: ["resim", "formalt", "hevmane", "dijmane", "jornav", "jernav", "bikaranin", "cavkani", "xwendin", "bnrh"] }, ]; // Steps that live behind the "Beşên din" picker — only these need an // explicit "open" before they're shown, even when their tab is active. // Derived from the group above so it can't drift out of sync. var BESENDIN_STEP_IDS = STEP_GROUPS[3].steps; // Reverse lookup: step id -> index into STEP_GROUPS (undefined for // ungrouped steps — now only lang/pos/posparams/cinsiyet/lektur/tr, // which stay always-visible since they're required to get to everything // else). var stepIdToGroup = {}; $.each(STEP_GROUPS, function (gi, g) { $.each(g.steps, function (_, sid) { stepIdToGroup[sid] = gi; }); }); // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "posparams", "cinsiyet", "jimar", "lektur", "tr", "resim", "dfn", "tewandin", "formalt", "bikaranin", "alfabeyendin", "hevmane", "dijmane", "jornav", "jernav", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans", "cavkani", "xwendin" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; // ── Bilêvkirin as a standalone section (v3 spec) ───────────────────── // Pronunciation belongs to the word, not to one part of speech, so it // sits beside Navdêr/Lêker in the section tab bar rather than inside // any of them, and is added once from "+ Beş zêde bike". // // Modelled as a flag rather than an entry in `sections`: activeSection // is used as an array index in a dozen places (saveCurrentSection, // restoreSection, sections[activeSection]…), and making it sometimes a // string would mean auditing all of them. Viewing Bilêvkirin instead // leaves activeSection pointing at the POS section you were on, so // coming back is free and nothing else has to change. // Always in the tab bar, and first — pronunciation applies to the whole // word, so it reads as the thing that comes before any part of speech // rather than an optional extra you have to know to add. Its content // only appears once you click it, like any other tab. var viewingPron = false; // is it the tab currently on screen // Which STEP_GROUPS tab is currently shown. Lives out here (like // activeSection above) so refresh() — which is not nested inside build() // — can read it and so renderGroupTabs()/updateGroupTabIndicators() below // can be called from refresh() too. Both operate on the tab bar via its // #wiktku-group-tabs id rather than a closured element reference, for the // same reason. var activeGroup = 0; // Unsaved-changes / autosave state. Lives out here (same reason as // activeGroup above) so destroy() — which runs on final submit and on // switching to the source editor, and is not nested inside build() — // can clear the timers and the beforeunload warning. build() assigns // into these; it doesn't re-declare them. var formDirty = false; var autosaveDebounceTimer = null; var autosaveInterval = null; /** Re-renders the step-group tab bar to reflect the current activeGroup. */ function renderGroupTabs() { var groupTabsDiv = $("#wiktku-group-tabs"); if (!groupTabsDiv.length) return; groupTabsDiv.empty(); $.each(STEP_GROUPS, function (i, g) { var tab = $("<span></span>") .addClass("wiktku-group-tab") .attr("data-group-idx", i) .text(g.label) .toggleClass("wiktku-tab-active", i === activeGroup); (function (idx) { tab.on("click", function () { if (idx === activeGroup) return; activeGroup = idx; renderGroupTabs(); if (idx === BESENDIN_GROUP_IDX) renderBesenDinPicker(); refresh(); }); }(i)); groupTabsDiv.append(tab); }); } /** * Toggles a "needs attention" dot on any group tab that still has a * required, unfilled field hidden inside it — so switching tabs doesn't * leave the person wondering why "Bişîne" stays disabled. */ function updateGroupTabIndicators(values) { var tabs = $("#wiktku-group-tabs .wiktku-group-tab"); if (!tabs.length) return; $.each(STEP_GROUPS, function (i, g) { var missing = false; $.each(g.steps, function (_, sid) { var step = steps[sid]; if (!step || !step.required) return; var val = values[sid]; if (val === "" || (step.multiple && $.isArray(val) && val.join("") === "")) { missing = true; } }); tabs.eq(i).toggleClass("wiktku-tab-missing", missing && i !== activeGroup); }); } // Wikihez, 14 Tebax 2026: "Beşên din" no longer shows all 16 fields // stacked at once — a picker reveals one at a time instead. This is // per-section state (like the field values themselves), snapshotted in // saveCurrentSection() and restored in restoreSection() below, and // auto-seeded from any field that already has content (so a returning // draft, or an older cache saved before this existed, doesn't hide // something the person already filled in). var openedOtherSections = {}; var BESENDIN_SET = {}; $.each(BESENDIN_STEP_IDS, function (_, sid) { BESENDIN_SET[sid] = true; }); // "besendin"'s index in STEP_GROUPS. Derived rather than hardcoded — // this was a literal 2 and silently pointed at the wrong tab the moment // Etîmolojî and Eleqedar were inserted ahead of it. var BESENDIN_GROUP_IDX = (function () { for (var i = 0; i < STEP_GROUPS.length; i++) { if (STEP_GROUPS[i].id === "besendin") return i; } return STEP_GROUPS.length - 1; }()); /** Re-renders the "Beşên din" picker to list only the not-yet-opened sections. */ function renderBesenDinPicker() { var wrap = $("#wiktku-besendin-picker"); if (!wrap.length) return; wrap.empty(); var pickerValues = getValues(); var unopened = $.grep(BESENDIN_STEP_IDS, function (sid) { if (openedOtherSections[sid]) return false; // Don't offer a section that would open onto nothing: several of // these are gated (Bi zaravayên din / Werger need lang=ku, most // need a pos). refresh() would hide it again straight away, so // picking it would read as a broken dropdown. var step = steps[sid]; if (step && typeof step.visible === "function") { try { if (!step.visible(pickerValues)) return false; } catch (e) { /* a step whose visible() needs DOM we lack yet — offer it */ } } return true; }); if (!unopened.length) return; // everything's open — nothing left to pick var sel = $("<select class='wiktku-besendin-select'></select>"); sel.attr("data-placeholder", "— beşek hilbijêre —"); sel.append($("<option value=''>— beşek hilbijêre —</option>")); $.each(unopened, function (_, sid) { var step = steps[sid]; if (!step) return; sel.append($("<option></option>").val(sid).text(capitalize(step.name))); }); sel.on("change", function () { var sid = $(this).val(); if (!sid) return; openedOtherSections[sid] = true; renderBesenDinPicker(); refresh(); }); wrap.append(sel); initSelects(wrap); } /** Marks any BESENDIN_STEP_IDS field that already has real content as * "opened", so restoring a draft doesn't bury filled-in sections behind * the picker. Reuses each step's own output() as the emptiness check — * it already knows what "empty" means per field, and it reads the DOM * the restore just populated. Call this AFTER the DOM has the restored * values in it. */ function seedOpenedFromContent() { var values = getValues(); $.each(BESENDIN_STEP_IDS, function (_, sid) { if (openedOtherSections[sid]) return; var step = steps[sid]; if (!step || typeof step.output !== "function") return; try { if (step.output(values)) openedOtherSections[sid] = true; } catch (e) { /* a step whose output() needs more state than we have yet — skip it */ } }); } function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } // Rebuilds the dfn DOM from a previously snapshotted senses array. function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. The // "+ Mane zêde bike" button goes with it — build() re-appends both, // and leaving the old one behind would both duplicate it and put it // above the rebuilt list. stepDiv.find("ol.wiktku-dfn-list").remove(); stepDiv.find(".wiktku-add-sense").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); // The picker is collapsed behind a link by default; a restored // sense that already uses a template has to show it, or the // chosen template is invisible and looks lost. var reveal = block.data("revealTplRow"); if (typeof reveal === "function") reveal(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // dfnArea is the only thing actually saved, so split it back into // tercime/îzah for editing (mirrors syncNonKuToMane's join format). var maneParts = splitTercimeIzah(sense.mane); block.find(".wiktku-dfn-tercime").val(maneParts ? maneParts.tercime : (sense.mane || "")); block.find(".wiktku-dfn-izah").val(maneParts ? maneParts.izah : ""); // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Same for the mane-box mode (plain vs tercime+îzah), since this // also depends on tplSelect's (and lang's) value. var updateMane = block.data("updateManeMode"); if (updateMane) updateMane(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found var useModifiers = !!MODIFIER_SUBGROUPS[cls]; // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true, useModifiers); }); subList.append(useModifiers ? makeModifierLi(ta) : $("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text).each(function () { highlightLinebreak(this); }); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder entries — accepts current array shape or a legacy // single object (older saved sections) for backwards compat. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote).each(function () { highlightLinebreak(this); }); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederCatTpl) { // Legacy format from before the şablon search switched rows to // manual mode directly — convert it the same way now, so it's // editable like any other free-form source. var catSelEl = li.find(".wiktku-dfn-quote-src-sel"); catSelEl.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val("{{" + j.jederCatTpl + "}}"); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); // Numbers and one-line summaries for the freshly rebuilt blocks, and // collapse everything that has content — on a restored draft nothing // is "the sense being edited" yet, so a five-sense entry would // otherwise come back fully expanded, which is the state this // accordion exists to avoid. steps.dfn.syncSenseHeaders(stepDiv); stepDiv.find("li.wiktku-dfn-sense").each(function () { var li = $(this); li.toggleClass("wiktku-sense-collapsed", steps.dfn.senseBlockHasContent(li)); }); } // Snapshots simple (non-dfn) per-section steps from the DOM into obj. function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } if (id === "cavkani") { snap.cavkani = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); return; } if (id === "posparams") { snap.posparams = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); return; } if (id === "resim") { // One entry per row, including blank ones, so a mid-edit draft // (e.g. a filename typed but no caption yet) survives a cache // restore instead of being silently dropped. snap.resim = $("#wiktku-start-resim li.wiktku-resim-item").map(function () { return { file: $.trim($(this).find(".wiktku-resim-file").val()), caption: $.trim($(this).find(".wiktku-resim-caption").val()), alt: $.trim($(this).find(".wiktku-resim-alt").val()) }; }).get(); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); // Item 3: which "Beşên din" sub-sections this section has already // opened via the picker — per-section, like everything else here. snap.openedOtherSections = $.extend({}, openedOtherSections); sections[activeSection] = snap; } // Restores a previously saved snapshot into the form DOM. function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); $("#wiktku-start-cavkani .wiktku-cavkani-text").val(snap.cavkani || ""); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); steps.posparams.build(ppDiv); var savedTa = snap.posparams || ""; ppDiv.find(".wiktku-posparams-text").val(savedTa); // Re-parse saved textarea to restore helper widget states. if (savedTa) { var cMatch = savedTa.match(/\|c=([^|}\s]+)/); var jMatch = savedTa.match(/\|j=([^|}\s]+)/); var trMatch = savedTa.match(/\|tr=([^|}\s]+)/); // Write into the shared hidden field (not the visible // select, which has no <option>s yet) — syncHelpers() // below reads it back to restore the dropdown once the // gender/number options for this language are populated. if (cMatch) $("#wiktku-start-cinsiyet-field").val(cMatch[1]); if (jMatch) $("#wiktku-start-jimar-field").val(jMatch[1]); if (trMatch) ppDiv.find(".wiktku-posparams-field[data-pp-key='tr']").val(trMatch[1]); // For lêker, c= holds the verb-type code instead of a // gender — split it back across the two dropdowns it is // now assembled from ("x-gh" → form "x" + base "gh"). if (cMatch && /^lêker/.test(snap.pos || "")) { var lekturParts = /^(?:([xphb])-)?(n?gh)$/.exec(cMatch[1]); if (lekturParts) { ppDiv.find(".wiktku-posparams-lektur-sel").val(lekturParts[2]); ppDiv.find(".wiktku-posparams-lekturform-sel").val(lekturParts[1] || ""); } } // Restore checked optional params. "form" is stored as // "erê" rather than "1" (see rebuildTa), so it needs its // own check here. ppDiv.find(".wiktku-posparams-opt-panel input[type='checkbox']").each(function () { var key = $(this).val(); var expected = key === "form" ? "erê" : "1"; $(this).prop("checked", savedTa.indexOf("|" + key + "=" + expected) !== -1); }); } steps.posparams.syncHelpers(ppDiv); return; } if (id === "resim") { var resimDiv = $("#wiktku-start-resim"); resimDiv.find(".wiktku-resim-wrap").remove(); steps.resim.build(resimDiv); // Accept both the new array-of-rows format and the older // single {file, caption} object saved before multi-image // support existed. var resimSnap = snap.resim; var rows = $.isArray(resimSnap) ? resimSnap : (resimSnap ? [resimSnap] : []); if (rows.length) { var list = resimDiv.find("ol.wiktku-resim-list"); list.empty(); $.each(rows, function (_, r) { var item = steps.resim.buildItem(resimDiv); item.find(".wiktku-resim-file").val(r.file || ""); item.find(".wiktku-resim-caption").val(r.caption || ""); item.find(".wiktku-resim-alt").val(r.alt || ""); list.append(item); }); // Always keep a blank trailing row, same as Nimûne/Dûnde. var lastItem = list.children("li.wiktku-resim-item").last(); if ($.trim(lastItem.find(".wiktku-resim-file").val())) { list.append(steps.resim.buildItem(resimDiv)); } } return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Tell the pickers about the programmatic value change. fields.filter("select").trigger("wiktku:refresh"); }); // Item 3: restore which "Beşên din" sub-sections were already opened // for this section, then seed in anything the DOM restore above just // filled in but that wasn't marked opened yet (e.g. an older cache // saved before this existed). openedOtherSections = $.extend({}, snap.openedOtherSections || {}); seedOpenedFromContent(); renderBesenDinPicker(); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); // Bilêvkirin is NOT emitted here — it is one shared field for the // whole word, so emitting it per section duplicated it. getWikitext() // prints it once, above the POS sections. steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.tewandin.output(values); entry += steps.bikaranin.output(values); entry += steps.alfabeyendin.output(values); entry += steps.formalt.output(values); entry += steps.hevmane.output(values); entry += steps.dijmane.output(values); entry += steps.jornav.output(values); entry += steps.jernav.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); entry += steps.cavkani.output(values); entry += steps.xwendin.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { // Each hop through here can be reached asynchronously: the dfn // step waits on mw.loader.using("ext.gadget.linkify") before // calling back, so from that point on the submit handler's own // try/catch is no longer on the stack. Guard every hop instead, // or a throw after linkify loads vanishes into an unhandled // rejection and the form just sits there looking busy. try { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } catch (e) { if (typeof onSubmitError === "function") onSubmitError(e); else throw e; } } processSection(0); } // Assembles wikitext for all sections plus the shared lang header. // pron used to be prepended here too (shared, above every section) — // it now nests inside each section instead, via getWikitextForCurrentSection. function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var bnrh = steps.bnrh.output(sharedValues); var entry = steps.lang.output(sharedValues); // One pronunciation per word, printed once between the language // header and the POS sections — see steps.pron.output. entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // bnr-h goes before the language section — only prepended when // generating fresh wikitext (not addLangMode, which handles it separately). if (!addLangMode && bnrh) entry = bnrh + entry; // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { if (s.mane) return s.mane; // Template sense (e.g. {{guharto|ku|somepage}}) — same // construction as the tplCall built in getOutput, so the // summary shows what actually gets written to the entry // instead of going blank. if (s.tpl && s.tplTitle) { return s.tplNoLang ? "{{" + s.tpl + "|" + s.tplTitle + "}}" : "{{" + s.tpl + "|" + sharedValues.lang + "|" + s.tplTitle + "}}"; } return ""; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; // Set by build() to its submitFailed(). Lives out here because the // wikitext-assembly functions below are outside build()'s closure but // still need a way to report a failure to the person rather than dying // silently in the console. var onSubmitError = null; // Item 7: whether Mane/Bi zaravayên din/Werger has anything in it — // kept outside refresh() so the click handler (defined separately, // where continueBtn is built) can read the latest value. var wiktkuContentGateOk = true; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues, placeholderText) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>").text(placeholderText || "")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice.label); if (choice.sortKey !== undefined) { // This is a language choice {code, label, sortKey} — show code. displayText = capitalize(choice.label) + " (" + choice.code + ")"; } var option = $(mw.html.element("option", { value: choice.code }, displayText)); if (disabledValues[choice.code]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } // Keys to disable for a key menu: already-taken or explicitly disabled. function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); populateMenus(input, step.keys, getDisabledKeys(step)); // Keep the key menus mutually exclusive: whatever one row selects is // disabled in every other row. Recomputed from the DOM on each change. input.on("change", function () { var all = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield"); var taken = {}; all.each(function () { var v = $(this).val(); if (v) taken[v] = true; }); all.not(this).each(function () { var self = $(this), own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (code) $(this).prop("disabled", !!taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }); // Return the wrapper; the select lives inside it and still fires change. return wrapNativeSelect(input); } // Adds another text field to the list if the last one now has text. function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); if (step.placeholder) { nextInput.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = step.modifiers ? makeModifierLi(nextInput).prepend(nextKeyInput || "") : $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) initSelects(nextItem); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } // Shows/hides steps based on whether their prerequisites are met, and // updates placeholders where applicable. function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); steps.cavkani.refreshTplSelect(); // Re-render any step's question label that depends on current values // (e.g. dfn's Werger-section reminder, which only applies to ku). $.each(steps, function (stepId, step) { if (typeof step.question_fmt === "function") { $("#wiktku-start-" + stepId + " .wiktku-start-step-question") .text(step.question_fmt(values)); } }); // Sync every sense block's mane-box mode (plain mane vs tercime+îzah) // to the current language, in case lang changes after blocks exist. $("#wiktku-start-dfn li.wiktku-dfn-sense").each(function () { var updateMane = $(this).data("updateManeMode"); if (updateMane) updateMane(); }); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Re-sync the "<label> bi <ziman>…" placeholder on every always-visible // sub-field list (etîket, kategorî, hevmane, …), since the language may // not have been chosen yet when these lists were first built, or may // have changed since. $("#wiktku-start-dfn .wiktku-dfn-sublist").each(function () { var upd = $(this).data("updatePlaceholders"); if (typeof upd === "function") upd(); }); // Same idea for word-list steps (jê, têkildar, binêre herwiha, …) // whose placeholder is a function of the current language. $.each(steps, function (stepId, step) { if (typeof step.placeholder === "function") { $("#wiktku-start-" + stepId + " textarea.wiktku-start-step-field") .attr("placeholder", step.placeholder()); } }); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // Insert after the quote textarea's resize-wrap (if the manual // resize handle has already been attached to it), not after the // bare textarea -- otherwise this lands *inside* that wrap, // between the textarea and its own grip, breaking jêgirtin's // handle and nesting the tr/t boxes inside it. var quoteTa = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap = quoteTa.closest(".wiktku-resize-wrap"); (quoteResizeWrap.length ? quoteResizeWrap : quoteTa).after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // See the tr-field branch above for why this targets the // resize-wrap instead of the bare textarea. var quoteTa2 = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap2 = quoteTa2.closest(".wiktku-resize-wrap"); (quoteResizeWrap2.length ? quoteResizeWrap2 : quoteTa2).after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { var groupIdx = stepIdToGroup[stepId]; var hiddenByTab = (groupIdx !== undefined && groupIdx !== activeGroup) || // Beşên din picker (point 3): stays hidden even while its tab // is active until explicitly opened from the dropdown. (BESENDIN_SET[stepId] && !openedOtherSections[stepId]); // Bilêvkirin is its own section now, so the two views are // mutually exclusive: on it, only pron shows (plus Ziman, which // is shared and stays above every section); off it, pron is // hidden no matter which tab is active. pron is deliberately // ungrouped — stepIdToGroup has no entry for it — so without // this branch it would show on all four tabs at once. if (stepId === "pron") { hiddenByTab = hiddenByTab || !viewingPron; } else if (viewingPron && stepId !== "lang") { hiddenByTab = true; } if (hiddenByTab || (typeof(step.visible) === "function" && !step.visible(values))) { $("#wiktku-start-" + stepId).hide(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } // After build, sync the posparams helper widgets whenever pos or lang changes. if (step.id === "posparams" && typeof step.syncHelpers === "function") { step.syncHelpers(stepDiv); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } stepDiv.slideDown(); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); // The four content tabs belong to a POS section — Bilêvkirin has no // sub-tabs of its own, so the bar goes away while it's on screen. $("#wiktku-group-tabs").toggle(!!values.pos && !viewingPron); var besenDinActive = activeGroup === BESENDIN_GROUP_IDX && !viewingPron; $("#wiktku-besendin-picker").toggle(besenDinActive); // The option list is filtered by each step's visible(), which depends // on lang/pos — so it has to be rebuilt when those change, not just // when a section is opened. Safe to call from here: rendering the // picker doesn't itself call refresh(), only picking an option does. if (besenDinActive) renderBesenDinPicker(); updateGroupTabIndicators(values); continueBtn.setDisabled(!canContinue); // Soft gate (item 7): stays a real, clickable OOUI button — a hard // setDisabled(true) here would swallow the click entirely, and then // there'd be no way to tell the person *why* nothing happened. The // CSS-only "looks disabled" class lets the click handler still run // and show wiktkuNotify's explanation. wiktkuContentGateOk = !canContinue || hasMinRequiredContent(values); continueBtn.$element.toggleClass("wiktku-btn-soft-disabled", !wiktkuContentGateOk); } function destroy() { if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); if (autosaveInterval) clearInterval(autosaveInterval); formDirty = false; $(window).off("beforeunload.wiktkuUnsaved"); $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard").slideDown(); // #editform was kept laid-out but off-screen (see build()) instead of // display:none, precisely so the editor never had to size itself // against a zero-width/height box. Just bring it back on-screen — // no slideDown needed since it was never actually collapsed. $("#editform").removeClass("wiktku-offscreen"); // Belt-and-braces: if WikiEditor/CodeMirror/mobile's auto-grow still // cached a stale size from some earlier point, nudge them to // recalculate now that the box is genuinely visible. $(window).trigger("resize"); if (window.CodeMirror) { var cm = $("#wpTextbox1").data("CodeMirror") || $("#wpTextbox1").data("cmInstance"); if (cm && typeof cm.refresh === "function") cm.refresh(); } $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and navz. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; // Inserts a new "== {{ziman|code}} ==" section at the correct sorted // position: navz, then ku/hac/sdh/lki/ckb/zza, then alphabetical by name. function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections — just write the new section. // Add \n\n only when there is real non-whitespace content above. var trimmed = existing.replace(/\s+$/, ""); return trimmed ? trimmed + "\n\n" + wikitext : wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // (?![\s\S]) matches only true end-of-string, since a bare "$" with // /m would stop at the section's first line break instead. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections, each separated by exactly \n\n. // Trim trailing whitespace off each section's content first so we // control the spacing precisely. var joined = sections.map(function (s) { return s.content.replace(/\s+$/, ""); }).join("\n\n"); // Only add a separator after the preamble when it has real content. var preambleTrimmed = preamble.replace(/\s+$/, ""); var prefix = preambleTrimmed ? preambleTrimmed + "\n\n" : ""; return prefix + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê zimanekî nû li rûpelê îlawe bikî. Eger ev ziman jixwe hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bike, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Muhtewaya rûpelê paqij bike (her tiştî jê bibe û rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); // Tab bar for switching between step-groups (topics) within a section. // renderGroupTabs()/updateGroupTabIndicators() (which populate and // maintain it) live outside build() — see near "var activeSection". var groupTabsDiv = $("<div id='wiktku-group-tabs'></div>"); // Wikihez, 15 Tebax 2026: both tab bars are sticky (CSS) so they stay // clickable while scrolling. group-tabs' sticky "top" has to sit right // below section-tabs' actual rendered height — which isn't a fixed // number, since the section-tabs bar can wrap onto a second line // (many sections open, or a narrow/mobile viewport). Measured here // and published as a CSS custom property the stylesheet reads back; // recomputed whenever section-tabs' own content changes // (renderSectionTabs) and on window resize. // // Wikihez, 15 Tebax 2026 (item 2 — "on desktop only Mane/Etîmolojî // is sticky"): Vector 2022 has its own sticky header // (.vector-sticky-header) that pins itself to the real top:0 once // you scroll past the page title. That put our section-tabs (also // pinned at top:0) directly behind it — invisible, which reads as // "not sticky" even though it technically was. Minerva (mobile) has // no such element, which is why mobile already worked. Fixed by // measuring how much of the viewport Vector's header is currently // occupying and offsetting BOTH our bars below it, published as // --wiktku-siteheader-h. Vector's header slides in/out with scroll // position (not just resize), so this has to be re-measured on // scroll too, not only on resize/content-change. function siteHeaderOffset() { var el = document.querySelector(".vector-sticky-header"); if (!el) return 0; var rect = el.getBoundingClientRect(); // Present in the DOM at all times on Vector 2022, but only // actually occupying screen space once scrolled into place — // before that it sits translated above the viewport (negative/ // zero rect), which must not add a phantom gap under our bars. if (rect.bottom <= 0 || rect.top > 4) return 0; return Math.max(0, rect.bottom); } var stickyOffsetQueued = false; function syncStickyTabsOffset() { var h = sectionTabsDiv.is(":visible") ? (sectionTabsDiv.outerHeight() || 0) : 0; startForm.css("--wiktku-stabs-h", h + "px"); startForm.css("--wiktku-siteheader-h", siteHeaderOffset() + "px"); } function queueStickyTabsOffsetSync() { if (stickyOffsetQueued) return; stickyOffsetQueued = true; window.requestAnimationFrame(function () { stickyOffsetQueued = false; syncStickyTabsOffset(); }); } $(window).on("resize.wiktkuStickyTabs scroll.wiktkuStickyTabs", queueStickyTabsOffsetSync); // Wikihez, 14 Tebax 2026 (item 3): "Beşên din" picker — sits right under // the group tab bar, only shown while that tab is active (toggled in // refresh(), see BESENDIN_GROUP_IDX); renderBesenDinPicker() fills it. var besenDinPickerDiv = $("<div id='wiktku-besendin-picker' class='wiktku-besendin-picker'></div>"); /** Puts the form back in a usable state after a failed submit and * says what happened. Without this the button stays disabled and * the spinner spins forever on any exception — the person is left * staring at a form that looks busy but is dead, with the reason * visible only in the browser console. */ function submitFailed(err) { spinner.hide(); continueBtn.setDisabled(false); continueBtn.$element.removeClass("wiktku-btn-sending"); var detail = (err && (err.message || err.toString())) || "sedem nediyar"; mw.notify( "Şandin bi ser neket: " + detail + " — tiştê ku te nivîsî winda nebûye. Heke ev dubare bibe, " + "bi 'Edîtora çavkaniyê veke' berdewam bike.", { type: "error", tag: "wiktku-submit", autoHide: false } ); // Deliberately console.error as well: the notification is for the // person, this is for whoever they report the bug to. if (window.console && console.error) console.error("[wiktku] submit failed", err); } onSubmitError = submitFailed; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); continueBtn.$element.addClass("wiktku-btn-sending"); spinner.show(); try { getWikitext(function (wikitext) { try { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page — write fresh content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // ── bnr-h merge ────────────────────────────────────────── // If the user filled bnr-h inputs, either merge into the // existing {{bnr-h|…}} call or prepend a new one. var bnrhOut = steps.bnrh.output(getValues()); if (bnrhOut) { var newPages = bnrhOut.replace(/^\{\{bnr-h\|/, "").replace(/\}\}\n?$/, "").split("|"); var bnrhRe = /\{\{bnr-h\|([^}]*)\}\}/i; if (bnrhRe.test(existing)) { existing = existing.replace(bnrhRe, function (_, inner) { var existingPages = inner.split("|").map(function (p) { return p.trim(); }); $.each(newPages, function (_, p) { p = p.trim(); if (p && existingPages.indexOf(p) === -1) existingPages.push(p); }); return "{{bnr-h|" + existingPages.join("|") + "}}"; }); } else { existing = bnrhOut + existing; } } // If this language's section already exists (whitespace // differences aside), merge into it; otherwise insert new. var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); } catch (e) { // Thrown while writing the result into #wpTextbox1. submitFailed(e); } }); } catch (e) { // Thrown synchronously inside getWikitext — this is where the // splitTercimeIzah ReferenceError surfaced, and it produced no // message at all before this guard existed. submitFailed(e); } }); // Tracks whether groupTabsDiv has been inserted yet — see the // step.id-driven check below, replaced because it silently broke // when bnrh/resim/pron moved ahead of "dfn" in ordered_steps. var groupTabsInserted = false; $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); var nameH3 = $("<h3></h3>").addClass("wiktku-start-step-name"); var nameLabel = $("<label></label>") .attr("for", "wiktku-start-" + step.id + "-field") .text(name); nameH3.append(nameLabel); stepDiv.append(nameH3); if (step.question_fmt) { // question_fmt can be a plain string, or a function of the // current values (used by steps whose question text depends // on e.g. the chosen language) — refresh() keeps it in sync // afterwards via the .wiktku-start-step-question class. var questionText = typeof step.question_fmt === "function" ? step.question_fmt(getValues()) : step.question_fmt; stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, questionText))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); // initSelects() runs over the whole form once it is in the DOM. stepDiv.append(input); } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.placeholder) { input.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append(step.modifiers ? makeModifierLi(input) : $("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Section tabs (switch between POS sections) sit above the // per-section fields, starting at "pos". if (step.id === "pos") { startForm.append(sectionTabsDiv); } // Step-group tabs sit just before the first grouped step in // ordered_steps — whichever one that is. This USED to be a // hardcoded "dfn" check, back when dfn was the first grouped // step. Once bnrh/resim/pron moved into STEP_GROUPS too (and // earlier in ordered_steps than dfn, so they render near // pos/posparams), that check stopped matching anything: dfn was // no longer first, so groupTabsDiv never got appended at all, // and every grouped step's div — bnrh/resim/pron included — sat // there with no tab bar above it to reveal them. Deriving the // insertion point from stepIdToGroup instead means this keeps // working no matter how STEP_GROUPS/ordered_steps get reordered // later. if (!groupTabsInserted && stepIdToGroup[step.id] !== undefined) { startForm.append(groupTabsDiv); startForm.append(besenDinPickerDiv); groupTabsInserted = true; } startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); /** Adds a new, empty POS section and switches to it. */ function addPosSection() { saveCurrentSection(); viewingPron = false; sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); stepDiv.find(".wiktku-add-sense").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); return; } if (id === "resim") { $("#wiktku-start-resim .wiktku-resim-wrap").remove(); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); stepDiv.find("select.wiktku-start-step-field").trigger("wiktku:refresh"); }); // Fresh section — no "Beşên din" sub-section has been opened yet. openedOtherSections = {}; renderBesenDinPicker(); renderSectionTabs(); refresh(); } // One action again: Bilêvkirin is always in the bar now, so the menu // that used to offer both would have had a single entry. addSectionBtn.on("click", addPosSection); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); syncStickyTabsOffset(); return; } sectionTabsDiv.show(); // Bilêvkirin leads the bar, ahead of the POS sections. var pronTab = $("<span></span>") .addClass("wiktku-section-tab wiktku-section-tab-pron") .text("Bilêvkirin") .toggleClass("wiktku-tab-active", viewingPron); pronTab.on("click", function () { if (viewingPron) return; saveCurrentSection(); viewingPron = true; refresh(); renderSectionTabs(); }); sectionTabsDiv.append(pronTab); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection && !viewingPron); (function (idx) { tab.on("click", function () { if (idx === activeSection && !viewingPron) return; // Leaving Bilêvkirin doesn't need a save — its field // is shared and never part of a section snapshot. if (!viewingPron) saveCurrentSection(); viewingPron = false; activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); syncStickyTabsOffset(); } renderSectionTabs(); /** * Re-populates a dynamically-growing "multiple" field list (bnrh, je, * tekildar, …) from a saved array of strings. Sets each value via * .val() + a triggered "input" event rather than touching the DOM * structure directly, so the normal refreshForTextField() growth * logic adds exactly as many rows as needed — the same thing that * happens when a person types into the last (empty) row. */ function restoreMultiField(id, values) { var container = $("#wiktku-start-" + id); $.each(values || [], function (i, v) { var field = container.find(".wiktku-start-step-field").eq(i); if (!field.length || !v) return; field.val(v).trigger("input"); }); } /** * Restores a full cached draft: shared lang/pron/bnrh fields, then * every section (via the same restoreSection()/refresh()/ * renderSectionTabs() sequence already used when switching tabs). * @param cached {{lang: string, pron: string, bnrh: Array, sections: Array, activeSection: number}} */ function restoreFromCache(cached) { if (cached.lang) { $("#wiktku-start-lang-field").val(cached.lang); $("#wiktku-start-lang-field").trigger("wiktku:refresh"); } // Rebuild dependent steps (pos, pron wrap, etc.) now that lang is set. refresh(); if (cached.pron !== undefined) { $("#wiktku-start-pron .wiktku-pron-text").val(cached.pron); } if (cached.bnrh) { restoreMultiField("bnrh", cached.bnrh); } sections = (cached.sections && cached.sections.length) ? cached.sections : [{}]; activeSection = (typeof cached.activeSection === "number" && cached.activeSection >= 0 && cached.activeSection < sections.length) ? cached.activeSection : 0; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); updateLastSavedIndicator(cached.savedAt || null); formDirty = false; wiktkuNotify("Danûstandina berê ya qeydkirî ji cache hate barkirin.", { type: "info", tag: "wiktku-cache-restore" }); } // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); // A new cureyê rêzimanî means any previously chosen cinsiyet/ // cureyê lêkerê no longer applies — clear both selections (and // the shared hidden cinsiyet field, since rebuildTa()/syncHelpers() // fall back to it) before wiping the textarea, so nothing stale // gets carried over into the rebuilt template. var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-cinsiyet-sel").val(""); ppDiv.find(".wiktku-posparams-jimar-sel").val(""); ppDiv.find(".wiktku-posparams-lektur-sel").prop("selectedIndex", 0); ppDiv.find(".wiktku-posparams-lekturform-sel").prop("selectedIndex", 0); $("#wiktku-start-cinsiyet-field").val(""); $("#wiktku-start-jimar-field").val(""); ppDiv.find(".wiktku-posparams-text").val(""); // refresh() runs steps.posparams.syncHelpers(), which toggles the // param rows for the new pos and — since the textarea is now // empty — calls rebuildTa() to repopulate it. Just clearing the // textarea (as before) never triggered this, so the params // section was left stale until some other field's change event // happened to fire a refresh(). refresh(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { // Immediate feedback that the click registered continueBtn.$element.addClass("wiktku-btn-flash"); setTimeout(function () { continueBtn.$element.removeClass("wiktku-btn-flash"); }, 500); // Item 7: Ziman/Cureyê rêzimanî already block submission via the // real OOUI setDisabled (see canContinue in refresh()) — this is // a second, softer check that still lets the click through so we // can explain *why*, instead of the button just silently doing // nothing. if (!wiktkuContentGateOk) { wiktkuNotify( "Berî şandinê, tiştekî binivîse: Mane, Bi zaravayên din, an jî Werger — kêmasî yek ji van sê beşan divê tijî be.", { type: "warn", tag: "wiktku-mincontent" } ); return; } wiktkuNotify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", flags: [ "destructive" ], }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Cache save/clear buttons ───────────────────────────────────────── // Manual, page-scoped save of the entire wizard (all sections, not // just the active one) via [[MediaWiki:Gadget-StorageUtils.js]]'s // ObjectStorage. Restoring happens silently on load at the end of // build(), once the full language list is available. // // Saving also happens automatically (debounced while typing, plus a // periodic fallback) — see "Autosave" below — since relying on the // person to remember to click "Li cache qeyd bike" before an // accidental tab close/reload defeats the point of having a cache // at all. function buildCacheSnapshot() { return { lang: getValues().lang || "", pron: $("#wiktku-start-pron .wiktku-pron-text").val() || "", // bnrh is shared (page-level), same as lang/pron above — not // per-section, so it doesn't live in sections[]. bnrh: getValuesForStep("bnrh"), sections: sections, activeSection: activeSection, savedAt: Date.now() }; } // ── Last-saved indicator ───────────────────────────────────────────── var lastSavedEl = $("<span id='wiktku-last-saved'></span>"); function formatSavedTime(ts) { try { return new Date(ts).toLocaleTimeString(mw.config.get("wgUserLanguage"), { hour: "2-digit", minute: "2-digit" }); } catch (e) { return new Date(ts).toLocaleTimeString(); } } function updateLastSavedIndicator(ts) { lastSavedEl.text(ts ? ("Cache: qeydkirî di saet " + formatSavedTime(ts) + " de") : ""); } // ── Dirty-state tracking + autosave ────────────────────────────────── // formDirty mirrors "does the live form differ from what's in cache". // Anything the person types/selects sets it; a successful save (auto // or manual) clears it; destroy() (final submit, or switching to the // source editor) also clears it since the wizard's job is over at // that point either way. formDirty/autosaveDebounceTimer/autosaveInterval // are declared in the outer scope (near activeGroup) — assigned here, // not re-declared — so destroy() can reach them too. var AUTOSAVE_DEBOUNCE_MS = 8000; // save shortly after typing pauses var AUTOSAVE_INTERVAL_MS = 60000; // …and at least this often regardless function performAutosave() { if (!formDirty) return; saveCurrentSection(); try { formCache.Set(buildCacheSnapshot()); formDirty = false; updateLastSavedIndicator(Date.now()); } catch (e) { // Silent on autosave failure (storage blocked/full, etc.) — the // manual button still surfaces a proper error if the person // tries it directly, no need to interrupt typing with a toast. } } function scheduleAutosave() { formDirty = true; if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = setTimeout(performAutosave, AUTOSAVE_DEBOUNCE_MS); } startForm.on("input change", "input, textarea, select", scheduleAutosave); autosaveInterval = setInterval(performAutosave, AUTOSAVE_INTERVAL_MS); // Warn on accidental tab close/reload while there's anything unsaved. $(window).on("beforeunload.wiktkuUnsaved", function (e) { if (!formDirty) return undefined; e.preventDefault(); e.returnValue = ""; return ""; }); var saveCacheBtn = new OO.ui.ButtonWidget({ label: "Li cache qeyd bike", title: "Halê vê formê yê niha (ziman, bilêvkirin û hemû beş) li cache (localStorage) qeyd bike, da ku eger rûpel bêyî xwestin were girtin an ji nû ve were barkirin, tu karibî berdewam bikî." }); saveCacheBtn.on("click", function () { saveCurrentSection(); // ObjectStorage.Set() doesn't return a success/failure value, so // the only way to detect a real failure (storage blocked, quota // exceeded, JSON.stringify choking on something unexpected) is to // catch it here rather than inspect a (nonexistent) return value. try { var snapshot = buildCacheSnapshot(); formCache.Set(snapshot); formDirty = false; updateLastSavedIndicator(snapshot.savedAt); wiktkuNotify("Halê formê li cache hate qeydkirin.", { type: "success", tag: "wiktku-cache-save" }); } catch (e) { mw.notify("Qeydkirina li cache bi ser neket.", { type: "error", tag: "wiktku-cache-save" }); } }); var clearCacheBtn = new OO.ui.ButtonWidget({ label: "Cache paqij bike", flags: [ "destructive" ], title: "Datayên qeydkirî yên vê rûpelê ji cache jê bibe (forma ku niha xuya dike naguherîne)." }); clearCacheBtn.on("click", function () { formCache.Set({}); // The live form still has whatever the person typed — it's just no // longer backed up anywhere, so treat this like a fresh unsaved edit. formDirty = true; updateLastSavedIndicator(null); wiktkuNotify("Cache hate paqijkirin.", { type: "success", tag: "wiktku-cache-clear" }); }); // ── "⋯" overflow ───────────────────────────────────────────── // v3: one primary action and one secondary stay on the bar; // everything else moves in here. Four same-weight buttons — two of // them red — was the loudest thing on the screen, and on a phone it // wrapped to three rows of a sticky footer. var moreBtn = $("<button type='button' class='wiktku-more-btn' title='Vebijarkên din'>⋯</button>"); var moreMenu = $("<div class='wiktku-more-menu'></div>").hide(); /** Moves an existing OOUI button into the overflow menu, keeping its * handlers — the widgets already carry the behaviour, so this is * purely about where they are shown. */ function intoMenu(btn, extraClass) { var row = $("<div class='wiktku-more-item'></div>"); if (extraClass) row.addClass(extraClass); btn.$element.on("click", function () { moreMenu.hide(); }); row.append(btn.$element); moreMenu.append(row); } intoMenu(saveCacheBtn); intoMenu(clearCacheBtn, "wiktku-more-item-danger"); moreMenu.append($("<div class='wiktku-more-sep'></div>")); moreMenu.append($("<div class='wiktku-more-item wiktku-more-note'></div>").append(lastSavedEl)); moreBtn.on("click", function (e) { e.preventDefault(); e.stopPropagation(); var open = moreMenu.is(":visible"); moreMenu.toggle(!open); if (!open) { setTimeout(function () { $(document).one("click.wiktkuMore", function () { moreMenu.hide(); }); }, 0); } }); var moreWrap = $("<span class='wiktku-more-wrap'></span>").append(moreBtn).append(moreMenu); footer.append(moreWrap); // Icon-only settings button — opens the Tercîh dialog. Plain OOUI // icon names depend on which icon-pack module happens to be loaded, // so this uses the actual Codex "settings" (color-subtle) SVG from // Commons directly, the same way the spinner above hotlinks its gif. var prefsBtn = $("<button></button>", { type: "button", "class": "wiktku-prefs-btn", title: "Tercîh — sazkariyên vê amûrê biguherîne" }); prefsBtn.on("click", function (e) { e.preventDefault(); wiktkuOpenPrefsDialog(); }); // The gear is icon-only on the bar; inside a text menu it needs a // label like everything else around it. prefsBtn.on("click", function () { moreMenu.hide(); }); moreMenu.prepend($("<div class='wiktku-more-sep'></div>")); moreMenu.prepend($("<div class='wiktku-more-item wiktku-more-item-prefs'></div>") .append(prefsBtn) .append($("<span class='wiktku-more-item-label'></span>").text("Tercîh"))); startForm.append(footer); // NOTE: deliberately NOT .hide() (display:none). WikiEditor/CodeMirror/ // the mobile editor's auto-grow logic measure #wpTextbox1's real // dimensions during their own init, which happens while the wizard is // up. A display:none ancestor reports 0 for offsetWidth/offsetHeight/ // scrollHeight, so those scripts bake in a near-zero height that never // gets recalculated later — slideDown() in destroy() only animates the // outer box, it doesn't re-trigger their sizing. Pushing #editform // off-screen instead keeps it laid out (real width/height available to // measure) without being visible, so the editbox opens at full size. $("#editform").addClass("wiktku-offscreen").before(startForm); // renderGroupTabs() looks up #wiktku-group-tabs via a live DOM // selector, so it must run after startForm is actually in the // document — calling it back in the build loop (while startForm was // still detached) silently no-op'd and left the tab bar empty. renderGroupTabs(); renderBesenDinPicker(); // One pass over the whole form: every select that hasn't already been // initialised, and isn't opted out with .wiktku-plain-select, gets // the searchable picker. initSelects(startForm); refresh(); // Give every draggable textarea a custom resize grip (works // consistently on Safari/iOS, unlike the native corner grip — see // the "Manual drag-to-resize handle" comment in styles.css), and // keep applying it to textareas added later on (new sense blocks, // quote-source fields, nimûne rows, …). wiktkuInitManualResize(startForm); new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { $(mutation.addedNodes).each(function () { if (this.nodeType !== 1) return; wiktkuInitManualResize(this); }); }); }).observe(startForm[0], { childList: true, subtree: true }); // Now that the full language list is loaded, silently restore any // draft the editor previously saved for this page. var cachedDraft = formCache.Get(); if (cachedDraft && cachedDraft.sections && cachedDraft.sections.length) { restoreFromCache(cachedDraft); } } mw.loader.using(["oojs-ui-core"], function () { function wiktkuProceedWithData(wiktkuData) { var d = wiktkuData || {}; // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Item 1: Jimar (number) code definitions — same shape as the wiki's // own Lua number-type table (code -> {cat, display[, req]}). if (d.numberLabels) $.extend(NUMBER_LABELS, d.numberLabels); // Populate lang choices (pinned list). if (d.langChoices) steps.lang.choices = choicesFromObject(d.langChoices, true); // Populate langsByCode and merge full language list from d.ziman. // d.ziman is a {code: name} object with all known languages. $.each(steps.lang.choices, function (i, choice) { if (choice.sortKey === undefined) choice.sortKey = choice.label; langsByCode[choice.code] = choice; }); if (d.ziman) { var pinnedCodes = {}; $.each(steps.lang.choices, function (i, c) { pinnedCodes[c.code] = true; }); var extraChoices = []; $.each(d.ziman, function (code, name) { if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; if (pinnedCodes[code]) return; var choice = { code: code, label: name, sortKey: name }; extraChoices.push(choice); langsByCode[code] = choice; }); extraChoices.sort(function (a, b) { return a.sortKey.localeCompare(b.sortKey, userLang); }); steps.lang.choices = steps.lang.choices.concat(extraChoices); } // Keep the full merged list around for trans/dunde/zarava — those // should still be able to reference any language even when the // Tercîh panel restricts the main "ziman" step below — then, if // the user set a restriction there, narrow steps.lang.choices // itself to just those codes. var wiktkuFullLangChoices = steps.lang.choices; if (wiktkuPrefs.langCodes && wiktkuPrefs.langCodes.length) { var wiktkuAllowedLangSet = {}; $.each(wiktkuPrefs.langCodes, function (i, code) { wiktkuAllowedLangSet[code] = true; }); var wiktkuRestrictedChoices = $.grep(wiktkuFullLangChoices, function (c) { return !!wiktkuAllowedLangSet[c.code]; }); // Fall back to the full list instead of showing an empty // dropdown if none of the saved codes matched anything // (typo'd code, data.json changed since, …). steps.lang.choices = wiktkuRestrictedChoices.length ? wiktkuRestrictedChoices : wiktkuFullLangChoices; } // Populate POS choices — also a plain {code: label} object in data.json. if (d.posChoices) steps.pos.choices = choicesFromObject(d.posChoices, false); // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the full language list // (not the possibly Tercîh-restricted steps.lang.choices). steps.trans.keys = wiktkuFullLangChoices; steps.dunde.keys = wiktkuFullLangChoices; steps.zarava.keys = getZaravaKeys(wiktkuFullLangChoices); build(); } // data.json ships inside this package module, so it is already parsed // and in memory — no action=raw round trip, and no Testing switch to // forget to flip back before deploying. wiktkuProceedWithData(require("./start/data.json")); }); }); //</nowiki> 80gy2ummg3i5qobv5uxnsbpca5iq3rr 6333824 6333818 2026-08-15T15:03:55Z Wikihez 7344 6333824 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. // implicit dependencies: StorageUtils (ObjectStorage) //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var addLangMode = mw.util.getParamValue("wiktkuaddlang") === "1"; // ── Tercîh (user settings) panel stored via mw.storage (localStorage), globally var WIKTKU_PREFS_KEY = "wiktku_start_prefs"; var WIKTKU_PREFS_DEFAULTS = { // [] = show the full language list in the "ziman" step; otherwise // only these codes are shown there (data.json codes, not names). langCodes: [], // true = never auto-open on a new/empty page — only via the // "+Ziman/beşeke din" portlet link. onlyOnClick: false, // "auto" | "p-cactions" | "p-tb" | "p-views" — where the // "+Ziman/beşeke din" portlet link is added. portlet: "auto", // true = suppress routine/informational mw.notify toasts (page // loading, cache auto-restored, cache saved/cleared, "tê şandin…"). // Errors and direct results of an explicit action (like saving // Tercîh itself) always show regardless of this setting. quiet: false }; function wiktkuLoadPrefs() { if (!(window.mw && mw.storage)) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var raw; try { raw = mw.storage.get(WIKTKU_PREFS_KEY); } catch (e) { raw = null; } if (!raw) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var parsed; try { parsed = JSON.parse(raw); } catch (e) { parsed = {}; } return $.extend({}, WIKTKU_PREFS_DEFAULTS, parsed); } function wiktkuSavePrefs(prefs) { if (!(window.mw && mw.storage)) return false; try { mw.storage.set(WIKTKU_PREFS_KEY, JSON.stringify(prefs)); return true; } catch (e) { return false; } } var wiktkuPrefs = wiktkuLoadPrefs(); // Routine/informational notices go through here so "quiet mode" can // suppress them; errors and explicit-action confirmations (like the // Tercîh save toast) call mw.notify directly instead, and always show. function wiktkuNotify(message, options) { if (wiktkuPrefs.quiet) return; mw.notify(message, options); } // Lazily built the first time it's opened; reused after that (see // wiktkuOpenPrefsDialog below, defined once we know OOUI is available). var wiktkuPrefsWindowManager = null; var wiktkuPrefsDialog = null; function wiktkuOpenPrefsDialog() { mw.loader.using(["oojs-ui-core", "oojs-ui-windows"], function () { function WiktkuPrefsDialog(config) { WiktkuPrefsDialog.super.call(this, config); } if (!wiktkuPrefsDialog) { OO.inheritClass(WiktkuPrefsDialog, OO.ui.ProcessDialog); WiktkuPrefsDialog.static.name = "wiktkuPrefsDialog"; WiktkuPrefsDialog.static.title = "Tercîhên min"; WiktkuPrefsDialog.static.actions = [ { action: "save", label: "Qeyd bike", flags: ["primary", "progressive"] }, { action: "cancel", label: "Betal bike", flags: "safe" } ]; WiktkuPrefsDialog.prototype.initialize = function () { WiktkuPrefsDialog.super.prototype.initialize.call(this); this.langCodesInput = new OO.ui.TextInputWidget({ placeholder: "ku, zza, ckb (vala bihêle ji bo hemû zimanan)" }); this.onlyOnClickCheckbox = new OO.ui.CheckboxInputWidget({}); this.quietCheckbox = new OO.ui.CheckboxInputWidget({}); this.portletDropdown = new OO.ui.DropdownInputWidget({ options: [ { data: "auto", label: "Otomatîk (li gorî rûyê wîkiyê)" }, { data: "p-cactions", label: "p-cactions - Li qismê Amûran" }, { data: "left-navigation", label: "left-navigation - Li qismê Gotar-Gotûbêj" }, { data: "p-tb", label: "p-tb - Li qismê Giştî" }, { data: "p-views", label: "p-views - Li qismê Bixwîne" } ] }); var fieldset = new OO.ui.FieldsetLayout({ label: "Eyar" }); fieldset.addItems([ new OO.ui.FieldLayout(this.langCodesInput, { label: "Kodên zimanan ku tê xuyakirin li qismê \"ziman\"", align: "top", help: "Kodan bi virgulê (,) ji hev veqetîne. Vala bihêle da ku hemû ziman were nîşandan.", helpInline: true }), new OO.ui.FieldLayout(this.onlyOnClickCheckbox, { label: "Tenê veke wextê \"+Ziman/beşeke din\" were tikandin", align: "inline", help: "Eger were hilbijartin, ev amûr êdî otomatîk li ser rûpelên nû/vala dest pê nake — divê meriv her carê pêl \"+Ziman/beşeke din\" bike.", helpInline: true }), new OO.ui.FieldLayout(this.portletDropdown, { label: "Cihê lînka \"+Ziman/beşeke din\"", align: "top", help: "\"Otomatîk\" li gorî rûyê wîkiyê hildibijêre.", helpInline: true }), new OO.ui.FieldLayout(this.quietCheckbox, { label: "Moda bêdeng (kêmtir agahdarî nîşan bide)", align: "inline", help: "Agahdariyên normal nîşan nede. Xeta her tim tên xuyakirin.", helpInline: true }) ]); this.$body.addClass("wiktku-prefs-dialog-body").append(fieldset.$element); }; WiktkuPrefsDialog.prototype.getSetupProcess = function (data) { return WiktkuPrefsDialog.super.prototype.getSetupProcess.call(this, data) .next(function () { this.langCodesInput.setValue(wiktkuPrefs.langCodes.join(", ")); this.onlyOnClickCheckbox.setSelected(!!wiktkuPrefs.onlyOnClick); this.portletDropdown.setValue(wiktkuPrefs.portlet || "auto"); this.quietCheckbox.setSelected(!!wiktkuPrefs.quiet); }, this); }; WiktkuPrefsDialog.prototype.getActionProcess = function (action) { var dialog = this; if (action === "save") { return new OO.ui.Process(function () { var codes = dialog.langCodesInput.getValue() .split(/[,\s]+/) .map(function (c) { return c.trim().toLowerCase(); }) .filter(function (c) { return !!c; }); wiktkuPrefs = { langCodes: codes, onlyOnClick: dialog.onlyOnClickCheckbox.isSelected(), portlet: dialog.portletDropdown.getValue() || "auto", quiet: dialog.quietCheckbox.isSelected() }; wiktkuSavePrefs(wiktkuPrefs); mw.notify( "Tercîh hatin qeydkirin. Rûpelê ji nû ve bar bike (F5).", { type: "success", tag: "wiktku-prefs-save" } ); dialog.close({ action: "save" }); }); } if (action === "cancel") { return new OO.ui.Process(function () { dialog.close({ action: "cancel" }); }); } return WiktkuPrefsDialog.super.prototype.getActionProcess.call(this, action); }; wiktkuPrefsWindowManager = new OO.ui.WindowManager(); $(document.body).append(wiktkuPrefsWindowManager.$element); wiktkuPrefsDialog = new WiktkuPrefsDialog(); wiktkuPrefsWindowManager.addWindows([wiktkuPrefsDialog]); } wiktkuPrefsWindowManager.openWindow(wiktkuPrefsDialog); }); } var targetContainer; var skin = mw.config.get('skin'); if (wiktkuPrefs.portlet && wiktkuPrefs.portlet !== "auto") { targetContainer = wiktkuPrefs.portlet; } else if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Li vê rûpelê, ziman an jî beşeke nû zêde bike"); // If "onlyOnClick" is set, the wizard should ONLY ever open via the // "+Ziman/beşeke din" link — never automatically var wiktkuNewPageDetected = $(".mw-newarticletext, .mw-newarticletextanon").length > 0; if (wiktkuPrefs.onlyOnClick ? !addLangMode : (!addLangMode && !wiktkuNewPageDetected)) { return; } // ── Shared helpers ─────────────────────────────────────────────────── // Generic text/UI utilities live in their own package file now — see the // header of util.js for why. Aliased to bare names here so the ~400 call // sites below read exactly as they did when these were local functions. var wiktkuUtil = require("./start/util.js"); var capitalize = wiktkuUtil.capitalize; var decapitalize = wiktkuUtil.decapitalize; var escapeRegExp = wiktkuUtil.escapeRegExp; var stripWikilinks = wiktkuUtil.stripWikilinks; var splitTercimeIzah = wiktkuUtil.splitTercimeIzah; var insertAtCursor = wiktkuUtil.insertAtCursor; var foldDiacritics = wiktkuUtil.foldDiacritics; var wrapNativeSelect = wiktkuUtil.wrapNativeSelect; var initSelects = wiktkuUtil.initSelects; var wiktkuInitManualResize = wiktkuUtil.initManualResize; function langHeaderSource(codePattern) { return "\n?==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } var catSrcTemplates = null; var catSrcTemplatesPromise = null; function fetchCatSrcTemplates() { if (catSrcTemplatesPromise) return catSrcTemplatesPromise; catSrcTemplatesPromise = new mw.Api().get({ action: "query", list: "categorymembers", cmtitle: "Kategorî:Çavkanî", cmnamespace: 10, cmlimit: "max", formatversion: 2 }).then(function (data) { var members = (data.query && data.query.categorymembers) || []; catSrcTemplates = $.map(members, function (m) { // Pêşgira navî ya "Şablon:" rake. return m.title.replace(/^[^:]+:/, ""); }); catSrcTemplates.sort(function (a, b) { return a.localeCompare(b, userLang); }); return catSrcTemplates; }, function () { catSrcTemplates = []; return catSrcTemplates; }); return catSrcTemplatesPromise; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var formCache = new ObjectStorage("wiktku_start_draft_" + mw.config.get("wgPageName"), 1); var langsByCode = {}; // Looks up the display label for a language code, falling back to the // code itself if it isn't known yet (e.g. langsByCode not loaded). function getLangLabel(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; // Converts a {code: label} object (langChoices/posChoices in data.json) // into the {code, label[, sortKey]} array the rest of the script uses. // isLang: true adds a sortKey and shows "(code)" after the label — // language choices only. function choicesFromObject(obj, isLang) { var result = []; $.each(obj || {}, function (code, label) { var choice = { code: code, label: label }; if (isLang) choice.sortKey = label; result.push(choice); }); return result; } function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c.code] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Number codes (y, s, d, p, p+, tp, j, j+, j/nj, nj, nj+, hj!, hj?) from // data.json's "numberLabels". Same {code: {cat, display[, req]}} shape as // the wiki's Lua number-type table; "display" can contain HTML (<abbr>) // or wikilinks, so it's only used as-is in wikitext output, never dropped // straight into an <option> (see stripMarkupForOption below). var NUMBER_LABELS = {}; // Distinguishes the Jimar dropdown (j= param) from the Cîns dropdown // (c= param): a code that's a key in NUMBER_LABELS is a number code, // everything else is a gender code. Compound codes like "m-p"/"n-p" are // gender+plural pairs and correctly stay on the gender side. function isNumberCode(code) { return Object.prototype.hasOwnProperty.call(NUMBER_LABELS, code); } // Strips the bit of markup "display" is allowed to contain so it's safe // to use as plain <option> text (options can't render HTML or wikilinks): // <abbr title="X">Y</abbr> -> "Y (X)", [[a|b]] -> "b", [[a]] -> "a". function stripMarkupForOption(html) { if (!html) return ""; return $.trim( String(html) .replace(/<abbr[^>]*title="([^"]*)"[^>]*>([\s\S]*?)<\/abbr>/gi, "$2 ($1)") .replace(/\[\[[^\]|]*\|([^\]]*)\]\]/g, "$1") .replace(/\[\[([^\]]*)\]\]/g, "$1") .replace(/<[^>]+>/g, "") ); } // Builds the Jimar dropdown's <option> text for one code: "j — jimarbar". function numberOptionLabel(code) { var def = NUMBER_LABELS[code]; if (!def) return code; var text = stripMarkupForOption(def.display); return text ? (code + " — " + text) : code; } // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } // ── Template explanations ──────────────────────────────────────────── // Every place a template can be picked shows the same row: a status // dot, the name, a link to the template page, and an ⓘ. This is the ⓘ. // // Text comes from the template's own TemplateData where it has any, so // the explanation stays right without anyone maintaining a second copy // by hand — with the desc already in data.json as the fallback for // templates that have none. var wiktkuTplDataCache = {}; // name -> {desc, params[]} or null when absent /** Fetches TemplateData for one template. Resolves to null if the * template has none (a plain, undocumented template — very common). */ function fetchTemplateData(name) { if (Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, name)) { return $.Deferred().resolve(wiktkuTplDataCache[name]).promise(); } return new mw.Api().get({ action: "templatedata", titles: "Şablon:" + name, redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; var first = null; $.each(pages, function (_, p) { if (!first) first = p; }); var out = null; if (first) { var desc = first.description; // TemplateData descriptions are language maps when the // template is documented in more than one language. if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(first.params || {}, function (key, p) { var label = p && p.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(p && p.required) }); }); out = { desc: desc || "", params: params }; } wiktkuTplDataCache[name] = out; return out; }, function () { // No TemplateData, or the API is unhappy — cache the miss so a // repeated ⓘ click doesn't re-request it every time. wiktkuTplDataCache[name] = null; return null; }); } /** Fetches TemplateData for many templates in one request and fills the * cache; resolves either way, a template with no TemplateData caches as null. */ function prefetchTemplateData(names) { var missing = $.grep(names || [], function (n) { return n && !Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n); }); if (!missing.length) return $.Deferred().resolve().promise(); // The API caps a titles list at 50 for normal users. missing = missing.slice(0, 50); return new mw.Api().get({ action: "templatedata", titles: $.map(missing, function (n) { return "Şablon:" + n; }).join("|"), redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; $.each(pages, function (_, page) { if (!page || !page.title) return; var name = String(page.title).replace(/^[^:]+:/, ""); var desc = page.description; if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(page.params || {}, function (key, prm) { var label = prm && prm.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(prm && prm.required) }); }); wiktkuTplDataCache[name] = { desc: desc || "", params: params }; }); // Anything the API didn't answer for simply has none — cache the // miss so the per-row ⓘ doesn't re-request it one at a time. $.each(missing, function (_, n) { if (!Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n)) wiktkuTplDataCache[n] = null; }); }, function () { $.each(missing, function (_, n) { wiktkuTplDataCache[n] = null; }); }); } /** Rewrites each tagged <option> in `sel` as "name — description", using * TemplateData. Only fills rows that have no description yet, so the * hand-written ones in data.json (which carry usage examples the API * does not) are left exactly as they are. */ function applyTplDescriptions(sel) { if (!sel || !sel.length) return; var changed = false; sel.find("option[data-tpl]").each(function () { var opt = $(this); var name = opt.attr("data-tpl"); if (opt.text().indexOf(" — ") !== -1) return; // already described var td = wiktkuTplDataCache[name]; var desc = (td && td.desc) || localTplDesc(name); if (!desc) return; // One line: TemplateData descriptions can run to a paragraph. desc = $.trim(String(desc).split("\n")[0]); if (desc.length > 90) desc = desc.slice(0, 90) + "…"; opt.text(name + " — " + desc); changed = true; }); // The picker caches option text for searching, so it has to re-read. if (changed) sel.trigger("wiktku:refresh"); } /** Hand-written fallback description, from data.json. * * This is the escape hatch for templates with no TemplateData on the * wiki: add a "desc" to the entry in data.json and it shows up in the * dropdown and in the ⓘ immediately, no code change. TemplateData is * still the better place — VisualEditor and every other tool reads it * too — but this keeps the picker useful in the meantime. * * Works for any pool: pronTpls, etymTpls, tplDefs, jederDefs. */ function localTplDesc(name) { var pools = [steps.pron.pronTpls, steps.etym.etymTpls, steps.dfn.tplDefs, steps.dfn.jederDefs]; var found = ""; $.each(pools, function (_, pool) { if (pool && pool[name] && pool[name].desc) { found = pool[name].desc; return false; } }); return found; } /** Opens the inline explanation panel for `name`, anchored under the * picker it was opened from. */ function showTemplateInfo(name, anchorWrap) { $(".wiktku-tpl-info").remove(); var panel = $("<div class='wiktku-tpl-info'></div>"); panel.append($("<div class='wiktku-tpl-info-name'></div>").text("{{" + name + "}}")); var body = $("<div class='wiktku-tpl-info-desc'></div>").text("Tê barkirin…"); panel.append(body); var params = $("<div class='wiktku-tpl-info-params'></div>"); panel.append(params); panel.append($("<a class='wiktku-tpl-info-link' target='_blank' rel='noopener'></a>") .attr("href", wiktkuUtil.tplPageUrl(name)) .text("Rûpela şablonê veke →")); var close = $("<button type='button' class='wiktku-tpl-info-close' title='Bigire'>✕</button>"); close.on("click", function () { panel.remove(); }); panel.prepend(close); $(anchorWrap).after(panel); fetchTemplateData(name).then(function (td) { var desc = (td && td.desc) || localTplDesc(name); body.text(desc || "Ji bo vê şablonê ravek nehatiye nivîsandin."); if (td && td.params && td.params.length) { params.append($("<div class='wiktku-tpl-info-params-title'></div>").text("Parametre:")); var listEl = $("<ul></ul>"); $.each(td.params, function (_, p) { var line = p.name + (p.label ? " — " + p.label : "") + (p.required ? " (pêwîst)" : ""); listEl.append($("<li></li>").text(line)); }); params.append(listEl); } }); } /** Marks a picker's <option>s as template rows so the searchable widget * renders them with the dot / 🔗 / ⓘ affordances, and wires the ⓘ * handler for that picker. `nameOf` maps an <option> to a template * name — the pickers store different things in value= (a snippet for * the insert dropdowns, the bare name for the sense selector). */ function markTemplateOptions(sel, nameOf) { if (!sel || !sel.length) return; var names = []; sel.find("option").each(function () { var opt = $(this); var name = nameOf(opt); if (!name) return; opt.attr("data-tpl", name); // Deprecated/typo templates are the "special cases only" ones. opt.attr("data-tpl-status", /kevnbûyî|şaşnivîs|kêmpeyda/i.test(opt.text()) ? "yellow" : "green"); names.push(name); }); sel.data("wiktkuTplInfo", showTemplateInfo); // Fill in the descriptions. Matters most for the Mane picker, whose // entries in data.json are names with no desc at all — "rastnivîs", // "ku-Latn", "guharto" on their own. One request covers every // template in the picker, cached for the per-row ⓘ as well. prefetchTemplateData(names).always(function () { applyTplDescriptions(sel); }); } /** Pulls the template name out of a snippet like "* {{ku-IPA}}" or * "{{ji|SOURCELANG|CODE|…}}". */ function tplNameFromSnippet(snippet) { var m = /\{\{\s*([^|}\n]+)/.exec(snippet || ""); return m ? $.trim(m[1]) : ""; } // True if a sense has content beyond mane worth keeping (etîket, word // lists, nimûne, jêder) — so it's still emitted with {{mane?}} if empty. function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } // A technically-"complete" entry (Ziman + Cureyê rêzimanî filled) with // nothing in Mane, Bi zaravayên din or Werger is still meaningfully // empty, so this is checked separately at submit-click time with its // own message. function hasMinRequiredContent(values) { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasMane = dfnSenses.some(function (s) { return (s.tpl && s.tplTitle) || (!s.tpl && (s.mane !== "" || senseHasExtraContent(s))); }); if (hasMane) return true; if (values.lang === "ku") { var hasWerger = false; $("#wiktku-start-trans .wiktku-trans-group").each(function () { if (steps.trans.getGroupTranslations($(this)).length) hasWerger = true; }); if (hasWerger) return true; var hasZarava = false; $("#wiktku-start-zarava .wiktku-zarava-group").each(function () { if (steps.zarava.getGroupTranslations($(this)).length) hasZarava = true; }); if (hasZarava) return true; } return false; } // Bolds the *first* occurrence of the page name function boldPageNameOnce(text) { if (!text || !pageNameRe) return text; var re = new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "i"); return text.replace(re, "'''$1'''"); } // Converts literal line breaks typed into a nimûne/jêgirtin box into // wikitext <br> tags, function nlToBr(text) { return text ? text.replace(/\r\n|\r|\n/g, "<br>") : text; } function escapeHtmlForBackdrop(str) { return String(str) .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;"); } // Mirrors a textarea's text, with a small highlighted marker placed // right after each line that's followed by an actual typed/pasted // linebreak. Rendered into a transparent backdrop layer behind the // textarea (see ensureLinebreakBackdrop()), so only the point of the // break is marked instead of the whole box. function buildLinebreakBackdropHtml(text) { var lines = text.split(/\r\n|\r|\n/); return $.map(lines, function (line, i) { var isLast = i === lines.length - 1; return escapeHtmlForBackdrop(line) + (isLast ? "" : "<mark class='wiktku-linebreak-mark'>↵</mark>\n"); }).join(""); } // Copies the metrics that affect where text wraps/lands (font, line // height, padding, border) from the real textarea onto its backdrop, // via computed style rather than shared CSS classes — most of the // box's own rules are written as "textarea.foo", which a <div> with // the same class wouldn't match. Re-run on every update in case a // responsive breakpoint changed the textarea's own font-size. function syncLinebreakBackdropMetrics(textarea, backdrop) { var cs = window.getComputedStyle(textarea[0]); backdrop.css({ "box-sizing": cs.boxSizing, "padding-top": cs.paddingTop, "padding-right": cs.paddingRight, "padding-bottom": cs.paddingBottom, "padding-left": cs.paddingLeft, "border-width": cs.borderWidth, "border-style": "solid", "font-family": cs.fontFamily, "font-size": cs.fontSize, "font-weight": cs.fontWeight, "line-height": cs.lineHeight, "letter-spacing": cs.letterSpacing }); } // Lazily wraps a textarea in its own positioning anchor (independent // of .wiktku-resize-wrap, so this doesn't depend on load order versus // wiktkuMakeManualResizable) and inserts the transparent backdrop // layer used to mark the exact point of a linebreak. Safe to call // more than once on the same textarea — the backdrop is cached. function ensureLinebreakBackdrop(textarea) { var existing = textarea.data("wiktkuLinebreakBackdrop"); if (existing) return existing; textarea.wrap("<div class='wiktku-linebreak-wrap'></div>"); var backdrop = $("<div aria-hidden='true'></div>").addClass("wiktku-linebreak-backdrop"); textarea.before(backdrop); textarea.data("wiktkuLinebreakBackdrop", backdrop); textarea.on("scroll.wiktkuLinebreak", function () { backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); }); return backdrop; } // Flags a nimûne/jêgirtin textarea (via CSS class, for the border // tint + tooltip) while it contains a typed/pasted linebreak, so the // user notices before it's silently turned into <br> on output. // Marks only the exact point of the break via a mirrored backdrop, // rather than tinting the whole box. function highlightLinebreak(el) { var textarea = $(el); var text = textarea.val(); var hasBreak = /\r|\n/.test(text); textarea .toggleClass("wiktku-has-linebreak", hasBreak) .attr("title", hasBreak ? "Xeta nû dê wek <br> bê nivîsandin" : ""); if (!hasBreak) { var cached = textarea.data("wiktkuLinebreakBackdrop"); if (cached) cached.hide(); textarea.removeClass("wiktku-has-linebreak-source"); return; } var backdrop = ensureLinebreakBackdrop(textarea); textarea.addClass("wiktku-has-linebreak-source"); syncLinebreakBackdropMetrics(textarea, backdrop); backdrop.html(buildLinebreakBackdropHtml(text)).show(); backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); } // Each nimûne item can be { text, tr, t }: text, transliteration, translation. function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{nimûne?|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = nlToBr(boldPageNameOnce(text)); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + nlToBr(n.tr); // Translation as third positional param (no key needed). if (n.t) tpl += "|" + nlToBr(n.t); } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 60 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } // Formats jêder (citation) entries into "#* {{jêder…|…}}" lines; skips // entries with no quote text. Falls back to the generic {{jêder}} // template when no specific template was chosen. function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; var quote = nlToBr(boldPageNameOnce(jeder.quote)); var quoteTr = nlToBr(jeder.quoteTr); var quoteT = nlToBr(jeder.quoteT); if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + quote; if (quoteTr) cite += "|tr=" + quoteTr; if (quoteT) cite += "|tercime=" + quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + quote; if (quoteTr) out += "|tr=" + quoteTr; if (quoteT) out += "|tercime=" + quoteT; // A şablon picked from Kategorî:Çavkanî is transcluded as the // source param (e.g. |{{Kovara X}}); manual text is used as-is. var srcParam = jeder.jederCatTpl ? ("{{" + jeder.jederCatTpl + "}}") : (jeder.jederManual ? jeder.jederManual : "çavkanî?"); // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } // True if a sense has at least one jêder entry with quote text. function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } // Builds "{{tplName|lang|part1|part2|…}}" from a sense field (kategori, // etiket), wrapped inline (" {{…}} ") or on its own line ("\n#: {{…}}"). function buildSenseTpl(sense, field, lang, tplName) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return call } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } // ── Inline modifier system ─────────────────────────────────────────────── // Appends a ⊕ button to a word input <li>. Clicking it shows a compact // modifier picker; selecting one prompts for the value and appends // <modifier:value> to the textarea's current content. 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îf" }, { 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: qualifier (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" }, { key: "qq", label: "qq: qualifier (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î" } ]; // Sub-groups (inside a sense/definition block) that get the same ⊕ // modifier button as makeWordListStep fields. var MODIFIER_SUBGROUPS = { "wiktku-dfn-alternativ": true, "wiktku-dfn-hevmane": true, "wiktku-dfn-dijmane": true, "wiktku-dfn-koordine": true, "wiktku-dfn-jornav": true, "wiktku-dfn-jernav": true }; /** * Wraps a freshly-created textarea in a <li> with a ⊕ modifier button. * `ta` — the jQuery textarea element. * Returns the <li>. */ function makeModifierLi(ta) { var li = $("<li class='wiktku-word-li'></li>"); var btn = $("<button type='button' class='wiktku-mod-btn' title='Modifiyerê lê zêde bike'>⊕</button>"); var picker = $("<div class='wiktku-mod-picker'></div>").hide(); // Which modifier keys are already present in the textarea's current // text — e.g. "<t:...>" → "t" used. Each modifier can only be // applied once per word, so its pill gets disabled once used. function usedKeys() { var used = {}; var re = /<([a-zA-Z]+):/g; var val = ta.val() || ""; var m; while ((m = re.exec(val)) !== null) used[m[1]] = true; return used; } $.each(WORD_MODIFIERS, function (_, mod) { var pill = $("<button type='button' class='wiktku-mod-pill'></button>").text(mod.label); pill.attr("title", mod.hint); pill.data("mod-key", mod.key); pill.on("click", function (e) { e.preventDefault(); if (pill.prop("disabled")) return; // already used on this word picker.hide(); // Show a tiny inline input for the modifier value. var valWrap = $("<span class='wiktku-mod-val-wrap'></span>"); var valInp = $("<input type='text' class='wiktku-mod-val-input'>") .attr("placeholder", mod.hint + "…") .attr("size", 20); var confirm = $("<button type='button' class='wiktku-mod-confirm'>✓</button>"); var cancel = $("<button type='button' class='wiktku-mod-cancel'>✕</button>"); function applyModifier() { var v = $.trim(valInp.val()); if (v) { ta.val(ta.val() + "<" + mod.key + ":" + v + ">"); ta.trigger("input"); } valWrap.remove(); ta.focus(); } confirm.on("click", applyModifier); cancel.on("click", function () { valWrap.remove(); ta.focus(); }); valInp.on("keydown", function (e) { if (e.which === 13) { e.preventDefault(); applyModifier(); } if (e.which === 27) { valWrap.remove(); ta.focus(); } }); valWrap.append(valInp).append(confirm).append(cancel); li.append(valWrap); valInp.focus(); }); picker.append(pill); }); btn.on("click", function (e) { e.preventDefault(); // Close any other open pickers in the same list. li.closest("ol, ul").find(".wiktku-mod-picker").not(picker).hide(); // Grey out modifiers already used on this word — refreshed on // every open since the text (and thus what's "used") can change. var used = usedKeys(); picker.find(".wiktku-mod-pill").each(function () { var isUsed = !!used[$(this).data("mod-key")]; $(this).prop("disabled", isUsed).toggleClass("wiktku-mod-pill-used", isUsed); }); picker.toggle(); }); // Close picker when focus leaves the li entirely. li.on("focusout", function () { setTimeout(function () { if (!$.contains(li[0], document.activeElement)) picker.hide(); }, 150); }); li.append(ta).append(btn).append(picker); return li; } function makeWordListStep(id, name, question_fmt) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, modifiers: true, // Function instead of a plain string so it can name the current // language — computed fresh at build time and re-applied by // refresh() whenever the language changes. placeholder: function () { var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return "Kelîme" + (langLabel ? " bi " + langLabel : "") + "…"; }, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); var header = capitalize(name); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: {}, visible: function (values) { if (!values.lang) return false; // addLangMode: skip pron only if this lang already has a section. if (addLangMode) { // Clearing the page makes existing content irrelevant. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, // Fills the insert-dropdown from pronTpls, filtered by language. refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); // Reassures the user this field is optional — the dropdown // below writes the template for them, no syntax needed up front. wrap.append( $("<p class='wiktku-step-hint'></p>").text( "Ev qad ne mecbûrî ye. Heke tu nizanî kîjan şablonî hilbijêrî, vale bihêle — an ji pêşkêşkariya jêrîn şablonekî hilbijêre, ew ê bixweber li vir were nivîsandin." ) ); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike "); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); // Clear the picker's search box sel.trigger("wiktku:refresh"); ta.focus(); return; } // The noLang templates (ku-IPA, ku-kîte, zza-IPA, zza-kîte) // auto-generate content from a Lua module reading the page // title, so show a live preview and require confirmation // before inserting. var tplLabel = selectedOption.text(); $(this).val(""); sel.trigger("wiktku:refresh"); steps.pron.showTplPreview(stepDiv, ta, snippet, tplLabel); }); wrap.append(sel).append(ta); stepDiv.append(wrap); steps.pron.buildIpaPalette(wrap, ta); initSelects(wrap); return ta; }, // ── IPA character palette ────────────────────────────────── // Modelled on fr.wiktionary's: every character is a button that // drops itself in at the cursor. Two sub-tabs, because the full // IPA chart is ~180 symbols and roughly twenty of them ever // appear in Kurmancî — "IPA (kurdî)" opens by default and the // full chart is one click away for loanwords and other // languages. Grouped with a label down the left so it reads as // a chart rather than one long line of glyphs. IPA_KU: [ { label: "Kît/stres", chars: ["ˈ", "ˌ", "ː"] }, { label: "Bêdeng", chars: ["d͡ʒ", "t͡ʃ", "ʒ", "ʃ", "ɫ", "ŋ", "ɾ", "r", "ʋ", "ħ", "ʕ", "ɣ", "χ", "ʔ"] }, { label: "Dengdêr", chars: ["ɑː", "eː", "ɛ", "ɪ", "iː", "ɯ", "ʊ", "uː", "yː", "ø", "œ"] } ], IPA_FULL: [ { label: "Bêdeng 1", chars: ["m", "ɱ", "n", "ɳ", "ɲ", "ŋ", "ɴ", "p", "b", "t", "d", "t̪", "d̪", "ʈ", "ɖ", "c", "ɟ", "k", "ɡ", "q", "ɢ", "ʡ", "ʔ"] }, { label: "Bêdeng 2", chars: ["ɸ", "β", "f", "v", "θ", "ð", "s", "z", "ʃ", "ʒ", "ʂ", "ʐ", "ɕ", "ʑ", "ç", "ʝ", "x", "ɣ", "χ", "ʁ", "ħ", "ʕ", "h", "ɦ", "ʜ", "ʢ", "ɧ"] }, { label: "Bêdeng 3", chars: ["ʋ", "ɹ", "ɻ", "j", "ɥ", "ɰ", "ʍ", "w", "ʙ", "ⱱ", "ɾ", "ɽ", "r", "ʀ", "ɺ", "l", "ɫ", "ɬ", "ɮ", "ɭ", "ʎ", "ʟ"] }, { label: "Bêdeng 4", chars: ["ɓ", "ɗ", "ᶑ", "ʄ", "ɠ", "ʛ", "ʘ", "ǀ", "ǃ", "ǂ", "ǁ"] }, { label: "Dengdêr", chars: ["i", "y", "ɪ", "ʏ", "ɨ", "ʉ", "ɯ", "u", "ʊ", "e", "ø", "ɘ", "ɵ", "ɤ", "o", "ə", "ɚ", "ɛ", "œ", "ɜ", "ɝ", "ɞ", "ʌ", "ɔ", "æ", "ɶ", "ɐ", "a", "ɑ", "ɒ"] }, { label: "Suprasegmental", chars: ["ˈ", "ˌ", "ː", "ˑ", "ʼ", "ˀ", "ˤ", "ᵝ", "ᵊ", "ˠ", "ʰ", "ʱ", "ʲ", "ˡ", "ⁿ", "ᵑ", "ʷ", "ᶣ", "˞", "‿"] }, { label: "Dîakrîtîk", chars: ["̚", "̪", "̺", "̻", "̼", "̬", "̊", "̥", "̞", "̝", "̘", "̙", "̽", "̟", "̠", "̈", "̤", "̹", "̜", "̍", "̩", "̆", "̯", "̃", "̰", "͡", "͜"] }, { label: "Ton", chars: ["̋", "́", "̄", "̀", "̏", "̌", "̂", "˥", "˦", "˧", "˨", "˩", "ꜛ", "ꜜ", "↗", "↘", "‖"] } ], /** Builds the two-sub-tab character palette under the textarea. */ buildIpaPalette: function (wrap, ta) { if (wrap.find(".wiktku-ipa-palette").length) return; var panel = $("<div class='wiktku-ipa-panel'></div>").hide(); var toggle = $("<a href='#' class='wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tîpên bilêvkirinê</span>")); toggle.on("click", function (e) { e.preventDefault(); var open = panel.is(":visible"); panel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); wrap.append($("<div class='wiktku-adv-toggle-row'></div>").append(toggle)); // Sub-tab bar, with the two template buttons pinned right. var subTabs = $("<div class='wiktku-ipa-subtabs'></div>"); var kuTab = $("<span class='wiktku-ipa-subtab wiktku-tab-active'>IPA (kurdî)</span>"); var fullTab = $("<span class='wiktku-ipa-subtab'>IPA</span>"); subTabs.append(kuTab).append(fullTab); var tplBtns = $("<span class='wiktku-ipa-tplbtns'></span>"); $.each([ { label: "{{ku-IPA|+}}", snippet: "{{ku-IPA|}}", back: 2 }, { label: "{{IPA|+}}", snippet: "{{IPA|ku|}}", back: 2 } ], function (_, t) { var b = $("<button type='button' class='wiktku-ipa-tplbtn'></button>").text(t.label); b.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], t.snippet); // Park the cursor inside the braces, where the value goes. var pos = ta[0].selectionStart - t.back; ta[0].selectionStart = ta[0].selectionEnd = pos; ta.focus(); }); tplBtns.append(b); }); subTabs.append(tplBtns); panel.append(subTabs); function buildGrid(groups) { var grid = $("<div class='wiktku-ipa-grid'></div>"); $.each(groups, function (_, g) { var row = $("<div class='wiktku-ipa-row'></div>"); row.append($("<span class='wiktku-ipa-rowlabel'></span>").text(g.label)); var keys = $("<span class='wiktku-ipa-keys'></span>"); $.each(g.chars, function (_, ch) { var btn = $("<button type='button' class='wiktku-ipa-key'></button>"); // A combining mark on its own renders as a stray // accent floating over whatever precedes it, so // show it on a dotted circle — but insert only // the mark itself. var combining = /^[̀-ͯ҃-҉]$/.test(ch); btn.text(combining ? "◌" + ch : ch); if (combining) btn.addClass("wiktku-ipa-key-combining"); btn.attr("title", ch); btn.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], ch); ta.focus(); }); keys.append(btn); }); row.append(keys); grid.append(row); }); return grid; } var kuGrid = buildGrid(steps.pron.IPA_KU); var fullGrid = buildGrid(steps.pron.IPA_FULL).hide(); panel.append(kuGrid).append(fullGrid); kuTab.on("click", function () { kuTab.addClass("wiktku-tab-active"); fullTab.removeClass("wiktku-tab-active"); kuGrid.show(); fullGrid.hide(); }); fullTab.on("click", function () { fullTab.addClass("wiktku-tab-active"); kuTab.removeClass("wiktku-tab-active"); fullGrid.show(); kuGrid.hide(); }); panel.addClass("wiktku-ipa-palette"); wrap.append(panel); }, /** Inline preview + confirm panel for a "noLang" (auto-content) * pronunciation template — fetches what the snippet expands to * for this page and only inserts it if the user confirms. */ showTplPreview: function (stepDiv, ta, snippet, tplLabel) { // Only one preview panel open at a time. stepDiv.find(".wiktku-pron-preview").remove(); var panel = $("<div class='wiktku-pron-preview'></div>"); panel.append($("<div class='wiktku-pron-preview-label'></div>") .text("Pêşdîtina " + tplLabel + ":")); var body = $("<div class='wiktku-pron-preview-body'></div>").text("Tê barkirin…"); panel.append(body); var actions = $("<div class='wiktku-pron-preview-actions'></div>"); var confirmBtn = $("<button type='button' class='wiktku-pron-preview-confirm'>✓ Tevlî bike</button>") .prop("disabled", true); var cancelBtn = $("<button type='button' class='wiktku-pron-preview-cancel'>✕ Betal bike</button>"); actions.append(confirmBtn).append(cancelBtn); panel.append(actions); ta.before(panel); confirmBtn.on("click", function () { insertAtCursor(ta[0], snippet); panel.remove(); ta.focus(); }); cancelBtn.on("click", function () { panel.remove(); }); // action=parse, not action=expandtemplates. expandtemplates // returns *expanded wikitext*, so the preview read as // [[IPA]]<sup>([[Wîkîferheng:IPA kurmancî|kilîd]])</sup>: // <span class="IPA">/-{kshhe}-/</span>[[Kategorî:…]] — which // is exactly what the person is trying to avoid having to // read. parse hands back the rendered HTML the page will // actually show. // // Drop the leading "* " first: it is wikitext list syntax // wrapping the template, and keeping it would render the // preview as a bulleted list rather than the line itself. new mw.Api().post({ action: "parse", title: pageName, text: snippet.replace(/^\*\s*/, ""), prop: "text", wrapoutputclass: "", disablelimitreport: 1, disableeditsection: 1, contentmodel: "wikitext", formatversion: 2 }).done(function (data) { var html = (data && data.parse && data.parse.text) || ""; if ($.trim($("<div>").html(html).text())) { body.html(html); // Category links render as nothing but still exist; // and any real link inside a preview should not // navigate away from a half-filled form. body.find("a").attr("target", "_blank").attr("rel", "noopener"); } else { body.text("(vala — ji bo vê rûpelê tiştek nehate afirandin)"); } confirmBtn.prop("disabled", false); }).fail(function () { body.text("Pêşdîtin nehate barkirin — tu dikarî hîn jî wê tevlî bikî."); confirmBtn.prop("disabled", false); }); }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line; }).join("\n"); // "===" heading under Ziman and above the POS sections; the // field is shared across sections, so it's emitted once by // getWikitext() rather than per-POS-section (would otherwise // print the pronunciation twice for a two-POS entry). return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var capitalizedPos = capitalize(pos); // "form" opt-param (checked in posparams) marks this as a // form-of/inflected entry — the section title becomes // "Formeke <pos>ê" instead of the plain pos name. The // template call itself still uses the unchanged pos name. var isForm = $("#wiktku-posparams-opt-form").is(":checked"); var header = isForm ? "\n=== Formeke " + pos + "ê ===\n" : "\n=== " + capitalizedPos + " ===\n"; // Image line (between header and template call) var imageLine = steps.resim.output(values); // Read the live wikitext from the posparams textarea. // Fall back to a plain {{pos|lang}} if the step hasn't been built yet. var tplLine = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); if (!tplLine) { tplLine = "{{" + pos + "|" + (values.lang || "") + "}}"; } return header + imageLine + tplLine + "\n"; } }, // cinsiyet (gender) — shown for navdêr/serenav only, with choices built // from metadata[lang].g since not every language has grammatical gender. cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams // Single source of truth for the selected gender code. The visible // dropdown lives inside the posparams step (see steps.posparams), // but it must always read/write THIS hidden field — not a field of // its own — since getValuesForStep("cinsiyet") reads from here. build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-cinsiyet-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // jimar (grammatical number) — same hidden-field pattern as cinsiyet // above, but writes into its own j= template parameter instead of // sharing c=. Shown for navdêr/serenav only, with choices built from // whichever of metadata[lang].g are number codes (see isNumberCode). jimar: { id: "jimar", name: "jimar", question_fmt: 'Jimara "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-jimar-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // Lêker transitivity — hidden step, handled inside posparams lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function () { return false; }, choices: [ { code: "gh", label: "gerguhêz" }, { code: "x-gh", label: "xwerû-gerguhêz" }, { code: "p-gh", label: "pêkhatî-gerguhêz" }, { code: "h-gh", label: "hevedudanî-gerguhêz" }, { code: "b-gh", label: "biwêjî-gerguhêz" }, { code: "ngh", label: "negerguhêz" }, { code: "x-ngh", label: "xwerû-negerguhêz" }, { code: "p-ngh", label: "pêkhatî-negerguhêz" }, { code: "h-ngh", label: "hevedudanî-negerguhêz" }, { code: "b-ngh", label: "biwêjî-negerguhêz" } ], output: function () { return ""; } }, // tr — hidden step, handled inside posparams tr: { id: "tr", name: "transliterasyon", question_fmt: "Transliterasyona vê kelîmeyê", multiple: false, narrow: true, visible: function () { return false; } }, posparams: { id: "posparams", // Fused onto the "pos" card visually (see #wiktku-start-posparams // in styles.css) so the two read as ONE question — this name is // only a no-CSS/no-JS fallback, since the h3 that would show it // is hidden by CSS. name: "taybetmendî", // Shows what's actually being asked for: gender for nouns, verb // type for verbs, a generic fallback otherwise. question_fmt: function (values) { var pos = values.pos || ""; // Cinsiyet/Jimar fields below are self-labelled, so no title needed here. if (pos === "navdêr" || pos === "serenav") return ""; if (/^lêker/.test(pos)) return "Cureyê lêkerê"; return "Taybetmendî"; }, visible: function (values) { return !!(values.lang && values.pos); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-posparams-wrap").length) return null; var wrap = $("<div class='wiktku-posparams-wrap'></div>"); var helpers = $("<div class='wiktku-posparams-helpers'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-posparams-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-posparams-text") .attr("rows", 2); var _rebuilding = false; function safeRebuild() { if (_rebuilding) return; _rebuilding = true; steps.posparams.rebuildTa(stepDiv); _rebuilding = false; refresh(); } // Generic text-input row factory function makeTextRow(key, labelText, placeholder) { var row = $("<div class='wiktku-posparams-row'></div>") .attr("id", "wiktku-posparams-row-" + key).hide(); var inp = $("<input type='text'>") .addClass("wiktku-start-narrow wiktku-posparams-field") .attr("data-pp-key", key) .attr("placeholder", placeholder || ""); inp.on("input", safeRebuild); row.append($("<label></label>").text(labelText + ": ")).append(inp); return row; } // cinsiyet var cinsiyetRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-c'></div>") .append($("<label></label>").text("Cinsiyet: ")).hide(); var cinsiyetSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-cinsiyet-sel") .append($("<option value=''>— hilbijêre —</option>")); // Writes into the real, shared #wiktku-start-cinsiyet-field (owned by // steps.cinsiyet) rather than a field of its own — see the comment // on steps.cinsiyet.build for why that matters. cinsiyetSel.on("change", function () { $("#wiktku-start-cinsiyet-field").val($(this).val()).trigger("change"); safeRebuild(); }); cinsiyetRow.append(cinsiyetSel); // jimar (number) — second dropdown next to Cinsiyet, writes // into the shared hidden #wiktku-start-jimar-field, into its // own j= param instead of sharing c=. Options + tooltip are // built in syncHelpers once the language's number codes are known. var jimarRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-jimar'></div>") .append($("<label></label>").text("Jimar: ")).hide(); var jimarSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-jimar-sel") .append($("<option value=''>— hilbijêre —</option>")); jimarSel.on("change", function () { $("#wiktku-start-jimar-field").val($(this).val()).trigger("change"); safeRebuild(); }); jimarRow.append(jimarSel); // lektur: two plain questions (transitivity + structural form) // instead of one 10-option dropdown. Emitted code: base alone // ("gh"), or prefix + "-" + base ("x-gh"). var lekturRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lektur'></div>") .append($("<label></label>").text("Lêker derbasdar e? ")).hide(); var lekturSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lektur-sel") .append($("<option value=''>— hilbijêre —</option>")) .append($("<option value='gh'>gerguhêz (bireser digire)</option>")) .append($("<option value='ngh'>negerguhêz (bireser nagire)</option>")); lekturSel.on("change", safeRebuild); lekturRow.append(lekturSel); // Second half of the same question — the structural form. // Blank = xwerû/sade, which is the common case. var lekturFormRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lekturform'></div>") .append($("<label></label>").text("Şiklê lêkerê: ")).hide(); var lekturFormSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lekturform-sel") .append($("<option value=''>sade (asayî)</option>")) .append($("<option value='x'>xwerû</option>")) .append($("<option value='p'>pêkhatî</option>")) .append($("<option value='h'>hevedudanî</option>")) .append($("<option value='b'>biwêjî</option>")); lekturFormSel.on("change", safeRebuild); lekturFormRow.append(lekturFormSel); helpers.append(cinsiyetRow).append(jimarRow).append(lekturRow).append(lekturFormRow); // ── Everything below here is "Tercîhên pêşketî" ────────────── // These rows live inside a collapsed panel, so the default // view of this card is two dropdowns instead of twenty-odd fields. // Transliteration is a primary field, not an advanced one, for // any language not written in Latin script: for those, an // entry without it is incomplete. syncHelpers already gates // the row on needsTransliteration(lang), so for Kurmancî and // other Latin-script languages it simply never appears. helpers.append(makeTextRow("tr", "Transliterasyon (tr)", "Transliterasyon…")); var advPanel = $("<div class='wiktku-posparams-adv-panel'></div>").hide(); advPanel .append(makeTextRow("cuda", "nîşankirina alternatîv", "cuda…")) .append(makeTextRow("ts", "Transkrîpsiyon (ts)", "Transkrîpsiyon…")) .append(makeTextRow("m", "Forma mê (m)", "Forma mê…")) .append(makeTextRow("mtr", "Translit. mê (mtr)", "Transliterasyona mê…")) .append(makeTextRow("n", "Forma nêr (n)", "Forma nêr…")) .append(makeTextRow("ntr", "Translit. nêr (ntr)", "Transliterasyona nêr…")) .append(makeTextRow("p", "Forma pirjimar (p)", "Forma pirjimar…")) .append(makeTextRow("ptr", "Translit. pirjimar", "Transliterasyona pirjimar…")) .append(makeTextRow("y", "Forma yekjimar (y)", "Forma yekjimar…")) .append(makeTextRow("ytr", "Translit. yekjimar", "Transliterasyona yekjimar…")) .append(makeTextRow("sûp", "Forma sûperlatîv (sûp)", "Forma sûperlatîv…")) .append(makeTextRow("sûptr", "Translit. sûperlatîv", "Transliterasyona sûperlatîv…")) .append(makeTextRow("komp", "Forma komparatîv (komp)", "Forma komparatîv…")) .append(makeTextRow("komptr", "Translit. komparatîv", "Transliterasyona komparatîv…")) .append(makeTextRow("gir", "Forma girdêk (gir)", "gir=…")) .append(makeTextRow("girtr", "Translit. gir", "girtr=…")) .append(makeTextRow("hûr", "Forma hûrek (hûr)", "hûr=…")) .append(makeTextRow("hûrtr", "Translit. hûr", "hûrtr=…")) .append(makeTextRow("hanja", "Forma hanja", "hanja=…")) .append(makeTextRow("hanjaTr","Translit. hanja", "hanjaTr=…")) // Lêker rehên demê (only shown when pos is lêker — see syncHelpers) .append(makeTextRow("niha", "Rehê dema niha (niha)", "Rehê dema niha…")) .append(makeTextRow("nihatr", "Translit. rehê dema niha", "Transliterasyona rehê dema niha…")) .append(makeTextRow("borî", "Rehê dema borî (borî)", "Rehê dema borî…")) .append(makeTextRow("borîtr", "Translit. rehê dema borî", "Transliterasyona rehê dema borî…")) .append(makeTextRow("subj", "Rehê dema bilanî (subj)", "Rehê dema bilanî…")) .append(makeTextRow("subjtr", "Translit. rehê dema bilanî", "Transliterasyona rehê dema bilanî…")); // Optional boolean params — nested inside the advanced panel // (they were already the most niche thing on the card). var optPanel = $("<div class='wiktku-posparams-opt-panel'></div>"); $.each([ { key: "form", label: "form — ev made forma tewandî ye" }, { key: "formaalt", label: "formaalt — vê madeyê bike forma alternatîv" }, { key: "nekatcure", label: "nekatcure — sinifa rêzimanî kategorîze neke" }, { key: "nekatcins", label: "nekatcins — kategoriya cinsiyetê neyîne" }, { key: "nekatçendterm", label: "nekatçendterm — kategoriya çend-term neyîne" }, { key: "serlînkneke", label: "serlînkneke — sernavê madeyê lînk neke" }, { key: "nekatpalîndrom", label: "nekatpalîndrom — kategoriya palîndromê neyîne" }, { key: "neformtr", label: "neformtr — transliterasyona forman neyîne" } ], function (_, p) { var cb = $("<input type='checkbox'>") .attr("id", "wiktku-posparams-opt-" + p.key).val(p.key).on("change", safeRebuild); var lbl = $("<label></label>").attr("for", "wiktku-posparams-opt-" + p.key).text(" " + p.label); optPanel.append($("<div class='wiktku-posparams-opt-row'></div>").append(cb).append(lbl)); }); advPanel.append(optPanel); var optToggle = $("<a href='#' class='wiktku-posparams-opt-toggle wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tercîhên pêşketî</span>")); optToggle.on("click", function (e) { e.preventDefault(); var open = advPanel.is(":visible"); advPanel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); helpers.append($("<div class='wiktku-adv-toggle-row'></div>") .append(optToggle)); helpers.append(advPanel); wrap.append(helpers).append(ta); // Typing directly in textarea keeps cinsiyet/jimar hidden // fields in sync, but does NOT call refresh() — preserves // manual edits. ta.on("input", function () { var text = $(this).val(); var cMatch = text.match(/\|c=([^|}\s]+)/); $("#wiktku-start-cinsiyet-field").val(cMatch ? cMatch[1] : ""); var jMatch = text.match(/\|j=([^|}\s]+)/); $("#wiktku-start-jimar-field").val(jMatch ? jMatch[1] : ""); }); stepDiv.append(wrap); return null; }, /** Reads all helper widget values and rewrites the textarea. * Called only by safeRebuild (user interaction) — never by syncHelpers, * so manual textarea edits are never overwritten by a refresh cycle. */ rebuildTa: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; if (!pos || !lang) return; var cinsiyet = stepDiv.find(".wiktku-posparams-cinsiyet-sel").val() || ""; var jimar = stepDiv.find(".wiktku-posparams-jimar-sel").val() || ""; // Two dropdowns, one code: "gh" / "ngh" on their own, or // prefixed with the structural form ("x-gh", "b-ngh", …). var lekturBase = stepDiv.find(".wiktku-posparams-lektur-sel").val() || ""; var lekturForm = stepDiv.find(".wiktku-posparams-lekturform-sel").val() || ""; var lektur = lekturBase ? (lekturForm ? lekturForm + "-" + lekturBase : lekturBase) : ""; function v(key) { return $.trim(stepDiv.find(".wiktku-posparams-field[data-pp-key='" + key + "']").val()); } var out = "{{" + pos + "|" + lang; if (pos === "navdêr" || pos === "serenav") { out += cinsiyet ? "|c=" + cinsiyet : (lang === "ku" ? "|c=?" : ""); // Number is its own j= param, separate from c= (which // holds gender, including compounds like m-p/n-p). if (jimar) out += "|j=" + jimar; } else if (/^lêker/.test(pos) && lektur) { out += "|c=" + lektur; } if (v("cuda")) out += "|" + v("cuda"); if (v("tr")) out += "|tr=" + v("tr"); if (v("ts")) out += "|ts=" + v("ts"); $.each(["m","n","p","y"], function (_, k) { if (v(k)) out += "|" + k + "=" + v(k); if (v(k+"tr")) out += "|" + k + "tr=" + v(k+"tr"); }); if (v("sûp")) out += "|sûp=" + v("sûp"); if (v("sûptr")) out += "|sûptr=" + v("sûptr"); if (v("komp")) out += "|komp=" + v("komp"); if (v("komptr")) out += "|komptr=" + v("komptr"); if (v("gir")) out += "|gir=" + v("gir"); if (v("girtr")) out += "|girtr=" + v("girtr"); if (v("hûr")) out += "|hûr=" + v("hûr"); if (v("hûrtr")) out += "|hûrtr=" + v("hûrtr"); if (v("hanja")) out += "|hanja=" + v("hanja"); if (v("hanjaTr")) out += "|hanjaTr=" + v("hanjaTr"); if (v("niha")) out += "|niha=" + v("niha"); if (v("nihatr")) out += "|nihatr=" + v("nihatr"); if (v("borî")) out += "|borî=" + v("borî"); if (v("borîtr")) out += "|borîtr=" + v("borîtr"); if (v("subj")) out += "|subj=" + v("subj"); if (v("subjtr")) out += "|subjtr=" + v("subjtr"); stepDiv.find(".wiktku-posparams-opt-panel input:checked").each(function () { var key = $(this).val(); // "form" marks this entry as a form-of/inflected entry — it // takes "erê" rather than the plain "1" the other boolean // opt params use. out += "|" + key + "=" + (key === "form" ? "erê" : "1"); }); out += "}}"; stepDiv.find(".wiktku-posparams-text").val(out); $("#wiktku-start-cinsiyet-field").val(cinsiyet); $("#wiktku-start-jimar-field").val(jimar); }, /** Called from refresh() — controls row visibility only. * Does NOT rewrite textarea so user edits are preserved. * Rebuilds only when textarea is empty (first pos selection). */ syncHelpers: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; var needsTr = needsTransliteration(lang); var isNom = pos === "navdêr" || pos === "serenav" || pos === "rengdêr"; var isAdj = pos === "rengdêr"; var isTîp = pos === "tîp"; var isJa = lang === "ja"; var isLeker = /^lêker/.test(pos); // metadata[lang].g lists gender AND number codes together — // split them here (see isNumberCode) so Cîns only ever offers // gender codes (and gender+plural compounds like m-p/n-p, // which aren't NUMBER_LABELS keys) and Jimar only offers number codes. var meta = metadata[lang]; var allCodes = (meta && meta.g) || []; var genderCodes = $.grep(allCodes, function (c) { return !isNumberCode(c); }); var jimarCodes = $.grep(allCodes, function (c) { return isNumberCode(c); }); var showC = (pos === "navdêr" || pos === "serenav") && genderCodes.length > 0; var cRow = stepDiv.find("#wiktku-posparams-row-c"); cRow.toggle(showC); if (showC) { var sel = cRow.find(".wiktku-posparams-cinsiyet-sel"); // Prefer the select's own current value (normal in-session // use); fall back to the shared hidden field, which is how // a cache/section restore communicates a saved gender // before this select has any <option>s to hold it. var prev = sel.val() || $("#wiktku-start-cinsiyet-field").val() || ""; sel.find("option[value!='']").remove(); $.each(genderCodes, function (_, code) { sel.append($("<option></option>").val(code).text(genderLabel(code))); }); if (prev) sel.val(prev); } var showJimar = (pos === "navdêr" || pos === "serenav") && jimarCodes.length > 0; var jimarRowEl = stepDiv.find("#wiktku-posparams-row-jimar"); jimarRowEl.toggle(showJimar); if (showJimar) { var jimarSelEl = jimarRowEl.find(".wiktku-posparams-jimar-sel"); var prevJimar = jimarSelEl.val() || $("#wiktku-start-jimar-field").val() || ""; jimarSelEl.find("option[value!='']").remove(); $.each(jimarCodes, function (_, code) { var def = NUMBER_LABELS[code] || {}; var opt = $("<option></option>").val(code).text(numberOptionLabel(code)); // The explanation (cat, e.g. "dualia tantum") shows as a // hover tooltip — <option> can't hold richer markup. if (def.cat) opt.attr("title", def.cat); jimarSelEl.append(opt); }); if (prevJimar) jimarSelEl.val(prevJimar); } stepDiv.find("#wiktku-posparams-row-lektur").toggle(isLeker); // Only ask for the structural form once gerguhêz/negerguhêz is answered. stepDiv.find("#wiktku-posparams-row-lekturform") .toggle(isLeker && !!stepDiv.find(".wiktku-posparams-lektur-sel").val()); stepDiv.find("#wiktku-posparams-row-tr").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-ts").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-m").toggle(isNom); stepDiv.find("#wiktku-posparams-row-mtr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-n").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ntr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-p").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ptr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-y").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ytr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-sûp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-sûptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-komp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-komptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-gir").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-girtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hûr").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-hûrtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hanja").toggle(isJa); stepDiv.find("#wiktku-posparams-row-hanjaTr").toggle(isJa); stepDiv.find("#wiktku-posparams-row-niha").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-nihatr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-borî").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-borîtr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-subj").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-subjtr").toggle(isLeker && needsTr); if (!$.trim(stepDiv.find(".wiktku-posparams-text").val())) { steps.posparams.rebuildTa(stepDiv); } }, output: function () { return ""; } // pos.output reads the textarea directly }, dfn: { id: "dfn", name: "Mane", // Field types that live behind "Malûmatên pêşketî". Kept as one // list so the collapse CSS, the count badge and the allGroups // adv: flags below can't drift apart. ADV_SUBGROUPS: [ "wiktku-dfn-etiket", "wiktku-dfn-kategori", "wiktku-dfn-alternativ", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ], question_fmt: function (values) { var base = "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin!"; if (values.lang === "ku") { return base + " Ji bo tercimeyan beşa 'Werger' bi kar bîne!"; } return base; }, multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, // Builds one sense block (<li>): mane textarea, nimûne list, and // sub-lists for alternatîv/hevmane/dijmane/etc. buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Tercime + Îzah boxes (non-ku alternative to the plain mane box) — // Non-ku entries get a direct translation plus a {{îzah|…}}-wrapped // gloss instead of a Kurdish-style gloss. Rather than teach every // consumer (getSenses/getOutput/linkify) a second data shape, these // boxes just write their combined text into dfnArea and re-fire its // "input" event, so dfnArea stays the single source of truth. var tercimeArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-tercime-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-tercime") .attr("rows", 2) .attr("placeholder", "Tercimeyên rasterast ên kurmancî… Ji bo school-a îngilîzî li vir 'mekteb, medrese' binivîse"); var izahArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-izah-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-izah") .attr("rows", 3) .attr("placeholder", "Îzaha kurmancî… Ji bo school-a îngilîzî li vir 'cihê tehsîlgirtinê' binivîse"); var nonKuWrap = $("<div class='wiktku-dfn-nonku-wrap'></div>") .append(tercimeArea).append(izahArea) .hide(); function syncNonKuToMane() { var t = $.trim(tercimeArea.val()); var iz = $.trim(izahArea.val()); // if tercime is blank, use îzah as definition var combined = t ? (iz ? t + " {{îzah|" + iz + "}}" : t) : iz; dfnArea.val(combined); // Re-fires onDfnInput so the sense list still grows and // refresh() still runs, exactly as if this were typed // directly into the mane textarea. dfnArea.trigger("input"); } tercimeArea.on("input", syncNonKuToMane); izahArea.on("input", syncNonKuToMane); // Switches between the plain mane box and the tercime+îzah pair — // only for non-ku entries with no tplSelect selected. function updateManeMode() { var lang = getValues().lang || ""; var isTpl = !!tplSelect.val(); if (lang && lang !== "ku" && !isTpl) { dfnArea.hide(); nonKuWrap.show(); } else { nonKuWrap.hide(); if (!isTpl) dfnArea.show(); } } // Store on the block so refresh() can re-sync every block when // lang changes, and restoreDfn() can re-sync after restoring. block.data("updateManeMode", updateManeMode); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || {}; // Cache of all non-placeholder option elements, so updateTplOptions // can detach/re-attach them without losing the full list. var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.attr("data-placeholder", "Li şablonekê bigere"); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (name, tpl) { // Shows "name — tpl.desc" when a tplDefs entry has a desc // in data.json, same pattern as steps.pron's template picker. var opt = $("<option></option>") .val(name) .text(tpl.desc ? name + " — " + tpl.desc : name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); // Same status-dot / 🔗 / ⓘ row treatment as every other // template picker. This one carries the bare name in value=, // so the name mapper is the identity rather than a snippet // parse; descriptions come from each template's TemplateData. markTemplateOptions(tplSelect, function (opt) { return opt.val(); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible // ones — native <select> won't reliably hide options any other way. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); // Options that were detached when the descriptions arrived // missed that pass, so describe whatever is attached now. // The cache is warm by this point, so this is synchronous. applyTplDescriptions(tplSelect); tplSelect.trigger("wiktku:refresh"); if (currentVal && !currentStillValid) { tplSelect.val(""); tplTitleInput.hide().val(""); updateManeMode(); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpela hedefê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // Şablon senses have no plain gloss, so hide alternatîv/hevmane/ // dijmane/etc. Etîket, Nimûne and Jêgirtin stay visible either way. function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); nonKuWrap.hide(); tplTitleInput.show().focus(); } else { tplTitleInput.hide().val(""); updateManeMode(); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); // The template picker is an alternative to writing a // definition, not a step before it — so the box comes first // and this sits under it as a quiet link. It only expands // for the minority of senses that are a pointer at another // word (guharto, şaşnivîs, kevnbûyî) rather than a meaning. var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput) .hide(); var tplLink = $("<a href='#' class='wiktku-dfn-tpl-link'></a>") .text("Ev ne pênase ye — şablonek bi kar bîne"); tplLink.on("click", function (e) { e.preventDefault(); tplRow.show(); $(this).hide(); tplRow.find("input.wiktku-ac-input").first().focus(); }); /** Opens the picker without a click — used on restore, when a * sense already has a template and hiding it would make the * chosen value invisible. */ function revealTplRow() { tplRow.show(); tplLink.hide(); } block.data("revealTplRow", revealTplRow); block.append(dfnArea); block.append(nonKuWrap); block.append(tplLink); block.append(tplRow); // Apply lang filter on initial build. updateTplOptions(); updateManeMode(); // — Sub-field groups. — // The four most-used groups (Nimûne, Jêgirtin, Hevmane, Dijmane) // stay open; the rest sit behind the "Malûmatên pêşketî" toggle // (adv: true → .wiktku-dfn-subgroup-adv, keyed off by the collapse CSS). // Jêgirtin isn't in this array — it's a compound widget built // after the loop — but it's inserted right after Nimûne so the // visible order matches the list above. var allGroups = [ { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "wekî etîket lê xuya nabe tenê kategorîze dike", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê", adv: true }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in", adv: true }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e", adv: true }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e", adv: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); if (g.adv) groupDiv.addClass("wiktku-dfn-subgroup-adv"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } // The placeholder names the current language, but that's // often not chosen yet when this block is first built — // so keep a function around that refresh() (and onSubInput, // for newly-grown fields) can call again once lang is set // or changes. function subPlaceholder() { if (g.noLangSuffix) return g.label + "…"; var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return g.label + (langLabel ? " bi " + langLabel : "") + "…"; } function updateSubPlaceholders() { list.find("> li > textarea.wiktku-dfn-subfield").attr("placeholder", subPlaceholder()); } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": ") .append($("<span></span>").addClass("wiktku-dfn-sublabel-hint").text(g.izah)); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var useModifiers = !!MODIFIER_SUBGROUPS[g.cls]; list.data("updatePlaceholders", updateSubPlaceholders); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", subPlaceholder()); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow, useModifiers); }); list.append(useModifiers ? makeModifierLi(firstInput) : $("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder group — growing list, same structure as Nimûne. — (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text("Jêgirtin")) .append(": "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<textarea></textarea>") .addClass("wiktku-dfn-subfield wiktku-dfn-quote-citoid-input") .attr("rows", 1) .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi otomatîk tijî bike", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); // Fetches citation data from Citoid and fills this citation's // şablon + fields — only rebuilds fields on template change, // and never overwrites values the user already typed. function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoid.fetchJederFields(query).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only rebuild if switching şablon, so a repeat fetch // doesn't clear fields already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel wiktku-plain-select"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); srcSel.append($("<option></option>").val("__category__").text("Ji Kategorî:Çavkanî şablonekê hilbijêre")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); // Citoid is only useful before a source is chosen — // hide it once a selection is made, restore on reset. if (chosen) { citoidWrap.hide(); } else { citoidWrap.show(); return; } if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } if (chosen === "__category__") { // Search widget over the members of [[Kategorî:Çavkanî]]. // Picking a şablon here immediately switches the row to // "Bi destê xwe binivîsim" mode with {{Şablon}} pre-filled, var catWrap = $("<span></span>").addClass("wiktku-native-select-wrap wiktku-dfn-quote-src-cat"); var catInput = $("<input type='search' autocomplete='off'>") .addClass("wiktku-start-narrow wiktku-dfn-quote-src-cat-input") .attr("placeholder", "Li navê şablonê bigere…"); var catResults = $("<ul></ul>").addClass("wiktku-ac-results wiktku-dfn-quote-src-cat-results").hide(); var catStatus = $("<span></span>").addClass("wiktku-dfn-quote-src-cat-status").text("Şablon tên barkirin…"); var showCatResults = function (query) { var q = $.trim(query).toLowerCase(); catResults.empty(); var list = catSrcTemplates || []; var matched = q ? $.grep(list, function (name) { return name.toLowerCase().indexOf(q) !== -1; }) : list; if (!matched.length) { catResults.hide(); return; } $.each(matched.slice(0, 50), function (_, name) { var li = $("<li></li>").text(name).attr("data-value", name); var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; e.preventDefault(); selectCatTpl(name); }); li.on("mousedown", function (e) { e.preventDefault(); selectCatTpl(name); }); catResults.append(li); }); catResults.show(); }; // Wraps the chosen şablon as {{Name}}, drops it into the // manual textarea, and switches the row into manual mode // so the user can keep editing it (add params, etc.). var selectCatTpl = function (name) { catResults.hide(); srcSel.val("__manual__"); srcSel.trigger("change"); srcFields.find(".wiktku-dfn-quote-src-manual") .val("{{" + name + "}}") .trigger("focus"); }; catInput.on("input", function () { showCatResults($(this).val()); }); catInput.on("focus", function () { showCatResults($(this).val()); }); catInput.on("blur", function () { setTimeout(function () { catResults.hide(); }, 200); }); catWrap.append(catInput).append(catResults).append(catStatus); srcFields.append(catWrap); fetchCatSrcTemplates().then(function () { catStatus.text(""); }, function () { catStatus.text("Şablon nehatin barkirin."); }); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (key, label) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", key) .attr("placeholder", label + "…"); // "Sernav" / "Sernavê orjînal" (title fields, e.g. for // kitêb/kovar/malper) get a taller, draggable box; every // other field in the template stays as-is. Field labels // come from the on-wiki jederDefs data, so match on the // (diacritic-folded) label text rather than a fixed key. var foldedLabel = foldDiacritics(label); if (/^sernav$/.test(foldedLabel) || /orjin/.test(foldedLabel)) { inp.addClass("wiktku-dfn-quote-src-input--title"); } row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); jederGroupDiv.append(jederLbl).append(jederList); // Straight after Nimûne rather than last: Jêgirtin is the // same kind of thing (an attested use of the word) and the // two belong together — see the allGroups comment above. var nimuneGroup = block.find(".wiktku-dfn-nimune-group"); if (nimuneGroup.length) jederGroupDiv.insertAfter(nimuneGroup); else block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); // ── "Malûmatên pêşketî" — per sense, after Dijmane ─────── // One toggle per sense rather than one for the whole step: // the fields behind it (Etîket, Kategorî, Jornav…) belong to // a single meaning, so a global switch flipped them for every // sense at once and gave a count that answered "across all // senses" — not a question anybody was asking. (function () { block.addClass("wiktku-sense-adv-hidden"); var advRow = $("<div class='wiktku-adv-toggle-row wiktku-sense-adv-row'></div>"); var advToggle = $("<a href='#' class='wiktku-adv-toggle'></a>").attr("aria-expanded", "false"); var advLabel = $("<span class='wiktku-adv-toggle-text'></span>"); advToggle.append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")).append(advLabel); function syncAdv() { var hidden = block.hasClass("wiktku-sense-adv-hidden"); advLabel.text(hidden ? "Malûmatên pêşketî nîşan bide" : "Malûmatên pêşketî veşêre"); advToggle.attr("aria-expanded", hidden ? "false" : "true") .toggleClass("wiktku-adv-open", !hidden); } advToggle.on("click", function (e) { e.preventDefault(); block.toggleClass("wiktku-sense-adv-hidden"); syncAdv(); }); block.data("syncSenseAdv", syncAdv); advRow.append(advToggle); // After the last always-visible group (Dijmane) and before // the advanced ones, which sit below it in DOM order. var lastPrimary = block.find(".wiktku-dfn-dijmane-group"); if (lastPrimary.length) advRow.insertAfter(lastPrimary); else block.append(advRow); syncAdv(); }()); // ── Accordion wrapper ───────────────────────────────────── // Everything built above becomes the collapsible body, and a // header row goes in front of it. Done here, at the end, // rather than by threading a container through the ~500 lines // of field-building above — every one of those appends to // `block`, and getSenses/restoreDfn reach fields with .find(), // which doesn't care how deep they sit. var body = $("<div class='wiktku-dfn-sense-body'></div>").append(block.children()); var header = $("<div class='wiktku-dfn-sense-header'></div>"); header .append($("<span class='wiktku-dfn-sense-num'></span>")) .append($("<span class='wiktku-dfn-sense-title'></span>")) .append($("<span class='wiktku-dfn-sense-summary'></span>")) .append($("<span class='wiktku-dfn-sense-chevron'>▾</span>")); header.on("click", function () { // Collapsed → open it (and close whichever was open). // Open → collapse it, unless it's the only one. if (block.hasClass("wiktku-sense-collapsed")) steps.dfn.setOpenSense(stepDiv, block); else block.addClass("wiktku-sense-collapsed"); steps.dfn.syncSenseHeaders(stepDiv); }); block.append(header).append(body); // Typing (or clicking) anywhere in a sense makes it the open // one — "tenê maneya ku tê nivîsandin vekirî ye". body.on("focusin", function () { if (!block.hasClass("wiktku-sense-collapsed")) { steps.dfn.setOpenSense(stepDiv, block); } }); return block; }, /** True if a sense block has anything worth summarising. */ senseBlockHasContent: function (block) { var found = false; block.find("textarea, input[type='text']").each(function () { if ($.trim($(this).val() || "")) { found = true; return false; } }); if (found) return true; return !!block.find(".wiktku-dfn-tpl-select").val(); }, /** Opens `block` and collapses every other sense that has content. * A sense with nothing in it is never collapsed — the trailing * empty one is how you add the next meaning, so hiding it would * hide the only way forward. */ setOpenSense: function (stepDiv, block) { stepDiv.find("li.wiktku-dfn-sense").each(function () { var li = $(this); var collapse = !li.is(block) && steps.dfn.senseBlockHasContent(li); li.toggleClass("wiktku-sense-collapsed", collapse); }); steps.dfn.syncSenseHeaders(stepDiv); }, /** Renumbers the sense badges and refreshes each collapsed row's * one-line summary. Cheap enough to just re-run on any change. */ syncSenseHeaders: function (stepDiv) { stepDiv.find("li.wiktku-dfn-sense").each(function (i) { var li = $(this); li.find("> .wiktku-dfn-sense-header .wiktku-dfn-sense-num").text(i + 1); li.find("> .wiktku-dfn-sense-header .wiktku-dfn-sense-title").text("Mane " + (i + 1)); var summary = $.trim(li.find("textarea.wiktku-dfn-mane").first().val() || ""); if (!summary) { // A template sense has no prose — show the call itself. var tpl = li.find(".wiktku-dfn-tpl-select").val(); var title = $.trim(li.find(".wiktku-dfn-tpl-title").val() || ""); if (tpl) summary = "{{" + tpl + (title ? "|" + title : "") + "}}"; } summary = summary.split("\n")[0]; if (summary.length > 70) summary = summary.slice(0, 70) + "…"; li.find("> .wiktku-dfn-sense-header .wiktku-dfn-sense-summary").text(summary); }); }, /** Keeps the header summary in step with what is being typed. * No longer grows the list: a second sense appears only when * "+ Mane zêde bike" is clicked. Auto-growing meant every entry * with one meaning still showed an empty second one, which reads * as an unfinished form. */ onDfnInput: function (stepDiv, block, textarea) { steps.dfn.syncSenseHeaders(stepDiv); refresh(); }, /** Appends a sense, opens it, and collapses the others. */ addSense: function (stepDiv) { var list = stepDiv.find("ol.wiktku-dfn-list"); var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); initSelects(newBlock); steps.dfn.setOpenSense(stepDiv, newBlock); newBlock.find("textarea.wiktku-dfn-mane").first().focus(); refresh(); return newBlock; }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow, modifiers) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow, modifiers); }); list.append(modifiers ? makeModifierLi(next) : $("<li></li>").append(next)); // New field starts with no placeholder — give it (and any // others in the list) the current one. var updatePlaceholders = list.data("updatePlaceholders"); if (typeof updatePlaceholders === "function") updatePlaceholders(); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: {}, posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; // One reassurance, shown once for the whole Mane step: the // "an jî şablonek hilbijêre" dropdown inside each sense is // optional — plain text is the normal path. if (!stepDiv.find(".wiktku-dfn-tpl-hint").length) { stepDiv.append( $("<p class='wiktku-step-hint wiktku-dfn-tpl-hint'></p>").text( "Ji bo her maneyekê, dropdown-a \"an jî şablonek hilbijêre\" ne mecbûrî ye — bi gelemperî tu tenê maneyê bi tîpên asayî dinivîsî. Ew şablon tenê ji bo rewşên taybet in (mînak: guherto, kevnbûyî, şaşnivîs); heke tu nizanî kîjan divê, vale bihêle." ) ); } var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); var addSenseBtn = $("<button type='button' class='wiktku-add-sense'></button>") .append($("<span class='wiktku-add-sense-plus'>+</span>")) .append(document.createTextNode("Mane zêde bike")); addSenseBtn.on("click", function (e) { e.preventDefault(); steps.dfn.addSense(stepDiv); }); stepDiv.append(addSenseBtn); steps.dfn.syncSenseHeaders(stepDiv); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName === "__category__") { // Reachable only if the user opened the category search but // never picked a şablon — picking one switches the row to // __manual__ (see selectCatTpl above), so there's nothing // meaningful to save here. } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: readList("wiktku-dfn-etiket"), kategori: readList("wiktku-dfn-kategori"), nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense var izahLines = []; // parallel — raw îzah gloss for that same sense // True only once some sense's *actual* dfn text (post tercime/îzah // split) is non-empty. var hasLinkableMane = false; $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("# " + (tplKatTpl ? tplKatTpl + " " : "") + (tplLabelTpl ? tplLabelTpl + " " : "") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(""); // template senses have no îzah return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty // Pull the îzah gloss (if any) out of the combined tercime+îzah // string — it's spliced back in separately below, after its // own linkify pass (see izahLines / the second linkifyText call). var izahRaw = null; var tercimeIzah = splitTercimeIzah(dfn); if (tercimeIzah) { dfn = tercimeIzah.tercime; izahRaw = stripWikilinks(tercimeIzah.izah); } if (dfn) { dfn = stripWikilinks(dfn); // Sentence-case + trailing period are for ku definitions, // which are written as full glosses. if (lang === "ku") { if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } // Real prose — this is what makes the sense worth running // through the main linkify pass. hasLinkableMane = true; } else if (izahRaw === null) { // No mane at all — this is just the "{{mane?|lang}}" // placeholder, a bare template call with no plain words // in it. Do NOT count it as linkable: sending nothing but // bracketed templates through the main linkify pass hangs // the linkify gadget (see the hasLinkableMane/hasIzah // check below). dfn = lang === "ku" ? "{{mane?|" + lang + "}}" : ""; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var out = "# " + (katTpl ? katTpl + " " : "") + (labelTpl ? labelTpl + " " : "") + dfn; var idx = defLines.length; var hasThisIzah = izahRaw !== null && $.trim(izahRaw) !== ""; // Bare {{...}} token — like {{wiktku-cite-N}}, this survives // linkify's first pass untouched (it treats template calls as // opaque), then gets swapped for {{îzah|…}} once the actual // gloss text has been linkified in its own separate pass. if (hasThisIzah) { out += (dfn ? " " : "") + "{{wiktku-izah-" + idx + "}}"; } function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(hasThisIzah ? izahRaw : ""); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } // Runs text through the linkify gadget if it's loaded, otherwise // just passes it through unchanged. Shared by both linkify passes // below (main mane text, and — separately — îzah glosses). function linkifyText(t, cb) { if (typeof $.kuLinkify === "function") { $.kuLinkify(t, cb); } else { cb(t); } } var hasIzah = izahLines.some(function (t) { return t && $.trim(t) !== ""; }); var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with nimûne?. text = "# {{mane?|" + lang + "}}\n#* {{nimûne?|" + lang + "}}\n"; callback(text); return; } // Runs the îzah-only linkify pass against `base` (either the raw // text, when there's no linkable mane to run the main pass on // first, or the already-linkified main text). Shared by both // branches below so the token-splice logic only lives once. function runIzahPass(base) { var izahJoined = $.map(izahLines, function (raw, idx) { if (!raw) return undefined; return "{{wiktku-izah-open-" + idx + "}}" + raw + "{{wiktku-izah-close-" + idx + "}}"; }).join("\n"); linkifyText(izahJoined, function (izahLinked) { var izahByIdx = {}; var re = /\{\{wiktku-izah-open-(\d+)\}\}([\s\S]*?)\{\{wiktku-izah-close-\1\}\}/g; var m; while ((m = re.exec(izahLinked)) !== null) { izahByIdx[parseInt(m[1], 10)] = m[2]; } var withIzah = base.replace(/\{\{wiktku-izah-(\d+)\}\}/g, function (_, n) { var linked = izahByIdx[parseInt(n, 10)]; return linked !== undefined ? "{{îzah|" + linked + "}}" : ""; }); callback(restoreCites(withIzah)); }); } if (!hasLinkableMane) { if (!hasIzah) { // All filled senses are template senses (or otherwise have // no plain text at all) — nothing here needs linkify. callback(restoreCites(text)); return; } // There's no plain mane text anywhere (e.g. tercime left blank // with only îzah filled in), so every defLine is just a bare // template call with nothing to word-link. Sending a line // like "# {{wiktku-izah-0}}" through the main linkify pass // gives it no plain words to work with, makes the linkify // gadget hang — so skip that pass entirely and run only // the îzah pass, splicing straight into the unlinkified text. var loadIzahOnly = function () { runIzahPass(text); }; mw.loader.using("ext.gadget.linkify", loadIzahOnly, loadIzahOnly); return; } var didTryToLoad = function () { // First pass: the main definition text (mane), same as before. linkifyText(text, function (mainLinked) { if (!hasIzah) { callback(restoreCites(mainLinked)); return; } // Second pass: îzah glosses, linkified via their own // separate call. Each gloss is wrapped in its own // {{wiktku-izah-open/close-N}} pair; like the existing // {{wiktku-cite-N}} tokens, these sit inside double // braces so linkify leaves the tokens themselves alone — // only the raw gloss text between each pair gets linked. runIzahPass(mainLinked); }); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, tewandin: { id: "tewandin", name: "tewandin", question_fmt: 'Tewandina "' + pageName + '" binivîse', visible: function (values) { return values.lang && values.pos; }, build: function (stepDiv) { if (stepDiv.find(".wiktku-tewandin-wrap").length) return null; var wrap = $("<div class='wiktku-tewandin-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-tewandin-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-tewandin-text") .attr("rows", 4) .attr("placeholder", "{{ku-tewîn-nav|nêr}}"); wrap.append(ta); stepDiv.append(wrap); function autoPopulate() { if (!ta.length) return; var vals = getValues(); var c = vals.cinsiyet || ""; var p = vals.pos || ""; if (!pageName.includes(" ") && c && GENDER_BASE_LABELS[c] && (p === "navdêr" || p === "serenav") && vals.lang === "ku" && c !== "mndudil") { var label = (c === "mnmane") ? "mê û nêr" : GENDER_BASE_LABELS[c]; var out = "{{ku-tewîn-nav|" + label; if (p === "serenav") out += "|y"; out += "}}"; if (!$.trim(ta.val())) ta.val(out); } } setTimeout(function () { autoPopulate(); $("#wiktku-start-form").on("change.tewandin", "#wiktku-start-lang-field, #wiktku-start-cinsiyet-field, #wiktku-start-pos-field", autoPopulate); }, 0); return ta; }, output: function () { var manualText = $.trim($("#wiktku-start-tewandin .wiktku-tewandin-text").val()); if (manualText) { return "\n==== Tewandin ====\n" + manualText + "\n"; } return ""; } }, // resim — one or more images resim: { id: "resim", name: "resim", question_fmt: "Resmekê lê zêde bike", visible: function (values) { return !!(values.lang && values.pos); }, /** Builds one image row: filename + caption + alt text. */ buildItem: function (stepDiv) { var item = $("<li class='wiktku-resim-item'></li>"); var fileRow = $("<div class='wiktku-posparams-row'></div>"); var fileInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-file") .attr("placeholder", "navê_dosyayê.jpg"); fileRow.append($("<label></label>").text("Navê dosyayê: ")).append(fileInp); var capRow = $("<div class='wiktku-posparams-row'></div>"); var capInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-caption") .attr("placeholder", "Danasîna resimê…"); capRow.append($("<label></label>").text("Danasîn: ")).append(capInp); // Alt text: what a screen reader announces for this image var altRow = $("<div class='wiktku-posparams-row'></div>"); var altInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-alt") .attr("placeholder", "Ji bo kesên nabînin, çi tê dîtin? (ne mecbûrî)"); altRow.append($("<label></label>").text("Nivîsa alternatîf: ")).append(altInp); // Auto-fill the caption with the plain page name when a filename // is typed fileInp.on("input", function () { var file = $.trim($(this).val()); var curCap = $.trim(capInp.val()); var isDefault = !curCap || curCap === pageName; if (file && isDefault) { capInp.val(pageName); } else if (!file && isDefault) { capInp.val(""); } steps.resim.onFileInput(stepDiv, item, this); }); item.append(fileRow).append(capRow).append(altRow); return item; }, /** Grows the image list when the last row's filename gets content. */ onFileInput: function (stepDiv, item, input) { var val = $.trim($(input).val()); var list = stepDiv.find("ol.wiktku-resim-list"); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { list.append(steps.resim.buildItem(stepDiv)); } }, build: function (stepDiv) { if (stepDiv.find(".wiktku-resim-wrap").length) return null; var wrap = $("<div class='wiktku-resim-wrap'></div>"); var list = $("<ol class='wiktku-resim-list'></ol>"); list.append(steps.resim.buildItem(stepDiv)); wrap.append(list); stepDiv.append(wrap); return null; }, /** Reads every filled row from the DOM into an array of {file, caption, alt} * objects — blank rows (missing filename or caption) are skipped. * Non-Kurdish captions get wrapped in {{zim|lang|…}} here, unless * the user already typed their own {{zim|…}} template. Alt text is * optional and left as plain text either way. */ getImages: function (values) { var lang = (values && values.lang) || getValues().lang || ""; var images = []; $("#wiktku-start-resim li.wiktku-resim-item").each(function () { var file = $.trim($(this).find(".wiktku-resim-file").val()); var caption = $.trim($(this).find(".wiktku-resim-caption").val()); var alt = $.trim($(this).find(".wiktku-resim-alt").val()); if (!file || !caption) return; // Strip leading "Wêne:" or "File:" if the user typed it — we add it ourselves. file = file.replace(/^(wêne|file|image)\s*:\s*/i, ""); if (lang && lang !== "ku" && !/^\{\{zim\s*\|/i.test(caption)) { caption = "{{zim|" + lang + "|" + caption + "}}"; } images.push({ file: file, caption: caption, alt: alt }); }); return images; }, output: function (values) { var images = steps.resim.getImages(values); if (!images.length) return ""; return images.map(function (img) { var altPart = img.alt ? "|alt=" + img.alt : ""; return "[[Wêne:" + img.file + "|thumb" + altPart + "|" + img.caption + "]]"; }).join("\n") + "\n"; } }, // bnr-h — {{bnr-h|Page1|Page2|…}} prepended before the lang section (shared, not per-section) bnrh: { id: "bnrh", name: "binêre herwiha (bnr-h)", question_fmt: "Şablona bnr-h li qismê herî jor a rûpelê", //visible: function (values) { return !!values.lang; }, multiple: true, narrow: true, placeholder: "Ji bo 'test' bnr 'Test', 'teşt'", output: function (values) { var pages = $.grep(values.bnrh || [], function (p) { return !!$.trim(p); }); if (!pages.length) return ""; return "{{bnr-h|" + pages.map(function (p) { return $.trim(p); }).join("|") + "}}\n"; } }, bikaranin: { id: "bikaranin", name: "Notên bikaranînê", question_fmt: "Notên bikaranînê yên li ser vê kelîmeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, output: function (values) { var text = $.trim(values.bikaranin || ""); if (!text) return ""; return "\n==== Notên bikaranînê ====\n" + text + "\n"; }, }, xwendin: { id: "xwendin", name: "Bêhtir bixwîne", question_fmt: "Lînkên derveyî eleqedarî vê madeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: function (values) { if (!values || !values.lang) { return `* {{wpedî}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; } const ziman = values.lang === "ku" ? "" : `|ziman=${values.lang}`; return `* {{wpedî${ziman}}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; }, output: function (values) { var text = $.trim(values.xwendin || ""); if (!text) return ""; return "\n==== Bêhtir bixwîne ====\n" + text + "\n"; }, }, alfabeyendin: { id: "alfabeyendin", name: "Bi alfabeyên din", question_fmt: function (values) { var base = "Nivîsîna vê kelîmeyê bi alfabeyên din" var langLabel = values.lang ? getLangLabel(values.lang) : ""; if (langLabel) { return base + " ên " + langLabel; } return base; }, visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: "Ji bo kurmancî: * {{ku-ar|şiklê alfaba erebî}}", output: function (values) { var text = $.trim(values.alfabeyendin || ""); if (!text) return ""; return "\n==== Bi alfabeyên din ====\n" + text + "\n"; }, }, formalt: makeWordListStep("formalt", "formên alternatîv", "Formên alternatîv ên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), hevmane: makeWordListStep("hevmane", "hevmane", "Hevmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), dijmane: makeWordListStep("dijmane", "dijmane", "Dijmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jornav: makeWordListStep("jornav", "jornav", "Jornavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jernav: makeWordListStep("jernav", "jêrnav", "Jêrnavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse"), binereherwiha: makeWordListStep("binereherwiha", "herwiha binêre", "Kelîmeyên din ên eleqedar binivîse"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: {}, visible: function (values) { return values.lang && values.pos; }, // Fills the insert-dropdown from the current etymTpls object. refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(ta); stepDiv.append(wrap); initSelects(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder. // Skip it only when every filled sense is a şablon sense // a completely empty entry with no şablon chosen still gets the placeholder var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasFilledTplSense = dfnSenses.some(function (s) { return !!s.tpl && !!s.tplTitle; }); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (hasFilledTplSense && !hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: function (values) { return {"navz": true, [values.lang]: true} }, // Language dropdown + growing word-input list; a new row appends // when the dropdown gets a value. Mirrors steps.trans, but flat. buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/build below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Attach the searchable picker now the select is in the DOM. initSelects(list); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", question_fmt: "'"+ pageName + "' di zaravayên din de çawa tê gotin?", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: {}, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zaravayekî bigere"); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; // A completely empty entry still gets a placeholder section // to fill in later; an individual placeholder gloss is only // skipped once some other sense already has real content. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", question_fmt: "Tercimeyên vê maneyê bi zimanên din binivîse", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide only when every sense is a filled template sense (no plain // gloss to attach translations to). A mix, or nothing filled in // yet, still shows Werger. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, // Language dropdown + growing word-input list, scoped to one gloss's // group (each gloss has its own group and row list). buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/buildGroup below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, // Builds (or fetches) the .wiktku-trans-group for one gloss. buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, // Syncs one .wiktku-trans-group per current gloss, keyed by // data-gloss-pos so groups stay matched across rebuilds. build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, // Reads all translation rows, grouped by gloss position. getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, // Builds the numbered "{ index, gloss }" list, one per dfn sense // with a real mane (skips template senses). index is 1-based and // matches the sense's position in the "#" definition list. // When nothing's filled in, returns one placeholder entry so // Werger still has a group to attach to; when every sense is a // filled template sense, stays empty (matches trans.visible()). glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane, but other fields are filled — still gets a // gloss group since dfn.getOutput() emits {{mane?}} for it. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // A completely empty entry (nothing filled in dfn at all, no // şablon chosen either) still gets a placeholder Werger section // to fill in later. Only // skip an individual placeholder gloss below when some other // sense actually has real content, making that particular // placeholder redundant. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it. If some other sense already has real // content, this placeholder is redundant — skip it. If the // whole entry is empty, keep it so Werger still gets a // section to fill in. if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, cavkani: { id: "cavkani", name: "çavkanî", question_fmt: "Çavkaniyên din (ne jêgirtin) lê zêde bike", visible: function (values) { return !!values.pos; }, // Fills the insert-dropdown from the members of [[Kategorî:Çavkanî]]. refreshTplSelect: function () { var sel = $("#wiktku-start-cavkani .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(catSrcTemplates || [], function (_, name) { sel.append($("<option></option>").val(name).text(name)); }); markTemplateOptions(sel, function (opt) { return opt.val(); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-cavkani-wrap").length) return null; var wrap = $("<div class='wiktku-cavkani-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-cavkani-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-cavkani-text") .attr("rows", 4) .attr("placeholder", "Şablonekî ji lîsteyê hilbijêre an rasterast binivîse…"); // Template insert dropdown, populated from [[Kategorî:Çavkanî]] — // options refreshed once the category members are fetched. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var status = $("<span class='wiktku-cavkani-status'></span>"); sel.on("change", function () { var name = $(this).val(); if (!name) return; insertAtCursor(ta[0], "\n* {{" + name + "}}"); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(status).append(ta); stepDiv.append(wrap); // build() runs again for every new beş (see the "+ Beş zêde bike" // handler), after the initial page-wide pass — so this select needs // its own init or it stays a plain, unsearchable native <select>. initSelects(wrap); if (catSrcTemplates) { steps.cavkani.refreshTplSelect(); } else { status.text("Şablon tên barkirin…"); fetchCatSrcTemplates().then(function () { steps.cavkani.refreshTplSelect(); status.text(""); }, function () { status.text("Şablon nehatin barkirin."); }); } return ta; }, output: function () { var text = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); if (!text) return ""; return "\n==== Çavkanî ====\n" + text + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); // This array only controls DOM build order — nothing else keys off it // (see the comment above stepIdToGroup). Mane tab order: Mane (senses, // with malûmatên pêşketî nested inside each, see steps.dfn.build) → // Wêne → Bi zaravayên din → Werger, so dfn/resim/zarava/trans sit // adjacent to each other in that order. var ordered_steps = [ steps.lang, steps.pos, steps.posparams, steps.cinsiyet, steps.jimar, steps.lektur, steps.tr, // Mane tab, in reading order: the senses, then the two things that // belong to the entry as a whole rather than to one sense. steps.dfn, steps.tewandin, steps.alfabeyendin, steps.zarava, steps.trans, // Etîmolojî tab. steps.etym, steps.dunde, // Eleqedar tab — three lists of the same shape. steps.je, steps.tekildar, steps.binereherwiha, // Bilêvkirin isn't part of any STEP_GROUPS tab, but still needs a // slot here because this array is what builds the DOM. steps.pron, // Beşên din, behind the picker. steps.resim, steps.bnrh, steps.bikaranin, steps.formalt, steps.hevmane, steps.dijmane, steps.jornav, steps.jernav, steps.cavkani, steps.xwendin]; // ── Step-group tabs ────────────────────────────────────────────────────── // Four tabs: "Mane" holds the senses (whose own blocks carry Nimûne, // Jêgirtin, Hevmane and Dijmane — see steps.dfn.allGroups), Tewandin, // alfabeyendin, zarava and trans; "Etîmolojî" and "Eleqedar" split out // the two other topical clusters; everything else lives behind the // "Beşên din" picker. "mane" stays first as the default-active tab // since Mane is required content. Tewandin keeps its own free-text // {{ku-tewîn-nav}} field and does NOT absorb the Cins/zayend form // parameters (m=/n=/p=), which stay on the headword template. var STEP_GROUPS = [ { id: "mane", label: "Mane", steps: ["dfn", "tewandin", "alfabeyendin", "zarava", "trans"] }, { id: "etimoloji", label: "Etîmolojî", steps: ["etym", "dunde"] }, { id: "eleqedar", label: "Eleqedar", steps: ["je", "tekildar", "binereherwiha"] }, { id: "besendin", label: "Beşên din", steps: ["resim", "formalt", "hevmane", "dijmane", "jornav", "jernav", "bikaranin", "cavkani", "xwendin", "bnrh"] }, ]; // Steps that live behind the "Beşên din" picker — only these need an // explicit "open" before they're shown, even when their tab is active. // Derived from the group above so it can't drift out of sync. var BESENDIN_STEP_IDS = STEP_GROUPS[3].steps; // Reverse lookup: step id -> index into STEP_GROUPS (undefined for // ungrouped steps — now only lang/pos/posparams/cinsiyet/lektur/tr, // which stay always-visible since they're required to get to everything // else). var stepIdToGroup = {}; $.each(STEP_GROUPS, function (gi, g) { $.each(g.steps, function (_, sid) { stepIdToGroup[sid] = gi; }); }); // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "posparams", "cinsiyet", "jimar", "lektur", "tr", "resim", "dfn", "tewandin", "formalt", "bikaranin", "alfabeyendin", "hevmane", "dijmane", "jornav", "jernav", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans", "cavkani", "xwendin" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; // ── Bilêvkirin as a standalone section ─────────────────────────────── // Pronunciation belongs to the word, not to one part of speech, so it // sits beside Navdêr/Lêker in the tab bar rather than inside any of them. // Modelled as a flag rather than an entry in `sections` since // activeSection is used as an array index in many places — viewing // Bilêvkirin leaves activeSection pointing at the POS section you were on. var viewingPron = false; // is it the tab currently on screen // Which STEP_GROUPS tab is currently shown. Lives out here (like // activeSection above) so refresh() — which is not nested inside build() // — can read it and so renderGroupTabs()/updateGroupTabIndicators() below // can be called from refresh() too. Both operate on the tab bar via its // #wiktku-group-tabs id rather than a closured element reference, for the // same reason. var activeGroup = 0; // Unsaved-changes / autosave state. Lives out here (same reason as // activeGroup above) so destroy() — which runs on final submit and on // switching to the source editor, and is not nested inside build() — // can clear the timers and the beforeunload warning. build() assigns // into these; it doesn't re-declare them. var formDirty = false; var autosaveDebounceTimer = null; var autosaveInterval = null; /** Re-renders the step-group tab bar to reflect the current activeGroup. */ function renderGroupTabs() { var groupTabsDiv = $("#wiktku-group-tabs"); if (!groupTabsDiv.length) return; groupTabsDiv.empty(); $.each(STEP_GROUPS, function (i, g) { var tab = $("<span></span>") .addClass("wiktku-group-tab") .attr("data-group-idx", i) .text(g.label) .toggleClass("wiktku-tab-active", i === activeGroup); (function (idx) { tab.on("click", function () { if (idx === activeGroup) return; activeGroup = idx; renderGroupTabs(); if (idx === BESENDIN_GROUP_IDX) renderBesenDinPicker(); refresh(); }); }(i)); groupTabsDiv.append(tab); }); } /** * Toggles a "needs attention" dot on any group tab that still has a * required, unfilled field hidden inside it — so switching tabs doesn't * leave the person wondering why "Bişîne" stays disabled. */ function updateGroupTabIndicators(values) { var tabs = $("#wiktku-group-tabs .wiktku-group-tab"); if (!tabs.length) return; $.each(STEP_GROUPS, function (i, g) { var missing = false; $.each(g.steps, function (_, sid) { var step = steps[sid]; if (!step || !step.required) return; var val = values[sid]; if (val === "" || (step.multiple && $.isArray(val) && val.join("") === "")) { missing = true; } }); tabs.eq(i).toggleClass("wiktku-tab-missing", missing && i !== activeGroup); }); } // "Beşên din" reveals one field at a time via a picker rather than // stacking them all. Per-section state, snapshotted in // saveCurrentSection() and restored in restoreSection() below, and // auto-seeded from any field that already has content (so a returning // draft doesn't hide something already filled in). var openedOtherSections = {}; var BESENDIN_SET = {}; $.each(BESENDIN_STEP_IDS, function (_, sid) { BESENDIN_SET[sid] = true; }); // "besendin"'s index in STEP_GROUPS. Derived rather than hardcoded — // this was a literal 2 and silently pointed at the wrong tab the moment // Etîmolojî and Eleqedar were inserted ahead of it. var BESENDIN_GROUP_IDX = (function () { for (var i = 0; i < STEP_GROUPS.length; i++) { if (STEP_GROUPS[i].id === "besendin") return i; } return STEP_GROUPS.length - 1; }()); /** Re-renders the "Beşên din" picker to list only the not-yet-opened sections. */ function renderBesenDinPicker() { var wrap = $("#wiktku-besendin-picker"); if (!wrap.length) return; wrap.empty(); var pickerValues = getValues(); var unopened = $.grep(BESENDIN_STEP_IDS, function (sid) { if (openedOtherSections[sid]) return false; // Don't offer a section that would open onto nothing: several of // these are gated (Bi zaravayên din / Werger need lang=ku, most // need a pos). refresh() would hide it again straight away, so // picking it would read as a broken dropdown. var step = steps[sid]; if (step && typeof step.visible === "function") { try { if (!step.visible(pickerValues)) return false; } catch (e) { /* a step whose visible() needs DOM we lack yet — offer it */ } } return true; }); if (!unopened.length) return; // everything's open — nothing left to pick var sel = $("<select class='wiktku-besendin-select'></select>"); sel.attr("data-placeholder", "— beşek hilbijêre —"); sel.append($("<option value=''>— beşek hilbijêre —</option>")); $.each(unopened, function (_, sid) { var step = steps[sid]; if (!step) return; sel.append($("<option></option>").val(sid).text(capitalize(step.name))); }); sel.on("change", function () { var sid = $(this).val(); if (!sid) return; openedOtherSections[sid] = true; // Newly opened section moves right under the picker, ahead of // whatever's already open, instead of wherever it happened to // sit in the fixed step order. $("#wiktku-start-" + sid).insertAfter(wrap); renderBesenDinPicker(); refresh(); }); wrap.append(sel); initSelects(wrap); } /** Marks any BESENDIN_STEP_IDS field that already has real content as * "opened", so restoring a draft doesn't bury filled-in sections behind * the picker. Reuses each step's own output() as the emptiness check — * it already knows what "empty" means per field, and it reads the DOM * the restore just populated. Call this AFTER the DOM has the restored * values in it. */ function seedOpenedFromContent() { var values = getValues(); $.each(BESENDIN_STEP_IDS, function (_, sid) { if (openedOtherSections[sid]) return; var step = steps[sid]; if (!step || typeof step.output !== "function") return; try { if (step.output(values)) openedOtherSections[sid] = true; } catch (e) { /* a step whose output() needs more state than we have yet — skip it */ } }); } function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } // Rebuilds the dfn DOM from a previously snapshotted senses array. function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. The // "+ Mane zêde bike" button goes with it — build() re-appends both, // and leaving the old one behind would both duplicate it and put it // above the rebuilt list. stepDiv.find("ol.wiktku-dfn-list").remove(); stepDiv.find(".wiktku-add-sense").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); // The picker is collapsed behind a link by default; a restored // sense that already uses a template has to show it, or the // chosen template is invisible and looks lost. var reveal = block.data("revealTplRow"); if (typeof reveal === "function") reveal(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // dfnArea is the only thing actually saved, so split it back into // tercime/îzah for editing (mirrors syncNonKuToMane's join format). var maneParts = splitTercimeIzah(sense.mane); block.find(".wiktku-dfn-tercime").val(maneParts ? maneParts.tercime : (sense.mane || "")); block.find(".wiktku-dfn-izah").val(maneParts ? maneParts.izah : ""); // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Same for the mane-box mode (plain vs tercime+îzah), since this // also depends on tplSelect's (and lang's) value. var updateMane = block.data("updateManeMode"); if (updateMane) updateMane(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found var useModifiers = !!MODIFIER_SUBGROUPS[cls]; // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true, useModifiers); }); subList.append(useModifiers ? makeModifierLi(ta) : $("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text).each(function () { highlightLinebreak(this); }); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder entries — accepts current array shape or a legacy // single object (older saved sections) for backwards compat. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote).each(function () { highlightLinebreak(this); }); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederCatTpl) { // Legacy format from before the şablon search switched rows to // manual mode directly — convert it the same way now, so it's // editable like any other free-form source. var catSelEl = li.find(".wiktku-dfn-quote-src-sel"); catSelEl.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val("{{" + j.jederCatTpl + "}}"); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); // Numbers and one-line summaries for the freshly rebuilt blocks, and // collapse everything that has content — on a restored draft nothing // is "the sense being edited" yet, so a five-sense entry would // otherwise come back fully expanded, which is the state this // accordion exists to avoid. steps.dfn.syncSenseHeaders(stepDiv); stepDiv.find("li.wiktku-dfn-sense").each(function () { var li = $(this); li.toggleClass("wiktku-sense-collapsed", steps.dfn.senseBlockHasContent(li)); }); } // Snapshots simple (non-dfn) per-section steps from the DOM into obj. function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } if (id === "cavkani") { snap.cavkani = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); return; } if (id === "posparams") { snap.posparams = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); return; } if (id === "resim") { // One entry per row, including blank ones, so a mid-edit draft // (e.g. a filename typed but no caption yet) survives a cache // restore instead of being silently dropped. snap.resim = $("#wiktku-start-resim li.wiktku-resim-item").map(function () { return { file: $.trim($(this).find(".wiktku-resim-file").val()), caption: $.trim($(this).find(".wiktku-resim-caption").val()), alt: $.trim($(this).find(".wiktku-resim-alt").val()) }; }).get(); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); // Which "Beşên din" sub-sections this section has already opened // via the picker — per-section, like everything else here. snap.openedOtherSections = $.extend({}, openedOtherSections); sections[activeSection] = snap; } // Restores a previously saved snapshot into the form DOM. function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); $("#wiktku-start-cavkani .wiktku-cavkani-text").val(snap.cavkani || ""); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); steps.posparams.build(ppDiv); var savedTa = snap.posparams || ""; ppDiv.find(".wiktku-posparams-text").val(savedTa); // Re-parse saved textarea to restore helper widget states. if (savedTa) { var cMatch = savedTa.match(/\|c=([^|}\s]+)/); var jMatch = savedTa.match(/\|j=([^|}\s]+)/); var trMatch = savedTa.match(/\|tr=([^|}\s]+)/); // Write into the shared hidden field (not the visible // select, which has no <option>s yet) — syncHelpers() // below reads it back to restore the dropdown once the // gender/number options for this language are populated. if (cMatch) $("#wiktku-start-cinsiyet-field").val(cMatch[1]); if (jMatch) $("#wiktku-start-jimar-field").val(jMatch[1]); if (trMatch) ppDiv.find(".wiktku-posparams-field[data-pp-key='tr']").val(trMatch[1]); // For lêker, c= holds the verb-type code instead of a // gender — split it back across the two dropdowns it is // now assembled from ("x-gh" → form "x" + base "gh"). if (cMatch && /^lêker/.test(snap.pos || "")) { var lekturParts = /^(?:([xphb])-)?(n?gh)$/.exec(cMatch[1]); if (lekturParts) { ppDiv.find(".wiktku-posparams-lektur-sel").val(lekturParts[2]); ppDiv.find(".wiktku-posparams-lekturform-sel").val(lekturParts[1] || ""); } } // Restore checked optional params. "form" is stored as // "erê" rather than "1" (see rebuildTa), so it needs its // own check here. ppDiv.find(".wiktku-posparams-opt-panel input[type='checkbox']").each(function () { var key = $(this).val(); var expected = key === "form" ? "erê" : "1"; $(this).prop("checked", savedTa.indexOf("|" + key + "=" + expected) !== -1); }); } steps.posparams.syncHelpers(ppDiv); return; } if (id === "resim") { var resimDiv = $("#wiktku-start-resim"); resimDiv.find(".wiktku-resim-wrap").remove(); steps.resim.build(resimDiv); // Accept both the new array-of-rows format and the older // single {file, caption} object saved before multi-image // support existed. var resimSnap = snap.resim; var rows = $.isArray(resimSnap) ? resimSnap : (resimSnap ? [resimSnap] : []); if (rows.length) { var list = resimDiv.find("ol.wiktku-resim-list"); list.empty(); $.each(rows, function (_, r) { var item = steps.resim.buildItem(resimDiv); item.find(".wiktku-resim-file").val(r.file || ""); item.find(".wiktku-resim-caption").val(r.caption || ""); item.find(".wiktku-resim-alt").val(r.alt || ""); list.append(item); }); // Always keep a blank trailing row, same as Nimûne/Dûnde. var lastItem = list.children("li.wiktku-resim-item").last(); if ($.trim(lastItem.find(".wiktku-resim-file").val())) { list.append(steps.resim.buildItem(resimDiv)); } } return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Tell the pickers about the programmatic value change. fields.filter("select").trigger("wiktku:refresh"); }); // Restore which "Beşên din" sub-sections were already opened for // this section, then seed in anything the DOM restore above just // filled in but that wasn't marked opened yet. openedOtherSections = $.extend({}, snap.openedOtherSections || {}); seedOpenedFromContent(); renderBesenDinPicker(); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); // Bilêvkirin is NOT emitted here — it is one shared field for the // whole word, so emitting it per section duplicated it. getWikitext() // prints it once, above the POS sections. steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.tewandin.output(values); entry += steps.bikaranin.output(values); entry += steps.alfabeyendin.output(values); entry += steps.formalt.output(values); entry += steps.hevmane.output(values); entry += steps.dijmane.output(values); entry += steps.jornav.output(values); entry += steps.jernav.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); entry += steps.cavkani.output(values); entry += steps.xwendin.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { // Each hop through here can be reached asynchronously: the dfn // step waits on mw.loader.using("ext.gadget.linkify") before // calling back, so from that point on the submit handler's own // try/catch is no longer on the stack. Guard every hop instead, // or a throw after linkify loads vanishes into an unhandled // rejection and the form just sits there looking busy. try { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } catch (e) { if (typeof onSubmitError === "function") onSubmitError(e); else throw e; } } processSection(0); } // Assembles wikitext for all sections plus the shared lang header. function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var bnrh = steps.bnrh.output(sharedValues); var entry = steps.lang.output(sharedValues); // One pronunciation per word, printed once between the language // header and the POS sections — see steps.pron.output. entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // bnr-h goes before the language section — only prepended when // generating fresh wikitext (not addLangMode, which handles it separately). if (!addLangMode && bnrh) entry = bnrh + entry; // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { if (s.mane) return s.mane; // Template sense (e.g. {{guharto|ku|somepage}}) — same // construction as the tplCall built in getOutput, so the // summary shows what actually gets written to the entry // instead of going blank. if (s.tpl && s.tplTitle) { return s.tplNoLang ? "{{" + s.tpl + "|" + s.tplTitle + "}}" : "{{" + s.tpl + "|" + sharedValues.lang + "|" + s.tplTitle + "}}"; } return ""; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; // Set by build() to its submitFailed(). Lives out here because the // wikitext-assembly functions below are outside build()'s closure but // still need a way to report a failure to the person rather than dying // silently in the console. var onSubmitError = null; // Whether Mane/Bi zaravayên din/Werger has anything in it — kept // outside refresh() so the click handler can read the latest value. var wiktkuContentGateOk = true; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues, placeholderText) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>").text(placeholderText || "")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice.label); if (choice.sortKey !== undefined) { // This is a language choice {code, label, sortKey} — show code. displayText = capitalize(choice.label) + " (" + choice.code + ")"; } var option = $(mw.html.element("option", { value: choice.code }, displayText)); if (disabledValues[choice.code]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } // Keys to disable for a key menu: already-taken or explicitly disabled. function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); populateMenus(input, step.keys, getDisabledKeys(step)); // Keep the key menus mutually exclusive: whatever one row selects is // disabled in every other row. Recomputed from the DOM on each change. input.on("change", function () { var all = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield"); var taken = {}; all.each(function () { var v = $(this).val(); if (v) taken[v] = true; }); all.not(this).each(function () { var self = $(this), own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (code) $(this).prop("disabled", !!taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }); // Return the wrapper; the select lives inside it and still fires change. return wrapNativeSelect(input); } // Adds another text field to the list if the last one now has text. function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); if (step.placeholder) { nextInput.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = step.modifiers ? makeModifierLi(nextInput).prepend(nextKeyInput || "") : $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) initSelects(nextItem); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } // Shows/hides steps based on whether their prerequisites are met, and // updates placeholders where applicable. function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); steps.cavkani.refreshTplSelect(); // Re-render any step's question label that depends on current values // (e.g. dfn's Werger-section reminder, which only applies to ku). $.each(steps, function (stepId, step) { if (typeof step.question_fmt === "function") { $("#wiktku-start-" + stepId + " .wiktku-start-step-question") .text(step.question_fmt(values)); } }); // Sync every sense block's mane-box mode (plain mane vs tercime+îzah) // to the current language, in case lang changes after blocks exist. $("#wiktku-start-dfn li.wiktku-dfn-sense").each(function () { var updateMane = $(this).data("updateManeMode"); if (updateMane) updateMane(); }); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Re-sync the "<label> bi <ziman>…" placeholder on every always-visible // sub-field list (etîket, kategorî, hevmane, …), since the language may // not have been chosen yet when these lists were first built, or may // have changed since. $("#wiktku-start-dfn .wiktku-dfn-sublist").each(function () { var upd = $(this).data("updatePlaceholders"); if (typeof upd === "function") upd(); }); // Same idea for word-list steps (jê, têkildar, binêre herwiha, …) // whose placeholder is a function of the current language. $.each(steps, function (stepId, step) { if (typeof step.placeholder === "function") { $("#wiktku-start-" + stepId + " textarea.wiktku-start-step-field") .attr("placeholder", step.placeholder()); } }); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // Insert after the quote textarea's resize-wrap (if the manual // resize handle has already been attached to it), not after the // bare textarea -- otherwise this lands *inside* that wrap, // between the textarea and its own grip, breaking jêgirtin's // handle and nesting the tr/t boxes inside it. var quoteTa = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap = quoteTa.closest(".wiktku-resize-wrap"); (quoteResizeWrap.length ? quoteResizeWrap : quoteTa).after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // See the tr-field branch above for why this targets the // resize-wrap instead of the bare textarea. var quoteTa2 = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap2 = quoteTa2.closest(".wiktku-resize-wrap"); (quoteResizeWrap2.length ? quoteResizeWrap2 : quoteTa2).after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { var groupIdx = stepIdToGroup[stepId]; var hiddenByTab = (groupIdx !== undefined && groupIdx !== activeGroup) || // Beşên din picker: stays hidden even while its tab is // active until explicitly opened from the dropdown. (BESENDIN_SET[stepId] && !openedOtherSections[stepId]); // Bilêvkirin is its own section now, so the two views are // mutually exclusive: on it, only pron shows (plus Ziman, which // is shared and stays above every section); off it, pron is // hidden no matter which tab is active. pron is deliberately // ungrouped — stepIdToGroup has no entry for it — so without // this branch it would show on all four tabs at once. if (stepId === "pron") { hiddenByTab = hiddenByTab || !viewingPron; } else if (viewingPron && stepId !== "lang") { hiddenByTab = true; } if (hiddenByTab || (typeof(step.visible) === "function" && !step.visible(values))) { $("#wiktku-start-" + stepId).hide(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } // After build, sync the posparams helper widgets whenever pos or lang changes. if (step.id === "posparams" && typeof step.syncHelpers === "function") { step.syncHelpers(stepDiv); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } stepDiv.slideDown(); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); // The four content tabs belong to a POS section — Bilêvkirin has no // sub-tabs of its own, so the bar goes away while it's on screen. $("#wiktku-group-tabs").toggle(!!values.pos && !viewingPron); var besenDinActive = activeGroup === BESENDIN_GROUP_IDX && !viewingPron; $("#wiktku-besendin-picker").toggle(besenDinActive); // The option list is filtered by each step's visible(), which depends // on lang/pos — so it has to be rebuilt when those change, not just // when a section is opened. Safe to call from here: rendering the // picker doesn't itself call refresh(), only picking an option does. if (besenDinActive) renderBesenDinPicker(); updateGroupTabIndicators(values); continueBtn.setDisabled(!canContinue); // Soft gate: stays a real, clickable OOUI button — a hard // setDisabled(true) here would swallow the click entirely, leaving // no way to tell the person why nothing happened. The CSS-only // "looks disabled" class lets the click handler still run and show // wiktkuNotify's explanation. wiktkuContentGateOk = !canContinue || hasMinRequiredContent(values); continueBtn.$element.toggleClass("wiktku-btn-soft-disabled", !wiktkuContentGateOk); } function destroy() { if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); if (autosaveInterval) clearInterval(autosaveInterval); formDirty = false; $(window).off("beforeunload.wiktkuUnsaved"); $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard").slideDown(); // #editform was kept laid-out but off-screen (see build()) instead of // display:none, precisely so the editor never had to size itself // against a zero-width/height box. Just bring it back on-screen — // no slideDown needed since it was never actually collapsed. $("#editform").removeClass("wiktku-offscreen"); // Belt-and-braces: if WikiEditor/CodeMirror/mobile's auto-grow still // cached a stale size from some earlier point, nudge them to // recalculate now that the box is genuinely visible. $(window).trigger("resize"); if (window.CodeMirror) { var cm = $("#wpTextbox1").data("CodeMirror") || $("#wpTextbox1").data("cmInstance"); if (cm && typeof cm.refresh === "function") cm.refresh(); } $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and navz. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; // Inserts a new "== {{ziman|code}} ==" section at the correct sorted // position: navz, then ku/hac/sdh/lki/ckb/zza, then alphabetical by name. function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections — just write the new section. // Add \n\n only when there is real non-whitespace content above. var trimmed = existing.replace(/\s+$/, ""); return trimmed ? trimmed + "\n\n" + wikitext : wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // (?![\s\S]) matches only true end-of-string, since a bare "$" with // /m would stop at the section's first line break instead. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections, each separated by exactly \n\n. // Trim trailing whitespace off each section's content first so we // control the spacing precisely. var joined = sections.map(function (s) { return s.content.replace(/\s+$/, ""); }).join("\n\n"); // Only add a separator after the preamble when it has real content. var preambleTrimmed = preamble.replace(/\s+$/, ""); var prefix = preambleTrimmed ? preambleTrimmed + "\n\n" : ""; return prefix + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê zimanekî nû li rûpelê îlawe bikî. Eger ev ziman jixwe hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bike, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Muhtewaya rûpelê paqij bike (her tiştî jê bibe û rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); // Tab bar for switching between step-groups (topics) within a section. // renderGroupTabs()/updateGroupTabIndicators() (which populate and // maintain it) live outside build() — see near "var activeSection". var groupTabsDiv = $("<div id='wiktku-group-tabs'></div>"); // Both tab bars are sticky (CSS). group-tabs' sticky "top" has to sit // right below section-tabs' actual rendered height, which isn't a // fixed number since the bar can wrap onto a second line. Measured // here and published as a CSS custom property the stylesheet reads // back; recomputed on content changes and window resize. // // Vector 2022 has its own sticky header (.vector-sticky-header) that // pins to the real top:0 once you scroll past the page title, which // would otherwise sit directly behind (and hide) our section-tabs. // Fixed by measuring how much of the viewport Vector's header // currently occupies and offsetting both our bars below it, via // --wiktku-siteheader-h. Vector's header slides in/out with scroll // position, so this is re-measured on scroll too, not just resize. function siteHeaderOffset() { var el = document.querySelector(".vector-sticky-header"); if (!el) return 0; var rect = el.getBoundingClientRect(); // Present in the DOM at all times on Vector 2022, but only // actually occupying screen space once scrolled into place — // before that it sits translated above the viewport (negative/ // zero rect), which must not add a phantom gap under our bars. if (rect.bottom <= 0 || rect.top > 4) return 0; return Math.max(0, rect.bottom); } var stickyOffsetQueued = false; function syncStickyTabsOffset() { var h = sectionTabsDiv.is(":visible") ? (sectionTabsDiv.outerHeight() || 0) : 0; startForm.css("--wiktku-stabs-h", h + "px"); startForm.css("--wiktku-siteheader-h", siteHeaderOffset() + "px"); } function queueStickyTabsOffsetSync() { if (stickyOffsetQueued) return; stickyOffsetQueued = true; window.requestAnimationFrame(function () { stickyOffsetQueued = false; syncStickyTabsOffset(); }); } $(window).on("resize.wiktkuStickyTabs scroll.wiktkuStickyTabs", queueStickyTabsOffsetSync); // "Beşên din" picker — sits right under the group tab bar, only // shown while that tab is active (toggled in refresh(), see // BESENDIN_GROUP_IDX); renderBesenDinPicker() fills it. var besenDinPickerDiv = $("<div id='wiktku-besendin-picker' class='wiktku-besendin-picker'></div>"); /** Puts the form back in a usable state after a failed submit and * says what happened. Without this the button stays disabled and * the spinner spins forever on any exception — the person is left * staring at a form that looks busy but is dead, with the reason * visible only in the browser console. */ function submitFailed(err) { spinner.hide(); continueBtn.setDisabled(false); continueBtn.$element.removeClass("wiktku-btn-sending"); var detail = (err && (err.message || err.toString())) || "sedem nediyar"; mw.notify( "Şandin bi ser neket: " + detail + " — tiştê ku te nivîsî winda nebûye. Heke ev dubare bibe, " + "bi 'Edîtora çavkaniyê veke' berdewam bike.", { type: "error", tag: "wiktku-submit", autoHide: false } ); // Deliberately console.error as well: the notification is for the // person, this is for whoever they report the bug to. if (window.console && console.error) console.error("[wiktku] submit failed", err); } onSubmitError = submitFailed; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); continueBtn.$element.addClass("wiktku-btn-sending"); spinner.show(); try { getWikitext(function (wikitext) { try { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page — write fresh content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // ── bnr-h merge ────────────────────────────────────────── // If the user filled bnr-h inputs, either merge into the // existing {{bnr-h|…}} call or prepend a new one. var bnrhOut = steps.bnrh.output(getValues()); if (bnrhOut) { var newPages = bnrhOut.replace(/^\{\{bnr-h\|/, "").replace(/\}\}\n?$/, "").split("|"); var bnrhRe = /\{\{bnr-h\|([^}]*)\}\}/i; if (bnrhRe.test(existing)) { existing = existing.replace(bnrhRe, function (_, inner) { var existingPages = inner.split("|").map(function (p) { return p.trim(); }); $.each(newPages, function (_, p) { p = p.trim(); if (p && existingPages.indexOf(p) === -1) existingPages.push(p); }); return "{{bnr-h|" + existingPages.join("|") + "}}"; }); } else { existing = bnrhOut + existing; } } // If this language's section already exists (whitespace // differences aside), merge into it; otherwise insert new. var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); } catch (e) { // Thrown while writing the result into #wpTextbox1. submitFailed(e); } }); } catch (e) { // Catches anything thrown synchronously inside getWikitext. submitFailed(e); } }); // Tracks whether groupTabsDiv has been inserted yet. var groupTabsInserted = false; $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); var nameH3 = $("<h3></h3>").addClass("wiktku-start-step-name"); var nameLabel = $("<label></label>") .attr("for", "wiktku-start-" + step.id + "-field") .text(name); nameH3.append(nameLabel); stepDiv.append(nameH3); if (step.question_fmt) { // question_fmt can be a plain string, or a function of the // current values (used by steps whose question text depends // on e.g. the chosen language) — refresh() keeps it in sync // afterwards via the .wiktku-start-step-question class. var questionText = typeof step.question_fmt === "function" ? step.question_fmt(getValues()) : step.question_fmt; stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, questionText))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); // initSelects() runs over the whole form once it is in the DOM. stepDiv.append(input); } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.placeholder) { input.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append(step.modifiers ? makeModifierLi(input) : $("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Section tabs (switch between POS sections) sit above the // per-section fields, starting at "pos". if (step.id === "pos") { startForm.append(sectionTabsDiv); } // Step-group tabs sit just before the first grouped step in // ordered_steps. Derived from stepIdToGroup so this keeps // working no matter how STEP_GROUPS/ordered_steps get reordered. if (!groupTabsInserted && stepIdToGroup[step.id] !== undefined) { startForm.append(groupTabsDiv); startForm.append(besenDinPickerDiv); groupTabsInserted = true; } startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); /** Adds a new, empty POS section and switches to it. */ function addPosSection() { saveCurrentSection(); viewingPron = false; sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); stepDiv.find(".wiktku-add-sense").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); return; } if (id === "resim") { $("#wiktku-start-resim .wiktku-resim-wrap").remove(); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); stepDiv.find("select.wiktku-start-step-field").trigger("wiktku:refresh"); }); // Fresh section — no "Beşên din" sub-section has been opened yet. openedOtherSections = {}; renderBesenDinPicker(); renderSectionTabs(); refresh(); } addSectionBtn.on("click", addPosSection); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); syncStickyTabsOffset(); return; } sectionTabsDiv.show(); // Bilêvkirin leads the bar, ahead of the POS sections. var pronTab = $("<span></span>") .addClass("wiktku-section-tab wiktku-section-tab-pron") .text("Bilêvkirin") .toggleClass("wiktku-tab-active", viewingPron); pronTab.on("click", function () { if (viewingPron) return; saveCurrentSection(); viewingPron = true; refresh(); renderSectionTabs(); }); sectionTabsDiv.append(pronTab); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection && !viewingPron); (function (idx) { tab.on("click", function () { if (idx === activeSection && !viewingPron) return; // Leaving Bilêvkirin doesn't need a save — its field // is shared and never part of a section snapshot. if (!viewingPron) saveCurrentSection(); viewingPron = false; activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); syncStickyTabsOffset(); } renderSectionTabs(); /** * Re-populates a dynamically-growing "multiple" field list (bnrh, je, * tekildar, …) from a saved array of strings. Sets each value via * .val() + a triggered "input" event rather than touching the DOM * structure directly, so the normal refreshForTextField() growth * logic adds exactly as many rows as needed — the same thing that * happens when a person types into the last (empty) row. */ function restoreMultiField(id, values) { var container = $("#wiktku-start-" + id); $.each(values || [], function (i, v) { var field = container.find(".wiktku-start-step-field").eq(i); if (!field.length || !v) return; field.val(v).trigger("input"); }); } /** * Restores a full cached draft: shared lang/pron/bnrh fields, then * every section (via the same restoreSection()/refresh()/ * renderSectionTabs() sequence already used when switching tabs). * @param cached {{lang: string, pron: string, bnrh: Array, sections: Array, activeSection: number}} */ function restoreFromCache(cached) { if (cached.lang) { $("#wiktku-start-lang-field").val(cached.lang); $("#wiktku-start-lang-field").trigger("wiktku:refresh"); } // Rebuild dependent steps (pos, pron wrap, etc.) now that lang is set. refresh(); if (cached.pron !== undefined) { $("#wiktku-start-pron .wiktku-pron-text").val(cached.pron); } if (cached.bnrh) { restoreMultiField("bnrh", cached.bnrh); } sections = (cached.sections && cached.sections.length) ? cached.sections : [{}]; activeSection = (typeof cached.activeSection === "number" && cached.activeSection >= 0 && cached.activeSection < sections.length) ? cached.activeSection : 0; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); updateLastSavedIndicator(cached.savedAt || null); formDirty = false; wiktkuNotify("Danûstandina berê ya qeydkirî ji cache hate barkirin.", { type: "info", tag: "wiktku-cache-restore" }); } // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); // A new cureyê rêzimanî means any previously chosen cinsiyet/ // cureyê lêkerê no longer applies — clear both selections (and // the shared hidden cinsiyet field, since rebuildTa()/syncHelpers() // fall back to it) before wiping the textarea, so nothing stale // gets carried over into the rebuilt template. var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-cinsiyet-sel").val(""); ppDiv.find(".wiktku-posparams-jimar-sel").val(""); ppDiv.find(".wiktku-posparams-lektur-sel").prop("selectedIndex", 0); ppDiv.find(".wiktku-posparams-lekturform-sel").prop("selectedIndex", 0); $("#wiktku-start-cinsiyet-field").val(""); $("#wiktku-start-jimar-field").val(""); ppDiv.find(".wiktku-posparams-text").val(""); // refresh() runs steps.posparams.syncHelpers(), which toggles the // param rows for the new pos and — since the textarea is now // empty — calls rebuildTa() to repopulate it. refresh(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { // Immediate feedback that the click registered continueBtn.$element.addClass("wiktku-btn-flash"); setTimeout(function () { continueBtn.$element.removeClass("wiktku-btn-flash"); }, 500); // Ziman/Cureyê rêzimanî already block submission via the real // OOUI setDisabled (see canContinue in refresh()) — this is a // second, softer check that still lets the click through so we // can explain why, instead of the button just silently doing nothing. if (!wiktkuContentGateOk) { wiktkuNotify( "Berî şandinê, tiştekî binivîse: Mane, Bi zaravayên din, an jî Werger — kêmasî yek ji van sê beşan divê tijî be.", { type: "warn", tag: "wiktku-mincontent" } ); return; } wiktkuNotify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", flags: [ "destructive" ], }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Cache save/clear buttons ───────────────────────────────────────── // Manual, page-scoped save of the entire wizard (all sections, not // just the active one) via [[MediaWiki:Gadget-StorageUtils.js]]'s // ObjectStorage. Restoring happens silently on load at the end of // build(), once the full language list is available. // // Saving also happens automatically (debounced while typing, plus a // periodic fallback) — see "Autosave" below — since relying on the // person to remember to click "Li cache qeyd bike" before an // accidental tab close/reload defeats the point of having a cache // at all. function buildCacheSnapshot() { return { lang: getValues().lang || "", pron: $("#wiktku-start-pron .wiktku-pron-text").val() || "", // bnrh is shared (page-level), same as lang/pron above — not // per-section, so it doesn't live in sections[]. bnrh: getValuesForStep("bnrh"), sections: sections, activeSection: activeSection, savedAt: Date.now() }; } // ── Last-saved indicator ───────────────────────────────────────────── var lastSavedEl = $("<span id='wiktku-last-saved'></span>"); function formatSavedTime(ts) { try { return new Date(ts).toLocaleTimeString(mw.config.get("wgUserLanguage"), { hour: "2-digit", minute: "2-digit" }); } catch (e) { return new Date(ts).toLocaleTimeString(); } } function updateLastSavedIndicator(ts) { lastSavedEl.text(ts ? ("Cache: qeydkirî di saet " + formatSavedTime(ts) + " de") : ""); } // ── Dirty-state tracking + autosave ────────────────────────────────── // formDirty mirrors "does the live form differ from what's in cache". // Anything the person types/selects sets it; a successful save (auto // or manual) clears it; destroy() (final submit, or switching to the // source editor) also clears it since the wizard's job is over at // that point either way. formDirty/autosaveDebounceTimer/autosaveInterval // are declared in the outer scope (near activeGroup) — assigned here, // not re-declared — so destroy() can reach them too. var AUTOSAVE_DEBOUNCE_MS = 8000; // save shortly after typing pauses var AUTOSAVE_INTERVAL_MS = 60000; // …and at least this often regardless function performAutosave() { if (!formDirty) return; saveCurrentSection(); try { formCache.Set(buildCacheSnapshot()); formDirty = false; updateLastSavedIndicator(Date.now()); } catch (e) { // Silent on autosave failure (storage blocked/full, etc.) — the // manual button still surfaces a proper error if the person // tries it directly, no need to interrupt typing with a toast. } } function scheduleAutosave() { formDirty = true; if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = setTimeout(performAutosave, AUTOSAVE_DEBOUNCE_MS); } startForm.on("input change", "input, textarea, select", scheduleAutosave); autosaveInterval = setInterval(performAutosave, AUTOSAVE_INTERVAL_MS); // Warn on accidental tab close/reload while there's anything unsaved. $(window).on("beforeunload.wiktkuUnsaved", function (e) { if (!formDirty) return undefined; e.preventDefault(); e.returnValue = ""; return ""; }); var saveCacheBtn = new OO.ui.ButtonWidget({ label: "Li cache qeyd bike", title: "Halê vê formê yê niha (ziman, bilêvkirin û hemû beş) li cache (localStorage) qeyd bike, da ku eger rûpel bêyî xwestin were girtin an ji nû ve were barkirin, tu karibî berdewam bikî." }); saveCacheBtn.on("click", function () { saveCurrentSection(); // ObjectStorage.Set() doesn't return a success/failure value, so // the only way to detect a real failure (storage blocked, quota // exceeded, JSON.stringify choking on something unexpected) is to // catch it here rather than inspect a (nonexistent) return value. try { var snapshot = buildCacheSnapshot(); formCache.Set(snapshot); formDirty = false; updateLastSavedIndicator(snapshot.savedAt); wiktkuNotify("Halê formê li cache hate qeydkirin.", { type: "success", tag: "wiktku-cache-save" }); } catch (e) { mw.notify("Qeydkirina li cache bi ser neket.", { type: "error", tag: "wiktku-cache-save" }); } }); var clearCacheBtn = new OO.ui.ButtonWidget({ label: "Cache paqij bike", flags: [ "destructive" ], title: "Datayên qeydkirî yên vê rûpelê ji cache jê bibe (forma ku niha xuya dike naguherîne)." }); clearCacheBtn.on("click", function () { formCache.Set({}); // The live form still has whatever the person typed — it's just no // longer backed up anywhere, so treat this like a fresh unsaved edit. formDirty = true; updateLastSavedIndicator(null); wiktkuNotify("Cache hate paqijkirin.", { type: "success", tag: "wiktku-cache-clear" }); }); // ── "⋯" overflow ───────────────────────────────────────────── // One primary action and one secondary stay on the bar; everything // else moves in here, to avoid four same-weight buttons crowding // (and wrapping to three rows on a phone). var moreBtn = $("<button type='button' class='wiktku-more-btn' title='Vebijarkên din'>⋯</button>"); var moreMenu = $("<div class='wiktku-more-menu'></div>").hide(); /** Moves an existing OOUI button into the overflow menu, keeping its * handlers — the widgets already carry the behaviour, so this is * purely about where they are shown. */ function intoMenu(btn, extraClass) { var row = $("<div class='wiktku-more-item'></div>"); if (extraClass) row.addClass(extraClass); btn.$element.on("click", function () { moreMenu.hide(); }); row.append(btn.$element); moreMenu.append(row); } intoMenu(saveCacheBtn); intoMenu(clearCacheBtn, "wiktku-more-item-danger"); moreMenu.append($("<div class='wiktku-more-sep'></div>")); moreMenu.append($("<div class='wiktku-more-item wiktku-more-note'></div>").append(lastSavedEl)); moreBtn.on("click", function (e) { e.preventDefault(); e.stopPropagation(); var open = moreMenu.is(":visible"); moreMenu.toggle(!open); if (!open) { setTimeout(function () { $(document).one("click.wiktkuMore", function () { moreMenu.hide(); }); }, 0); } }); var moreWrap = $("<span class='wiktku-more-wrap'></span>").append(moreBtn).append(moreMenu); footer.append(moreWrap); // Icon-only settings button — opens the Tercîh dialog. Plain OOUI // icon names depend on which icon-pack module happens to be loaded, // so this uses the actual Codex "settings" (color-subtle) SVG from // Commons directly, the same way the spinner above hotlinks its gif. var prefsBtn = $("<button></button>", { type: "button", "class": "wiktku-prefs-btn", title: "Tercîh — sazkariyên vê amûrê biguherîne" }); prefsBtn.on("click", function (e) { e.preventDefault(); wiktkuOpenPrefsDialog(); }); // The gear is icon-only on the bar; inside a text menu it needs a // label like everything else around it. prefsBtn.on("click", function () { moreMenu.hide(); }); moreMenu.prepend($("<div class='wiktku-more-sep'></div>")); moreMenu.prepend($("<div class='wiktku-more-item wiktku-more-item-prefs'></div>") .append(prefsBtn) .append($("<span class='wiktku-more-item-label'></span>").text("Tercîh"))); startForm.append(footer); // NOTE: deliberately NOT .hide() (display:none). WikiEditor/CodeMirror/ // the mobile editor's auto-grow logic measure #wpTextbox1's real // dimensions during their own init, which happens while the wizard is // up. A display:none ancestor reports 0 for offsetWidth/offsetHeight/ // scrollHeight, so those scripts bake in a near-zero height that never // gets recalculated later — slideDown() in destroy() only animates the // outer box, it doesn't re-trigger their sizing. Pushing #editform // off-screen instead keeps it laid out (real width/height available to // measure) without being visible, so the editbox opens at full size. $("#editform").addClass("wiktku-offscreen").before(startForm); // renderGroupTabs() looks up #wiktku-group-tabs via a live DOM // selector, so it must run after startForm is actually in the document. renderGroupTabs(); renderBesenDinPicker(); // One pass over the whole form: every select that hasn't already been // initialised, and isn't opted out with .wiktku-plain-select, gets // the searchable picker. initSelects(startForm); refresh(); // Give every draggable textarea a custom resize grip (works // consistently on Safari/iOS, unlike the native corner grip — see // the "Manual drag-to-resize handle" comment in styles.css), and // keep applying it to textareas added later on (new sense blocks, // quote-source fields, nimûne rows, …). wiktkuInitManualResize(startForm); new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { $(mutation.addedNodes).each(function () { if (this.nodeType !== 1) return; wiktkuInitManualResize(this); }); }); }).observe(startForm[0], { childList: true, subtree: true }); // Now that the full language list is loaded, silently restore any // draft the editor previously saved for this page. var cachedDraft = formCache.Get(); if (cachedDraft && cachedDraft.sections && cachedDraft.sections.length) { restoreFromCache(cachedDraft); } } mw.loader.using(["oojs-ui-core"], function () { function wiktkuProceedWithData(wiktkuData) { var d = wiktkuData || {}; // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Jimar (number) code definitions — same shape as the wiki's // own Lua number-type table (code -> {cat, display[, req]}). if (d.numberLabels) $.extend(NUMBER_LABELS, d.numberLabels); // Populate lang choices (pinned list). if (d.langChoices) steps.lang.choices = choicesFromObject(d.langChoices, true); // Populate langsByCode and merge full language list from d.ziman. // d.ziman is a {code: name} object with all known languages. $.each(steps.lang.choices, function (i, choice) { if (choice.sortKey === undefined) choice.sortKey = choice.label; langsByCode[choice.code] = choice; }); if (d.ziman) { var pinnedCodes = {}; $.each(steps.lang.choices, function (i, c) { pinnedCodes[c.code] = true; }); var extraChoices = []; $.each(d.ziman, function (code, name) { if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; if (pinnedCodes[code]) return; var choice = { code: code, label: name, sortKey: name }; extraChoices.push(choice); langsByCode[code] = choice; }); extraChoices.sort(function (a, b) { return a.sortKey.localeCompare(b.sortKey, userLang); }); steps.lang.choices = steps.lang.choices.concat(extraChoices); } // Keep the full merged list around for trans/dunde/zarava — those // should still be able to reference any language even when the // Tercîh panel restricts the main "ziman" step below — then, if // the user set a restriction there, narrow steps.lang.choices // itself to just those codes. var wiktkuFullLangChoices = steps.lang.choices; if (wiktkuPrefs.langCodes && wiktkuPrefs.langCodes.length) { var wiktkuAllowedLangSet = {}; $.each(wiktkuPrefs.langCodes, function (i, code) { wiktkuAllowedLangSet[code] = true; }); var wiktkuRestrictedChoices = $.grep(wiktkuFullLangChoices, function (c) { return !!wiktkuAllowedLangSet[c.code]; }); // Fall back to the full list instead of showing an empty // dropdown if none of the saved codes matched anything // (typo'd code, data.json changed since, …). steps.lang.choices = wiktkuRestrictedChoices.length ? wiktkuRestrictedChoices : wiktkuFullLangChoices; } // Populate POS choices — also a plain {code: label} object in data.json. if (d.posChoices) steps.pos.choices = choicesFromObject(d.posChoices, false); // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the full language list // (not the possibly Tercîh-restricted steps.lang.choices). steps.trans.keys = wiktkuFullLangChoices; steps.dunde.keys = wiktkuFullLangChoices; steps.zarava.keys = getZaravaKeys(wiktkuFullLangChoices); build(); } // data.json ships inside this package module, so it is already parsed // and in memory — no action=raw round trip, and no Testing switch to // forget to flip back before deploying. wiktkuProceedWithData(require("./start/data.json")); }); }); //</nowiki> l84kkx46xxeg0sij61ldi3uxytdjlyu 6333831 6333824 2026-08-15T15:13:19Z Wikihez 7344 6333831 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. // implicit dependencies: StorageUtils (ObjectStorage) //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var addLangMode = mw.util.getParamValue("wiktkuaddlang") === "1"; // ── Tercîh (user settings) panel stored via mw.storage (localStorage), globally var WIKTKU_PREFS_KEY = "wiktku_start_prefs"; var WIKTKU_PREFS_DEFAULTS = { // [] = show the full language list in the "ziman" step; otherwise // only these codes are shown there (data.json codes, not names). langCodes: [], // true = never auto-open on a new/empty page — only via the // "+Ziman/beşeke din" portlet link. onlyOnClick: false, // "auto" | "p-cactions" | "p-tb" | "p-views" — where the // "+Ziman/beşeke din" portlet link is added. portlet: "auto", // true = suppress routine/informational mw.notify toasts (page // loading, cache auto-restored, cache saved/cleared, "tê şandin…"). // Errors and direct results of an explicit action (like saving // Tercîh itself) always show regardless of this setting. quiet: false }; function wiktkuLoadPrefs() { if (!(window.mw && mw.storage)) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var raw; try { raw = mw.storage.get(WIKTKU_PREFS_KEY); } catch (e) { raw = null; } if (!raw) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var parsed; try { parsed = JSON.parse(raw); } catch (e) { parsed = {}; } return $.extend({}, WIKTKU_PREFS_DEFAULTS, parsed); } function wiktkuSavePrefs(prefs) { if (!(window.mw && mw.storage)) return false; try { mw.storage.set(WIKTKU_PREFS_KEY, JSON.stringify(prefs)); return true; } catch (e) { return false; } } var wiktkuPrefs = wiktkuLoadPrefs(); // Routine/informational notices go through here so "quiet mode" can // suppress them; errors and explicit-action confirmations (like the // Tercîh save toast) call mw.notify directly instead, and always show. function wiktkuNotify(message, options) { if (wiktkuPrefs.quiet) return; mw.notify(message, options); } // Lazily built the first time it's opened; reused after that (see // wiktkuOpenPrefsDialog below, defined once we know OOUI is available). var wiktkuPrefsWindowManager = null; var wiktkuPrefsDialog = null; function wiktkuOpenPrefsDialog() { mw.loader.using(["oojs-ui-core", "oojs-ui-windows"], function () { function WiktkuPrefsDialog(config) { WiktkuPrefsDialog.super.call(this, config); } if (!wiktkuPrefsDialog) { OO.inheritClass(WiktkuPrefsDialog, OO.ui.ProcessDialog); WiktkuPrefsDialog.static.name = "wiktkuPrefsDialog"; WiktkuPrefsDialog.static.title = "Tercîhên min"; WiktkuPrefsDialog.static.actions = [ { action: "save", label: "Qeyd bike", flags: ["primary", "progressive"] }, { action: "cancel", label: "Betal bike", flags: "safe" } ]; WiktkuPrefsDialog.prototype.initialize = function () { WiktkuPrefsDialog.super.prototype.initialize.call(this); this.langCodesInput = new OO.ui.TextInputWidget({ placeholder: "ku, zza, ckb (vala bihêle ji bo hemû zimanan)" }); this.onlyOnClickCheckbox = new OO.ui.CheckboxInputWidget({}); this.quietCheckbox = new OO.ui.CheckboxInputWidget({}); this.portletDropdown = new OO.ui.DropdownInputWidget({ options: [ { data: "auto", label: "Otomatîk (li gorî rûyê wîkiyê)" }, { data: "p-cactions", label: "p-cactions - Li qismê Amûran" }, { data: "left-navigation", label: "left-navigation - Li qismê Gotar-Gotûbêj" }, { data: "p-tb", label: "p-tb - Li qismê Giştî" }, { data: "p-views", label: "p-views - Li qismê Bixwîne" } ] }); var fieldset = new OO.ui.FieldsetLayout({ label: "Eyar" }); fieldset.addItems([ new OO.ui.FieldLayout(this.langCodesInput, { label: "Kodên zimanan ku tê xuyakirin li qismê \"ziman\"", align: "top", help: "Kodan bi virgulê (,) ji hev veqetîne. Vala bihêle da ku hemû ziman were nîşandan.", helpInline: true }), new OO.ui.FieldLayout(this.onlyOnClickCheckbox, { label: "Tenê veke wextê \"+Ziman/beşeke din\" were tikandin", align: "inline", help: "Eger were hilbijartin, ev amûr êdî otomatîk li ser rûpelên nû/vala dest pê nake — divê meriv her carê pêl \"+Ziman/beşeke din\" bike.", helpInline: true }), new OO.ui.FieldLayout(this.portletDropdown, { label: "Cihê lînka \"+Ziman/beşeke din\"", align: "top", help: "\"Otomatîk\" li gorî rûyê wîkiyê hildibijêre.", helpInline: true }), new OO.ui.FieldLayout(this.quietCheckbox, { label: "Moda bêdeng (kêmtir agahdarî nîşan bide)", align: "inline", help: "Agahdariyên normal nîşan nede. Xeta her tim tên xuyakirin.", helpInline: true }) ]); this.$body.addClass("wiktku-prefs-dialog-body").append(fieldset.$element); }; WiktkuPrefsDialog.prototype.getSetupProcess = function (data) { return WiktkuPrefsDialog.super.prototype.getSetupProcess.call(this, data) .next(function () { this.langCodesInput.setValue(wiktkuPrefs.langCodes.join(", ")); this.onlyOnClickCheckbox.setSelected(!!wiktkuPrefs.onlyOnClick); this.portletDropdown.setValue(wiktkuPrefs.portlet || "auto"); this.quietCheckbox.setSelected(!!wiktkuPrefs.quiet); }, this); }; WiktkuPrefsDialog.prototype.getActionProcess = function (action) { var dialog = this; if (action === "save") { return new OO.ui.Process(function () { var codes = dialog.langCodesInput.getValue() .split(/[,\s]+/) .map(function (c) { return c.trim().toLowerCase(); }) .filter(function (c) { return !!c; }); wiktkuPrefs = { langCodes: codes, onlyOnClick: dialog.onlyOnClickCheckbox.isSelected(), portlet: dialog.portletDropdown.getValue() || "auto", quiet: dialog.quietCheckbox.isSelected() }; wiktkuSavePrefs(wiktkuPrefs); mw.notify( "Tercîh hatin qeydkirin. Rûpelê ji nû ve bar bike (F5).", { type: "success", tag: "wiktku-prefs-save" } ); dialog.close({ action: "save" }); }); } if (action === "cancel") { return new OO.ui.Process(function () { dialog.close({ action: "cancel" }); }); } return WiktkuPrefsDialog.super.prototype.getActionProcess.call(this, action); }; wiktkuPrefsWindowManager = new OO.ui.WindowManager(); $(document.body).append(wiktkuPrefsWindowManager.$element); wiktkuPrefsDialog = new WiktkuPrefsDialog(); wiktkuPrefsWindowManager.addWindows([wiktkuPrefsDialog]); } wiktkuPrefsWindowManager.openWindow(wiktkuPrefsDialog); }); } var targetContainer; var skin = mw.config.get('skin'); if (wiktkuPrefs.portlet && wiktkuPrefs.portlet !== "auto") { targetContainer = wiktkuPrefs.portlet; } else if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Li vê rûpelê, ziman an jî beşeke nû zêde bike"); // If "onlyOnClick" is set, the wizard should ONLY ever open via the // "+Ziman/beşeke din" link — never automatically var wiktkuNewPageDetected = $(".mw-newarticletext, .mw-newarticletextanon").length > 0; if (wiktkuPrefs.onlyOnClick ? !addLangMode : (!addLangMode && !wiktkuNewPageDetected)) { return; } // ── Shared helpers ─────────────────────────────────────────────────── // Generic text/UI utilities live in their own package file now — see the // header of util.js for why. Aliased to bare names here so the ~400 call // sites below read exactly as they did when these were local functions. var wiktkuUtil = require("./start/util.js"); var capitalize = wiktkuUtil.capitalize; var decapitalize = wiktkuUtil.decapitalize; var escapeRegExp = wiktkuUtil.escapeRegExp; var stripWikilinks = wiktkuUtil.stripWikilinks; var splitTercimeIzah = wiktkuUtil.splitTercimeIzah; var insertAtCursor = wiktkuUtil.insertAtCursor; var foldDiacritics = wiktkuUtil.foldDiacritics; var wrapNativeSelect = wiktkuUtil.wrapNativeSelect; var initSelects = wiktkuUtil.initSelects; var wiktkuInitManualResize = wiktkuUtil.initManualResize; function langHeaderSource(codePattern) { return "\n?==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } var catSrcTemplates = null; var catSrcTemplatesPromise = null; function fetchCatSrcTemplates() { if (catSrcTemplatesPromise) return catSrcTemplatesPromise; catSrcTemplatesPromise = new mw.Api().get({ action: "query", list: "categorymembers", cmtitle: "Kategorî:Çavkanî", cmnamespace: 10, cmlimit: "max", formatversion: 2 }).then(function (data) { var members = (data.query && data.query.categorymembers) || []; catSrcTemplates = $.map(members, function (m) { // Pêşgira navî ya "Şablon:" rake. return m.title.replace(/^[^:]+:/, ""); }); catSrcTemplates.sort(function (a, b) { return a.localeCompare(b, userLang); }); return catSrcTemplates; }, function () { catSrcTemplates = []; return catSrcTemplates; }); return catSrcTemplatesPromise; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var formCache = new ObjectStorage("wiktku_start_draft_" + mw.config.get("wgPageName"), 1); var langsByCode = {}; // Looks up the display label for a language code, falling back to the // code itself if it isn't known yet (e.g. langsByCode not loaded). function getLangLabel(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; // Converts a {code: label} object (langChoices/posChoices in data.json) // into the {code, label[, sortKey]} array the rest of the script uses. // isLang: true adds a sortKey and shows "(code)" after the label — // language choices only. function choicesFromObject(obj, isLang) { var result = []; $.each(obj || {}, function (code, label) { var choice = { code: code, label: label }; if (isLang) choice.sortKey = label; result.push(choice); }); return result; } function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c.code] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Number codes (y, s, d, p, p+, tp, j, j+, j/nj, nj, nj+, hj!, hj?) from // data.json's "numberLabels". Same {code: {cat, display[, req]}} shape as // the wiki's Lua number-type table; "display" can contain HTML (<abbr>) // or wikilinks, so it's only used as-is in wikitext output, never dropped // straight into an <option> (see stripMarkupForOption below). var NUMBER_LABELS = {}; // Distinguishes the Jimar dropdown (j= param) from the Cîns dropdown // (c= param): a code that's a key in NUMBER_LABELS is a number code, // everything else is a gender code. Compound codes like "m-p"/"n-p" are // gender+plural pairs and correctly stay on the gender side. function isNumberCode(code) { return Object.prototype.hasOwnProperty.call(NUMBER_LABELS, code); } // Strips the bit of markup "display" is allowed to contain so it's safe // to use as plain <option> text (options can't render HTML or wikilinks): // <abbr title="X">Y</abbr> -> "Y (X)", [[a|b]] -> "b", [[a]] -> "a". function stripMarkupForOption(html) { if (!html) return ""; return $.trim( String(html) .replace(/<abbr[^>]*title="([^"]*)"[^>]*>([\s\S]*?)<\/abbr>/gi, "$2 ($1)") .replace(/\[\[[^\]|]*\|([^\]]*)\]\]/g, "$1") .replace(/\[\[([^\]]*)\]\]/g, "$1") .replace(/<[^>]+>/g, "") ); } // Builds the Jimar dropdown's <option> text for one code: "j — jimarbar". function numberOptionLabel(code) { var def = NUMBER_LABELS[code]; if (!def) return code; var text = stripMarkupForOption(def.display); return text ? (code + " — " + text) : code; } // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } // ── Template explanations ──────────────────────────────────────────── // Every place a template can be picked shows the same row: a status // dot, the name, a link to the template page, and an ⓘ. This is the ⓘ. // // Text comes from the template's own TemplateData where it has any, so // the explanation stays right without anyone maintaining a second copy // by hand — with the desc already in data.json as the fallback for // templates that have none. var wiktkuTplDataCache = {}; // name -> {desc, params[]} or null when absent /** Fetches TemplateData for one template. Resolves to null if the * template has none (a plain, undocumented template — very common). */ function fetchTemplateData(name) { if (Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, name)) { return $.Deferred().resolve(wiktkuTplDataCache[name]).promise(); } return new mw.Api().get({ action: "templatedata", titles: "Şablon:" + name, redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; var first = null; $.each(pages, function (_, p) { if (!first) first = p; }); var out = null; if (first) { var desc = first.description; // TemplateData descriptions are language maps when the // template is documented in more than one language. if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(first.params || {}, function (key, p) { var label = p && p.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(p && p.required) }); }); out = { desc: desc || "", params: params }; } wiktkuTplDataCache[name] = out; return out; }, function () { // No TemplateData, or the API is unhappy — cache the miss so a // repeated ⓘ click doesn't re-request it every time. wiktkuTplDataCache[name] = null; return null; }); } /** Fetches TemplateData for many templates in one request and fills the * cache; resolves either way, a template with no TemplateData caches as null. */ function prefetchTemplateData(names) { var missing = $.grep(names || [], function (n) { return n && !Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n); }); if (!missing.length) return $.Deferred().resolve().promise(); // The API caps a titles list at 50 for normal users. missing = missing.slice(0, 50); return new mw.Api().get({ action: "templatedata", titles: $.map(missing, function (n) { return "Şablon:" + n; }).join("|"), redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; $.each(pages, function (_, page) { if (!page || !page.title) return; var name = String(page.title).replace(/^[^:]+:/, ""); var desc = page.description; if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(page.params || {}, function (key, prm) { var label = prm && prm.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(prm && prm.required) }); }); wiktkuTplDataCache[name] = { desc: desc || "", params: params }; }); // Anything the API didn't answer for simply has none — cache the // miss so the per-row ⓘ doesn't re-request it one at a time. $.each(missing, function (_, n) { if (!Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n)) wiktkuTplDataCache[n] = null; }); }, function () { $.each(missing, function (_, n) { wiktkuTplDataCache[n] = null; }); }); } /** Rewrites each tagged <option> in `sel` as "name — description", using * TemplateData. Only fills rows that have no description yet, so the * hand-written ones in data.json (which carry usage examples the API * does not) are left exactly as they are. */ function applyTplDescriptions(sel) { if (!sel || !sel.length) return; var changed = false; sel.find("option[data-tpl]").each(function () { var opt = $(this); var name = opt.attr("data-tpl"); if (opt.text().indexOf(" — ") !== -1) return; // already described var td = wiktkuTplDataCache[name]; var desc = (td && td.desc) || localTplDesc(name); if (!desc) return; // One line: TemplateData descriptions can run to a paragraph. desc = $.trim(String(desc).split("\n")[0]); if (desc.length > 90) desc = desc.slice(0, 90) + "…"; opt.text(name + " — " + desc); changed = true; }); // The picker caches option text for searching, so it has to re-read. if (changed) sel.trigger("wiktku:refresh"); } /** Hand-written fallback description, from data.json. * * This is the escape hatch for templates with no TemplateData on the * wiki: add a "desc" to the entry in data.json and it shows up in the * dropdown and in the ⓘ immediately, no code change. TemplateData is * still the better place — VisualEditor and every other tool reads it * too — but this keeps the picker useful in the meantime. * * Works for any pool: pronTpls, etymTpls, tplDefs, jederDefs. */ function localTplDesc(name) { var pools = [steps.pron.pronTpls, steps.etym.etymTpls, steps.dfn.tplDefs, steps.dfn.jederDefs]; var found = ""; $.each(pools, function (_, pool) { if (pool && pool[name] && pool[name].desc) { found = pool[name].desc; return false; } }); return found; } /** Opens the inline explanation panel for `name`, anchored under the * picker it was opened from. */ function showTemplateInfo(name, anchorWrap) { $(".wiktku-tpl-info").remove(); var panel = $("<div class='wiktku-tpl-info'></div>"); panel.append($("<div class='wiktku-tpl-info-name'></div>").text("{{" + name + "}}")); var body = $("<div class='wiktku-tpl-info-desc'></div>").text("Tê barkirin…"); panel.append(body); var params = $("<div class='wiktku-tpl-info-params'></div>"); panel.append(params); panel.append($("<a class='wiktku-tpl-info-link' target='_blank' rel='noopener'></a>") .attr("href", wiktkuUtil.tplPageUrl(name)) .text("Rûpela şablonê veke →")); var close = $("<button type='button' class='wiktku-tpl-info-close' title='Bigire'>✕</button>"); close.on("click", function () { panel.remove(); }); panel.prepend(close); $(anchorWrap).after(panel); fetchTemplateData(name).then(function (td) { var desc = (td && td.desc) || localTplDesc(name); body.text(desc || "Ji bo vê şablonê ravek nehatiye nivîsandin."); if (td && td.params && td.params.length) { params.append($("<div class='wiktku-tpl-info-params-title'></div>").text("Parametre:")); var listEl = $("<ul></ul>"); $.each(td.params, function (_, p) { var line = p.name + (p.label ? " — " + p.label : "") + (p.required ? " (pêwîst)" : ""); listEl.append($("<li></li>").text(line)); }); params.append(listEl); } }); } /** Marks a picker's <option>s as template rows so the searchable widget * renders them with the dot / 🔗 / ⓘ affordances, and wires the ⓘ * handler for that picker. `nameOf` maps an <option> to a template * name — the pickers store different things in value= (a snippet for * the insert dropdowns, the bare name for the sense selector). */ function markTemplateOptions(sel, nameOf) { if (!sel || !sel.length) return; var names = []; sel.find("option").each(function () { var opt = $(this); var name = nameOf(opt); if (!name) return; opt.attr("data-tpl", name); // Deprecated/typo templates are the "special cases only" ones. opt.attr("data-tpl-status", /kevnbûyî|şaşnivîs|kêmpeyda/i.test(opt.text()) ? "yellow" : "green"); names.push(name); }); sel.data("wiktkuTplInfo", showTemplateInfo); // Fill in the descriptions. Matters most for the Mane picker, whose // entries in data.json are names with no desc at all — "rastnivîs", // "ku-Latn", "guharto" on their own. One request covers every // template in the picker, cached for the per-row ⓘ as well. prefetchTemplateData(names).always(function () { applyTplDescriptions(sel); }); } /** Pulls the template name out of a snippet like "* {{ku-IPA}}" or * "{{ji|SOURCELANG|CODE|…}}". */ function tplNameFromSnippet(snippet) { var m = /\{\{\s*([^|}\n]+)/.exec(snippet || ""); return m ? $.trim(m[1]) : ""; } // True if a sense has content beyond mane worth keeping (etîket, word // lists, nimûne, jêder) — so it's still emitted with {{mane?}} if empty. function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } // A technically-"complete" entry (Ziman + Cureyê rêzimanî filled) with // nothing in Mane, Bi zaravayên din or Werger is still meaningfully // empty, so this is checked separately at submit-click time with its // own message. function hasMinRequiredContent(values) { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasMane = dfnSenses.some(function (s) { return (s.tpl && s.tplTitle) || (!s.tpl && (s.mane !== "" || senseHasExtraContent(s))); }); if (hasMane) return true; if (values.lang === "ku") { var hasWerger = false; $("#wiktku-start-trans .wiktku-trans-group").each(function () { if (steps.trans.getGroupTranslations($(this)).length) hasWerger = true; }); if (hasWerger) return true; var hasZarava = false; $("#wiktku-start-zarava .wiktku-zarava-group").each(function () { if (steps.zarava.getGroupTranslations($(this)).length) hasZarava = true; }); if (hasZarava) return true; } return false; } // Bolds the *first* occurrence of the page name function boldPageNameOnce(text) { if (!text || !pageNameRe) return text; var re = new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "i"); return text.replace(re, "'''$1'''"); } // Converts literal line breaks typed into a nimûne/jêgirtin box into // wikitext <br> tags, function nlToBr(text) { return text ? text.replace(/\r\n|\r|\n/g, "<br>") : text; } function escapeHtmlForBackdrop(str) { return String(str) .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;"); } // Mirrors a textarea's text, with a small highlighted marker placed // right after each line that's followed by an actual typed/pasted // linebreak. Rendered into a transparent backdrop layer behind the // textarea (see ensureLinebreakBackdrop()), so only the point of the // break is marked instead of the whole box. function buildLinebreakBackdropHtml(text) { var lines = text.split(/\r\n|\r|\n/); return $.map(lines, function (line, i) { var isLast = i === lines.length - 1; return escapeHtmlForBackdrop(line) + (isLast ? "" : "<mark class='wiktku-linebreak-mark'>↵</mark>\n"); }).join(""); } // Copies the metrics that affect where text wraps/lands (font, line // height, padding, border) from the real textarea onto its backdrop, // via computed style rather than shared CSS classes — most of the // box's own rules are written as "textarea.foo", which a <div> with // the same class wouldn't match. Re-run on every update in case a // responsive breakpoint changed the textarea's own font-size. function syncLinebreakBackdropMetrics(textarea, backdrop) { var cs = window.getComputedStyle(textarea[0]); backdrop.css({ "box-sizing": cs.boxSizing, "padding-top": cs.paddingTop, "padding-right": cs.paddingRight, "padding-bottom": cs.paddingBottom, "padding-left": cs.paddingLeft, "border-width": cs.borderWidth, "border-style": "solid", "font-family": cs.fontFamily, "font-size": cs.fontSize, "font-weight": cs.fontWeight, "line-height": cs.lineHeight, "letter-spacing": cs.letterSpacing }); } // Lazily wraps a textarea in its own positioning anchor (independent // of .wiktku-resize-wrap, so this doesn't depend on load order versus // wiktkuMakeManualResizable) and inserts the transparent backdrop // layer used to mark the exact point of a linebreak. Safe to call // more than once on the same textarea — the backdrop is cached. function ensureLinebreakBackdrop(textarea) { var existing = textarea.data("wiktkuLinebreakBackdrop"); if (existing) return existing; textarea.wrap("<div class='wiktku-linebreak-wrap'></div>"); var backdrop = $("<div aria-hidden='true'></div>").addClass("wiktku-linebreak-backdrop"); textarea.before(backdrop); textarea.data("wiktkuLinebreakBackdrop", backdrop); textarea.on("scroll.wiktkuLinebreak", function () { backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); }); return backdrop; } // Flags a nimûne/jêgirtin textarea (via CSS class, for the border // tint + tooltip) while it contains a typed/pasted linebreak, so the // user notices before it's silently turned into <br> on output. // Marks only the exact point of the break via a mirrored backdrop, // rather than tinting the whole box. function highlightLinebreak(el) { var textarea = $(el); var text = textarea.val(); var hasBreak = /\r|\n/.test(text); textarea .toggleClass("wiktku-has-linebreak", hasBreak) .attr("title", hasBreak ? "Xeta nû dê wek <br> bê nivîsandin" : ""); if (!hasBreak) { var cached = textarea.data("wiktkuLinebreakBackdrop"); if (cached) cached.hide(); textarea.removeClass("wiktku-has-linebreak-source"); return; } var backdrop = ensureLinebreakBackdrop(textarea); textarea.addClass("wiktku-has-linebreak-source"); syncLinebreakBackdropMetrics(textarea, backdrop); backdrop.html(buildLinebreakBackdropHtml(text)).show(); backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); } // Each nimûne item can be { text, tr, t }: text, transliteration, translation. function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{nimûne?|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = nlToBr(boldPageNameOnce(text)); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + nlToBr(n.tr); // Translation as third positional param (no key needed). if (n.t) tpl += "|" + nlToBr(n.t); } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 60 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } // Formats jêder (citation) entries into "#* {{jêder…|…}}" lines; skips // entries with no quote text. Falls back to the generic {{jêder}} // template when no specific template was chosen. function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; var quote = nlToBr(boldPageNameOnce(jeder.quote)); var quoteTr = nlToBr(jeder.quoteTr); var quoteT = nlToBr(jeder.quoteT); if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + quote; if (quoteTr) cite += "|tr=" + quoteTr; if (quoteT) cite += "|tercime=" + quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + quote; if (quoteTr) out += "|tr=" + quoteTr; if (quoteT) out += "|tercime=" + quoteT; // A şablon picked from Kategorî:Çavkanî is transcluded as the // source param (e.g. |{{Kovara X}}); manual text is used as-is. var srcParam = jeder.jederCatTpl ? ("{{" + jeder.jederCatTpl + "}}") : (jeder.jederManual ? jeder.jederManual : "çavkanî?"); // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } // True if a sense has at least one jêder entry with quote text. function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } // Builds "{{tplName|lang|part1|part2|…}}" from a sense field (kategori, // etiket), wrapped inline (" {{…}} ") or on its own line ("\n#: {{…}}"). function buildSenseTpl(sense, field, lang, tplName) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return call } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } // ── Inline modifier system ─────────────────────────────────────────────── // Appends a ⊕ button to a word input <li>. Clicking it shows a compact // modifier picker; selecting one prompts for the value and appends // <modifier:value> to the textarea's current content. 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îf" }, { 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: qualifier (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" }, { key: "qq", label: "qq: qualifier (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î" } ]; // Sub-groups (inside a sense/definition block) that get the same ⊕ // modifier button as makeWordListStep fields. var MODIFIER_SUBGROUPS = { "wiktku-dfn-alternativ": true, "wiktku-dfn-hevmane": true, "wiktku-dfn-dijmane": true, "wiktku-dfn-koordine": true, "wiktku-dfn-jornav": true, "wiktku-dfn-jernav": true }; /** * Wraps a freshly-created textarea in a <li> with a ⊕ modifier button. * `ta` — the jQuery textarea element. * Returns the <li>. */ function makeModifierLi(ta) { var li = $("<li class='wiktku-word-li'></li>"); var btn = $("<button type='button' class='wiktku-mod-btn' title='Modifiyerê lê zêde bike'>⊕</button>"); var picker = $("<div class='wiktku-mod-picker'></div>").hide(); // Which modifier keys are already present in the textarea's current // text — e.g. "<t:...>" → "t" used. Each modifier can only be // applied once per word, so its pill gets disabled once used. function usedKeys() { var used = {}; var re = /<([a-zA-Z]+):/g; var val = ta.val() || ""; var m; while ((m = re.exec(val)) !== null) used[m[1]] = true; return used; } $.each(WORD_MODIFIERS, function (_, mod) { var pill = $("<button type='button' class='wiktku-mod-pill'></button>").text(mod.label); pill.attr("title", mod.hint); pill.data("mod-key", mod.key); pill.on("click", function (e) { e.preventDefault(); if (pill.prop("disabled")) return; // already used on this word picker.hide(); // Show a tiny inline input for the modifier value. var valWrap = $("<span class='wiktku-mod-val-wrap'></span>"); var valInp = $("<input type='text' class='wiktku-mod-val-input'>") .attr("placeholder", mod.hint + "…") .attr("size", 20); var confirm = $("<button type='button' class='wiktku-mod-confirm'>✓</button>"); var cancel = $("<button type='button' class='wiktku-mod-cancel'>✕</button>"); function applyModifier() { var v = $.trim(valInp.val()); if (v) { ta.val(ta.val() + "<" + mod.key + ":" + v + ">"); ta.trigger("input"); } valWrap.remove(); ta.focus(); } confirm.on("click", applyModifier); cancel.on("click", function () { valWrap.remove(); ta.focus(); }); valInp.on("keydown", function (e) { if (e.which === 13) { e.preventDefault(); applyModifier(); } if (e.which === 27) { valWrap.remove(); ta.focus(); } }); valWrap.append(valInp).append(confirm).append(cancel); li.append(valWrap); valInp.focus(); }); picker.append(pill); }); btn.on("click", function (e) { e.preventDefault(); // Close any other open pickers in the same list. li.closest("ol, ul").find(".wiktku-mod-picker").not(picker).hide(); // Grey out modifiers already used on this word — refreshed on // every open since the text (and thus what's "used") can change. var used = usedKeys(); picker.find(".wiktku-mod-pill").each(function () { var isUsed = !!used[$(this).data("mod-key")]; $(this).prop("disabled", isUsed).toggleClass("wiktku-mod-pill-used", isUsed); }); picker.toggle(); }); // Close picker when focus leaves the li entirely. li.on("focusout", function () { setTimeout(function () { if (!$.contains(li[0], document.activeElement)) picker.hide(); }, 150); }); li.append(ta).append(btn).append(picker); return li; } function makeWordListStep(id, name, question_fmt) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, modifiers: true, // Function instead of a plain string so it can name the current // language — computed fresh at build time and re-applied by // refresh() whenever the language changes. placeholder: function () { var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return "Kelîme" + (langLabel ? " bi " + langLabel : "") + "…"; }, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); var header = capitalize(name); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: {}, visible: function (values) { if (!values.lang) return false; // addLangMode: skip pron only if this lang already has a section. if (addLangMode) { // Clearing the page makes existing content irrelevant. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, // Fills the insert-dropdown from pronTpls, filtered by language. refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); // Reassures the user this field is optional — the dropdown // below writes the template for them, no syntax needed up front. wrap.append( $("<p class='wiktku-step-hint'></p>").text( "Ev qad ne mecbûrî ye. Heke tu nizanî kîjan şablonî hilbijêrî, vale bihêle — an ji pêşkêşkariya jêrîn şablonekî hilbijêre, ew ê bixweber li vir were nivîsandin." ) ); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike "); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); // Clear the picker's search box sel.trigger("wiktku:refresh"); ta.focus(); return; } // The noLang templates (ku-IPA, ku-kîte, zza-IPA, zza-kîte) // auto-generate content from a Lua module reading the page // title, so show a live preview and require confirmation // before inserting. var tplLabel = selectedOption.text(); $(this).val(""); sel.trigger("wiktku:refresh"); steps.pron.showTplPreview(stepDiv, ta, snippet, tplLabel); }); wrap.append(sel).append(ta); stepDiv.append(wrap); steps.pron.buildIpaPalette(wrap, ta); initSelects(wrap); return ta; }, // ── IPA character palette ────────────────────────────────── // Modelled on fr.wiktionary's: every character is a button that // drops itself in at the cursor. Two sub-tabs, because the full // IPA chart is ~180 symbols and roughly twenty of them ever // appear in Kurmancî — "IPA (kurdî)" opens by default and the // full chart is one click away for loanwords and other // languages. Grouped with a label down the left so it reads as // a chart rather than one long line of glyphs. IPA_KU: [ { label: "Kît/stres", chars: ["ˈ", "ˌ", "ː"] }, { label: "Bêdeng", chars: ["d͡ʒ", "t͡ʃ", "ʒ", "ʃ", "ɫ", "ŋ", "ɾ", "r", "ʋ", "ħ", "ʕ", "ɣ", "χ", "ʔ"] }, { label: "Dengdêr", chars: ["ɑː", "eː", "ɛ", "ɪ", "iː", "ɯ", "ʊ", "uː", "yː", "ø", "œ"] } ], IPA_FULL: [ { label: "Bêdeng 1", chars: ["m", "ɱ", "n", "ɳ", "ɲ", "ŋ", "ɴ", "p", "b", "t", "d", "t̪", "d̪", "ʈ", "ɖ", "c", "ɟ", "k", "ɡ", "q", "ɢ", "ʡ", "ʔ"] }, { label: "Bêdeng 2", chars: ["ɸ", "β", "f", "v", "θ", "ð", "s", "z", "ʃ", "ʒ", "ʂ", "ʐ", "ɕ", "ʑ", "ç", "ʝ", "x", "ɣ", "χ", "ʁ", "ħ", "ʕ", "h", "ɦ", "ʜ", "ʢ", "ɧ"] }, { label: "Bêdeng 3", chars: ["ʋ", "ɹ", "ɻ", "j", "ɥ", "ɰ", "ʍ", "w", "ʙ", "ⱱ", "ɾ", "ɽ", "r", "ʀ", "ɺ", "l", "ɫ", "ɬ", "ɮ", "ɭ", "ʎ", "ʟ"] }, { label: "Bêdeng 4", chars: ["ɓ", "ɗ", "ᶑ", "ʄ", "ɠ", "ʛ", "ʘ", "ǀ", "ǃ", "ǂ", "ǁ"] }, { label: "Dengdêr", chars: ["i", "y", "ɪ", "ʏ", "ɨ", "ʉ", "ɯ", "u", "ʊ", "e", "ø", "ɘ", "ɵ", "ɤ", "o", "ə", "ɚ", "ɛ", "œ", "ɜ", "ɝ", "ɞ", "ʌ", "ɔ", "æ", "ɶ", "ɐ", "a", "ɑ", "ɒ"] }, { label: "Suprasegmental", chars: ["ˈ", "ˌ", "ː", "ˑ", "ʼ", "ˀ", "ˤ", "ᵝ", "ᵊ", "ˠ", "ʰ", "ʱ", "ʲ", "ˡ", "ⁿ", "ᵑ", "ʷ", "ᶣ", "˞", "‿"] }, { label: "Dîakrîtîk", chars: ["̚", "̪", "̺", "̻", "̼", "̬", "̊", "̥", "̞", "̝", "̘", "̙", "̽", "̟", "̠", "̈", "̤", "̹", "̜", "̍", "̩", "̆", "̯", "̃", "̰", "͡", "͜"] }, { label: "Ton", chars: ["̋", "́", "̄", "̀", "̏", "̌", "̂", "˥", "˦", "˧", "˨", "˩", "ꜛ", "ꜜ", "↗", "↘", "‖"] } ], /** Builds the two-sub-tab character palette under the textarea. */ buildIpaPalette: function (wrap, ta) { if (wrap.find(".wiktku-ipa-palette").length) return; var panel = $("<div class='wiktku-ipa-panel'></div>").hide(); var toggle = $("<a href='#' class='wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tîpên bilêvkirinê</span>")); toggle.on("click", function (e) { e.preventDefault(); var open = panel.is(":visible"); panel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); wrap.append($("<div class='wiktku-adv-toggle-row'></div>").append(toggle)); // Sub-tab bar, with the two template buttons pinned right. var subTabs = $("<div class='wiktku-ipa-subtabs'></div>"); var kuTab = $("<span class='wiktku-ipa-subtab wiktku-tab-active'>IPA (kurdî)</span>"); var fullTab = $("<span class='wiktku-ipa-subtab'>IPA</span>"); subTabs.append(kuTab).append(fullTab); var tplBtns = $("<span class='wiktku-ipa-tplbtns'></span>"); $.each([ { label: "{{ku-IPA|+}}", snippet: "{{ku-IPA|}}", back: 2 }, { label: "{{IPA|+}}", snippet: "{{IPA|ku|}}", back: 2 } ], function (_, t) { var b = $("<button type='button' class='wiktku-ipa-tplbtn'></button>").text(t.label); b.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], t.snippet); // Park the cursor inside the braces, where the value goes. var pos = ta[0].selectionStart - t.back; ta[0].selectionStart = ta[0].selectionEnd = pos; ta.focus(); }); tplBtns.append(b); }); subTabs.append(tplBtns); panel.append(subTabs); function buildGrid(groups) { var grid = $("<div class='wiktku-ipa-grid'></div>"); $.each(groups, function (_, g) { var row = $("<div class='wiktku-ipa-row'></div>"); row.append($("<span class='wiktku-ipa-rowlabel'></span>").text(g.label)); var keys = $("<span class='wiktku-ipa-keys'></span>"); $.each(g.chars, function (_, ch) { var btn = $("<button type='button' class='wiktku-ipa-key'></button>"); // A combining mark on its own renders as a stray // accent floating over whatever precedes it, so // show it on a dotted circle — but insert only // the mark itself. var combining = /^[̀-ͯ҃-҉]$/.test(ch); btn.text(combining ? "◌" + ch : ch); if (combining) btn.addClass("wiktku-ipa-key-combining"); btn.attr("title", ch); btn.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], ch); ta.focus(); }); keys.append(btn); }); row.append(keys); grid.append(row); }); return grid; } var kuGrid = buildGrid(steps.pron.IPA_KU); var fullGrid = buildGrid(steps.pron.IPA_FULL).hide(); panel.append(kuGrid).append(fullGrid); kuTab.on("click", function () { kuTab.addClass("wiktku-tab-active"); fullTab.removeClass("wiktku-tab-active"); kuGrid.show(); fullGrid.hide(); }); fullTab.on("click", function () { fullTab.addClass("wiktku-tab-active"); kuTab.removeClass("wiktku-tab-active"); fullGrid.show(); kuGrid.hide(); }); panel.addClass("wiktku-ipa-palette"); wrap.append(panel); }, /** Inline preview + confirm panel for a "noLang" (auto-content) * pronunciation template — fetches what the snippet expands to * for this page and only inserts it if the user confirms. */ showTplPreview: function (stepDiv, ta, snippet, tplLabel) { // Only one preview panel open at a time. stepDiv.find(".wiktku-pron-preview").remove(); var panel = $("<div class='wiktku-pron-preview'></div>"); panel.append($("<div class='wiktku-pron-preview-label'></div>") .text("Pêşdîtina " + tplLabel + ":")); var body = $("<div class='wiktku-pron-preview-body'></div>").text("Tê barkirin…"); panel.append(body); var actions = $("<div class='wiktku-pron-preview-actions'></div>"); var confirmBtn = $("<button type='button' class='wiktku-pron-preview-confirm'>✓ Tevlî bike</button>") .prop("disabled", true); var cancelBtn = $("<button type='button' class='wiktku-pron-preview-cancel'>✕ Betal bike</button>"); actions.append(confirmBtn).append(cancelBtn); panel.append(actions); ta.before(panel); confirmBtn.on("click", function () { insertAtCursor(ta[0], snippet); panel.remove(); ta.focus(); }); cancelBtn.on("click", function () { panel.remove(); }); // action=parse, not action=expandtemplates. expandtemplates // returns *expanded wikitext*, so the preview read as // [[IPA]]<sup>([[Wîkîferheng:IPA kurmancî|kilîd]])</sup>: // <span class="IPA">/-{kshhe}-/</span>[[Kategorî:…]] — which // is exactly what the person is trying to avoid having to // read. parse hands back the rendered HTML the page will // actually show. // // Drop the leading "* " first: it is wikitext list syntax // wrapping the template, and keeping it would render the // preview as a bulleted list rather than the line itself. new mw.Api().post({ action: "parse", title: pageName, text: snippet.replace(/^\*\s*/, ""), prop: "text", wrapoutputclass: "", disablelimitreport: 1, disableeditsection: 1, contentmodel: "wikitext", formatversion: 2 }).done(function (data) { var html = (data && data.parse && data.parse.text) || ""; if ($.trim($("<div>").html(html).text())) { body.html(html); // Category links render as nothing but still exist; // and any real link inside a preview should not // navigate away from a half-filled form. body.find("a").attr("target", "_blank").attr("rel", "noopener"); } else { body.text("(vala — ji bo vê rûpelê tiştek nehate afirandin)"); } confirmBtn.prop("disabled", false); }).fail(function () { body.text("Pêşdîtin nehate barkirin — tu dikarî hîn jî wê tevlî bikî."); confirmBtn.prop("disabled", false); }); }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line; }).join("\n"); // "===" heading under Ziman and above the POS sections; the // field is shared across sections, so it's emitted once by // getWikitext() rather than per-POS-section (would otherwise // print the pronunciation twice for a two-POS entry). return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var capitalizedPos = capitalize(pos); // "form" opt-param (checked in posparams) marks this as a // form-of/inflected entry — the section title becomes // "Formeke <pos>ê" instead of the plain pos name. The // template call itself still uses the unchanged pos name. var isForm = $("#wiktku-posparams-opt-form").is(":checked"); var header = isForm ? "\n=== Formeke " + pos + "ê ===\n" : "\n=== " + capitalizedPos + " ===\n"; // Image line (between header and template call) var imageLine = steps.resim.output(values); // Read the live wikitext from the posparams textarea. // Fall back to a plain {{pos|lang}} if the step hasn't been built yet. var tplLine = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); if (!tplLine) { tplLine = "{{" + pos + "|" + (values.lang || "") + "}}"; } return header + imageLine + tplLine + "\n"; } }, // cinsiyet (gender) — shown for navdêr/serenav only, with choices built // from metadata[lang].g since not every language has grammatical gender. cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams // Single source of truth for the selected gender code. The visible // dropdown lives inside the posparams step (see steps.posparams), // but it must always read/write THIS hidden field — not a field of // its own — since getValuesForStep("cinsiyet") reads from here. build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-cinsiyet-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // jimar (grammatical number) — same hidden-field pattern as cinsiyet // above, but writes into its own j= template parameter instead of // sharing c=. Shown for navdêr/serenav only, with choices built from // whichever of metadata[lang].g are number codes (see isNumberCode). jimar: { id: "jimar", name: "jimar", question_fmt: 'Jimara "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-jimar-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // Lêker transitivity — hidden step, handled inside posparams lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function () { return false; }, choices: [ { code: "gh", label: "gerguhêz" }, { code: "x-gh", label: "xwerû-gerguhêz" }, { code: "p-gh", label: "pêkhatî-gerguhêz" }, { code: "h-gh", label: "hevedudanî-gerguhêz" }, { code: "b-gh", label: "biwêjî-gerguhêz" }, { code: "ngh", label: "negerguhêz" }, { code: "x-ngh", label: "xwerû-negerguhêz" }, { code: "p-ngh", label: "pêkhatî-negerguhêz" }, { code: "h-ngh", label: "hevedudanî-negerguhêz" }, { code: "b-ngh", label: "biwêjî-negerguhêz" } ], output: function () { return ""; } }, // tr — hidden step, handled inside posparams tr: { id: "tr", name: "transliterasyon", question_fmt: "Transliterasyona vê kelîmeyê", multiple: false, narrow: true, visible: function () { return false; } }, posparams: { id: "posparams", // Fused onto the "pos" card visually (see #wiktku-start-posparams // in styles.css) so the two read as ONE question — this name is // only a no-CSS/no-JS fallback, since the h3 that would show it // is hidden by CSS. name: "taybetmendî", // Shows what's actually being asked for: gender for nouns, verb // type for verbs, a generic fallback otherwise. question_fmt: function (values) { var pos = values.pos || ""; // Cinsiyet/Jimar fields below are self-labelled, so no title needed here. if (pos === "navdêr" || pos === "serenav") return ""; if (/^lêker/.test(pos)) return "Cureyê lêkerê"; return "Taybetmendî"; }, visible: function (values) { return !!(values.lang && values.pos); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-posparams-wrap").length) return null; var wrap = $("<div class='wiktku-posparams-wrap'></div>"); var helpers = $("<div class='wiktku-posparams-helpers'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-posparams-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-posparams-text") .attr("rows", 2); var _rebuilding = false; function safeRebuild() { if (_rebuilding) return; _rebuilding = true; steps.posparams.rebuildTa(stepDiv); _rebuilding = false; refresh(); } // Generic text-input row factory function makeTextRow(key, labelText, placeholder) { var row = $("<div class='wiktku-posparams-row'></div>") .attr("id", "wiktku-posparams-row-" + key).hide(); var inp = $("<input type='text'>") .addClass("wiktku-start-narrow wiktku-posparams-field") .attr("data-pp-key", key) .attr("placeholder", placeholder || ""); inp.on("input", safeRebuild); row.append($("<label></label>").text(labelText + ": ")).append(inp); return row; } // cinsiyet var cinsiyetRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-c'></div>") .append($("<label></label>").text("Cinsiyet: ")).hide(); var cinsiyetSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-cinsiyet-sel") .append($("<option value=''>— hilbijêre —</option>")); // Writes into the real, shared #wiktku-start-cinsiyet-field (owned by // steps.cinsiyet) rather than a field of its own — see the comment // on steps.cinsiyet.build for why that matters. cinsiyetSel.on("change", function () { $("#wiktku-start-cinsiyet-field").val($(this).val()).trigger("change"); safeRebuild(); }); cinsiyetRow.append(cinsiyetSel); // jimar (number) — second dropdown next to Cinsiyet, writes // into the shared hidden #wiktku-start-jimar-field, into its // own j= param instead of sharing c=. Options + tooltip are // built in syncHelpers once the language's number codes are known. var jimarRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-jimar'></div>") .append($("<label></label>").text("Jimar: ")).hide(); var jimarSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-jimar-sel") .append($("<option value=''>— hilbijêre —</option>")); jimarSel.on("change", function () { $("#wiktku-start-jimar-field").val($(this).val()).trigger("change"); safeRebuild(); }); jimarRow.append(jimarSel); // lektur: two plain questions (transitivity + structural form) // instead of one 10-option dropdown. Emitted code: base alone // ("gh"), or prefix + "-" + base ("x-gh"). var lekturRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lektur'></div>") .append($("<label></label>").text("Lêker derbasdar e? ")).hide(); var lekturSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lektur-sel") .append($("<option value=''>— hilbijêre —</option>")) .append($("<option value='gh'>gerguhêz (bireser digire)</option>")) .append($("<option value='ngh'>negerguhêz (bireser nagire)</option>")); lekturSel.on("change", safeRebuild); lekturRow.append(lekturSel); // Second half of the same question — the structural form. // Blank = xwerû/sade, which is the common case. var lekturFormRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lekturform'></div>") .append($("<label></label>").text("Şiklê lêkerê: ")).hide(); var lekturFormSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lekturform-sel") .append($("<option value=''>sade (asayî)</option>")) .append($("<option value='x'>xwerû</option>")) .append($("<option value='p'>pêkhatî</option>")) .append($("<option value='h'>hevedudanî</option>")) .append($("<option value='b'>biwêjî</option>")); lekturFormSel.on("change", safeRebuild); lekturFormRow.append(lekturFormSel); helpers.append(cinsiyetRow).append(jimarRow).append(lekturRow).append(lekturFormRow); // ── Everything below here is "Tercîhên pêşketî" ────────────── // These rows live inside a collapsed panel, so the default // view of this card is two dropdowns instead of twenty-odd fields. // Transliteration is a primary field, not an advanced one, for // any language not written in Latin script: for those, an // entry without it is incomplete. syncHelpers already gates // the row on needsTransliteration(lang), so for Kurmancî and // other Latin-script languages it simply never appears. helpers.append(makeTextRow("tr", "Transliterasyon (tr)", "Transliterasyon…")); var advPanel = $("<div class='wiktku-posparams-adv-panel'></div>").hide(); advPanel .append(makeTextRow("cuda", "nîşankirina alternatîv", "cuda…")) .append(makeTextRow("ts", "Transkrîpsiyon (ts)", "Transkrîpsiyon…")) .append(makeTextRow("m", "Forma mê (m)", "Forma mê…")) .append(makeTextRow("mtr", "Translit. mê (mtr)", "Transliterasyona mê…")) .append(makeTextRow("n", "Forma nêr (n)", "Forma nêr…")) .append(makeTextRow("ntr", "Translit. nêr (ntr)", "Transliterasyona nêr…")) .append(makeTextRow("p", "Forma pirjimar (p)", "Forma pirjimar…")) .append(makeTextRow("ptr", "Translit. pirjimar", "Transliterasyona pirjimar…")) .append(makeTextRow("y", "Forma yekjimar (y)", "Forma yekjimar…")) .append(makeTextRow("ytr", "Translit. yekjimar", "Transliterasyona yekjimar…")) .append(makeTextRow("sûp", "Forma sûperlatîv (sûp)", "Forma sûperlatîv…")) .append(makeTextRow("sûptr", "Translit. sûperlatîv", "Transliterasyona sûperlatîv…")) .append(makeTextRow("komp", "Forma komparatîv (komp)", "Forma komparatîv…")) .append(makeTextRow("komptr", "Translit. komparatîv", "Transliterasyona komparatîv…")) .append(makeTextRow("gir", "Forma girdêk (gir)", "gir=…")) .append(makeTextRow("girtr", "Translit. gir", "girtr=…")) .append(makeTextRow("hûr", "Forma hûrek (hûr)", "hûr=…")) .append(makeTextRow("hûrtr", "Translit. hûr", "hûrtr=…")) .append(makeTextRow("hanja", "Forma hanja", "hanja=…")) .append(makeTextRow("hanjaTr","Translit. hanja", "hanjaTr=…")) // Lêker rehên demê (only shown when pos is lêker — see syncHelpers) .append(makeTextRow("niha", "Rehê dema niha (niha)", "Rehê dema niha…")) .append(makeTextRow("nihatr", "Translit. rehê dema niha", "Transliterasyona rehê dema niha…")) .append(makeTextRow("borî", "Rehê dema borî (borî)", "Rehê dema borî…")) .append(makeTextRow("borîtr", "Translit. rehê dema borî", "Transliterasyona rehê dema borî…")) .append(makeTextRow("subj", "Rehê dema bilanî (subj)", "Rehê dema bilanî…")) .append(makeTextRow("subjtr", "Translit. rehê dema bilanî", "Transliterasyona rehê dema bilanî…")); // Optional boolean params — nested inside the advanced panel // (they were already the most niche thing on the card). var optPanel = $("<div class='wiktku-posparams-opt-panel'></div>"); $.each([ { key: "form", label: "form — ev made forma tewandî ye" }, { key: "formaalt", label: "formaalt — vê madeyê bike forma alternatîv" }, { key: "nekatcure", label: "nekatcure — sinifa rêzimanî kategorîze neke" }, { key: "nekatcins", label: "nekatcins — kategoriya cinsiyetê neyîne" }, { key: "nekatçendterm", label: "nekatçendterm — kategoriya çend-term neyîne" }, { key: "serlînkneke", label: "serlînkneke — sernavê madeyê lînk neke" }, { key: "nekatpalîndrom", label: "nekatpalîndrom — kategoriya palîndromê neyîne" }, { key: "neformtr", label: "neformtr — transliterasyona forman neyîne" } ], function (_, p) { var cb = $("<input type='checkbox'>") .attr("id", "wiktku-posparams-opt-" + p.key).val(p.key).on("change", safeRebuild); var lbl = $("<label></label>").attr("for", "wiktku-posparams-opt-" + p.key).text(" " + p.label); optPanel.append($("<div class='wiktku-posparams-opt-row'></div>").append(cb).append(lbl)); }); advPanel.append(optPanel); var optToggle = $("<a href='#' class='wiktku-posparams-opt-toggle wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tercîhên pêşketî</span>")); optToggle.on("click", function (e) { e.preventDefault(); var open = advPanel.is(":visible"); advPanel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); helpers.append($("<div class='wiktku-adv-toggle-row'></div>") .append(optToggle)); helpers.append(advPanel); wrap.append(helpers).append(ta); // Typing directly in textarea keeps cinsiyet/jimar hidden // fields in sync, but does NOT call refresh() — preserves // manual edits. ta.on("input", function () { var text = $(this).val(); var cMatch = text.match(/\|c=([^|}\s]+)/); $("#wiktku-start-cinsiyet-field").val(cMatch ? cMatch[1] : ""); var jMatch = text.match(/\|j=([^|}\s]+)/); $("#wiktku-start-jimar-field").val(jMatch ? jMatch[1] : ""); }); stepDiv.append(wrap); return null; }, /** Reads all helper widget values and rewrites the textarea. * Called only by safeRebuild (user interaction) — never by syncHelpers, * so manual textarea edits are never overwritten by a refresh cycle. */ rebuildTa: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; if (!pos || !lang) return; var cinsiyet = stepDiv.find(".wiktku-posparams-cinsiyet-sel").val() || ""; var jimar = stepDiv.find(".wiktku-posparams-jimar-sel").val() || ""; // Two dropdowns, one code: "gh" / "ngh" on their own, or // prefixed with the structural form ("x-gh", "b-ngh", …). var lekturBase = stepDiv.find(".wiktku-posparams-lektur-sel").val() || ""; var lekturForm = stepDiv.find(".wiktku-posparams-lekturform-sel").val() || ""; var lektur = lekturBase ? (lekturForm ? lekturForm + "-" + lekturBase : lekturBase) : ""; function v(key) { return $.trim(stepDiv.find(".wiktku-posparams-field[data-pp-key='" + key + "']").val()); } var out = "{{" + pos + "|" + lang; if (pos === "navdêr" || pos === "serenav") { out += cinsiyet ? "|c=" + cinsiyet : (lang === "ku" ? "|c=?" : ""); // Number is its own j= param, separate from c= (which // holds gender, including compounds like m-p/n-p). if (jimar) out += "|j=" + jimar; } else if (/^lêker/.test(pos) && lektur) { out += "|c=" + lektur; } if (v("cuda")) out += "|" + v("cuda"); if (v("tr")) out += "|tr=" + v("tr"); if (v("ts")) out += "|ts=" + v("ts"); $.each(["m","n","p","y"], function (_, k) { if (v(k)) out += "|" + k + "=" + v(k); if (v(k+"tr")) out += "|" + k + "tr=" + v(k+"tr"); }); if (v("sûp")) out += "|sûp=" + v("sûp"); if (v("sûptr")) out += "|sûptr=" + v("sûptr"); if (v("komp")) out += "|komp=" + v("komp"); if (v("komptr")) out += "|komptr=" + v("komptr"); if (v("gir")) out += "|gir=" + v("gir"); if (v("girtr")) out += "|girtr=" + v("girtr"); if (v("hûr")) out += "|hûr=" + v("hûr"); if (v("hûrtr")) out += "|hûrtr=" + v("hûrtr"); if (v("hanja")) out += "|hanja=" + v("hanja"); if (v("hanjaTr")) out += "|hanjaTr=" + v("hanjaTr"); if (v("niha")) out += "|niha=" + v("niha"); if (v("nihatr")) out += "|nihatr=" + v("nihatr"); if (v("borî")) out += "|borî=" + v("borî"); if (v("borîtr")) out += "|borîtr=" + v("borîtr"); if (v("subj")) out += "|subj=" + v("subj"); if (v("subjtr")) out += "|subjtr=" + v("subjtr"); stepDiv.find(".wiktku-posparams-opt-panel input:checked").each(function () { var key = $(this).val(); // "form" marks this entry as a form-of/inflected entry — it // takes "erê" rather than the plain "1" the other boolean // opt params use. out += "|" + key + "=" + (key === "form" ? "erê" : "1"); }); out += "}}"; stepDiv.find(".wiktku-posparams-text").val(out); $("#wiktku-start-cinsiyet-field").val(cinsiyet); $("#wiktku-start-jimar-field").val(jimar); }, /** Called from refresh() — controls row visibility only. * Does NOT rewrite textarea so user edits are preserved. * Rebuilds only when textarea is empty (first pos selection). */ syncHelpers: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; var needsTr = needsTransliteration(lang); var isNom = pos === "navdêr" || pos === "serenav" || pos === "rengdêr"; var isAdj = pos === "rengdêr"; var isTîp = pos === "tîp"; var isJa = lang === "ja"; var isLeker = /^lêker/.test(pos); // metadata[lang].g lists gender AND number codes together — // split them here (see isNumberCode) so Cîns only ever offers // gender codes (and gender+plural compounds like m-p/n-p, // which aren't NUMBER_LABELS keys) and Jimar only offers number codes. var meta = metadata[lang]; var allCodes = (meta && meta.g) || []; var genderCodes = $.grep(allCodes, function (c) { return !isNumberCode(c); }); var jimarCodes = $.grep(allCodes, function (c) { return isNumberCode(c); }); var showC = (pos === "navdêr" || pos === "serenav") && genderCodes.length > 0; var cRow = stepDiv.find("#wiktku-posparams-row-c"); cRow.toggle(showC); if (showC) { var sel = cRow.find(".wiktku-posparams-cinsiyet-sel"); // Prefer the select's own current value (normal in-session // use); fall back to the shared hidden field, which is how // a cache/section restore communicates a saved gender // before this select has any <option>s to hold it. var prev = sel.val() || $("#wiktku-start-cinsiyet-field").val() || ""; sel.find("option[value!='']").remove(); $.each(genderCodes, function (_, code) { sel.append($("<option></option>").val(code).text(genderLabel(code))); }); if (prev) sel.val(prev); } var showJimar = (pos === "navdêr" || pos === "serenav") && jimarCodes.length > 0; var jimarRowEl = stepDiv.find("#wiktku-posparams-row-jimar"); jimarRowEl.toggle(showJimar); if (showJimar) { var jimarSelEl = jimarRowEl.find(".wiktku-posparams-jimar-sel"); var prevJimar = jimarSelEl.val() || $("#wiktku-start-jimar-field").val() || ""; jimarSelEl.find("option[value!='']").remove(); $.each(jimarCodes, function (_, code) { var def = NUMBER_LABELS[code] || {}; var opt = $("<option></option>").val(code).text(numberOptionLabel(code)); // The explanation (cat, e.g. "dualia tantum") shows as a // hover tooltip — <option> can't hold richer markup. if (def.cat) opt.attr("title", def.cat); jimarSelEl.append(opt); }); if (prevJimar) jimarSelEl.val(prevJimar); } stepDiv.find("#wiktku-posparams-row-lektur").toggle(isLeker); // Only ask for the structural form once gerguhêz/negerguhêz is answered. stepDiv.find("#wiktku-posparams-row-lekturform") .toggle(isLeker && !!stepDiv.find(".wiktku-posparams-lektur-sel").val()); stepDiv.find("#wiktku-posparams-row-tr").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-ts").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-m").toggle(isNom); stepDiv.find("#wiktku-posparams-row-mtr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-n").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ntr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-p").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ptr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-y").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ytr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-sûp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-sûptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-komp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-komptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-gir").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-girtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hûr").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-hûrtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hanja").toggle(isJa); stepDiv.find("#wiktku-posparams-row-hanjaTr").toggle(isJa); stepDiv.find("#wiktku-posparams-row-niha").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-nihatr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-borî").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-borîtr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-subj").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-subjtr").toggle(isLeker && needsTr); if (!$.trim(stepDiv.find(".wiktku-posparams-text").val())) { steps.posparams.rebuildTa(stepDiv); } }, output: function () { return ""; } // pos.output reads the textarea directly }, dfn: { id: "dfn", name: "Mane", // Field types that live behind "Malûmatên pêşketî". Kept as one // list so the collapse CSS, the count badge and the allGroups // adv: flags below can't drift apart. ADV_SUBGROUPS: [ "wiktku-dfn-etiket", "wiktku-dfn-kategori", "wiktku-dfn-alternativ", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ], question_fmt: function (values) { var base = "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin!"; if (values.lang === "ku") { return base + " Ji bo tercimeyan beşa 'Werger' bi kar bîne!"; } return base; }, multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, // Builds one sense block (<li>): mane textarea, nimûne list, and // sub-lists for alternatîv/hevmane/dijmane/etc. buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Tercime + Îzah boxes (non-ku alternative to the plain mane box) — // Non-ku entries get a direct translation plus a {{îzah|…}}-wrapped // gloss instead of a Kurdish-style gloss. Rather than teach every // consumer (getSenses/getOutput/linkify) a second data shape, these // boxes just write their combined text into dfnArea and re-fire its // "input" event, so dfnArea stays the single source of truth. var tercimeArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-tercime-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-tercime") .attr("rows", 2) .attr("placeholder", "Tercimeyên rasterast ên kurmancî… Ji bo school-a îngilîzî li vir 'mekteb, medrese' binivîse"); var izahArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-izah-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-izah") .attr("rows", 3) .attr("placeholder", "Îzaha kurmancî… Ji bo school-a îngilîzî li vir 'cihê tehsîlgirtinê' binivîse"); var nonKuWrap = $("<div class='wiktku-dfn-nonku-wrap'></div>") .append(tercimeArea).append(izahArea) .hide(); function syncNonKuToMane() { var t = $.trim(tercimeArea.val()); var iz = $.trim(izahArea.val()); // if tercime is blank, use îzah as definition var combined = t ? (iz ? t + " {{îzah|" + iz + "}}" : t) : iz; dfnArea.val(combined); // Re-fires onDfnInput, as if this were typed directly into // the mane textarea. dfnArea.trigger("input"); } tercimeArea.on("input", syncNonKuToMane); izahArea.on("input", syncNonKuToMane); // Switches between the plain mane box and the tercime+îzah pair — // only for non-ku entries with no tplSelect selected. function updateManeMode() { var lang = getValues().lang || ""; var isTpl = !!tplSelect.val(); if (lang && lang !== "ku" && !isTpl) { dfnArea.hide(); nonKuWrap.show(); } else { nonKuWrap.hide(); if (!isTpl) dfnArea.show(); } } // Store on the block so refresh() can re-sync every block when // lang changes, and restoreDfn() can re-sync after restoring. block.data("updateManeMode", updateManeMode); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || {}; // Cache of all non-placeholder option elements, so updateTplOptions // can detach/re-attach them without losing the full list. var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.attr("data-placeholder", "Li şablonekê bigere"); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (name, tpl) { // Shows "name — tpl.desc" when a tplDefs entry has a desc // in data.json, same pattern as steps.pron's template picker. var opt = $("<option></option>") .val(name) .text(tpl.desc ? name + " — " + tpl.desc : name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); // Same status-dot / 🔗 / ⓘ row treatment as every other // template picker. This one carries the bare name in value=, // so the name mapper is the identity rather than a snippet // parse; descriptions come from each template's TemplateData. markTemplateOptions(tplSelect, function (opt) { return opt.val(); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible // ones — native <select> won't reliably hide options any other way. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); // Options that were detached when the descriptions arrived // missed that pass, so describe whatever is attached now. // The cache is warm by this point, so this is synchronous. applyTplDescriptions(tplSelect); tplSelect.trigger("wiktku:refresh"); if (currentVal && !currentStillValid) { tplSelect.val(""); tplTitleInput.hide().val(""); updateManeMode(); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpela hedefê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // Şablon senses have no plain gloss, so hide alternatîv/hevmane/ // dijmane/etc. Etîket, Nimûne and Jêgirtin stay visible either way. function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); nonKuWrap.hide(); tplTitleInput.show().focus(); } else { tplTitleInput.hide().val(""); updateManeMode(); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); // The template picker is an alternative to writing a // definition, not a step before it — so the box comes first // and this sits under it as a quiet link. It only expands // for the minority of senses that are a pointer at another // word (guharto, şaşnivîs, kevnbûyî) rather than a meaning. var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput) .hide(); var tplLink = $("<a href='#' class='wiktku-dfn-tpl-link'></a>") .text("Ev ne pênase ye — şablonek bi kar bîne"); tplLink.on("click", function (e) { e.preventDefault(); tplRow.show(); $(this).hide(); tplRow.find("input.wiktku-ac-input").first().focus(); }); /** Opens the picker without a click — used on restore, when a * sense already has a template and hiding it would make the * chosen value invisible. */ function revealTplRow() { tplRow.show(); tplLink.hide(); } block.data("revealTplRow", revealTplRow); block.append(dfnArea); block.append(nonKuWrap); block.append(tplLink); block.append(tplRow); // Apply lang filter on initial build. updateTplOptions(); updateManeMode(); // — Sub-field groups. — // The four most-used groups (Nimûne, Jêgirtin, Hevmane, Dijmane) // stay open; the rest sit behind the "Malûmatên pêşketî" toggle // (adv: true → .wiktku-dfn-subgroup-adv, keyed off by the collapse CSS). // Jêgirtin isn't in this array — it's a compound widget built // after the loop — but it's inserted right after Nimûne so the // visible order matches the list above. var allGroups = [ { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "wekî etîket lê xuya nabe tenê kategorîze dike", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê", adv: true }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in", adv: true }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e", adv: true }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e", adv: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); if (g.adv) groupDiv.addClass("wiktku-dfn-subgroup-adv"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } // The placeholder names the current language, but that's // often not chosen yet when this block is first built — // so keep a function around that refresh() (and onSubInput, // for newly-grown fields) can call again once lang is set // or changes. function subPlaceholder() { if (g.noLangSuffix) return g.label + "…"; var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return g.label + (langLabel ? " bi " + langLabel : "") + "…"; } function updateSubPlaceholders() { list.find("> li > textarea.wiktku-dfn-subfield").attr("placeholder", subPlaceholder()); } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": ") .append($("<span></span>").addClass("wiktku-dfn-sublabel-hint").text(g.izah)); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var useModifiers = !!MODIFIER_SUBGROUPS[g.cls]; list.data("updatePlaceholders", updateSubPlaceholders); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", subPlaceholder()); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow, useModifiers); }); list.append(useModifiers ? makeModifierLi(firstInput) : $("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder group — growing list, same structure as Nimûne. — (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text("Jêgirtin")) .append(": "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<textarea></textarea>") .addClass("wiktku-dfn-subfield wiktku-dfn-quote-citoid-input") .attr("rows", 1) .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi otomatîk tijî bike", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); // Fetches citation data from Citoid and fills this citation's // şablon + fields — only rebuilds fields on template change, // and never overwrites values the user already typed. function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoid.fetchJederFields(query).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only rebuild if switching şablon, so a repeat fetch // doesn't clear fields already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel wiktku-plain-select"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); srcSel.append($("<option></option>").val("__category__").text("Ji Kategorî:Çavkanî şablonekê hilbijêre")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); // Citoid is only useful before a source is chosen — // hide it once a selection is made, restore on reset. if (chosen) { citoidWrap.hide(); } else { citoidWrap.show(); return; } if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } if (chosen === "__category__") { // Search widget over the members of [[Kategorî:Çavkanî]]. // Picking a şablon here immediately switches the row to // "Bi destê xwe binivîsim" mode with {{Şablon}} pre-filled, var catWrap = $("<span></span>").addClass("wiktku-native-select-wrap wiktku-dfn-quote-src-cat"); var catInput = $("<input type='search' autocomplete='off'>") .addClass("wiktku-start-narrow wiktku-dfn-quote-src-cat-input") .attr("placeholder", "Li navê şablonê bigere…"); var catResults = $("<ul></ul>").addClass("wiktku-ac-results wiktku-dfn-quote-src-cat-results").hide(); var catStatus = $("<span></span>").addClass("wiktku-dfn-quote-src-cat-status").text("Şablon tên barkirin…"); var showCatResults = function (query) { var q = $.trim(query).toLowerCase(); catResults.empty(); var list = catSrcTemplates || []; var matched = q ? $.grep(list, function (name) { return name.toLowerCase().indexOf(q) !== -1; }) : list; if (!matched.length) { catResults.hide(); return; } $.each(matched.slice(0, 50), function (_, name) { var li = $("<li></li>").text(name).attr("data-value", name); var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; e.preventDefault(); selectCatTpl(name); }); li.on("mousedown", function (e) { e.preventDefault(); selectCatTpl(name); }); catResults.append(li); }); catResults.show(); }; // Wraps the chosen şablon as {{Name}}, drops it into the // manual textarea, and switches the row into manual mode // so the user can keep editing it (add params, etc.). var selectCatTpl = function (name) { catResults.hide(); srcSel.val("__manual__"); srcSel.trigger("change"); srcFields.find(".wiktku-dfn-quote-src-manual") .val("{{" + name + "}}") .trigger("focus"); }; catInput.on("input", function () { showCatResults($(this).val()); }); catInput.on("focus", function () { showCatResults($(this).val()); }); catInput.on("blur", function () { setTimeout(function () { catResults.hide(); }, 200); }); catWrap.append(catInput).append(catResults).append(catStatus); srcFields.append(catWrap); fetchCatSrcTemplates().then(function () { catStatus.text(""); }, function () { catStatus.text("Şablon nehatin barkirin."); }); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (key, label) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", key) .attr("placeholder", label + "…"); // "Sernav" / "Sernavê orjînal" (title fields, e.g. for // kitêb/kovar/malper) get a taller, draggable box; every // other field in the template stays as-is. Field labels // come from the on-wiki jederDefs data, so match on the // (diacritic-folded) label text rather than a fixed key. var foldedLabel = foldDiacritics(label); if (/^sernav$/.test(foldedLabel) || /orjin/.test(foldedLabel)) { inp.addClass("wiktku-dfn-quote-src-input--title"); } row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); jederGroupDiv.append(jederLbl).append(jederList); // Straight after Nimûne rather than last: Jêgirtin is the // same kind of thing (an attested use of the word) and the // two belong together — see the allGroups comment above. var nimuneGroup = block.find(".wiktku-dfn-nimune-group"); if (nimuneGroup.length) jederGroupDiv.insertAfter(nimuneGroup); else block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); // ── "Malûmatên pêşketî" — per sense, after Dijmane ─────── // One toggle per sense rather than one for the whole step: // the fields behind it (Etîket, Kategorî, Jornav…) belong to // a single meaning, so a global switch flipped them for every // sense at once and gave a count that answered "across all // senses" — not a question anybody was asking. (function () { block.addClass("wiktku-sense-adv-hidden"); var advRow = $("<div class='wiktku-adv-toggle-row wiktku-sense-adv-row'></div>"); var advToggle = $("<a href='#' class='wiktku-adv-toggle'></a>").attr("aria-expanded", "false"); var advLabel = $("<span class='wiktku-adv-toggle-text'></span>"); advToggle.append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")).append(advLabel); function syncAdv() { var hidden = block.hasClass("wiktku-sense-adv-hidden"); advLabel.text(hidden ? "Malûmatên pêşketî nîşan bide" : "Malûmatên pêşketî veşêre"); advToggle.attr("aria-expanded", hidden ? "false" : "true") .toggleClass("wiktku-adv-open", !hidden); } advToggle.on("click", function (e) { e.preventDefault(); block.toggleClass("wiktku-sense-adv-hidden"); syncAdv(); }); block.data("syncSenseAdv", syncAdv); advRow.append(advToggle); // After the last always-visible group (Dijmane) and before // the advanced ones, which sit below it in DOM order. var lastPrimary = block.find(".wiktku-dfn-dijmane-group"); if (lastPrimary.length) advRow.insertAfter(lastPrimary); else block.append(advRow); syncAdv(); }()); return block; }, /** Shows only `block` among the sense list; hides every other one. */ setOpenSense: function (stepDiv, block) { stepDiv.find("li.wiktku-dfn-sense").each(function () { $(this).toggleClass("wiktku-sense-collapsed", !$(this).is(block)); }); steps.dfn.renderSenseTabs(stepDiv); }, /** Rebuilds the "Mane 1 / Mane 2 / + Mane zêde bike" tab row from the current sense list. */ renderSenseTabs: function (stepDiv) { var tabsDiv = stepDiv.find(".wiktku-dfn-sense-tabs"); if (!tabsDiv.length) return; tabsDiv.empty(); stepDiv.find("li.wiktku-dfn-sense").each(function (i) { var li = $(this); var tab = $("<span class='wiktku-dfn-sense-tab'></span>") .text("Mane " + (i + 1)) .toggleClass("wiktku-tab-active", !li.hasClass("wiktku-sense-collapsed")); tab.on("click", function () { steps.dfn.setOpenSense(stepDiv, li); }); tabsDiv.append(tab); }); var addBtn = $("<button type='button' class='wiktku-add-sense'></button>") .append($("<span class='wiktku-add-sense-plus'>+</span>")) .append(document.createTextNode("Mane zêde bike")); addBtn.on("click", function (e) { e.preventDefault(); steps.dfn.addSense(stepDiv); }); tabsDiv.append(addBtn); }, onDfnInput: function (stepDiv, block, textarea) { refresh(); }, /** Appends a sense, opens it, and hides the others. */ addSense: function (stepDiv) { var list = stepDiv.find("ol.wiktku-dfn-list"); var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); initSelects(newBlock); steps.dfn.setOpenSense(stepDiv, newBlock); newBlock.find("textarea.wiktku-dfn-mane").first().focus(); refresh(); return newBlock; }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow, modifiers) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow, modifiers); }); list.append(modifiers ? makeModifierLi(next) : $("<li></li>").append(next)); // New field starts with no placeholder — give it (and any // others in the list) the current one. var updatePlaceholders = list.data("updatePlaceholders"); if (typeof updatePlaceholders === "function") updatePlaceholders(); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: {}, posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; // One reassurance, shown once for the whole Mane step: the // "an jî şablonek hilbijêre" dropdown inside each sense is // optional — plain text is the normal path. if (!stepDiv.find(".wiktku-dfn-tpl-hint").length) { stepDiv.append( $("<p class='wiktku-step-hint wiktku-dfn-tpl-hint'></p>").text( "Ji bo her maneyekê, dropdown-a \"an jî şablonek hilbijêre\" ne mecbûrî ye — bi gelemperî tu tenê maneyê bi tîpên asayî dinivîsî. Ew şablon tenê ji bo rewşên taybet in (mînak: guherto, kevnbûyî, şaşnivîs); heke tu nizanî kîjan divê, vale bihêle." ) ); } var tabsDiv = $("<div class='wiktku-dfn-sense-tabs'></div>"); stepDiv.append(tabsDiv); var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); steps.dfn.renderSenseTabs(stepDiv); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName === "__category__") { // Reachable only if the user opened the category search but // never picked a şablon — picking one switches the row to // __manual__ (see selectCatTpl above), so there's nothing // meaningful to save here. } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: readList("wiktku-dfn-etiket"), kategori: readList("wiktku-dfn-kategori"), nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense var izahLines = []; // parallel — raw îzah gloss for that same sense // True only once some sense's *actual* dfn text (post tercime/îzah // split) is non-empty. var hasLinkableMane = false; $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("# " + (tplKatTpl ? tplKatTpl + " " : "") + (tplLabelTpl ? tplLabelTpl + " " : "") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(""); // template senses have no îzah return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty // Pull the îzah gloss (if any) out of the combined tercime+îzah // string — it's spliced back in separately below, after its // own linkify pass (see izahLines / the second linkifyText call). var izahRaw = null; var tercimeIzah = splitTercimeIzah(dfn); if (tercimeIzah) { dfn = tercimeIzah.tercime; izahRaw = stripWikilinks(tercimeIzah.izah); } if (dfn) { dfn = stripWikilinks(dfn); // Sentence-case + trailing period are for ku definitions, // which are written as full glosses. if (lang === "ku") { if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } // Real prose — this is what makes the sense worth running // through the main linkify pass. hasLinkableMane = true; } else if (izahRaw === null) { // No mane at all — this is just the "{{mane?|lang}}" // placeholder, a bare template call with no plain words // in it. Do NOT count it as linkable: sending nothing but // bracketed templates through the main linkify pass hangs // the linkify gadget (see the hasLinkableMane/hasIzah // check below). dfn = lang === "ku" ? "{{mane?|" + lang + "}}" : ""; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var out = "# " + (katTpl ? katTpl + " " : "") + (labelTpl ? labelTpl + " " : "") + dfn; var idx = defLines.length; var hasThisIzah = izahRaw !== null && $.trim(izahRaw) !== ""; // Bare {{...}} token — like {{wiktku-cite-N}}, this survives // linkify's first pass untouched (it treats template calls as // opaque), then gets swapped for {{îzah|…}} once the actual // gloss text has been linkified in its own separate pass. if (hasThisIzah) { out += (dfn ? " " : "") + "{{wiktku-izah-" + idx + "}}"; } function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(hasThisIzah ? izahRaw : ""); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } // Runs text through the linkify gadget if it's loaded, otherwise // just passes it through unchanged. Shared by both linkify passes // below (main mane text, and — separately — îzah glosses). function linkifyText(t, cb) { if (typeof $.kuLinkify === "function") { $.kuLinkify(t, cb); } else { cb(t); } } var hasIzah = izahLines.some(function (t) { return t && $.trim(t) !== ""; }); var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with nimûne?. text = "# {{mane?|" + lang + "}}\n#* {{nimûne?|" + lang + "}}\n"; callback(text); return; } // Runs the îzah-only linkify pass against `base` (either the raw // text, when there's no linkable mane to run the main pass on // first, or the already-linkified main text). Shared by both // branches below so the token-splice logic only lives once. function runIzahPass(base) { var izahJoined = $.map(izahLines, function (raw, idx) { if (!raw) return undefined; return "{{wiktku-izah-open-" + idx + "}}" + raw + "{{wiktku-izah-close-" + idx + "}}"; }).join("\n"); linkifyText(izahJoined, function (izahLinked) { var izahByIdx = {}; var re = /\{\{wiktku-izah-open-(\d+)\}\}([\s\S]*?)\{\{wiktku-izah-close-\1\}\}/g; var m; while ((m = re.exec(izahLinked)) !== null) { izahByIdx[parseInt(m[1], 10)] = m[2]; } var withIzah = base.replace(/\{\{wiktku-izah-(\d+)\}\}/g, function (_, n) { var linked = izahByIdx[parseInt(n, 10)]; return linked !== undefined ? "{{îzah|" + linked + "}}" : ""; }); callback(restoreCites(withIzah)); }); } if (!hasLinkableMane) { if (!hasIzah) { // All filled senses are template senses (or otherwise have // no plain text at all) — nothing here needs linkify. callback(restoreCites(text)); return; } // There's no plain mane text anywhere (e.g. tercime left blank // with only îzah filled in), so every defLine is just a bare // template call with nothing to word-link. Sending a line // like "# {{wiktku-izah-0}}" through the main linkify pass // gives it no plain words to work with, makes the linkify // gadget hang — so skip that pass entirely and run only // the îzah pass, splicing straight into the unlinkified text. var loadIzahOnly = function () { runIzahPass(text); }; mw.loader.using("ext.gadget.linkify", loadIzahOnly, loadIzahOnly); return; } var didTryToLoad = function () { // First pass: the main definition text (mane), same as before. linkifyText(text, function (mainLinked) { if (!hasIzah) { callback(restoreCites(mainLinked)); return; } // Second pass: îzah glosses, linkified via their own // separate call. Each gloss is wrapped in its own // {{wiktku-izah-open/close-N}} pair; like the existing // {{wiktku-cite-N}} tokens, these sit inside double // braces so linkify leaves the tokens themselves alone — // only the raw gloss text between each pair gets linked. runIzahPass(mainLinked); }); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, tewandin: { id: "tewandin", name: "tewandin", question_fmt: 'Tewandina "' + pageName + '" binivîse', visible: function (values) { return values.lang && values.pos; }, build: function (stepDiv) { if (stepDiv.find(".wiktku-tewandin-wrap").length) return null; var wrap = $("<div class='wiktku-tewandin-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-tewandin-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-tewandin-text") .attr("rows", 4) .attr("placeholder", "{{ku-tewîn-nav|nêr}}"); wrap.append(ta); stepDiv.append(wrap); function autoPopulate() { if (!ta.length) return; var vals = getValues(); var c = vals.cinsiyet || ""; var p = vals.pos || ""; if (!pageName.includes(" ") && c && GENDER_BASE_LABELS[c] && (p === "navdêr" || p === "serenav") && vals.lang === "ku" && c !== "mndudil") { var label = (c === "mnmane") ? "mê û nêr" : GENDER_BASE_LABELS[c]; var out = "{{ku-tewîn-nav|" + label; if (p === "serenav") out += "|y"; out += "}}"; if (!$.trim(ta.val())) ta.val(out); } } setTimeout(function () { autoPopulate(); $("#wiktku-start-form").on("change.tewandin", "#wiktku-start-lang-field, #wiktku-start-cinsiyet-field, #wiktku-start-pos-field", autoPopulate); }, 0); return ta; }, output: function () { var manualText = $.trim($("#wiktku-start-tewandin .wiktku-tewandin-text").val()); if (manualText) { return "\n==== Tewandin ====\n" + manualText + "\n"; } return ""; } }, // resim — one or more images resim: { id: "resim", name: "resim", question_fmt: "Resmekê lê zêde bike", visible: function (values) { return !!(values.lang && values.pos); }, /** Builds one image row: filename + caption + alt text. */ buildItem: function (stepDiv) { var item = $("<li class='wiktku-resim-item'></li>"); var fileRow = $("<div class='wiktku-posparams-row'></div>"); var fileInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-file") .attr("placeholder", "navê_dosyayê.jpg"); fileRow.append($("<label></label>").text("Navê dosyayê: ")).append(fileInp); var capRow = $("<div class='wiktku-posparams-row'></div>"); var capInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-caption") .attr("placeholder", "Danasîna resimê…"); capRow.append($("<label></label>").text("Danasîn: ")).append(capInp); // Alt text: what a screen reader announces for this image var altRow = $("<div class='wiktku-posparams-row'></div>"); var altInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-alt") .attr("placeholder", "Ji bo kesên nabînin, çi tê dîtin? (ne mecbûrî)"); altRow.append($("<label></label>").text("Nivîsa alternatîf: ")).append(altInp); // Auto-fill the caption with the plain page name when a filename // is typed fileInp.on("input", function () { var file = $.trim($(this).val()); var curCap = $.trim(capInp.val()); var isDefault = !curCap || curCap === pageName; if (file && isDefault) { capInp.val(pageName); } else if (!file && isDefault) { capInp.val(""); } steps.resim.onFileInput(stepDiv, item, this); }); item.append(fileRow).append(capRow).append(altRow); return item; }, /** Grows the image list when the last row's filename gets content. */ onFileInput: function (stepDiv, item, input) { var val = $.trim($(input).val()); var list = stepDiv.find("ol.wiktku-resim-list"); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { list.append(steps.resim.buildItem(stepDiv)); } }, build: function (stepDiv) { if (stepDiv.find(".wiktku-resim-wrap").length) return null; var wrap = $("<div class='wiktku-resim-wrap'></div>"); var list = $("<ol class='wiktku-resim-list'></ol>"); list.append(steps.resim.buildItem(stepDiv)); wrap.append(list); stepDiv.append(wrap); return null; }, /** Reads every filled row from the DOM into an array of {file, caption, alt} * objects — blank rows (missing filename or caption) are skipped. * Non-Kurdish captions get wrapped in {{zim|lang|…}} here, unless * the user already typed their own {{zim|…}} template. Alt text is * optional and left as plain text either way. */ getImages: function (values) { var lang = (values && values.lang) || getValues().lang || ""; var images = []; $("#wiktku-start-resim li.wiktku-resim-item").each(function () { var file = $.trim($(this).find(".wiktku-resim-file").val()); var caption = $.trim($(this).find(".wiktku-resim-caption").val()); var alt = $.trim($(this).find(".wiktku-resim-alt").val()); if (!file || !caption) return; // Strip leading "Wêne:" or "File:" if the user typed it — we add it ourselves. file = file.replace(/^(wêne|file|image)\s*:\s*/i, ""); if (lang && lang !== "ku" && !/^\{\{zim\s*\|/i.test(caption)) { caption = "{{zim|" + lang + "|" + caption + "}}"; } images.push({ file: file, caption: caption, alt: alt }); }); return images; }, output: function (values) { var images = steps.resim.getImages(values); if (!images.length) return ""; return images.map(function (img) { var altPart = img.alt ? "|alt=" + img.alt : ""; return "[[Wêne:" + img.file + "|thumb" + altPart + "|" + img.caption + "]]"; }).join("\n") + "\n"; } }, // bnr-h — {{bnr-h|Page1|Page2|…}} prepended before the lang section (shared, not per-section) bnrh: { id: "bnrh", name: "binêre herwiha (bnr-h)", question_fmt: "Şablona bnr-h li qismê herî jor a rûpelê", //visible: function (values) { return !!values.lang; }, multiple: true, narrow: true, placeholder: "Ji bo 'test' bnr 'Test', 'teşt'", output: function (values) { var pages = $.grep(values.bnrh || [], function (p) { return !!$.trim(p); }); if (!pages.length) return ""; return "{{bnr-h|" + pages.map(function (p) { return $.trim(p); }).join("|") + "}}\n"; } }, bikaranin: { id: "bikaranin", name: "Notên bikaranînê", question_fmt: "Notên bikaranînê yên li ser vê kelîmeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, output: function (values) { var text = $.trim(values.bikaranin || ""); if (!text) return ""; return "\n==== Notên bikaranînê ====\n" + text + "\n"; }, }, xwendin: { id: "xwendin", name: "Bêhtir bixwîne", question_fmt: "Lînkên derveyî eleqedarî vê madeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: function (values) { if (!values || !values.lang) { return `* {{wpedî}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; } const ziman = values.lang === "ku" ? "" : `|ziman=${values.lang}`; return `* {{wpedî${ziman}}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; }, output: function (values) { var text = $.trim(values.xwendin || ""); if (!text) return ""; return "\n==== Bêhtir bixwîne ====\n" + text + "\n"; }, }, alfabeyendin: { id: "alfabeyendin", name: "Bi alfabeyên din", question_fmt: function (values) { var base = "Nivîsîna vê kelîmeyê bi alfabeyên din" var langLabel = values.lang ? getLangLabel(values.lang) : ""; if (langLabel) { return base + " ên " + langLabel; } return base; }, visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: "Ji bo kurmancî: * {{ku-ar|şiklê alfaba erebî}}", output: function (values) { var text = $.trim(values.alfabeyendin || ""); if (!text) return ""; return "\n==== Bi alfabeyên din ====\n" + text + "\n"; }, }, formalt: makeWordListStep("formalt", "formên alternatîv", "Formên alternatîv ên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), hevmane: makeWordListStep("hevmane", "hevmane", "Hevmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), dijmane: makeWordListStep("dijmane", "dijmane", "Dijmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jornav: makeWordListStep("jornav", "jornav", "Jornavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jernav: makeWordListStep("jernav", "jêrnav", "Jêrnavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse"), binereherwiha: makeWordListStep("binereherwiha", "herwiha binêre", "Kelîmeyên din ên eleqedar binivîse"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: {}, visible: function (values) { return values.lang && values.pos; }, // Fills the insert-dropdown from the current etymTpls object. refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(ta); stepDiv.append(wrap); initSelects(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder. // Skip it only when every filled sense is a şablon sense // a completely empty entry with no şablon chosen still gets the placeholder var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasFilledTplSense = dfnSenses.some(function (s) { return !!s.tpl && !!s.tplTitle; }); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (hasFilledTplSense && !hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: function (values) { return {"navz": true, [values.lang]: true} }, // Language dropdown + growing word-input list; a new row appends // when the dropdown gets a value. Mirrors steps.trans, but flat. buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/build below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Attach the searchable picker now the select is in the DOM. initSelects(list); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", question_fmt: "'"+ pageName + "' di zaravayên din de çawa tê gotin?", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: {}, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zaravayekî bigere"); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; // A completely empty entry still gets a placeholder section // to fill in later; an individual placeholder gloss is only // skipped once some other sense already has real content. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", question_fmt: "Tercimeyên vê maneyê bi zimanên din binivîse", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide only when every sense is a filled template sense (no plain // gloss to attach translations to). A mix, or nothing filled in // yet, still shows Werger. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, // Language dropdown + growing word-input list, scoped to one gloss's // group (each gloss has its own group and row list). buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/buildGroup below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, // Builds (or fetches) the .wiktku-trans-group for one gloss. buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, // Syncs one .wiktku-trans-group per current gloss, keyed by // data-gloss-pos so groups stay matched across rebuilds. build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, // Reads all translation rows, grouped by gloss position. getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, // Builds the numbered "{ index, gloss }" list, one per dfn sense // with a real mane (skips template senses). index is 1-based and // matches the sense's position in the "#" definition list. // When nothing's filled in, returns one placeholder entry so // Werger still has a group to attach to; when every sense is a // filled template sense, stays empty (matches trans.visible()). glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane, but other fields are filled — still gets a // gloss group since dfn.getOutput() emits {{mane?}} for it. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // A completely empty entry (nothing filled in dfn at all, no // şablon chosen either) still gets a placeholder Werger section // to fill in later. Only // skip an individual placeholder gloss below when some other // sense actually has real content, making that particular // placeholder redundant. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it. If some other sense already has real // content, this placeholder is redundant — skip it. If the // whole entry is empty, keep it so Werger still gets a // section to fill in. if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, cavkani: { id: "cavkani", name: "çavkanî", question_fmt: "Çavkaniyên din (ne jêgirtin) lê zêde bike", visible: function (values) { return !!values.pos; }, // Fills the insert-dropdown from the members of [[Kategorî:Çavkanî]]. refreshTplSelect: function () { var sel = $("#wiktku-start-cavkani .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(catSrcTemplates || [], function (_, name) { sel.append($("<option></option>").val(name).text(name)); }); markTemplateOptions(sel, function (opt) { return opt.val(); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-cavkani-wrap").length) return null; var wrap = $("<div class='wiktku-cavkani-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-cavkani-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-cavkani-text") .attr("rows", 4) .attr("placeholder", "Şablonekî ji lîsteyê hilbijêre an rasterast binivîse…"); // Template insert dropdown, populated from [[Kategorî:Çavkanî]] — // options refreshed once the category members are fetched. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var status = $("<span class='wiktku-cavkani-status'></span>"); sel.on("change", function () { var name = $(this).val(); if (!name) return; insertAtCursor(ta[0], "\n* {{" + name + "}}"); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(status).append(ta); stepDiv.append(wrap); // build() runs again for every new beş (see the "+ Beş zêde bike" // handler), after the initial page-wide pass — so this select needs // its own init or it stays a plain, unsearchable native <select>. initSelects(wrap); if (catSrcTemplates) { steps.cavkani.refreshTplSelect(); } else { status.text("Şablon tên barkirin…"); fetchCatSrcTemplates().then(function () { steps.cavkani.refreshTplSelect(); status.text(""); }, function () { status.text("Şablon nehatin barkirin."); }); } return ta; }, output: function () { var text = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); if (!text) return ""; return "\n==== Çavkanî ====\n" + text + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); // This array only controls DOM build order — nothing else keys off it // (see the comment above stepIdToGroup). Mane tab order: Mane (senses, // with malûmatên pêşketî nested inside each, see steps.dfn.build) → // Wêne → Bi zaravayên din → Werger, so dfn/resim/zarava/trans sit // adjacent to each other in that order. var ordered_steps = [ steps.lang, steps.pos, steps.posparams, steps.cinsiyet, steps.jimar, steps.lektur, steps.tr, // Mane tab, in reading order: the senses, then the two things that // belong to the entry as a whole rather than to one sense. steps.dfn, steps.tewandin, steps.alfabeyendin, steps.zarava, steps.trans, // Etîmolojî tab. steps.etym, steps.dunde, // Eleqedar tab — three lists of the same shape. steps.je, steps.tekildar, steps.binereherwiha, // Bilêvkirin isn't part of any STEP_GROUPS tab, but still needs a // slot here because this array is what builds the DOM. steps.pron, // Beşên din, behind the picker. steps.resim, steps.bnrh, steps.bikaranin, steps.formalt, steps.hevmane, steps.dijmane, steps.jornav, steps.jernav, steps.cavkani, steps.xwendin]; // ── Step-group tabs ────────────────────────────────────────────────────── // Four tabs: "Mane" holds the senses (whose own blocks carry Nimûne, // Jêgirtin, Hevmane and Dijmane — see steps.dfn.allGroups), Tewandin, // alfabeyendin, zarava and trans; "Etîmolojî" and "Eleqedar" split out // the two other topical clusters; everything else lives behind the // "Beşên din" picker. "mane" stays first as the default-active tab // since Mane is required content. Tewandin keeps its own free-text // {{ku-tewîn-nav}} field and does NOT absorb the Cins/zayend form // parameters (m=/n=/p=), which stay on the headword template. var STEP_GROUPS = [ { id: "mane", label: "Mane", steps: ["dfn", "tewandin", "alfabeyendin", "zarava", "trans"] }, { id: "etimoloji", label: "Etîmolojî", steps: ["etym", "dunde"] }, { id: "eleqedar", label: "Eleqedar", steps: ["je", "tekildar", "binereherwiha"] }, { id: "besendin", label: "Beşên din", steps: ["resim", "formalt", "hevmane", "dijmane", "jornav", "jernav", "bikaranin", "cavkani", "xwendin", "bnrh"] }, ]; // Steps that live behind the "Beşên din" picker — only these need an // explicit "open" before they're shown, even when their tab is active. // Derived from the group above so it can't drift out of sync. var BESENDIN_STEP_IDS = STEP_GROUPS[3].steps; // Reverse lookup: step id -> index into STEP_GROUPS (undefined for // ungrouped steps — now only lang/pos/posparams/cinsiyet/lektur/tr, // which stay always-visible since they're required to get to everything // else). var stepIdToGroup = {}; $.each(STEP_GROUPS, function (gi, g) { $.each(g.steps, function (_, sid) { stepIdToGroup[sid] = gi; }); }); // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "posparams", "cinsiyet", "jimar", "lektur", "tr", "resim", "dfn", "tewandin", "formalt", "bikaranin", "alfabeyendin", "hevmane", "dijmane", "jornav", "jernav", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans", "cavkani", "xwendin" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; // ── Bilêvkirin as a standalone section ─────────────────────────────── // Pronunciation belongs to the word, not to one part of speech, so it // sits beside Navdêr/Lêker in the tab bar rather than inside any of them. // Modelled as a flag rather than an entry in `sections` since // activeSection is used as an array index in many places — viewing // Bilêvkirin leaves activeSection pointing at the POS section you were on. var viewingPron = false; // is it the tab currently on screen // Which STEP_GROUPS tab is currently shown. Lives out here (like // activeSection above) so refresh() — which is not nested inside build() // — can read it and so renderGroupTabs()/updateGroupTabIndicators() below // can be called from refresh() too. Both operate on the tab bar via its // #wiktku-group-tabs id rather than a closured element reference, for the // same reason. var activeGroup = 0; // Unsaved-changes / autosave state. Lives out here (same reason as // activeGroup above) so destroy() — which runs on final submit and on // switching to the source editor, and is not nested inside build() — // can clear the timers and the beforeunload warning. build() assigns // into these; it doesn't re-declare them. var formDirty = false; var autosaveDebounceTimer = null; var autosaveInterval = null; /** Re-renders the step-group tab bar to reflect the current activeGroup. */ function renderGroupTabs() { var groupTabsDiv = $("#wiktku-group-tabs"); if (!groupTabsDiv.length) return; groupTabsDiv.empty(); $.each(STEP_GROUPS, function (i, g) { var tab = $("<span></span>") .addClass("wiktku-group-tab") .attr("data-group-idx", i) .text(g.label) .toggleClass("wiktku-tab-active", i === activeGroup); (function (idx) { tab.on("click", function () { if (idx === activeGroup) return; activeGroup = idx; renderGroupTabs(); if (idx === BESENDIN_GROUP_IDX) renderBesenDinPicker(); refresh(); }); }(i)); groupTabsDiv.append(tab); }); } /** * Toggles a "needs attention" dot on any group tab that still has a * required, unfilled field hidden inside it — so switching tabs doesn't * leave the person wondering why "Bişîne" stays disabled. */ function updateGroupTabIndicators(values) { var tabs = $("#wiktku-group-tabs .wiktku-group-tab"); if (!tabs.length) return; $.each(STEP_GROUPS, function (i, g) { var missing = false; $.each(g.steps, function (_, sid) { var step = steps[sid]; if (!step || !step.required) return; var val = values[sid]; if (val === "" || (step.multiple && $.isArray(val) && val.join("") === "")) { missing = true; } }); tabs.eq(i).toggleClass("wiktku-tab-missing", missing && i !== activeGroup); }); } // "Beşên din" reveals one field at a time via a picker rather than // stacking them all. Per-section state, snapshotted in // saveCurrentSection() and restored in restoreSection() below, and // auto-seeded from any field that already has content (so a returning // draft doesn't hide something already filled in). var openedOtherSections = {}; var BESENDIN_SET = {}; $.each(BESENDIN_STEP_IDS, function (_, sid) { BESENDIN_SET[sid] = true; }); // "besendin"'s index in STEP_GROUPS. Derived rather than hardcoded — // this was a literal 2 and silently pointed at the wrong tab the moment // Etîmolojî and Eleqedar were inserted ahead of it. var BESENDIN_GROUP_IDX = (function () { for (var i = 0; i < STEP_GROUPS.length; i++) { if (STEP_GROUPS[i].id === "besendin") return i; } return STEP_GROUPS.length - 1; }()); /** Re-renders the "Beşên din" picker to list only the not-yet-opened sections. */ function renderBesenDinPicker() { var wrap = $("#wiktku-besendin-picker"); if (!wrap.length) return; wrap.empty(); var pickerValues = getValues(); var unopened = $.grep(BESENDIN_STEP_IDS, function (sid) { if (openedOtherSections[sid]) return false; // Don't offer a section that would open onto nothing: several of // these are gated (Bi zaravayên din / Werger need lang=ku, most // need a pos). refresh() would hide it again straight away, so // picking it would read as a broken dropdown. var step = steps[sid]; if (step && typeof step.visible === "function") { try { if (!step.visible(pickerValues)) return false; } catch (e) { /* a step whose visible() needs DOM we lack yet — offer it */ } } return true; }); if (!unopened.length) return; // everything's open — nothing left to pick var sel = $("<select class='wiktku-besendin-select'></select>"); sel.attr("data-placeholder", "— beşek hilbijêre —"); sel.append($("<option value=''>— beşek hilbijêre —</option>")); $.each(unopened, function (_, sid) { var step = steps[sid]; if (!step) return; sel.append($("<option></option>").val(sid).text(capitalize(step.name))); }); sel.on("change", function () { var sid = $(this).val(); if (!sid) return; openedOtherSections[sid] = true; // Newly opened section moves right under the picker, ahead of // whatever's already open, instead of wherever it happened to // sit in the fixed step order. $("#wiktku-start-" + sid).insertAfter(wrap); renderBesenDinPicker(); refresh(); }); wrap.append(sel); initSelects(wrap); } /** Marks any BESENDIN_STEP_IDS field that already has real content as * "opened", so restoring a draft doesn't bury filled-in sections behind * the picker. Reuses each step's own output() as the emptiness check — * it already knows what "empty" means per field, and it reads the DOM * the restore just populated. Call this AFTER the DOM has the restored * values in it. */ function seedOpenedFromContent() { var values = getValues(); $.each(BESENDIN_STEP_IDS, function (_, sid) { if (openedOtherSections[sid]) return; var step = steps[sid]; if (!step || typeof step.output !== "function") return; try { if (step.output(values)) openedOtherSections[sid] = true; } catch (e) { /* a step whose output() needs more state than we have yet — skip it */ } }); } function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } // Rebuilds the dfn DOM from a previously snapshotted senses array. function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing tab bar + list so build() recreates them cleanly. stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); // The picker is collapsed behind a link by default; a restored // sense that already uses a template has to show it, or the // chosen template is invisible and looks lost. var reveal = block.data("revealTplRow"); if (typeof reveal === "function") reveal(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // dfnArea is the only thing actually saved, so split it back into // tercime/îzah for editing (mirrors syncNonKuToMane's join format). var maneParts = splitTercimeIzah(sense.mane); block.find(".wiktku-dfn-tercime").val(maneParts ? maneParts.tercime : (sense.mane || "")); block.find(".wiktku-dfn-izah").val(maneParts ? maneParts.izah : ""); // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Same for the mane-box mode (plain vs tercime+îzah), since this // also depends on tplSelect's (and lang's) value. var updateMane = block.data("updateManeMode"); if (updateMane) updateMane(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found var useModifiers = !!MODIFIER_SUBGROUPS[cls]; // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true, useModifiers); }); subList.append(useModifiers ? makeModifierLi(ta) : $("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text).each(function () { highlightLinebreak(this); }); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder entries — accepts current array shape or a legacy // single object (older saved sections) for backwards compat. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote).each(function () { highlightLinebreak(this); }); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederCatTpl) { // Legacy format from before the şablon search switched rows to // manual mode directly — convert it the same way now, so it's // editable like any other free-form source. var catSelEl = li.find(".wiktku-dfn-quote-src-sel"); catSelEl.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val("{{" + j.jederCatTpl + "}}"); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); // Restoring a draft opens the first sense's tab by default. steps.dfn.setOpenSense(stepDiv, list.find("li.wiktku-dfn-sense").first()); } // Snapshots simple (non-dfn) per-section steps from the DOM into obj. function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } if (id === "cavkani") { snap.cavkani = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); return; } if (id === "posparams") { snap.posparams = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); return; } if (id === "resim") { // One entry per row, including blank ones, so a mid-edit draft // (e.g. a filename typed but no caption yet) survives a cache // restore instead of being silently dropped. snap.resim = $("#wiktku-start-resim li.wiktku-resim-item").map(function () { return { file: $.trim($(this).find(".wiktku-resim-file").val()), caption: $.trim($(this).find(".wiktku-resim-caption").val()), alt: $.trim($(this).find(".wiktku-resim-alt").val()) }; }).get(); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); // Which "Beşên din" sub-sections this section has already opened // via the picker — per-section, like everything else here. snap.openedOtherSections = $.extend({}, openedOtherSections); sections[activeSection] = snap; } // Restores a previously saved snapshot into the form DOM. function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); $("#wiktku-start-cavkani .wiktku-cavkani-text").val(snap.cavkani || ""); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); steps.posparams.build(ppDiv); var savedTa = snap.posparams || ""; ppDiv.find(".wiktku-posparams-text").val(savedTa); // Re-parse saved textarea to restore helper widget states. if (savedTa) { var cMatch = savedTa.match(/\|c=([^|}\s]+)/); var jMatch = savedTa.match(/\|j=([^|}\s]+)/); var trMatch = savedTa.match(/\|tr=([^|}\s]+)/); // Write into the shared hidden field (not the visible // select, which has no <option>s yet) — syncHelpers() // below reads it back to restore the dropdown once the // gender/number options for this language are populated. if (cMatch) $("#wiktku-start-cinsiyet-field").val(cMatch[1]); if (jMatch) $("#wiktku-start-jimar-field").val(jMatch[1]); if (trMatch) ppDiv.find(".wiktku-posparams-field[data-pp-key='tr']").val(trMatch[1]); // For lêker, c= holds the verb-type code instead of a // gender — split it back across the two dropdowns it is // now assembled from ("x-gh" → form "x" + base "gh"). if (cMatch && /^lêker/.test(snap.pos || "")) { var lekturParts = /^(?:([xphb])-)?(n?gh)$/.exec(cMatch[1]); if (lekturParts) { ppDiv.find(".wiktku-posparams-lektur-sel").val(lekturParts[2]); ppDiv.find(".wiktku-posparams-lekturform-sel").val(lekturParts[1] || ""); } } // Restore checked optional params. "form" is stored as // "erê" rather than "1" (see rebuildTa), so it needs its // own check here. ppDiv.find(".wiktku-posparams-opt-panel input[type='checkbox']").each(function () { var key = $(this).val(); var expected = key === "form" ? "erê" : "1"; $(this).prop("checked", savedTa.indexOf("|" + key + "=" + expected) !== -1); }); } steps.posparams.syncHelpers(ppDiv); return; } if (id === "resim") { var resimDiv = $("#wiktku-start-resim"); resimDiv.find(".wiktku-resim-wrap").remove(); steps.resim.build(resimDiv); // Accept both the new array-of-rows format and the older // single {file, caption} object saved before multi-image // support existed. var resimSnap = snap.resim; var rows = $.isArray(resimSnap) ? resimSnap : (resimSnap ? [resimSnap] : []); if (rows.length) { var list = resimDiv.find("ol.wiktku-resim-list"); list.empty(); $.each(rows, function (_, r) { var item = steps.resim.buildItem(resimDiv); item.find(".wiktku-resim-file").val(r.file || ""); item.find(".wiktku-resim-caption").val(r.caption || ""); item.find(".wiktku-resim-alt").val(r.alt || ""); list.append(item); }); // Always keep a blank trailing row, same as Nimûne/Dûnde. var lastItem = list.children("li.wiktku-resim-item").last(); if ($.trim(lastItem.find(".wiktku-resim-file").val())) { list.append(steps.resim.buildItem(resimDiv)); } } return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Tell the pickers about the programmatic value change. fields.filter("select").trigger("wiktku:refresh"); }); // Restore which "Beşên din" sub-sections were already opened for // this section, then seed in anything the DOM restore above just // filled in but that wasn't marked opened yet. openedOtherSections = $.extend({}, snap.openedOtherSections || {}); seedOpenedFromContent(); renderBesenDinPicker(); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); // Bilêvkirin is NOT emitted here — it is one shared field for the // whole word, so emitting it per section duplicated it. getWikitext() // prints it once, above the POS sections. steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.tewandin.output(values); entry += steps.bikaranin.output(values); entry += steps.alfabeyendin.output(values); entry += steps.formalt.output(values); entry += steps.hevmane.output(values); entry += steps.dijmane.output(values); entry += steps.jornav.output(values); entry += steps.jernav.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); entry += steps.cavkani.output(values); entry += steps.xwendin.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { // Each hop through here can be reached asynchronously: the dfn // step waits on mw.loader.using("ext.gadget.linkify") before // calling back, so from that point on the submit handler's own // try/catch is no longer on the stack. Guard every hop instead, // or a throw after linkify loads vanishes into an unhandled // rejection and the form just sits there looking busy. try { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } catch (e) { if (typeof onSubmitError === "function") onSubmitError(e); else throw e; } } processSection(0); } // Assembles wikitext for all sections plus the shared lang header. function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var bnrh = steps.bnrh.output(sharedValues); var entry = steps.lang.output(sharedValues); // One pronunciation per word, printed once between the language // header and the POS sections — see steps.pron.output. entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // bnr-h goes before the language section — only prepended when // generating fresh wikitext (not addLangMode, which handles it separately). if (!addLangMode && bnrh) entry = bnrh + entry; // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { if (s.mane) return s.mane; // Template sense (e.g. {{guharto|ku|somepage}}) — same // construction as the tplCall built in getOutput, so the // summary shows what actually gets written to the entry // instead of going blank. if (s.tpl && s.tplTitle) { return s.tplNoLang ? "{{" + s.tpl + "|" + s.tplTitle + "}}" : "{{" + s.tpl + "|" + sharedValues.lang + "|" + s.tplTitle + "}}"; } return ""; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; // Set by build() to its submitFailed(). Lives out here because the // wikitext-assembly functions below are outside build()'s closure but // still need a way to report a failure to the person rather than dying // silently in the console. var onSubmitError = null; // Whether Mane/Bi zaravayên din/Werger has anything in it — kept // outside refresh() so the click handler can read the latest value. var wiktkuContentGateOk = true; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues, placeholderText) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>").text(placeholderText || "")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice.label); if (choice.sortKey !== undefined) { // This is a language choice {code, label, sortKey} — show code. displayText = capitalize(choice.label) + " (" + choice.code + ")"; } var option = $(mw.html.element("option", { value: choice.code }, displayText)); if (disabledValues[choice.code]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } // Keys to disable for a key menu: already-taken or explicitly disabled. function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); populateMenus(input, step.keys, getDisabledKeys(step)); // Keep the key menus mutually exclusive: whatever one row selects is // disabled in every other row. Recomputed from the DOM on each change. input.on("change", function () { var all = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield"); var taken = {}; all.each(function () { var v = $(this).val(); if (v) taken[v] = true; }); all.not(this).each(function () { var self = $(this), own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (code) $(this).prop("disabled", !!taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }); // Return the wrapper; the select lives inside it and still fires change. return wrapNativeSelect(input); } // Adds another text field to the list if the last one now has text. function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); if (step.placeholder) { nextInput.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = step.modifiers ? makeModifierLi(nextInput).prepend(nextKeyInput || "") : $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) initSelects(nextItem); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } // Shows/hides steps based on whether their prerequisites are met, and // updates placeholders where applicable. function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); steps.cavkani.refreshTplSelect(); // Re-render any step's question label that depends on current values // (e.g. dfn's Werger-section reminder, which only applies to ku). $.each(steps, function (stepId, step) { if (typeof step.question_fmt === "function") { $("#wiktku-start-" + stepId + " .wiktku-start-step-question") .text(step.question_fmt(values)); } }); // Sync every sense block's mane-box mode (plain mane vs tercime+îzah) // to the current language, in case lang changes after blocks exist. $("#wiktku-start-dfn li.wiktku-dfn-sense").each(function () { var updateMane = $(this).data("updateManeMode"); if (updateMane) updateMane(); }); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Re-sync the "<label> bi <ziman>…" placeholder on every always-visible // sub-field list (etîket, kategorî, hevmane, …), since the language may // not have been chosen yet when these lists were first built, or may // have changed since. $("#wiktku-start-dfn .wiktku-dfn-sublist").each(function () { var upd = $(this).data("updatePlaceholders"); if (typeof upd === "function") upd(); }); // Same idea for word-list steps (jê, têkildar, binêre herwiha, …) // whose placeholder is a function of the current language. $.each(steps, function (stepId, step) { if (typeof step.placeholder === "function") { $("#wiktku-start-" + stepId + " textarea.wiktku-start-step-field") .attr("placeholder", step.placeholder()); } }); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // Insert after the quote textarea's resize-wrap (if the manual // resize handle has already been attached to it), not after the // bare textarea -- otherwise this lands *inside* that wrap, // between the textarea and its own grip, breaking jêgirtin's // handle and nesting the tr/t boxes inside it. var quoteTa = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap = quoteTa.closest(".wiktku-resize-wrap"); (quoteResizeWrap.length ? quoteResizeWrap : quoteTa).after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // See the tr-field branch above for why this targets the // resize-wrap instead of the bare textarea. var quoteTa2 = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap2 = quoteTa2.closest(".wiktku-resize-wrap"); (quoteResizeWrap2.length ? quoteResizeWrap2 : quoteTa2).after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { var groupIdx = stepIdToGroup[stepId]; var hiddenByTab = (groupIdx !== undefined && groupIdx !== activeGroup) || // Beşên din picker: stays hidden even while its tab is // active until explicitly opened from the dropdown. (BESENDIN_SET[stepId] && !openedOtherSections[stepId]); // Bilêvkirin is its own section now, so the two views are // mutually exclusive: on it, only pron shows (plus Ziman, which // is shared and stays above every section); off it, pron is // hidden no matter which tab is active. pron is deliberately // ungrouped — stepIdToGroup has no entry for it — so without // this branch it would show on all four tabs at once. if (stepId === "pron") { hiddenByTab = hiddenByTab || !viewingPron; } else if (viewingPron && stepId !== "lang") { hiddenByTab = true; } if (hiddenByTab || (typeof(step.visible) === "function" && !step.visible(values))) { $("#wiktku-start-" + stepId).hide(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } // After build, sync the posparams helper widgets whenever pos or lang changes. if (step.id === "posparams" && typeof step.syncHelpers === "function") { step.syncHelpers(stepDiv); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } stepDiv.slideDown(); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); // The four content tabs belong to a POS section — Bilêvkirin has no // sub-tabs of its own, so the bar goes away while it's on screen. $("#wiktku-group-tabs").toggle(!!values.pos && !viewingPron); var besenDinActive = activeGroup === BESENDIN_GROUP_IDX && !viewingPron; $("#wiktku-besendin-picker").toggle(besenDinActive); // The option list is filtered by each step's visible(), which depends // on lang/pos — so it has to be rebuilt when those change, not just // when a section is opened. Safe to call from here: rendering the // picker doesn't itself call refresh(), only picking an option does. if (besenDinActive) renderBesenDinPicker(); updateGroupTabIndicators(values); continueBtn.setDisabled(!canContinue); // Soft gate: stays a real, clickable OOUI button — a hard // setDisabled(true) here would swallow the click entirely, leaving // no way to tell the person why nothing happened. The CSS-only // "looks disabled" class lets the click handler still run and show // wiktkuNotify's explanation. wiktkuContentGateOk = !canContinue || hasMinRequiredContent(values); continueBtn.$element.toggleClass("wiktku-btn-soft-disabled", !wiktkuContentGateOk); } function destroy() { if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); if (autosaveInterval) clearInterval(autosaveInterval); formDirty = false; $(window).off("beforeunload.wiktkuUnsaved"); $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard").slideDown(); // #editform was kept laid-out but off-screen (see build()) instead of // display:none, precisely so the editor never had to size itself // against a zero-width/height box. Just bring it back on-screen — // no slideDown needed since it was never actually collapsed. $("#editform").removeClass("wiktku-offscreen"); // Belt-and-braces: if WikiEditor/CodeMirror/mobile's auto-grow still // cached a stale size from some earlier point, nudge them to // recalculate now that the box is genuinely visible. $(window).trigger("resize"); if (window.CodeMirror) { var cm = $("#wpTextbox1").data("CodeMirror") || $("#wpTextbox1").data("cmInstance"); if (cm && typeof cm.refresh === "function") cm.refresh(); } $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and navz. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; // Inserts a new "== {{ziman|code}} ==" section at the correct sorted // position: navz, then ku/hac/sdh/lki/ckb/zza, then alphabetical by name. function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections — just write the new section. // Add \n\n only when there is real non-whitespace content above. var trimmed = existing.replace(/\s+$/, ""); return trimmed ? trimmed + "\n\n" + wikitext : wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // (?![\s\S]) matches only true end-of-string, since a bare "$" with // /m would stop at the section's first line break instead. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections, each separated by exactly \n\n. // Trim trailing whitespace off each section's content first so we // control the spacing precisely. var joined = sections.map(function (s) { return s.content.replace(/\s+$/, ""); }).join("\n\n"); // Only add a separator after the preamble when it has real content. var preambleTrimmed = preamble.replace(/\s+$/, ""); var prefix = preambleTrimmed ? preambleTrimmed + "\n\n" : ""; return prefix + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê zimanekî nû li rûpelê îlawe bikî. Eger ev ziman jixwe hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bike, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Muhtewaya rûpelê paqij bike (her tiştî jê bibe û rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); // Tab bar for switching between step-groups (topics) within a section. // renderGroupTabs()/updateGroupTabIndicators() (which populate and // maintain it) live outside build() — see near "var activeSection". var groupTabsDiv = $("<div id='wiktku-group-tabs'></div>"); // Both tab bars are sticky (CSS). group-tabs' sticky "top" has to sit // right below section-tabs' actual rendered height, which isn't a // fixed number since the bar can wrap onto a second line. Measured // here and published as a CSS custom property the stylesheet reads // back; recomputed on content changes and window resize. // // Vector 2022 has its own sticky header (.vector-sticky-header) that // pins to the real top:0 once you scroll past the page title, which // would otherwise sit directly behind (and hide) our section-tabs. // Fixed by measuring how much of the viewport Vector's header // currently occupies and offsetting both our bars below it, via // --wiktku-siteheader-h. Vector's header slides in/out with scroll // position, so this is re-measured on scroll too, not just resize. function siteHeaderOffset() { var el = document.querySelector(".vector-sticky-header"); if (!el) return 0; var rect = el.getBoundingClientRect(); // Present in the DOM at all times on Vector 2022, but only // actually occupying screen space once scrolled into place — // before that it sits translated above the viewport (negative/ // zero rect), which must not add a phantom gap under our bars. if (rect.bottom <= 0 || rect.top > 4) return 0; return Math.max(0, rect.bottom); } var stickyOffsetQueued = false; function syncStickyTabsOffset() { var h = sectionTabsDiv.is(":visible") ? (sectionTabsDiv.outerHeight() || 0) : 0; startForm.css("--wiktku-stabs-h", h + "px"); startForm.css("--wiktku-siteheader-h", siteHeaderOffset() + "px"); } function queueStickyTabsOffsetSync() { if (stickyOffsetQueued) return; stickyOffsetQueued = true; window.requestAnimationFrame(function () { stickyOffsetQueued = false; syncStickyTabsOffset(); }); } $(window).on("resize.wiktkuStickyTabs scroll.wiktkuStickyTabs", queueStickyTabsOffsetSync); // "Beşên din" picker — sits right under the group tab bar, only // shown while that tab is active (toggled in refresh(), see // BESENDIN_GROUP_IDX); renderBesenDinPicker() fills it. var besenDinPickerDiv = $("<div id='wiktku-besendin-picker' class='wiktku-besendin-picker'></div>"); /** Puts the form back in a usable state after a failed submit and * says what happened. Without this the button stays disabled and * the spinner spins forever on any exception — the person is left * staring at a form that looks busy but is dead, with the reason * visible only in the browser console. */ function submitFailed(err) { spinner.hide(); continueBtn.setDisabled(false); continueBtn.$element.removeClass("wiktku-btn-sending"); var detail = (err && (err.message || err.toString())) || "sedem nediyar"; mw.notify( "Şandin bi ser neket: " + detail + " — tiştê ku te nivîsî winda nebûye. Heke ev dubare bibe, " + "bi 'Edîtora çavkaniyê veke' berdewam bike.", { type: "error", tag: "wiktku-submit", autoHide: false } ); // Deliberately console.error as well: the notification is for the // person, this is for whoever they report the bug to. if (window.console && console.error) console.error("[wiktku] submit failed", err); } onSubmitError = submitFailed; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); continueBtn.$element.addClass("wiktku-btn-sending"); spinner.show(); try { getWikitext(function (wikitext) { try { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page — write fresh content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // ── bnr-h merge ────────────────────────────────────────── // If the user filled bnr-h inputs, either merge into the // existing {{bnr-h|…}} call or prepend a new one. var bnrhOut = steps.bnrh.output(getValues()); if (bnrhOut) { var newPages = bnrhOut.replace(/^\{\{bnr-h\|/, "").replace(/\}\}\n?$/, "").split("|"); var bnrhRe = /\{\{bnr-h\|([^}]*)\}\}/i; if (bnrhRe.test(existing)) { existing = existing.replace(bnrhRe, function (_, inner) { var existingPages = inner.split("|").map(function (p) { return p.trim(); }); $.each(newPages, function (_, p) { p = p.trim(); if (p && existingPages.indexOf(p) === -1) existingPages.push(p); }); return "{{bnr-h|" + existingPages.join("|") + "}}"; }); } else { existing = bnrhOut + existing; } } // If this language's section already exists (whitespace // differences aside), merge into it; otherwise insert new. var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); } catch (e) { // Thrown while writing the result into #wpTextbox1. submitFailed(e); } }); } catch (e) { // Catches anything thrown synchronously inside getWikitext. submitFailed(e); } }); // Tracks whether groupTabsDiv has been inserted yet. var groupTabsInserted = false; $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); var nameH3 = $("<h3></h3>").addClass("wiktku-start-step-name"); var nameLabel = $("<label></label>") .attr("for", "wiktku-start-" + step.id + "-field") .text(name); nameH3.append(nameLabel); stepDiv.append(nameH3); if (step.question_fmt) { // question_fmt can be a plain string, or a function of the // current values (used by steps whose question text depends // on e.g. the chosen language) — refresh() keeps it in sync // afterwards via the .wiktku-start-step-question class. var questionText = typeof step.question_fmt === "function" ? step.question_fmt(getValues()) : step.question_fmt; stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, questionText))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); // initSelects() runs over the whole form once it is in the DOM. stepDiv.append(input); } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.placeholder) { input.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append(step.modifiers ? makeModifierLi(input) : $("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Section tabs (switch between POS sections) sit above the // per-section fields, starting at "pos". if (step.id === "pos") { startForm.append(sectionTabsDiv); } // Step-group tabs sit just before the first grouped step in // ordered_steps. Derived from stepIdToGroup so this keeps // working no matter how STEP_GROUPS/ordered_steps get reordered. if (!groupTabsInserted && stepIdToGroup[step.id] !== undefined) { startForm.append(groupTabsDiv); startForm.append(besenDinPickerDiv); groupTabsInserted = true; } startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); /** Adds a new, empty POS section and switches to it. */ function addPosSection() { saveCurrentSection(); viewingPron = false; sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); return; } if (id === "resim") { $("#wiktku-start-resim .wiktku-resim-wrap").remove(); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); stepDiv.find("select.wiktku-start-step-field").trigger("wiktku:refresh"); }); // Fresh section — no "Beşên din" sub-section has been opened yet. openedOtherSections = {}; renderBesenDinPicker(); renderSectionTabs(); refresh(); } addSectionBtn.on("click", addPosSection); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); syncStickyTabsOffset(); return; } sectionTabsDiv.show(); // Bilêvkirin leads the bar, ahead of the POS sections. var pronTab = $("<span></span>") .addClass("wiktku-section-tab wiktku-section-tab-pron") .text("Bilêvkirin") .toggleClass("wiktku-tab-active", viewingPron); pronTab.on("click", function () { if (viewingPron) return; saveCurrentSection(); viewingPron = true; refresh(); renderSectionTabs(); }); sectionTabsDiv.append(pronTab); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection && !viewingPron); (function (idx) { tab.on("click", function () { if (idx === activeSection && !viewingPron) return; // Leaving Bilêvkirin doesn't need a save — its field // is shared and never part of a section snapshot. if (!viewingPron) saveCurrentSection(); viewingPron = false; activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); syncStickyTabsOffset(); } renderSectionTabs(); /** * Re-populates a dynamically-growing "multiple" field list (bnrh, je, * tekildar, …) from a saved array of strings. Sets each value via * .val() + a triggered "input" event rather than touching the DOM * structure directly, so the normal refreshForTextField() growth * logic adds exactly as many rows as needed — the same thing that * happens when a person types into the last (empty) row. */ function restoreMultiField(id, values) { var container = $("#wiktku-start-" + id); $.each(values || [], function (i, v) { var field = container.find(".wiktku-start-step-field").eq(i); if (!field.length || !v) return; field.val(v).trigger("input"); }); } /** * Restores a full cached draft: shared lang/pron/bnrh fields, then * every section (via the same restoreSection()/refresh()/ * renderSectionTabs() sequence already used when switching tabs). * @param cached {{lang: string, pron: string, bnrh: Array, sections: Array, activeSection: number}} */ function restoreFromCache(cached) { if (cached.lang) { $("#wiktku-start-lang-field").val(cached.lang); $("#wiktku-start-lang-field").trigger("wiktku:refresh"); } // Rebuild dependent steps (pos, pron wrap, etc.) now that lang is set. refresh(); if (cached.pron !== undefined) { $("#wiktku-start-pron .wiktku-pron-text").val(cached.pron); } if (cached.bnrh) { restoreMultiField("bnrh", cached.bnrh); } sections = (cached.sections && cached.sections.length) ? cached.sections : [{}]; activeSection = (typeof cached.activeSection === "number" && cached.activeSection >= 0 && cached.activeSection < sections.length) ? cached.activeSection : 0; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); updateLastSavedIndicator(cached.savedAt || null); formDirty = false; wiktkuNotify("Danûstandina berê ya qeydkirî ji cache hate barkirin.", { type: "info", tag: "wiktku-cache-restore" }); } // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); // A new cureyê rêzimanî means any previously chosen cinsiyet/ // cureyê lêkerê no longer applies — clear both selections (and // the shared hidden cinsiyet field, since rebuildTa()/syncHelpers() // fall back to it) before wiping the textarea, so nothing stale // gets carried over into the rebuilt template. var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-cinsiyet-sel").val(""); ppDiv.find(".wiktku-posparams-jimar-sel").val(""); ppDiv.find(".wiktku-posparams-lektur-sel").prop("selectedIndex", 0); ppDiv.find(".wiktku-posparams-lekturform-sel").prop("selectedIndex", 0); $("#wiktku-start-cinsiyet-field").val(""); $("#wiktku-start-jimar-field").val(""); ppDiv.find(".wiktku-posparams-text").val(""); // refresh() runs steps.posparams.syncHelpers(), which toggles the // param rows for the new pos and — since the textarea is now // empty — calls rebuildTa() to repopulate it. refresh(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { // Immediate feedback that the click registered continueBtn.$element.addClass("wiktku-btn-flash"); setTimeout(function () { continueBtn.$element.removeClass("wiktku-btn-flash"); }, 500); // Ziman/Cureyê rêzimanî already block submission via the real // OOUI setDisabled (see canContinue in refresh()) — this is a // second, softer check that still lets the click through so we // can explain why, instead of the button just silently doing nothing. if (!wiktkuContentGateOk) { wiktkuNotify( "Berî şandinê, tiştekî binivîse: Mane, Bi zaravayên din, an jî Werger — kêmasî yek ji van sê beşan divê tijî be.", { type: "warn", tag: "wiktku-mincontent" } ); return; } wiktkuNotify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", flags: [ "destructive" ], }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Cache save/clear buttons ───────────────────────────────────────── // Manual, page-scoped save of the entire wizard (all sections, not // just the active one) via [[MediaWiki:Gadget-StorageUtils.js]]'s // ObjectStorage. Restoring happens silently on load at the end of // build(), once the full language list is available. // // Saving also happens automatically (debounced while typing, plus a // periodic fallback) — see "Autosave" below — since relying on the // person to remember to click "Li cache qeyd bike" before an // accidental tab close/reload defeats the point of having a cache // at all. function buildCacheSnapshot() { return { lang: getValues().lang || "", pron: $("#wiktku-start-pron .wiktku-pron-text").val() || "", // bnrh is shared (page-level), same as lang/pron above — not // per-section, so it doesn't live in sections[]. bnrh: getValuesForStep("bnrh"), sections: sections, activeSection: activeSection, savedAt: Date.now() }; } // ── Last-saved indicator ───────────────────────────────────────────── var lastSavedEl = $("<span id='wiktku-last-saved'></span>"); function formatSavedTime(ts) { try { return new Date(ts).toLocaleTimeString(mw.config.get("wgUserLanguage"), { hour: "2-digit", minute: "2-digit" }); } catch (e) { return new Date(ts).toLocaleTimeString(); } } function updateLastSavedIndicator(ts) { lastSavedEl.text(ts ? ("Cache: qeydkirî di saet " + formatSavedTime(ts) + " de") : ""); } // ── Dirty-state tracking + autosave ────────────────────────────────── // formDirty mirrors "does the live form differ from what's in cache". // Anything the person types/selects sets it; a successful save (auto // or manual) clears it; destroy() (final submit, or switching to the // source editor) also clears it since the wizard's job is over at // that point either way. formDirty/autosaveDebounceTimer/autosaveInterval // are declared in the outer scope (near activeGroup) — assigned here, // not re-declared — so destroy() can reach them too. var AUTOSAVE_DEBOUNCE_MS = 8000; // save shortly after typing pauses var AUTOSAVE_INTERVAL_MS = 60000; // …and at least this often regardless function performAutosave() { if (!formDirty) return; saveCurrentSection(); try { formCache.Set(buildCacheSnapshot()); formDirty = false; updateLastSavedIndicator(Date.now()); } catch (e) { // Silent on autosave failure (storage blocked/full, etc.) — the // manual button still surfaces a proper error if the person // tries it directly, no need to interrupt typing with a toast. } } function scheduleAutosave() { formDirty = true; if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = setTimeout(performAutosave, AUTOSAVE_DEBOUNCE_MS); } startForm.on("input change", "input, textarea, select", scheduleAutosave); autosaveInterval = setInterval(performAutosave, AUTOSAVE_INTERVAL_MS); // Warn on accidental tab close/reload while there's anything unsaved. $(window).on("beforeunload.wiktkuUnsaved", function (e) { if (!formDirty) return undefined; e.preventDefault(); e.returnValue = ""; return ""; }); var saveCacheBtn = new OO.ui.ButtonWidget({ label: "Li cache qeyd bike", title: "Halê vê formê yê niha (ziman, bilêvkirin û hemû beş) li cache (localStorage) qeyd bike, da ku eger rûpel bêyî xwestin were girtin an ji nû ve were barkirin, tu karibî berdewam bikî." }); saveCacheBtn.on("click", function () { saveCurrentSection(); // ObjectStorage.Set() doesn't return a success/failure value, so // the only way to detect a real failure (storage blocked, quota // exceeded, JSON.stringify choking on something unexpected) is to // catch it here rather than inspect a (nonexistent) return value. try { var snapshot = buildCacheSnapshot(); formCache.Set(snapshot); formDirty = false; updateLastSavedIndicator(snapshot.savedAt); wiktkuNotify("Halê formê li cache hate qeydkirin.", { type: "success", tag: "wiktku-cache-save" }); } catch (e) { mw.notify("Qeydkirina li cache bi ser neket.", { type: "error", tag: "wiktku-cache-save" }); } }); var clearCacheBtn = new OO.ui.ButtonWidget({ label: "Cache paqij bike", flags: [ "destructive" ], title: "Datayên qeydkirî yên vê rûpelê ji cache jê bibe (forma ku niha xuya dike naguherîne)." }); clearCacheBtn.on("click", function () { formCache.Set({}); // The live form still has whatever the person typed — it's just no // longer backed up anywhere, so treat this like a fresh unsaved edit. formDirty = true; updateLastSavedIndicator(null); wiktkuNotify("Cache hate paqijkirin.", { type: "success", tag: "wiktku-cache-clear" }); }); // ── "⋯" overflow ───────────────────────────────────────────── // One primary action and one secondary stay on the bar; everything // else moves in here, to avoid four same-weight buttons crowding // (and wrapping to three rows on a phone). var moreBtn = $("<button type='button' class='wiktku-more-btn' title='Vebijarkên din'>⋯</button>"); var moreMenu = $("<div class='wiktku-more-menu'></div>").hide(); /** Moves an existing OOUI button into the overflow menu, keeping its * handlers — the widgets already carry the behaviour, so this is * purely about where they are shown. */ function intoMenu(btn, extraClass) { var row = $("<div class='wiktku-more-item'></div>"); if (extraClass) row.addClass(extraClass); btn.$element.on("click", function () { moreMenu.hide(); }); row.append(btn.$element); moreMenu.append(row); } intoMenu(saveCacheBtn); intoMenu(clearCacheBtn, "wiktku-more-item-danger"); moreMenu.append($("<div class='wiktku-more-sep'></div>")); moreMenu.append($("<div class='wiktku-more-item wiktku-more-note'></div>").append(lastSavedEl)); moreBtn.on("click", function (e) { e.preventDefault(); e.stopPropagation(); var open = moreMenu.is(":visible"); moreMenu.toggle(!open); if (!open) { setTimeout(function () { $(document).one("click.wiktkuMore", function () { moreMenu.hide(); }); }, 0); } }); var moreWrap = $("<span class='wiktku-more-wrap'></span>").append(moreBtn).append(moreMenu); footer.append(moreWrap); // Icon-only settings button — opens the Tercîh dialog. Plain OOUI // icon names depend on which icon-pack module happens to be loaded, // so this uses the actual Codex "settings" (color-subtle) SVG from // Commons directly, the same way the spinner above hotlinks its gif. var prefsBtn = $("<button></button>", { type: "button", "class": "wiktku-prefs-btn", title: "Tercîh — sazkariyên vê amûrê biguherîne" }); prefsBtn.on("click", function (e) { e.preventDefault(); wiktkuOpenPrefsDialog(); }); // The gear is icon-only on the bar; inside a text menu it needs a // label like everything else around it. prefsBtn.on("click", function () { moreMenu.hide(); }); moreMenu.prepend($("<div class='wiktku-more-sep'></div>")); moreMenu.prepend($("<div class='wiktku-more-item wiktku-more-item-prefs'></div>") .append(prefsBtn) .append($("<span class='wiktku-more-item-label'></span>").text("Tercîh"))); startForm.append(footer); // NOTE: deliberately NOT .hide() (display:none). WikiEditor/CodeMirror/ // the mobile editor's auto-grow logic measure #wpTextbox1's real // dimensions during their own init, which happens while the wizard is // up. A display:none ancestor reports 0 for offsetWidth/offsetHeight/ // scrollHeight, so those scripts bake in a near-zero height that never // gets recalculated later — slideDown() in destroy() only animates the // outer box, it doesn't re-trigger their sizing. Pushing #editform // off-screen instead keeps it laid out (real width/height available to // measure) without being visible, so the editbox opens at full size. $("#editform").addClass("wiktku-offscreen").before(startForm); // renderGroupTabs() looks up #wiktku-group-tabs via a live DOM // selector, so it must run after startForm is actually in the document. renderGroupTabs(); renderBesenDinPicker(); // One pass over the whole form: every select that hasn't already been // initialised, and isn't opted out with .wiktku-plain-select, gets // the searchable picker. initSelects(startForm); refresh(); // Give every draggable textarea a custom resize grip (works // consistently on Safari/iOS, unlike the native corner grip — see // the "Manual drag-to-resize handle" comment in styles.css), and // keep applying it to textareas added later on (new sense blocks, // quote-source fields, nimûne rows, …). wiktkuInitManualResize(startForm); new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { $(mutation.addedNodes).each(function () { if (this.nodeType !== 1) return; wiktkuInitManualResize(this); }); }); }).observe(startForm[0], { childList: true, subtree: true }); // Now that the full language list is loaded, silently restore any // draft the editor previously saved for this page. var cachedDraft = formCache.Get(); if (cachedDraft && cachedDraft.sections && cachedDraft.sections.length) { restoreFromCache(cachedDraft); } } mw.loader.using(["oojs-ui-core"], function () { function wiktkuProceedWithData(wiktkuData) { var d = wiktkuData || {}; // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Jimar (number) code definitions — same shape as the wiki's // own Lua number-type table (code -> {cat, display[, req]}). if (d.numberLabels) $.extend(NUMBER_LABELS, d.numberLabels); // Populate lang choices (pinned list). if (d.langChoices) steps.lang.choices = choicesFromObject(d.langChoices, true); // Populate langsByCode and merge full language list from d.ziman. // d.ziman is a {code: name} object with all known languages. $.each(steps.lang.choices, function (i, choice) { if (choice.sortKey === undefined) choice.sortKey = choice.label; langsByCode[choice.code] = choice; }); if (d.ziman) { var pinnedCodes = {}; $.each(steps.lang.choices, function (i, c) { pinnedCodes[c.code] = true; }); var extraChoices = []; $.each(d.ziman, function (code, name) { if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; if (pinnedCodes[code]) return; var choice = { code: code, label: name, sortKey: name }; extraChoices.push(choice); langsByCode[code] = choice; }); extraChoices.sort(function (a, b) { return a.sortKey.localeCompare(b.sortKey, userLang); }); steps.lang.choices = steps.lang.choices.concat(extraChoices); } // Keep the full merged list around for trans/dunde/zarava — those // should still be able to reference any language even when the // Tercîh panel restricts the main "ziman" step below — then, if // the user set a restriction there, narrow steps.lang.choices // itself to just those codes. var wiktkuFullLangChoices = steps.lang.choices; if (wiktkuPrefs.langCodes && wiktkuPrefs.langCodes.length) { var wiktkuAllowedLangSet = {}; $.each(wiktkuPrefs.langCodes, function (i, code) { wiktkuAllowedLangSet[code] = true; }); var wiktkuRestrictedChoices = $.grep(wiktkuFullLangChoices, function (c) { return !!wiktkuAllowedLangSet[c.code]; }); // Fall back to the full list instead of showing an empty // dropdown if none of the saved codes matched anything // (typo'd code, data.json changed since, …). steps.lang.choices = wiktkuRestrictedChoices.length ? wiktkuRestrictedChoices : wiktkuFullLangChoices; } // Populate POS choices — also a plain {code: label} object in data.json. if (d.posChoices) steps.pos.choices = choicesFromObject(d.posChoices, false); // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the full language list // (not the possibly Tercîh-restricted steps.lang.choices). steps.trans.keys = wiktkuFullLangChoices; steps.dunde.keys = wiktkuFullLangChoices; steps.zarava.keys = getZaravaKeys(wiktkuFullLangChoices); build(); } // data.json ships inside this package module, so it is already parsed // and in memory — no action=raw round trip, and no Testing switch to // forget to flip back before deploying. wiktkuProceedWithData(require("./start/data.json")); }); }); //</nowiki> me7j3yq2ok3j725bri0j73l3i0vp27u 6333853 6333831 2026-08-15T17:17:28Z Wikihez 7344 6333853 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. // implicit dependencies: StorageUtils (ObjectStorage) //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var addLangMode = mw.util.getParamValue("wiktkuaddlang") === "1"; // ── Tercîh (user settings) panel stored via mw.storage (localStorage), globally var WIKTKU_PREFS_KEY = "wiktku_start_prefs"; var WIKTKU_PREFS_DEFAULTS = { // [] = show the full language list in the "ziman" step; otherwise // only these codes are shown there (data.json codes, not names). langCodes: [], // true = never auto-open on a new/empty page — only via the // "+Ziman/beşeke din" portlet link. onlyOnClick: false, // "auto" | "p-cactions" | "p-tb" | "p-views" — where the // "+Ziman/beşeke din" portlet link is added. portlet: "auto", // true = suppress routine/informational mw.notify toasts (page // loading, cache auto-restored, cache saved/cleared, "tê şandin…"). // Errors and direct results of an explicit action (like saving // Tercîh itself) always show regardless of this setting. quiet: false }; function wiktkuLoadPrefs() { if (!(window.mw && mw.storage)) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var raw; try { raw = mw.storage.get(WIKTKU_PREFS_KEY); } catch (e) { raw = null; } if (!raw) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var parsed; try { parsed = JSON.parse(raw); } catch (e) { parsed = {}; } return $.extend({}, WIKTKU_PREFS_DEFAULTS, parsed); } function wiktkuSavePrefs(prefs) { if (!(window.mw && mw.storage)) return false; try { mw.storage.set(WIKTKU_PREFS_KEY, JSON.stringify(prefs)); return true; } catch (e) { return false; } } var wiktkuPrefs = wiktkuLoadPrefs(); // Routine/informational notices go through here so "quiet mode" can // suppress them; errors and explicit-action confirmations (like the // Tercîh save toast) call mw.notify directly instead, and always show. function wiktkuNotify(message, options) { if (wiktkuPrefs.quiet) return; mw.notify(message, options); } // Lazily built the first time it's opened; reused after that (see // wiktkuOpenPrefsDialog below, defined once we know OOUI is available). var wiktkuPrefsWindowManager = null; var wiktkuPrefsDialog = null; function wiktkuOpenPrefsDialog() { mw.loader.using(["oojs-ui-core", "oojs-ui-windows"], function () { function WiktkuPrefsDialog(config) { WiktkuPrefsDialog.super.call(this, config); } if (!wiktkuPrefsDialog) { OO.inheritClass(WiktkuPrefsDialog, OO.ui.ProcessDialog); WiktkuPrefsDialog.static.name = "wiktkuPrefsDialog"; WiktkuPrefsDialog.static.title = "Tercîhên min"; WiktkuPrefsDialog.static.actions = [ { action: "save", label: "Qeyd bike", flags: ["primary", "progressive"] }, { action: "cancel", label: "Betal bike", flags: "safe" } ]; WiktkuPrefsDialog.prototype.initialize = function () { WiktkuPrefsDialog.super.prototype.initialize.call(this); this.langCodesInput = new OO.ui.TextInputWidget({ placeholder: "ku, zza, ckb (vala bihêle ji bo hemû zimanan)" }); this.onlyOnClickCheckbox = new OO.ui.CheckboxInputWidget({}); this.quietCheckbox = new OO.ui.CheckboxInputWidget({}); this.portletDropdown = new OO.ui.DropdownInputWidget({ options: [ { data: "auto", label: "Otomatîk (li gorî rûyê wîkiyê)" }, { data: "p-cactions", label: "p-cactions - Li qismê Amûran" }, { data: "left-navigation", label: "left-navigation - Li qismê Gotar-Gotûbêj" }, { data: "p-tb", label: "p-tb - Li qismê Giştî" }, { data: "p-views", label: "p-views - Li qismê Bixwîne" } ] }); var fieldset = new OO.ui.FieldsetLayout({ label: "Eyar" }); fieldset.addItems([ new OO.ui.FieldLayout(this.langCodesInput, { label: "Kodên zimanan ku tê xuyakirin li qismê \"ziman\"", align: "top", help: "Kodan bi virgulê (,) ji hev veqetîne. Vala bihêle da ku hemû ziman were nîşandan.", helpInline: true }), new OO.ui.FieldLayout(this.onlyOnClickCheckbox, { label: "Tenê veke wextê \"+Ziman/beşeke din\" were tikandin", align: "inline", help: "Eger were hilbijartin, ev amûr êdî otomatîk li ser rûpelên nû/vala dest pê nake — divê meriv her carê pêl \"+Ziman/beşeke din\" bike.", helpInline: true }), new OO.ui.FieldLayout(this.portletDropdown, { label: "Cihê lînka \"+Ziman/beşeke din\"", align: "top", help: "\"Otomatîk\" li gorî rûyê wîkiyê hildibijêre.", helpInline: true }), new OO.ui.FieldLayout(this.quietCheckbox, { label: "Moda bêdeng (kêmtir agahdarî nîşan bide)", align: "inline", help: "Agahdariyên normal nîşan nede. Xeta her tim tên xuyakirin.", helpInline: true }) ]); this.$body.addClass("wiktku-prefs-dialog-body").append(fieldset.$element); }; WiktkuPrefsDialog.prototype.getSetupProcess = function (data) { return WiktkuPrefsDialog.super.prototype.getSetupProcess.call(this, data) .next(function () { this.langCodesInput.setValue(wiktkuPrefs.langCodes.join(", ")); this.onlyOnClickCheckbox.setSelected(!!wiktkuPrefs.onlyOnClick); this.portletDropdown.setValue(wiktkuPrefs.portlet || "auto"); this.quietCheckbox.setSelected(!!wiktkuPrefs.quiet); }, this); }; WiktkuPrefsDialog.prototype.getActionProcess = function (action) { var dialog = this; if (action === "save") { return new OO.ui.Process(function () { var codes = dialog.langCodesInput.getValue() .split(/[,\s]+/) .map(function (c) { return c.trim().toLowerCase(); }) .filter(function (c) { return !!c; }); wiktkuPrefs = { langCodes: codes, onlyOnClick: dialog.onlyOnClickCheckbox.isSelected(), portlet: dialog.portletDropdown.getValue() || "auto", quiet: dialog.quietCheckbox.isSelected() }; wiktkuSavePrefs(wiktkuPrefs); mw.notify( "Tercîh hatin qeydkirin. Rûpelê ji nû ve bar bike (F5).", { type: "success", tag: "wiktku-prefs-save" } ); dialog.close({ action: "save" }); }); } if (action === "cancel") { return new OO.ui.Process(function () { dialog.close({ action: "cancel" }); }); } return WiktkuPrefsDialog.super.prototype.getActionProcess.call(this, action); }; wiktkuPrefsWindowManager = new OO.ui.WindowManager(); $(document.body).append(wiktkuPrefsWindowManager.$element); wiktkuPrefsDialog = new WiktkuPrefsDialog(); wiktkuPrefsWindowManager.addWindows([wiktkuPrefsDialog]); } wiktkuPrefsWindowManager.openWindow(wiktkuPrefsDialog); }); } var targetContainer; var skin = mw.config.get('skin'); if (wiktkuPrefs.portlet && wiktkuPrefs.portlet !== "auto") { targetContainer = wiktkuPrefs.portlet; } else if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Li vê rûpelê, ziman an jî beşeke nû zêde bike"); // If "onlyOnClick" is set, the wizard should ONLY ever open via the // "+Ziman/beşeke din" link — never automatically var wiktkuNewPageDetected = $(".mw-newarticletext, .mw-newarticletextanon").length > 0; if (wiktkuPrefs.onlyOnClick ? !addLangMode : (!addLangMode && !wiktkuNewPageDetected)) { return; } // ── Shared helpers ─────────────────────────────────────────────────── // Generic text/UI utilities live in their own package file now — see the // header of util.js for why. Aliased to bare names here so the ~400 call // sites below read exactly as they did when these were local functions. var wiktkuUtil = require("./start/util.js"); var capitalize = wiktkuUtil.capitalize; var decapitalize = wiktkuUtil.decapitalize; var escapeRegExp = wiktkuUtil.escapeRegExp; var stripWikilinks = wiktkuUtil.stripWikilinks; var splitTercimeIzah = wiktkuUtil.splitTercimeIzah; var insertAtCursor = wiktkuUtil.insertAtCursor; var foldDiacritics = wiktkuUtil.foldDiacritics; var wrapNativeSelect = wiktkuUtil.wrapNativeSelect; var initSelects = wiktkuUtil.initSelects; var wiktkuInitManualResize = wiktkuUtil.initManualResize; function langHeaderSource(codePattern) { return "\n?==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } var catSrcTemplates = null; var catSrcTemplatesPromise = null; function fetchCatSrcTemplates() { if (catSrcTemplatesPromise) return catSrcTemplatesPromise; catSrcTemplatesPromise = new mw.Api().get({ action: "query", list: "categorymembers", cmtitle: "Kategorî:Çavkanî", cmnamespace: 10, cmlimit: "max", formatversion: 2 }).then(function (data) { var members = (data.query && data.query.categorymembers) || []; catSrcTemplates = $.map(members, function (m) { // Pêşgira navî ya "Şablon:" rake. return m.title.replace(/^[^:]+:/, ""); }); catSrcTemplates.sort(function (a, b) { return a.localeCompare(b, userLang); }); return catSrcTemplates; }, function () { catSrcTemplates = []; return catSrcTemplates; }); return catSrcTemplatesPromise; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var formCache = new ObjectStorage("wiktku_start_draft_" + mw.config.get("wgPageName"), 1); var langsByCode = {}; // Looks up the display label for a language code, falling back to the // code itself if it isn't known yet (e.g. langsByCode not loaded). function getLangLabel(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; // Converts a {code: label} object (langChoices/posChoices in data.json) // into the {code, label[, sortKey]} array the rest of the script uses. // isLang: true adds a sortKey and shows "(code)" after the label — // language choices only. function choicesFromObject(obj, isLang) { var result = []; $.each(obj || {}, function (code, label) { var choice = { code: code, label: label }; if (isLang) choice.sortKey = label; result.push(choice); }); return result; } function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c.code] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Number codes (y, s, d, p, p+, tp, j, j+, j/nj, nj, nj+, hj!, hj?) from // data.json's "numberLabels". Same {code: {cat, display[, req]}} shape as // the wiki's Lua number-type table; "display" can contain HTML (<abbr>) // or wikilinks, so it's only used as-is in wikitext output, never dropped // straight into an <option> (see stripMarkupForOption below). var NUMBER_LABELS = {}; // Distinguishes the Jimar dropdown (j= param) from the Cîns dropdown // (c= param): a code that's a key in NUMBER_LABELS is a number code, // everything else is a gender code. Compound codes like "m-p"/"n-p" are // gender+plural pairs and correctly stay on the gender side. function isNumberCode(code) { return Object.prototype.hasOwnProperty.call(NUMBER_LABELS, code); } // Strips the bit of markup "display" is allowed to contain so it's safe // to use as plain <option> text (options can't render HTML or wikilinks): // <abbr title="X">Y</abbr> -> "Y (X)", [[a|b]] -> "b", [[a]] -> "a". function stripMarkupForOption(html) { if (!html) return ""; return $.trim( String(html) .replace(/<abbr[^>]*title="([^"]*)"[^>]*>([\s\S]*?)<\/abbr>/gi, "$2 ($1)") .replace(/\[\[[^\]|]*\|([^\]]*)\]\]/g, "$1") .replace(/\[\[([^\]]*)\]\]/g, "$1") .replace(/<[^>]+>/g, "") ); } // Builds the Jimar dropdown's <option> text for one code: "j — jimarbar". function numberOptionLabel(code) { var def = NUMBER_LABELS[code]; if (!def) return code; var text = stripMarkupForOption(def.display); return text ? (code + " — " + text) : code; } // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } // ── Template explanations ──────────────────────────────────────────── // Every place a template can be picked shows the same row: a status // dot, the name, a link to the template page, and an ⓘ. This is the ⓘ. // // Text comes from the template's own TemplateData where it has any, so // the explanation stays right without anyone maintaining a second copy // by hand — with the desc already in data.json as the fallback for // templates that have none. var wiktkuTplDataCache = {}; // name -> {desc, params[]} or null when absent /** Fetches TemplateData for one template. Resolves to null if the * template has none (a plain, undocumented template — very common). */ function fetchTemplateData(name) { if (Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, name)) { return $.Deferred().resolve(wiktkuTplDataCache[name]).promise(); } return new mw.Api().get({ action: "templatedata", titles: "Şablon:" + name, redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; var first = null; $.each(pages, function (_, p) { if (!first) first = p; }); var out = null; if (first) { var desc = first.description; // TemplateData descriptions are language maps when the // template is documented in more than one language. if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(first.params || {}, function (key, p) { var label = p && p.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(p && p.required) }); }); out = { desc: desc || "", params: params }; } wiktkuTplDataCache[name] = out; return out; }, function () { // No TemplateData, or the API is unhappy — cache the miss so a // repeated ⓘ click doesn't re-request it every time. wiktkuTplDataCache[name] = null; return null; }); } /** Fetches TemplateData for many templates in one request and fills the * cache; resolves either way, a template with no TemplateData caches as null. */ function prefetchTemplateData(names) { var missing = $.grep(names || [], function (n) { return n && !Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n); }); if (!missing.length) return $.Deferred().resolve().promise(); // The API caps a titles list at 50 for normal users. missing = missing.slice(0, 50); return new mw.Api().get({ action: "templatedata", titles: $.map(missing, function (n) { return "Şablon:" + n; }).join("|"), redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; $.each(pages, function (_, page) { if (!page || !page.title) return; var name = String(page.title).replace(/^[^:]+:/, ""); var desc = page.description; if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(page.params || {}, function (key, prm) { var label = prm && prm.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(prm && prm.required) }); }); wiktkuTplDataCache[name] = { desc: desc || "", params: params }; }); // Anything the API didn't answer for simply has none — cache the // miss so the per-row ⓘ doesn't re-request it one at a time. $.each(missing, function (_, n) { if (!Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n)) wiktkuTplDataCache[n] = null; }); }, function () { $.each(missing, function (_, n) { wiktkuTplDataCache[n] = null; }); }); } /** Rewrites each tagged <option> in `sel` as "name — description", using * TemplateData. Only fills rows that have no description yet, so the * hand-written ones in data.json (which carry usage examples the API * does not) are left exactly as they are. */ function applyTplDescriptions(sel) { if (!sel || !sel.length) return; var changed = false; sel.find("option[data-tpl]").each(function () { var opt = $(this); var name = opt.attr("data-tpl"); if (opt.text().indexOf(" — ") !== -1) return; // already described var td = wiktkuTplDataCache[name]; var desc = (td && td.desc) || localTplDesc(name); if (!desc) return; // One line: TemplateData descriptions can run to a paragraph. desc = $.trim(String(desc).split("\n")[0]); if (desc.length > 90) desc = desc.slice(0, 90) + "…"; opt.text(name + " — " + desc); changed = true; }); // The picker caches option text for searching, so it has to re-read. if (changed) sel.trigger("wiktku:refresh"); } /** Hand-written fallback description, from data.json. * * This is the escape hatch for templates with no TemplateData on the * wiki: add a "desc" to the entry in data.json and it shows up in the * dropdown and in the ⓘ immediately, no code change. TemplateData is * still the better place — VisualEditor and every other tool reads it * too — but this keeps the picker useful in the meantime. * * Works for any pool: pronTpls, etymTpls, tplDefs, jederDefs. */ function localTplDesc(name) { var pools = [steps.pron.pronTpls, steps.etym.etymTpls, steps.dfn.tplDefs, steps.dfn.jederDefs]; var found = ""; $.each(pools, function (_, pool) { if (pool && pool[name] && pool[name].desc) { found = pool[name].desc; return false; } }); return found; } /** Opens the inline explanation panel for `name`, anchored under the * picker it was opened from. */ function showTemplateInfo(name, anchorWrap) { $(".wiktku-tpl-info").remove(); var panel = $("<div class='wiktku-tpl-info'></div>"); panel.append($("<div class='wiktku-tpl-info-name'></div>").text("{{" + name + "}}")); var body = $("<div class='wiktku-tpl-info-desc'></div>").text("Tê barkirin…"); panel.append(body); var params = $("<div class='wiktku-tpl-info-params'></div>"); panel.append(params); panel.append($("<a class='wiktku-tpl-info-link' target='_blank' rel='noopener'></a>") .attr("href", wiktkuUtil.tplPageUrl(name)) .text("Rûpela şablonê veke →")); var close = $("<button type='button' class='wiktku-tpl-info-close' title='Bigire'>✕</button>"); close.on("click", function () { panel.remove(); }); panel.prepend(close); $(anchorWrap).after(panel); fetchTemplateData(name).then(function (td) { var desc = (td && td.desc) || localTplDesc(name); body.text(desc || "Ji bo vê şablonê ravek nehatiye nivîsandin."); if (td && td.params && td.params.length) { params.append($("<div class='wiktku-tpl-info-params-title'></div>").text("Parametre:")); var listEl = $("<ul></ul>"); $.each(td.params, function (_, p) { var line = p.name + (p.label ? " — " + p.label : "") + (p.required ? " (pêwîst)" : ""); listEl.append($("<li></li>").text(line)); }); params.append(listEl); } }); } /** Marks a picker's <option>s as template rows so the searchable widget * renders them with the dot / 🔗 / ⓘ affordances, and wires the ⓘ * handler for that picker. `nameOf` maps an <option> to a template * name — the pickers store different things in value= (a snippet for * the insert dropdowns, the bare name for the sense selector). */ function markTemplateOptions(sel, nameOf) { if (!sel || !sel.length) return; var names = []; sel.find("option").each(function () { var opt = $(this); var name = nameOf(opt); if (!name) return; opt.attr("data-tpl", name); // Deprecated/typo templates are the "special cases only" ones. opt.attr("data-tpl-status", /kevnbûyî|şaşnivîs|kêmpeyda/i.test(opt.text()) ? "yellow" : "green"); names.push(name); }); sel.data("wiktkuTplInfo", showTemplateInfo); // Fill in the descriptions. Matters most for the Mane picker, whose // entries in data.json are names with no desc at all — "rastnivîs", // "ku-Latn", "guharto" on their own. One request covers every // template in the picker, cached for the per-row ⓘ as well. prefetchTemplateData(names).always(function () { applyTplDescriptions(sel); }); } /** Pulls the template name out of a snippet like "* {{ku-IPA}}" or * "{{ji|SOURCELANG|CODE|…}}". */ function tplNameFromSnippet(snippet) { var m = /\{\{\s*([^|}\n]+)/.exec(snippet || ""); return m ? $.trim(m[1]) : ""; } // True if a sense has content beyond mane worth keeping (etîket, word // lists, nimûne, jêder) — so it's still emitted with {{mane?}} if empty. function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } // A technically-"complete" entry (Ziman + Cureyê rêzimanî filled) with // nothing in Mane, Bi zaravayên din or Werger is still meaningfully // empty, so this is checked separately at submit-click time with its // own message. function hasMinRequiredContent(values) { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasMane = dfnSenses.some(function (s) { return (s.tpl && s.tplTitle) || (!s.tpl && (s.mane !== "" || senseHasExtraContent(s))); }); if (hasMane) return true; if (values.lang === "ku") { var hasWerger = false; $("#wiktku-start-trans .wiktku-trans-group").each(function () { if (steps.trans.getGroupTranslations($(this)).length) hasWerger = true; }); if (hasWerger) return true; var hasZarava = false; $("#wiktku-start-zarava .wiktku-zarava-group").each(function () { if (steps.zarava.getGroupTranslations($(this)).length) hasZarava = true; }); if (hasZarava) return true; } return false; } // Bolds the *first* occurrence of the page name function boldPageNameOnce(text) { if (!text || !pageNameRe) return text; var re = new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "i"); return text.replace(re, "'''$1'''"); } // Converts literal line breaks typed into a nimûne/jêgirtin box into // wikitext <br> tags, function nlToBr(text) { return text ? text.replace(/\r\n|\r|\n/g, "<br>") : text; } function escapeHtmlForBackdrop(str) { return String(str) .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;"); } // Mirrors a textarea's text, with a small highlighted marker placed // right after each line that's followed by an actual typed/pasted // linebreak. Rendered into a transparent backdrop layer behind the // textarea (see ensureLinebreakBackdrop()), so only the point of the // break is marked instead of the whole box. function buildLinebreakBackdropHtml(text) { var lines = text.split(/\r\n|\r|\n/); return $.map(lines, function (line, i) { var isLast = i === lines.length - 1; return escapeHtmlForBackdrop(line) + (isLast ? "" : "<mark class='wiktku-linebreak-mark'>↵</mark>\n"); }).join(""); } // Copies the metrics that affect where text wraps/lands (font, line // height, padding, border) from the real textarea onto its backdrop, // via computed style rather than shared CSS classes — most of the // box's own rules are written as "textarea.foo", which a <div> with // the same class wouldn't match. Re-run on every update in case a // responsive breakpoint changed the textarea's own font-size. function syncLinebreakBackdropMetrics(textarea, backdrop) { var cs = window.getComputedStyle(textarea[0]); backdrop.css({ "box-sizing": cs.boxSizing, "padding-top": cs.paddingTop, "padding-right": cs.paddingRight, "padding-bottom": cs.paddingBottom, "padding-left": cs.paddingLeft, "border-width": cs.borderWidth, "border-style": "solid", "font-family": cs.fontFamily, "font-size": cs.fontSize, "font-weight": cs.fontWeight, "line-height": cs.lineHeight, "letter-spacing": cs.letterSpacing }); } // Lazily wraps a textarea in its own positioning anchor (independent // of .wiktku-resize-wrap, so this doesn't depend on load order versus // wiktkuMakeManualResizable) and inserts the transparent backdrop // layer used to mark the exact point of a linebreak. Safe to call // more than once on the same textarea — the backdrop is cached. function ensureLinebreakBackdrop(textarea) { var existing = textarea.data("wiktkuLinebreakBackdrop"); if (existing) return existing; textarea.wrap("<div class='wiktku-linebreak-wrap'></div>"); var backdrop = $("<div aria-hidden='true'></div>").addClass("wiktku-linebreak-backdrop"); textarea.before(backdrop); textarea.data("wiktkuLinebreakBackdrop", backdrop); textarea.on("scroll.wiktkuLinebreak", function () { backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); }); return backdrop; } // Flags a nimûne/jêgirtin textarea (via CSS class, for the border // tint + tooltip) while it contains a typed/pasted linebreak, so the // user notices before it's silently turned into <br> on output. // Marks only the exact point of the break via a mirrored backdrop, // rather than tinting the whole box. function highlightLinebreak(el) { var textarea = $(el); var text = textarea.val(); var hasBreak = /\r|\n/.test(text); textarea .toggleClass("wiktku-has-linebreak", hasBreak) .attr("title", hasBreak ? "Xeta nû dê wek <br> bê nivîsandin" : ""); if (!hasBreak) { var cached = textarea.data("wiktkuLinebreakBackdrop"); if (cached) cached.hide(); textarea.removeClass("wiktku-has-linebreak-source"); return; } var backdrop = ensureLinebreakBackdrop(textarea); textarea.addClass("wiktku-has-linebreak-source"); syncLinebreakBackdropMetrics(textarea, backdrop); backdrop.html(buildLinebreakBackdropHtml(text)).show(); backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); } // Each nimûne item can be { text, tr, t }: text, transliteration, translation. function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{nimûne?|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = nlToBr(boldPageNameOnce(text)); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + nlToBr(n.tr); // Translation as third positional param (no key needed). if (n.t) tpl += "|" + nlToBr(n.t); } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 60 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } // Formats jêder (citation) entries into "#* {{jêder…|…}}" lines; skips // entries with no quote text. Falls back to the generic {{jêder}} // template when no specific template was chosen. function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; var quote = nlToBr(boldPageNameOnce(jeder.quote)); var quoteTr = nlToBr(jeder.quoteTr); var quoteT = nlToBr(jeder.quoteT); if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + quote; if (quoteTr) cite += "|tr=" + quoteTr; if (quoteT) cite += "|tercime=" + quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + quote; if (quoteTr) out += "|tr=" + quoteTr; if (quoteT) out += "|tercime=" + quoteT; // A şablon picked from Kategorî:Çavkanî is transcluded as the // source param (e.g. |{{Kovara X}}); manual text is used as-is. var srcParam = jeder.jederCatTpl ? ("{{" + jeder.jederCatTpl + "}}") : (jeder.jederManual ? jeder.jederManual : "çavkanî?"); // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } // True if a sense has at least one jêder entry with quote text. function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } // Builds "{{tplName|lang|part1|part2|…}}" from a sense field (kategori, // etiket), wrapped inline (" {{…}} ") or on its own line ("\n#: {{…}}"). function buildSenseTpl(sense, field, lang, tplName) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return call } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } // ── Inline modifier system ─────────────────────────────────────────────── // Appends a ⊕ button to a word input <li>. Clicking it shows a compact // modifier picker; selecting one prompts for the value and appends // <modifier:value> to the textarea's current content. 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îf" }, { 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: qualifier (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" }, { key: "qq", label: "qq: qualifier (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î" } ]; // Sub-groups (inside a sense/definition block) that get the same ⊕ // modifier button as makeWordListStep fields. var MODIFIER_SUBGROUPS = { "wiktku-dfn-alternativ": true, "wiktku-dfn-hevmane": true, "wiktku-dfn-dijmane": true, "wiktku-dfn-koordine": true, "wiktku-dfn-jornav": true, "wiktku-dfn-jernav": true }; /** * Wraps a freshly-created textarea in a <li> with a ⊕ modifier button. * `ta` — the jQuery textarea element. * Returns the <li>. */ function makeModifierLi(ta) { var li = $("<li class='wiktku-word-li'></li>"); var btn = $("<button type='button' class='wiktku-mod-btn' title='Modifiyerê lê zêde bike'>⊕</button>"); var picker = $("<div class='wiktku-mod-picker'></div>").hide(); // Which modifier keys are already present in the textarea's current // text — e.g. "<t:...>" → "t" used. Each modifier can only be // applied once per word, so its pill gets disabled once used. function usedKeys() { var used = {}; var re = /<([a-zA-Z]+):/g; var val = ta.val() || ""; var m; while ((m = re.exec(val)) !== null) used[m[1]] = true; return used; } $.each(WORD_MODIFIERS, function (_, mod) { var pill = $("<button type='button' class='wiktku-mod-pill'></button>").text(mod.label); pill.attr("title", mod.hint); pill.data("mod-key", mod.key); pill.on("click", function (e) { e.preventDefault(); if (pill.prop("disabled")) return; // already used on this word picker.hide(); // Show a tiny inline input for the modifier value. var valWrap = $("<span class='wiktku-mod-val-wrap'></span>"); var valInp = $("<input type='text' class='wiktku-mod-val-input'>") .attr("placeholder", mod.hint + "…") .attr("size", 20); var confirm = $("<button type='button' class='wiktku-mod-confirm'>✓</button>"); var cancel = $("<button type='button' class='wiktku-mod-cancel'>✕</button>"); function applyModifier() { var v = $.trim(valInp.val()); if (v) { ta.val(ta.val() + "<" + mod.key + ":" + v + ">"); ta.trigger("input"); } valWrap.remove(); ta.focus(); } confirm.on("click", applyModifier); cancel.on("click", function () { valWrap.remove(); ta.focus(); }); valInp.on("keydown", function (e) { if (e.which === 13) { e.preventDefault(); applyModifier(); } if (e.which === 27) { valWrap.remove(); ta.focus(); } }); valWrap.append(valInp).append(confirm).append(cancel); li.append(valWrap); valInp.focus(); }); picker.append(pill); }); btn.on("click", function (e) { e.preventDefault(); // Close any other open pickers in the same list. li.closest("ol, ul").find(".wiktku-mod-picker").not(picker).hide(); // Grey out modifiers already used on this word — refreshed on // every open since the text (and thus what's "used") can change. var used = usedKeys(); picker.find(".wiktku-mod-pill").each(function () { var isUsed = !!used[$(this).data("mod-key")]; $(this).prop("disabled", isUsed).toggleClass("wiktku-mod-pill-used", isUsed); }); picker.toggle(); }); // Close picker when focus leaves the li entirely. li.on("focusout", function () { setTimeout(function () { if (!$.contains(li[0], document.activeElement)) picker.hide(); }, 150); }); li.append(ta).append(btn).append(picker); return li; } function makeWordListStep(id, name, question_fmt) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, modifiers: true, // Function instead of a plain string so it can name the current // language — computed fresh at build time and re-applied by // refresh() whenever the language changes. placeholder: function () { var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return "Kelîme" + (langLabel ? " bi " + langLabel : "") + "…"; }, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); var header = capitalize(name); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: {}, visible: function (values) { if (!values.lang) return false; // addLangMode: skip pron only if this lang already has a section. if (addLangMode) { // Clearing the page makes existing content irrelevant. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, // Fills the insert-dropdown from pronTpls, filtered by language. refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); // Reassures the user this field is optional — the dropdown // below writes the template for them, no syntax needed up front. wrap.append( $("<p class='wiktku-step-hint'></p>").text( "Ev qad ne mecbûrî ye. Heke tu nizanî kîjan şablonî hilbijêrî, vale bihêle — an ji pêşkêşkariya jêrîn şablonekî hilbijêre, ew ê bixweber li vir were nivîsandin." ) ); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike "); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); // Clear the picker's search box sel.trigger("wiktku:refresh"); ta.focus(); return; } // The noLang templates (ku-IPA, ku-kîte, zza-IPA, zza-kîte) // auto-generate content from a Lua module reading the page // title, so show a live preview and require confirmation // before inserting. var tplLabel = selectedOption.text(); $(this).val(""); sel.trigger("wiktku:refresh"); steps.pron.showTplPreview(stepDiv, ta, snippet, tplLabel); }); wrap.append(sel).append(ta); stepDiv.append(wrap); steps.pron.buildIpaPalette(wrap, ta); initSelects(wrap); return ta; }, // ── IPA character palette ────────────────────────────────── // Modelled on fr.wiktionary's: every character is a button that // drops itself in at the cursor. Two sub-tabs, because the full // IPA chart is ~180 symbols and roughly twenty of them ever // appear in Kurmancî — "IPA (kurdî)" opens by default and the // full chart is one click away for loanwords and other // languages. Grouped with a label down the left so it reads as // a chart rather than one long line of glyphs. IPA_KU: [ { label: "Kît/stres", chars: ["ˈ", "ˌ", "ː"] }, { label: "Bêdeng", chars: ["d͡ʒ", "t͡ʃ", "ʒ", "ʃ", "ɫ", "ŋ", "ɾ", "r", "ʋ", "ħ", "ʕ", "ɣ", "χ", "ʔ"] }, { label: "Dengdêr", chars: ["ɑː", "eː", "ɛ", "ɪ", "iː", "ɯ", "ʊ", "uː", "yː", "ø", "œ"] } ], IPA_FULL: [ { label: "Bêdeng 1", chars: ["m", "ɱ", "n", "ɳ", "ɲ", "ŋ", "ɴ", "p", "b", "t", "d", "t̪", "d̪", "ʈ", "ɖ", "c", "ɟ", "k", "ɡ", "q", "ɢ", "ʡ", "ʔ"] }, { label: "Bêdeng 2", chars: ["ɸ", "β", "f", "v", "θ", "ð", "s", "z", "ʃ", "ʒ", "ʂ", "ʐ", "ɕ", "ʑ", "ç", "ʝ", "x", "ɣ", "χ", "ʁ", "ħ", "ʕ", "h", "ɦ", "ʜ", "ʢ", "ɧ"] }, { label: "Bêdeng 3", chars: ["ʋ", "ɹ", "ɻ", "j", "ɥ", "ɰ", "ʍ", "w", "ʙ", "ⱱ", "ɾ", "ɽ", "r", "ʀ", "ɺ", "l", "ɫ", "ɬ", "ɮ", "ɭ", "ʎ", "ʟ"] }, { label: "Bêdeng 4", chars: ["ɓ", "ɗ", "ᶑ", "ʄ", "ɠ", "ʛ", "ʘ", "ǀ", "ǃ", "ǂ", "ǁ"] }, { label: "Dengdêr", chars: ["i", "y", "ɪ", "ʏ", "ɨ", "ʉ", "ɯ", "u", "ʊ", "e", "ø", "ɘ", "ɵ", "ɤ", "o", "ə", "ɚ", "ɛ", "œ", "ɜ", "ɝ", "ɞ", "ʌ", "ɔ", "æ", "ɶ", "ɐ", "a", "ɑ", "ɒ"] }, { label: "Suprasegmental", chars: ["ˈ", "ˌ", "ː", "ˑ", "ʼ", "ˀ", "ˤ", "ᵝ", "ᵊ", "ˠ", "ʰ", "ʱ", "ʲ", "ˡ", "ⁿ", "ᵑ", "ʷ", "ᶣ", "˞", "‿"] }, { label: "Dîakrîtîk", chars: ["̚", "̪", "̺", "̻", "̼", "̬", "̊", "̥", "̞", "̝", "̘", "̙", "̽", "̟", "̠", "̈", "̤", "̹", "̜", "̍", "̩", "̆", "̯", "̃", "̰", "͡", "͜"] }, { label: "Ton", chars: ["̋", "́", "̄", "̀", "̏", "̌", "̂", "˥", "˦", "˧", "˨", "˩", "ꜛ", "ꜜ", "↗", "↘", "‖"] } ], /** Builds the two-sub-tab character palette under the textarea. */ buildIpaPalette: function (wrap, ta) { if (wrap.find(".wiktku-ipa-palette").length) return; var panel = $("<div class='wiktku-ipa-panel'></div>").hide(); var toggle = $("<a href='#' class='wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tîpên bilêvkirinê</span>")); toggle.on("click", function (e) { e.preventDefault(); var open = panel.is(":visible"); panel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); wrap.append($("<div class='wiktku-adv-toggle-row'></div>").append(toggle)); // Sub-tab bar, with the two template buttons pinned right. var subTabs = $("<div class='wiktku-ipa-subtabs'></div>"); var kuTab = $("<span class='wiktku-ipa-subtab wiktku-tab-active'>IPA (kurdî)</span>"); var fullTab = $("<span class='wiktku-ipa-subtab'>IPA</span>"); subTabs.append(kuTab).append(fullTab); var tplBtns = $("<span class='wiktku-ipa-tplbtns'></span>"); $.each([ { label: "{{ku-IPA|+}}", snippet: "{{ku-IPA|}}", back: 2 }, { label: "{{IPA|+}}", snippet: "{{IPA|ku|}}", back: 2 } ], function (_, t) { var b = $("<button type='button' class='wiktku-ipa-tplbtn'></button>").text(t.label); b.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], t.snippet); // Park the cursor inside the braces, where the value goes. var pos = ta[0].selectionStart - t.back; ta[0].selectionStart = ta[0].selectionEnd = pos; ta.focus(); }); tplBtns.append(b); }); subTabs.append(tplBtns); panel.append(subTabs); function buildGrid(groups) { var grid = $("<div class='wiktku-ipa-grid'></div>"); $.each(groups, function (_, g) { var row = $("<div class='wiktku-ipa-row'></div>"); row.append($("<span class='wiktku-ipa-rowlabel'></span>").text(g.label)); var keys = $("<span class='wiktku-ipa-keys'></span>"); $.each(g.chars, function (_, ch) { var btn = $("<button type='button' class='wiktku-ipa-key'></button>"); // A combining mark on its own renders as a stray // accent floating over whatever precedes it, so // show it on a dotted circle — but insert only // the mark itself. var combining = /^[̀-ͯ҃-҉]$/.test(ch); btn.text(combining ? "◌" + ch : ch); if (combining) btn.addClass("wiktku-ipa-key-combining"); btn.attr("title", ch); btn.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], ch); ta.focus(); }); keys.append(btn); }); row.append(keys); grid.append(row); }); return grid; } var kuGrid = buildGrid(steps.pron.IPA_KU); var fullGrid = buildGrid(steps.pron.IPA_FULL).hide(); panel.append(kuGrid).append(fullGrid); kuTab.on("click", function () { kuTab.addClass("wiktku-tab-active"); fullTab.removeClass("wiktku-tab-active"); kuGrid.show(); fullGrid.hide(); }); fullTab.on("click", function () { fullTab.addClass("wiktku-tab-active"); kuTab.removeClass("wiktku-tab-active"); fullGrid.show(); kuGrid.hide(); }); panel.addClass("wiktku-ipa-palette"); wrap.append(panel); }, /** Inline preview + confirm panel for a "noLang" (auto-content) * pronunciation template — fetches what the snippet expands to * for this page and only inserts it if the user confirms. */ showTplPreview: function (stepDiv, ta, snippet, tplLabel) { // Only one preview panel open at a time. stepDiv.find(".wiktku-pron-preview").remove(); var panel = $("<div class='wiktku-pron-preview'></div>"); panel.append($("<div class='wiktku-pron-preview-label'></div>") .text("Pêşdîtina " + tplLabel + ":")); var body = $("<div class='wiktku-pron-preview-body'></div>").text("Tê barkirin…"); panel.append(body); var actions = $("<div class='wiktku-pron-preview-actions'></div>"); var confirmBtn = $("<button type='button' class='wiktku-pron-preview-confirm'>✓ Tevlî bike</button>") .prop("disabled", true); var cancelBtn = $("<button type='button' class='wiktku-pron-preview-cancel'>✕ Betal bike</button>"); actions.append(confirmBtn).append(cancelBtn); panel.append(actions); ta.before(panel); confirmBtn.on("click", function () { insertAtCursor(ta[0], snippet); panel.remove(); ta.focus(); }); cancelBtn.on("click", function () { panel.remove(); }); // action=parse, not action=expandtemplates. expandtemplates // returns *expanded wikitext*, so the preview read as // [[IPA]]<sup>([[Wîkîferheng:IPA kurmancî|kilîd]])</sup>: // <span class="IPA">/-{kshhe}-/</span>[[Kategorî:…]] — which // is exactly what the person is trying to avoid having to // read. parse hands back the rendered HTML the page will // actually show. // // Drop the leading "* " first: it is wikitext list syntax // wrapping the template, and keeping it would render the // preview as a bulleted list rather than the line itself. new mw.Api().post({ action: "parse", title: pageName, text: snippet.replace(/^\*\s*/, ""), prop: "text", wrapoutputclass: "", disablelimitreport: 1, disableeditsection: 1, contentmodel: "wikitext", formatversion: 2 }).done(function (data) { var html = (data && data.parse && data.parse.text) || ""; if ($.trim($("<div>").html(html).text())) { body.html(html); // Category links render as nothing but still exist; // and any real link inside a preview should not // navigate away from a half-filled form. body.find("a").attr("target", "_blank").attr("rel", "noopener"); } else { body.text("(vala — ji bo vê rûpelê tiştek nehate afirandin)"); } confirmBtn.prop("disabled", false); }).fail(function () { body.text("Pêşdîtin nehate barkirin — tu dikarî hîn jî wê tevlî bikî."); confirmBtn.prop("disabled", false); }); }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line; }).join("\n"); // "===" heading under Ziman and above the POS sections; the // field is shared across sections, so it's emitted once by // getWikitext() rather than per-POS-section (would otherwise // print the pronunciation twice for a two-POS entry). return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var capitalizedPos = capitalize(pos); // "form" opt-param (checked in posparams) marks this as a // form-of/inflected entry — the section title becomes // "Formeke <pos>ê" instead of the plain pos name. The // template call itself still uses the unchanged pos name. var isForm = $("#wiktku-posparams-opt-form").is(":checked"); var header = isForm ? "\n=== Formeke " + pos + "ê ===\n" : "\n=== " + capitalizedPos + " ===\n"; // Image line (between header and template call) var imageLine = steps.resim.output(values); // Read the live wikitext from the posparams textarea. // Fall back to a plain {{pos|lang}} if the step hasn't been built yet. var tplLine = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); if (!tplLine) { tplLine = "{{" + pos + "|" + (values.lang || "") + "}}"; } return header + imageLine + tplLine + "\n"; } }, // cinsiyet (gender) — shown for navdêr/serenav only, with choices built // from metadata[lang].g since not every language has grammatical gender. cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams // Single source of truth for the selected gender code. The visible // dropdown lives inside the posparams step (see steps.posparams), // but it must always read/write THIS hidden field — not a field of // its own — since getValuesForStep("cinsiyet") reads from here. build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-cinsiyet-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // jimar (grammatical number) — same hidden-field pattern as cinsiyet // above, but writes into its own j= template parameter instead of // sharing c=. Shown for navdêr/serenav only, with choices built from // whichever of metadata[lang].g are number codes (see isNumberCode). jimar: { id: "jimar", name: "jimar", question_fmt: 'Jimara "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-jimar-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // Lêker transitivity — hidden step, handled inside posparams lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function () { return false; }, choices: [ { code: "gh", label: "gerguhêz" }, { code: "x-gh", label: "xwerû-gerguhêz" }, { code: "p-gh", label: "pêkhatî-gerguhêz" }, { code: "h-gh", label: "hevedudanî-gerguhêz" }, { code: "b-gh", label: "biwêjî-gerguhêz" }, { code: "ngh", label: "negerguhêz" }, { code: "x-ngh", label: "xwerû-negerguhêz" }, { code: "p-ngh", label: "pêkhatî-negerguhêz" }, { code: "h-ngh", label: "hevedudanî-negerguhêz" }, { code: "b-ngh", label: "biwêjî-negerguhêz" } ], output: function () { return ""; } }, // tr — hidden step, handled inside posparams tr: { id: "tr", name: "transliterasyon", question_fmt: "Transliterasyona vê kelîmeyê", multiple: false, narrow: true, visible: function () { return false; } }, posparams: { id: "posparams", // Fused onto the "pos" card visually (see #wiktku-start-posparams // in styles.css) so the two read as ONE question — this name is // only a no-CSS/no-JS fallback, since the h3 that would show it // is hidden by CSS. name: "taybetmendî", // Shows what's actually being asked for: gender for nouns, verb // type for verbs, a generic fallback otherwise. question_fmt: function (values) { var pos = values.pos || ""; // Cinsiyet/Jimar fields below are self-labelled, so no title needed here. if (pos === "navdêr" || pos === "serenav") return ""; if (/^lêker/.test(pos)) return "Cureyê lêkerê"; return "Taybetmendî"; }, visible: function (values) { return !!(values.lang && values.pos); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-posparams-wrap").length) return null; var wrap = $("<div class='wiktku-posparams-wrap'></div>"); var helpers = $("<div class='wiktku-posparams-helpers'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-posparams-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-posparams-text") .attr("rows", 2); var _rebuilding = false; function safeRebuild() { if (_rebuilding) return; _rebuilding = true; steps.posparams.rebuildTa(stepDiv); _rebuilding = false; refresh(); } // Generic text-input row factory function makeTextRow(key, labelText, placeholder) { var row = $("<div class='wiktku-posparams-row'></div>") .attr("id", "wiktku-posparams-row-" + key).hide(); var inp = $("<input type='text'>") .addClass("wiktku-start-narrow wiktku-posparams-field") .attr("data-pp-key", key) .attr("placeholder", placeholder || ""); inp.on("input", safeRebuild); row.append($("<label></label>").text(labelText + ": ")).append(inp); return row; } // cinsiyet var cinsiyetRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-c'></div>") .append($("<label></label>").text("Cinsiyet: ")).hide(); var cinsiyetSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-cinsiyet-sel") .append($("<option value=''>— hilbijêre —</option>")); // Writes into the real, shared #wiktku-start-cinsiyet-field (owned by // steps.cinsiyet) rather than a field of its own — see the comment // on steps.cinsiyet.build for why that matters. cinsiyetSel.on("change", function () { $("#wiktku-start-cinsiyet-field").val($(this).val()).trigger("change"); safeRebuild(); }); cinsiyetRow.append(cinsiyetSel); // jimar (number) — second dropdown next to Cinsiyet, writes // into the shared hidden #wiktku-start-jimar-field, into its // own j= param instead of sharing c=. Options + tooltip are // built in syncHelpers once the language's number codes are known. var jimarRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-jimar'></div>") .append($("<label></label>").text("Jimar: ")).hide(); var jimarSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-jimar-sel") .append($("<option value=''>— hilbijêre —</option>")); jimarSel.on("change", function () { $("#wiktku-start-jimar-field").val($(this).val()).trigger("change"); safeRebuild(); }); jimarRow.append(jimarSel); // lektur: two plain questions (transitivity + structural form) // instead of one 10-option dropdown. Emitted code: base alone // ("gh"), or prefix + "-" + base ("x-gh"). var lekturRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lektur'></div>") .append($("<label></label>").text("Lêker derbasdar e? ")).hide(); var lekturSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lektur-sel") .append($("<option value=''>— hilbijêre —</option>")) .append($("<option value='gh'>gerguhêz (bireser digire)</option>")) .append($("<option value='ngh'>negerguhêz (bireser nagire)</option>")); lekturSel.on("change", safeRebuild); lekturRow.append(lekturSel); // Second half of the same question — the structural form. // Blank = xwerû/sade, which is the common case. var lekturFormRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lekturform'></div>") .append($("<label></label>").text("Şiklê lêkerê: ")).hide(); var lekturFormSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lekturform-sel") .append($("<option value=''>sade (asayî)</option>")) .append($("<option value='x'>xwerû</option>")) .append($("<option value='p'>pêkhatî</option>")) .append($("<option value='h'>hevedudanî</option>")) .append($("<option value='b'>biwêjî</option>")); lekturFormSel.on("change", safeRebuild); lekturFormRow.append(lekturFormSel); helpers.append(cinsiyetRow).append(jimarRow).append(lekturRow).append(lekturFormRow); // ── Everything below here is "Tercîhên pêşketî" ────────────── // These rows live inside a collapsed panel, so the default // view of this card is two dropdowns instead of twenty-odd fields. // Transliteration is a primary field, not an advanced one, for // any language not written in Latin script: for those, an // entry without it is incomplete. syncHelpers already gates // the row on needsTransliteration(lang), so for Kurmancî and // other Latin-script languages it simply never appears. helpers.append(makeTextRow("tr", "Transliterasyon (tr)", "Transliterasyon…")); var advPanel = $("<div class='wiktku-posparams-adv-panel'></div>").hide(); advPanel .append(makeTextRow("cuda", "nîşankirina alternatîv", "cuda…")) .append(makeTextRow("ts", "Transkrîpsiyon (ts)", "Transkrîpsiyon…")) .append(makeTextRow("m", "Forma mê (m)", "Forma mê…")) .append(makeTextRow("mtr", "Translit. mê (mtr)", "Transliterasyona mê…")) .append(makeTextRow("n", "Forma nêr (n)", "Forma nêr…")) .append(makeTextRow("ntr", "Translit. nêr (ntr)", "Transliterasyona nêr…")) .append(makeTextRow("p", "Forma pirjimar (p)", "Forma pirjimar…")) .append(makeTextRow("ptr", "Translit. pirjimar", "Transliterasyona pirjimar…")) .append(makeTextRow("y", "Forma yekjimar (y)", "Forma yekjimar…")) .append(makeTextRow("ytr", "Translit. yekjimar", "Transliterasyona yekjimar…")) .append(makeTextRow("sûp", "Forma sûperlatîv (sûp)", "Forma sûperlatîv…")) .append(makeTextRow("sûptr", "Translit. sûperlatîv", "Transliterasyona sûperlatîv…")) .append(makeTextRow("komp", "Forma komparatîv (komp)", "Forma komparatîv…")) .append(makeTextRow("komptr", "Translit. komparatîv", "Transliterasyona komparatîv…")) .append(makeTextRow("gir", "Forma girdêk (gir)", "gir=…")) .append(makeTextRow("girtr", "Translit. gir", "girtr=…")) .append(makeTextRow("hûr", "Forma hûrek (hûr)", "hûr=…")) .append(makeTextRow("hûrtr", "Translit. hûr", "hûrtr=…")) .append(makeTextRow("hanja", "Forma hanja", "hanja=…")) .append(makeTextRow("hanjaTr","Translit. hanja", "hanjaTr=…")) // Lêker rehên demê (only shown when pos is lêker — see syncHelpers) .append(makeTextRow("niha", "Rehê dema niha (niha)", "Rehê dema niha…")) .append(makeTextRow("nihatr", "Translit. rehê dema niha", "Transliterasyona rehê dema niha…")) .append(makeTextRow("borî", "Rehê dema borî (borî)", "Rehê dema borî…")) .append(makeTextRow("borîtr", "Translit. rehê dema borî", "Transliterasyona rehê dema borî…")) .append(makeTextRow("subj", "Rehê dema bilanî (subj)", "Rehê dema bilanî…")) .append(makeTextRow("subjtr", "Translit. rehê dema bilanî", "Transliterasyona rehê dema bilanî…")); // Optional boolean params — nested inside the advanced panel // (they were already the most niche thing on the card). var optPanel = $("<div class='wiktku-posparams-opt-panel'></div>"); $.each([ { key: "form", label: "form — ev made forma tewandî ye" }, { key: "formaalt", label: "formaalt — vê madeyê bike forma alternatîv" }, { key: "nekatcure", label: "nekatcure — sinifa rêzimanî kategorîze neke" }, { key: "nekatcins", label: "nekatcins — kategoriya cinsiyetê neyîne" }, { key: "nekatçendterm", label: "nekatçendterm — kategoriya çend-term neyîne" }, { key: "serlînkneke", label: "serlînkneke — sernavê madeyê lînk neke" }, { key: "nekatpalîndrom", label: "nekatpalîndrom — kategoriya palîndromê neyîne" }, { key: "neformtr", label: "neformtr — transliterasyona forman neyîne" } ], function (_, p) { var cb = $("<input type='checkbox'>") .attr("id", "wiktku-posparams-opt-" + p.key).val(p.key).on("change", safeRebuild); var lbl = $("<label></label>").attr("for", "wiktku-posparams-opt-" + p.key).text(" " + p.label); optPanel.append($("<div class='wiktku-posparams-opt-row'></div>").append(cb).append(lbl)); }); advPanel.append(optPanel); var optToggle = $("<a href='#' class='wiktku-posparams-opt-toggle wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tercîhên pêşketî</span>")); optToggle.on("click", function (e) { e.preventDefault(); var open = advPanel.is(":visible"); advPanel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); helpers.append($("<div class='wiktku-adv-toggle-row'></div>") .append(optToggle)); helpers.append(advPanel); wrap.append(helpers).append(ta); // Typing directly in textarea keeps cinsiyet/jimar hidden // fields in sync, but does NOT call refresh() — preserves // manual edits. ta.on("input", function () { var text = $(this).val(); var cMatch = text.match(/\|c=([^|}\s]+)/); $("#wiktku-start-cinsiyet-field").val(cMatch ? cMatch[1] : ""); var jMatch = text.match(/\|j=([^|}\s]+)/); $("#wiktku-start-jimar-field").val(jMatch ? jMatch[1] : ""); }); stepDiv.append(wrap); return null; }, /** Reads all helper widget values and rewrites the textarea. * Called only by safeRebuild (user interaction) — never by syncHelpers, * so manual textarea edits are never overwritten by a refresh cycle. */ rebuildTa: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; if (!pos || !lang) return; var cinsiyet = stepDiv.find(".wiktku-posparams-cinsiyet-sel").val() || ""; var jimar = stepDiv.find(".wiktku-posparams-jimar-sel").val() || ""; // Two dropdowns, one code: "gh" / "ngh" on their own, or // prefixed with the structural form ("x-gh", "b-ngh", …). var lekturBase = stepDiv.find(".wiktku-posparams-lektur-sel").val() || ""; var lekturForm = stepDiv.find(".wiktku-posparams-lekturform-sel").val() || ""; var lektur = lekturBase ? (lekturForm ? lekturForm + "-" + lekturBase : lekturBase) : ""; function v(key) { return $.trim(stepDiv.find(".wiktku-posparams-field[data-pp-key='" + key + "']").val()); } var out = "{{" + pos + "|" + lang; if (pos === "navdêr" || pos === "serenav") { out += cinsiyet ? "|c=" + cinsiyet : (lang === "ku" ? "|c=?" : ""); // Number is its own j= param, separate from c= (which // holds gender, including compounds like m-p/n-p). if (jimar) out += "|j=" + jimar; } else if (/^lêker/.test(pos) && lektur) { out += "|c=" + lektur; } if (v("cuda")) out += "|" + v("cuda"); if (v("tr")) out += "|tr=" + v("tr"); if (v("ts")) out += "|ts=" + v("ts"); $.each(["m","n","p","y"], function (_, k) { if (v(k)) out += "|" + k + "=" + v(k); if (v(k+"tr")) out += "|" + k + "tr=" + v(k+"tr"); }); if (v("sûp")) out += "|sûp=" + v("sûp"); if (v("sûptr")) out += "|sûptr=" + v("sûptr"); if (v("komp")) out += "|komp=" + v("komp"); if (v("komptr")) out += "|komptr=" + v("komptr"); if (v("gir")) out += "|gir=" + v("gir"); if (v("girtr")) out += "|girtr=" + v("girtr"); if (v("hûr")) out += "|hûr=" + v("hûr"); if (v("hûrtr")) out += "|hûrtr=" + v("hûrtr"); if (v("hanja")) out += "|hanja=" + v("hanja"); if (v("hanjaTr")) out += "|hanjaTr=" + v("hanjaTr"); if (v("niha")) out += "|niha=" + v("niha"); if (v("nihatr")) out += "|nihatr=" + v("nihatr"); if (v("borî")) out += "|borî=" + v("borî"); if (v("borîtr")) out += "|borîtr=" + v("borîtr"); if (v("subj")) out += "|subj=" + v("subj"); if (v("subjtr")) out += "|subjtr=" + v("subjtr"); stepDiv.find(".wiktku-posparams-opt-panel input:checked").each(function () { var key = $(this).val(); // "form" marks this entry as a form-of/inflected entry — it // takes "erê" rather than the plain "1" the other boolean // opt params use. out += "|" + key + "=" + (key === "form" ? "erê" : "1"); }); out += "}}"; stepDiv.find(".wiktku-posparams-text").val(out); $("#wiktku-start-cinsiyet-field").val(cinsiyet); $("#wiktku-start-jimar-field").val(jimar); }, /** Called from refresh() — controls row visibility only. * Does NOT rewrite textarea so user edits are preserved. * Rebuilds only when textarea is empty (first pos selection). */ syncHelpers: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; var needsTr = needsTransliteration(lang); var isNom = pos === "navdêr" || pos === "serenav" || pos === "rengdêr"; var isAdj = pos === "rengdêr"; var isTîp = pos === "tîp"; var isJa = lang === "ja"; var isLeker = /^lêker/.test(pos); // metadata[lang].g lists gender AND number codes together — // split them here (see isNumberCode) so Cîns only ever offers // gender codes (and gender+plural compounds like m-p/n-p, // which aren't NUMBER_LABELS keys) and Jimar only offers number codes. var meta = metadata[lang]; var allCodes = (meta && meta.g) || []; var genderCodes = $.grep(allCodes, function (c) { return !isNumberCode(c); }); var jimarCodes = $.grep(allCodes, function (c) { return isNumberCode(c); }); var showC = (pos === "navdêr" || pos === "serenav") && genderCodes.length > 0; var cRow = stepDiv.find("#wiktku-posparams-row-c"); cRow.toggle(showC); if (showC) { var sel = cRow.find(".wiktku-posparams-cinsiyet-sel"); // Prefer the select's own current value (normal in-session // use); fall back to the shared hidden field, which is how // a cache/section restore communicates a saved gender // before this select has any <option>s to hold it. var prev = sel.val() || $("#wiktku-start-cinsiyet-field").val() || ""; sel.find("option[value!='']").remove(); $.each(genderCodes, function (_, code) { sel.append($("<option></option>").val(code).text(genderLabel(code))); }); if (prev) sel.val(prev); } var showJimar = (pos === "navdêr" || pos === "serenav") && jimarCodes.length > 0; var jimarRowEl = stepDiv.find("#wiktku-posparams-row-jimar"); jimarRowEl.toggle(showJimar); if (showJimar) { var jimarSelEl = jimarRowEl.find(".wiktku-posparams-jimar-sel"); var prevJimar = jimarSelEl.val() || $("#wiktku-start-jimar-field").val() || ""; jimarSelEl.find("option[value!='']").remove(); $.each(jimarCodes, function (_, code) { var def = NUMBER_LABELS[code] || {}; var opt = $("<option></option>").val(code).text(numberOptionLabel(code)); // The explanation (cat, e.g. "dualia tantum") shows as a // hover tooltip — <option> can't hold richer markup. if (def.cat) opt.attr("title", def.cat); jimarSelEl.append(opt); }); if (prevJimar) jimarSelEl.val(prevJimar); } stepDiv.find("#wiktku-posparams-row-lektur").toggle(isLeker); // Only ask for the structural form once gerguhêz/negerguhêz is answered. stepDiv.find("#wiktku-posparams-row-lekturform") .toggle(isLeker && !!stepDiv.find(".wiktku-posparams-lektur-sel").val()); stepDiv.find("#wiktku-posparams-row-tr").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-ts").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-m").toggle(isNom); stepDiv.find("#wiktku-posparams-row-mtr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-n").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ntr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-p").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ptr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-y").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ytr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-sûp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-sûptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-komp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-komptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-gir").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-girtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hûr").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-hûrtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hanja").toggle(isJa); stepDiv.find("#wiktku-posparams-row-hanjaTr").toggle(isJa); stepDiv.find("#wiktku-posparams-row-niha").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-nihatr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-borî").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-borîtr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-subj").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-subjtr").toggle(isLeker && needsTr); if (!$.trim(stepDiv.find(".wiktku-posparams-text").val())) { steps.posparams.rebuildTa(stepDiv); } }, output: function () { return ""; } // pos.output reads the textarea directly }, dfn: { id: "dfn", name: "Mane", // Field types that live behind "Malûmatên pêşketî". Kept as one // list so the collapse CSS, the count badge and the allGroups // adv: flags below can't drift apart. ADV_SUBGROUPS: [ "wiktku-dfn-etiket", "wiktku-dfn-kategori", "wiktku-dfn-alternativ", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ], question_fmt: function (values) { var base = "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin!"; if (values.lang === "ku") { return base + " Ji bo tercimeyan beşa 'Werger' bi kar bîne!"; } return base; }, multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, // Builds one sense block (<li>): mane textarea, nimûne list, and // sub-lists for alternatîv/hevmane/dijmane/etc. buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Tercime + Îzah boxes (non-ku alternative to the plain mane box) — // Non-ku entries get a direct translation plus a {{îzah|…}}-wrapped // gloss instead of a Kurdish-style gloss. Rather than teach every // consumer (getSenses/getOutput/linkify) a second data shape, these // boxes just write their combined text into dfnArea and re-fire its // "input" event, so dfnArea stays the single source of truth. var tercimeArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-tercime-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-tercime") .attr("rows", 2) .attr("placeholder", "Tercimeyên rasterast ên kurmancî… Ji bo school-a îngilîzî li vir 'mekteb, medrese' binivîse"); var izahArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-izah-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-izah") .attr("rows", 3) .attr("placeholder", "Îzaha kurmancî… Ji bo school-a îngilîzî li vir 'cihê tehsîlgirtinê' binivîse"); var nonKuWrap = $("<div class='wiktku-dfn-nonku-wrap'></div>") .append(tercimeArea).append(izahArea) .hide(); function syncNonKuToMane() { var t = $.trim(tercimeArea.val()); var iz = $.trim(izahArea.val()); // if tercime is blank, use îzah as definition var combined = t ? (iz ? t + " {{îzah|" + iz + "}}" : t) : iz; dfnArea.val(combined); // Re-fires onDfnInput, as if this were typed directly into // the mane textarea. dfnArea.trigger("input"); } tercimeArea.on("input", syncNonKuToMane); izahArea.on("input", syncNonKuToMane); // Switches between the plain mane box and the tercime+îzah pair — // only for non-ku entries with no tplSelect selected. function updateManeMode() { var lang = getValues().lang || ""; var isTpl = !!tplSelect.val(); if (lang && lang !== "ku" && !isTpl) { dfnArea.hide(); nonKuWrap.show(); } else { nonKuWrap.hide(); if (!isTpl) dfnArea.show(); } } // Store on the block so refresh() can re-sync every block when // lang changes, and restoreDfn() can re-sync after restoring. block.data("updateManeMode", updateManeMode); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || {}; // Cache of all non-placeholder option elements, so updateTplOptions // can detach/re-attach them without losing the full list. var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.attr("data-placeholder", "Li şablonekê bigere"); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (name, tpl) { // Shows "name — tpl.desc" when a tplDefs entry has a desc // in data.json, same pattern as steps.pron's template picker. var opt = $("<option></option>") .val(name) .text(tpl.desc ? name + " — " + tpl.desc : name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); // Same status-dot / 🔗 / ⓘ row treatment as every other // template picker. This one carries the bare name in value=, // so the name mapper is the identity rather than a snippet // parse; descriptions come from each template's TemplateData. markTemplateOptions(tplSelect, function (opt) { return opt.val(); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible // ones — native <select> won't reliably hide options any other way. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); // Options that were detached when the descriptions arrived // missed that pass, so describe whatever is attached now. // The cache is warm by this point, so this is synchronous. applyTplDescriptions(tplSelect); tplSelect.trigger("wiktku:refresh"); if (currentVal && !currentStillValid) { tplSelect.val(""); tplTitleInput.hide().val(""); updateManeMode(); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpela hedefê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // Şablon senses have no plain gloss, so hide alternatîv/hevmane/ // dijmane/etc. Etîket, Nimûne and Jêgirtin stay visible either way. function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); nonKuWrap.hide(); tplTitleInput.show().focus(); } else { tplTitleInput.hide().val(""); updateManeMode(); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); // The template picker is an alternative to writing a // definition, not a step before it — so the box comes first // and this sits under it as a quiet link. It only expands // for the minority of senses that are a pointer at another // word (guharto, şaşnivîs, kevnbûyî) rather than a meaning. var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput) .hide(); var tplLink = $("<a href='#' class='wiktku-dfn-tpl-link'></a>") .text("Ev ne pênase ye — şablonek bi kar bîne"); tplLink.on("click", function (e) { e.preventDefault(); tplRow.show(); $(this).hide(); tplRow.find("input.wiktku-ac-input").first().focus(); }); /** Opens the picker without a click — used on restore, when a * sense already has a template and hiding it would make the * chosen value invisible. */ function revealTplRow() { tplRow.show(); tplLink.hide(); } block.data("revealTplRow", revealTplRow); block.append(dfnArea); block.append(nonKuWrap); block.append(tplLink); block.append(tplRow); // Apply lang filter on initial build. updateTplOptions(); updateManeMode(); // — Sub-field groups. — // The four most-used groups (Nimûne, Jêgirtin, Hevmane, Dijmane) // stay open; the rest sit behind the "Malûmatên pêşketî" toggle // (adv: true → .wiktku-dfn-subgroup-adv, keyed off by the collapse CSS). // Jêgirtin isn't in this array — it's a compound widget built // after the loop — but it's inserted right after Nimûne so the // visible order matches the list above. var allGroups = [ { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "wekî etîket lê xuya nabe tenê kategorîze dike", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê", adv: true }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in", adv: true }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e", adv: true }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e", adv: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); if (g.adv) groupDiv.addClass("wiktku-dfn-subgroup-adv"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } // The placeholder names the current language, but that's // often not chosen yet when this block is first built — // so keep a function around that refresh() (and onSubInput, // for newly-grown fields) can call again once lang is set // or changes. function subPlaceholder() { if (g.noLangSuffix) return g.label + "…"; var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return g.label + (langLabel ? " bi " + langLabel : "") + "…"; } function updateSubPlaceholders() { list.find("> li > textarea.wiktku-dfn-subfield").attr("placeholder", subPlaceholder()); } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": ") .append($("<span></span>").addClass("wiktku-dfn-sublabel-hint").text(g.izah)); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var useModifiers = !!MODIFIER_SUBGROUPS[g.cls]; list.data("updatePlaceholders", updateSubPlaceholders); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", subPlaceholder()); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow, useModifiers); }); list.append(useModifiers ? makeModifierLi(firstInput) : $("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder group — growing list, same structure as Nimûne. — (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text("Jêgirtin")) .append(": "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<textarea></textarea>") .addClass("wiktku-dfn-subfield wiktku-dfn-quote-citoid-input") .attr("rows", 1) .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi otomatîk tijî bike", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); // Fetches citation data from Citoid and fills this citation's // şablon + fields — only rebuilds fields on template change, // and never overwrites values the user already typed. function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoid.fetchJederFields(query).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only rebuild if switching şablon, so a repeat fetch // doesn't clear fields already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel wiktku-plain-select"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); srcSel.append($("<option></option>").val("__category__").text("Ji Kategorî:Çavkanî şablonekê hilbijêre")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); // Citoid is only useful before a source is chosen — // hide it once a selection is made, restore on reset. if (chosen) { citoidWrap.hide(); } else { citoidWrap.show(); return; } if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } if (chosen === "__category__") { // Search widget over the members of [[Kategorî:Çavkanî]]. // Picking a şablon here immediately switches the row to // "Bi destê xwe binivîsim" mode with {{Şablon}} pre-filled, var catWrap = $("<span></span>").addClass("wiktku-native-select-wrap wiktku-dfn-quote-src-cat"); var catInput = $("<input type='search' autocomplete='off'>") .addClass("wiktku-start-narrow wiktku-dfn-quote-src-cat-input") .attr("placeholder", "Li navê şablonê bigere…"); var catResults = $("<ul></ul>").addClass("wiktku-ac-results wiktku-dfn-quote-src-cat-results").hide(); var catStatus = $("<span></span>").addClass("wiktku-dfn-quote-src-cat-status").text("Şablon tên barkirin…"); var showCatResults = function (query) { var q = $.trim(query).toLowerCase(); catResults.empty(); var list = catSrcTemplates || []; var matched = q ? $.grep(list, function (name) { return name.toLowerCase().indexOf(q) !== -1; }) : list; if (!matched.length) { catResults.hide(); return; } $.each(matched.slice(0, 50), function (_, name) { var li = $("<li></li>").text(name).attr("data-value", name); var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; e.preventDefault(); selectCatTpl(name); }); li.on("mousedown", function (e) { e.preventDefault(); selectCatTpl(name); }); catResults.append(li); }); catResults.show(); }; // Wraps the chosen şablon as {{Name}}, drops it into the // manual textarea, and switches the row into manual mode // so the user can keep editing it (add params, etc.). var selectCatTpl = function (name) { catResults.hide(); srcSel.val("__manual__"); srcSel.trigger("change"); srcFields.find(".wiktku-dfn-quote-src-manual") .val("{{" + name + "}}") .trigger("focus"); }; catInput.on("input", function () { showCatResults($(this).val()); }); catInput.on("focus", function () { showCatResults($(this).val()); }); catInput.on("blur", function () { setTimeout(function () { catResults.hide(); }, 200); }); catWrap.append(catInput).append(catResults).append(catStatus); srcFields.append(catWrap); fetchCatSrcTemplates().then(function () { catStatus.text(""); }, function () { catStatus.text("Şablon nehatin barkirin."); }); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (key, label) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", key) .attr("placeholder", label + "…"); // "Sernav" / "Sernavê orjînal" (title fields, e.g. for // kitêb/kovar/malper) get a taller, draggable box; every // other field in the template stays as-is. Field labels // come from the on-wiki jederDefs data, so match on the // (diacritic-folded) label text rather than a fixed key. var foldedLabel = foldDiacritics(label); if (/^sernav$/.test(foldedLabel) || /orjin/.test(foldedLabel)) { inp.addClass("wiktku-dfn-quote-src-input--title"); } row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); jederGroupDiv.append(jederLbl).append(jederList); // Straight after Nimûne rather than last: Jêgirtin is the // same kind of thing (an attested use of the word) and the // two belong together — see the allGroups comment above. var nimuneGroup = block.find(".wiktku-dfn-nimune-group"); if (nimuneGroup.length) jederGroupDiv.insertAfter(nimuneGroup); else block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); // ── "Malûmatên pêşketî" — per sense, after Dijmane ─────── // One toggle per sense rather than one for the whole step: // the fields behind it (Etîket, Kategorî, Jornav…) belong to // a single meaning, so a global switch flipped them for every // sense at once and gave a count that answered "across all // senses" — not a question anybody was asking. (function () { block.addClass("wiktku-sense-adv-hidden"); var advRow = $("<div class='wiktku-adv-toggle-row wiktku-sense-adv-row'></div>"); var advToggle = $("<a href='#' class='wiktku-adv-toggle'></a>").attr("aria-expanded", "false"); var advLabel = $("<span class='wiktku-adv-toggle-text'></span>"); advToggle.append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")).append(advLabel); function syncAdv() { var hidden = block.hasClass("wiktku-sense-adv-hidden"); advLabel.text(hidden ? "Malûmatên pêşketî nîşan bide" : "Malûmatên pêşketî veşêre"); advToggle.attr("aria-expanded", hidden ? "false" : "true") .toggleClass("wiktku-adv-open", !hidden); } advToggle.on("click", function (e) { e.preventDefault(); block.toggleClass("wiktku-sense-adv-hidden"); syncAdv(); }); block.data("syncSenseAdv", syncAdv); advRow.append(advToggle); // After the last always-visible group (Dijmane) and before // the advanced ones, which sit below it in DOM order. var lastPrimary = block.find(".wiktku-dfn-dijmane-group"); if (lastPrimary.length) advRow.insertAfter(lastPrimary); else block.append(advRow); syncAdv(); }()); return block; }, /** Shows only `block` among the sense list; hides every other one. */ setOpenSense: function (stepDiv, block) { stepDiv.find("li.wiktku-dfn-sense").each(function () { $(this).toggleClass("wiktku-sense-collapsed", !$(this).is(block)); }); steps.dfn.renderSenseTabs(stepDiv); }, /** Rebuilds the "Mane 1 / Mane 2 / + Mane zêde bike" tab row from the current sense list. */ renderSenseTabs: function (stepDiv) { var tabsDiv = stepDiv.find(".wiktku-dfn-sense-tabs"); if (!tabsDiv.length) return; tabsDiv.empty(); stepDiv.find("li.wiktku-dfn-sense").each(function (i) { var li = $(this); var tab = $("<span class='wiktku-dfn-sense-tab'></span>") .text("Mane " + (i + 1)) .toggleClass("wiktku-tab-active", !li.hasClass("wiktku-sense-collapsed")); tab.on("click", function () { steps.dfn.setOpenSense(stepDiv, li); }); tabsDiv.append(tab); }); var addBtn = $("<button type='button' class='wiktku-add-sense'></button>") .append($("<span class='wiktku-add-sense-plus'>+</span>")) .append(document.createTextNode("Mane zêde bike")); addBtn.on("click", function (e) { e.preventDefault(); steps.dfn.addSense(stepDiv); }); tabsDiv.append(addBtn); }, onDfnInput: function (stepDiv, block, textarea) { refresh(); }, /** Appends a sense, opens it, and hides the others. */ addSense: function (stepDiv) { var list = stepDiv.find("ol.wiktku-dfn-list"); var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); initSelects(newBlock); steps.dfn.setOpenSense(stepDiv, newBlock); newBlock.find("textarea.wiktku-dfn-mane").first().focus(); refresh(); return newBlock; }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow, modifiers) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow, modifiers); }); list.append(modifiers ? makeModifierLi(next) : $("<li></li>").append(next)); // New field starts with no placeholder — give it (and any // others in the list) the current one. var updatePlaceholders = list.data("updatePlaceholders"); if (typeof updatePlaceholders === "function") updatePlaceholders(); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: {}, posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; // One reassurance, shown once for the whole Mane step: the // "an jî şablonek hilbijêre" dropdown inside each sense is // optional — plain text is the normal path. if (!stepDiv.find(".wiktku-dfn-tpl-hint").length) { stepDiv.append( $("<p class='wiktku-step-hint wiktku-dfn-tpl-hint'></p>").text( "Ji bo her maneyekê, dropdown-a \"an jî şablonek hilbijêre\" ne mecbûrî ye — bi gelemperî tu tenê maneyê bi tîpên asayî dinivîsî. Ew şablon tenê ji bo rewşên taybet in (mînak: guherto, kevnbûyî, şaşnivîs); heke tu nizanî kîjan divê, vale bihêle." ) ); } var tabsDiv = $("<div class='wiktku-dfn-sense-tabs'></div>"); stepDiv.append(tabsDiv); var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); steps.dfn.renderSenseTabs(stepDiv); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName === "__category__") { // Reachable only if the user opened the category search but // never picked a şablon — picking one switches the row to // __manual__ (see selectCatTpl above), so there's nothing // meaningful to save here. } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: readList("wiktku-dfn-etiket"), kategori: readList("wiktku-dfn-kategori"), nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense var izahLines = []; // parallel — raw îzah gloss for that same sense // True only once some sense's *actual* dfn text (post tercime/îzah // split) is non-empty. var hasLinkableMane = false; $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("# " + (tplKatTpl ? tplKatTpl + " " : "") + (tplLabelTpl ? tplLabelTpl + " " : "") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(""); // template senses have no îzah return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty // Pull the îzah gloss (if any) out of the combined tercime+îzah // string — it's spliced back in separately below, after its // own linkify pass (see izahLines / the second linkifyText call). var izahRaw = null; var tercimeIzah = splitTercimeIzah(dfn); if (tercimeIzah) { dfn = tercimeIzah.tercime; izahRaw = stripWikilinks(tercimeIzah.izah); } if (dfn) { dfn = stripWikilinks(dfn); // Sentence-case + trailing period are for ku definitions, // which are written as full glosses. if (lang === "ku") { if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } // Real prose — this is what makes the sense worth running // through the main linkify pass. hasLinkableMane = true; } else if (izahRaw === null) { // No mane at all — this is just the "{{mane?|lang}}" // placeholder, a bare template call with no plain words // in it. Do NOT count it as linkable: sending nothing but // bracketed templates through the main linkify pass hangs // the linkify gadget (see the hasLinkableMane/hasIzah // check below). dfn = lang === "ku" ? "{{mane?|" + lang + "}}" : ""; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var out = "# " + (katTpl ? katTpl + " " : "") + (labelTpl ? labelTpl + " " : "") + dfn; var idx = defLines.length; var hasThisIzah = izahRaw !== null && $.trim(izahRaw) !== ""; // Bare {{...}} token — like {{wiktku-cite-N}}, this survives // linkify's first pass untouched (it treats template calls as // opaque), then gets swapped for {{îzah|…}} once the actual // gloss text has been linkified in its own separate pass. if (hasThisIzah) { out += (dfn ? " " : "") + "{{wiktku-izah-" + idx + "}}"; } function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(hasThisIzah ? izahRaw : ""); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } // Runs text through the linkify gadget if it's loaded, otherwise // just passes it through unchanged. Shared by both linkify passes // below (main mane text, and — separately — îzah glosses). function linkifyText(t, cb) { if (typeof $.kuLinkify === "function") { $.kuLinkify(t, cb); } else { cb(t); } } var hasIzah = izahLines.some(function (t) { return t && $.trim(t) !== ""; }); var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with nimûne?. text = "# {{mane?|" + lang + "}}\n#* {{nimûne?|" + lang + "}}\n"; callback(text); return; } // Runs the îzah-only linkify pass against `base` (either the raw // text, when there's no linkable mane to run the main pass on // first, or the already-linkified main text). Shared by both // branches below so the token-splice logic only lives once. function runIzahPass(base) { var izahJoined = $.map(izahLines, function (raw, idx) { if (!raw) return undefined; return "{{wiktku-izah-open-" + idx + "}}" + raw + "{{wiktku-izah-close-" + idx + "}}"; }).join("\n"); linkifyText(izahJoined, function (izahLinked) { var izahByIdx = {}; var re = /\{\{wiktku-izah-open-(\d+)\}\}([\s\S]*?)\{\{wiktku-izah-close-\1\}\}/g; var m; while ((m = re.exec(izahLinked)) !== null) { izahByIdx[parseInt(m[1], 10)] = m[2]; } var withIzah = base.replace(/\{\{wiktku-izah-(\d+)\}\}/g, function (_, n) { var linked = izahByIdx[parseInt(n, 10)]; return linked !== undefined ? "{{îzah|" + linked + "}}" : ""; }); callback(restoreCites(withIzah)); }); } if (!hasLinkableMane) { if (!hasIzah) { // All filled senses are template senses (or otherwise have // no plain text at all) — nothing here needs linkify. callback(restoreCites(text)); return; } // There's no plain mane text anywhere (e.g. tercime left blank // with only îzah filled in), so every defLine is just a bare // template call with nothing to word-link. Sending a line // like "# {{wiktku-izah-0}}" through the main linkify pass // gives it no plain words to work with, makes the linkify // gadget hang — so skip that pass entirely and run only // the îzah pass, splicing straight into the unlinkified text. var loadIzahOnly = function () { runIzahPass(text); }; mw.loader.using("ext.gadget.linkify", loadIzahOnly, loadIzahOnly); return; } var didTryToLoad = function () { // First pass: the main definition text (mane), same as before. linkifyText(text, function (mainLinked) { if (!hasIzah) { callback(restoreCites(mainLinked)); return; } // Second pass: îzah glosses, linkified via their own // separate call. Each gloss is wrapped in its own // {{wiktku-izah-open/close-N}} pair; like the existing // {{wiktku-cite-N}} tokens, these sit inside double // braces so linkify leaves the tokens themselves alone — // only the raw gloss text between each pair gets linked. runIzahPass(mainLinked); }); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, tewandin: { id: "tewandin", name: "tewandin", question_fmt: 'Tewandina "' + pageName + '" binivîse', visible: function (values) { return values.lang && values.pos; }, build: function (stepDiv) { if (stepDiv.find(".wiktku-tewandin-wrap").length) return null; var wrap = $("<div class='wiktku-tewandin-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-tewandin-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-tewandin-text") .attr("rows", 4) .attr("placeholder", "{{ku-tewîn-nav|nêr}}"); wrap.append(ta); stepDiv.append(wrap); function autoPopulate() { if (!ta.length) return; var vals = getValues(); var c = vals.cinsiyet || ""; var p = vals.pos || ""; if (!pageName.includes(" ") && c && GENDER_BASE_LABELS[c] && (p === "navdêr" || p === "serenav") && vals.lang === "ku" && c !== "mndudil") { var label = (c === "mnmane") ? "mê û nêr" : GENDER_BASE_LABELS[c]; var out = "{{ku-tewîn-nav|" + label; if (p === "serenav") out += "|y"; out += "}}"; if (!$.trim(ta.val())) ta.val(out); } } setTimeout(function () { autoPopulate(); $("#wiktku-start-form").on("change.tewandin", "#wiktku-start-lang-field, #wiktku-start-cinsiyet-field, #wiktku-start-pos-field", autoPopulate); }, 0); return ta; }, output: function () { var manualText = $.trim($("#wiktku-start-tewandin .wiktku-tewandin-text").val()); if (manualText) { return "\n==== Tewandin ====\n" + manualText + "\n"; } return ""; } }, // resim — one or more images resim: { id: "resim", name: "resim", question_fmt: "Resmekê lê zêde bike", visible: function (values) { return !!(values.lang && values.pos); }, /** Builds one image row: filename + caption + alt text. */ buildItem: function (stepDiv) { var item = $("<li class='wiktku-resim-item'></li>"); var fileRow = $("<div class='wiktku-posparams-row'></div>"); var fileInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-file") .attr("placeholder", "navê_dosyayê.jpg"); fileRow.append($("<label></label>").text("Navê dosyayê: ")).append(fileInp); var capRow = $("<div class='wiktku-posparams-row'></div>"); var capInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-caption") .attr("placeholder", "Danasîna resimê…"); capRow.append($("<label></label>").text("Danasîn: ")).append(capInp); // Alt text: what a screen reader announces for this image var altRow = $("<div class='wiktku-posparams-row'></div>"); var altInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-alt") .attr("placeholder", "Ji bo kesên nabînin, çi tê dîtin? (ne mecbûrî)"); altRow.append($("<label></label>").text("Nivîsa alternatîf: ")).append(altInp); // Auto-fill the caption with the plain page name when a filename // is typed fileInp.on("input", function () { var file = $.trim($(this).val()); var curCap = $.trim(capInp.val()); var isDefault = !curCap || curCap === pageName; if (file && isDefault) { capInp.val(pageName); } else if (!file && isDefault) { capInp.val(""); } steps.resim.onFileInput(stepDiv, item, this); }); item.append(fileRow).append(capRow).append(altRow); return item; }, /** Grows the image list when the last row's filename gets content. */ onFileInput: function (stepDiv, item, input) { var val = $.trim($(input).val()); var list = stepDiv.find("ol.wiktku-resim-list"); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { list.append(steps.resim.buildItem(stepDiv)); } }, build: function (stepDiv) { if (stepDiv.find(".wiktku-resim-wrap").length) return null; var wrap = $("<div class='wiktku-resim-wrap'></div>"); var list = $("<ol class='wiktku-resim-list'></ol>"); list.append(steps.resim.buildItem(stepDiv)); wrap.append(list); stepDiv.append(wrap); return null; }, /** Reads every filled row from the DOM into an array of {file, caption, alt} * objects — blank rows (missing filename or caption) are skipped. * Non-Kurdish captions get wrapped in {{zim|lang|…}} here, unless * the user already typed their own {{zim|…}} template. Alt text is * optional and left as plain text either way. */ getImages: function (values) { var lang = (values && values.lang) || getValues().lang || ""; var images = []; $("#wiktku-start-resim li.wiktku-resim-item").each(function () { var file = $.trim($(this).find(".wiktku-resim-file").val()); var caption = $.trim($(this).find(".wiktku-resim-caption").val()); var alt = $.trim($(this).find(".wiktku-resim-alt").val()); if (!file || !caption) return; // Strip leading "Wêne:" or "File:" if the user typed it — we add it ourselves. file = file.replace(/^(wêne|file|image)\s*:\s*/i, ""); if (lang && lang !== "ku" && !/^\{\{zim\s*\|/i.test(caption)) { caption = "{{zim|" + lang + "|" + caption + "}}"; } images.push({ file: file, caption: caption, alt: alt }); }); return images; }, output: function (values) { var images = steps.resim.getImages(values); if (!images.length) return ""; return images.map(function (img) { var altPart = img.alt ? "|alt=" + img.alt : ""; return "[[Wêne:" + img.file + "|thumb" + altPart + "|" + img.caption + "]]"; }).join("\n") + "\n"; } }, // bnr-h — {{bnr-h|Page1|Page2|…}} prepended before the lang section (shared, not per-section) bnrh: { id: "bnrh", name: "binêre herwiha (bnr-h)", question_fmt: "Şablona bnr-h li qismê herî jor a rûpelê", //visible: function (values) { return !!values.lang; }, multiple: true, narrow: true, placeholder: "Ji bo 'test' bnr 'Test', 'teşt'", output: function (values) { var pages = $.grep(values.bnrh || [], function (p) { return !!$.trim(p); }); if (!pages.length) return ""; return "{{bnr-h|" + pages.map(function (p) { return $.trim(p); }).join("|") + "}}\n"; } }, bikaranin: { id: "bikaranin", name: "Notên bikaranînê", question_fmt: "Notên bikaranînê yên li ser vê kelîmeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, output: function (values) { var text = $.trim(values.bikaranin || ""); if (!text) return ""; return "\n==== Notên bikaranînê ====\n" + text + "\n"; }, }, xwendin: { id: "xwendin", name: "Bêhtir bixwîne", question_fmt: "Lînkên derveyî eleqedarî vê madeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: function (values) { if (!values || !values.lang) { return `* {{wpedî}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; } const ziman = values.lang === "ku" ? "" : `|ziman=${values.lang}`; return `* {{wpedî${ziman}}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; }, output: function (values) { var text = $.trim(values.xwendin || ""); if (!text) return ""; return "\n==== Bêhtir bixwîne ====\n" + text + "\n"; }, }, alfabeyendin: { id: "alfabeyendin", name: "Bi alfabeyên din", question_fmt: function (values) { var base = "Nivîsîna vê kelîmeyê bi alfabeyên din" var langLabel = values.lang ? getLangLabel(values.lang) : ""; if (langLabel) { return base + " ên " + langLabel; } return base; }, visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: "Ji bo kurmancî: * {{ku-ar|şiklê alfaba erebî}}", output: function (values) { var text = $.trim(values.alfabeyendin || ""); if (!text) return ""; return "\n==== Bi alfabeyên din ====\n" + text + "\n"; }, }, formalt: makeWordListStep("formalt", "formên alternatîv", "Formên alternatîv ên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), hevmane: makeWordListStep("hevmane", "hevmane", "Hevmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), dijmane: makeWordListStep("dijmane", "dijmane", "Dijmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jornav: makeWordListStep("jornav", "jornav", "Jornavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jernav: makeWordListStep("jernav", "jêrnav", "Jêrnavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse"), binereherwiha: makeWordListStep("binereherwiha", "herwiha binêre", "Kelîmeyên din ên eleqedar binivîse"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: {}, visible: function (values) { return values.lang && values.pos; }, // Fills the insert-dropdown from the current etymTpls object. refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(ta); stepDiv.append(wrap); initSelects(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder. // Skip it only when every filled sense is a şablon sense // a completely empty entry with no şablon chosen still gets the placeholder var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasFilledTplSense = dfnSenses.some(function (s) { return !!s.tpl && !!s.tplTitle; }); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (hasFilledTplSense && !hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: function (values) { return {"navz": true, [values.lang]: true} }, // Language dropdown + growing word-input list; a new row appends // when the dropdown gets a value. Mirrors steps.trans, but flat. buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/build below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Attach the searchable picker now the select is in the DOM. initSelects(list); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", question_fmt: "'"+ pageName + "' di zaravayên din de çawa tê gotin?", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: {}, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zaravayekî bigere"); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; // A completely empty entry still gets a placeholder section // to fill in later; an individual placeholder gloss is only // skipped once some other sense already has real content. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", question_fmt: "Tercimeyên vê maneyê bi zimanên din binivîse", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide only when every sense is a filled template sense (no plain // gloss to attach translations to). A mix, or nothing filled in // yet, still shows Werger. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, // Language dropdown + growing word-input list, scoped to one gloss's // group (each gloss has its own group and row list). buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/buildGroup below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, // Builds (or fetches) the .wiktku-trans-group for one gloss. buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, // Syncs one .wiktku-trans-group per current gloss, keyed by // data-gloss-pos so groups stay matched across rebuilds. build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, // Reads all translation rows, grouped by gloss position. getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, // Builds the numbered "{ index, gloss }" list, one per dfn sense // with a real mane (skips template senses). index is 1-based and // matches the sense's position in the "#" definition list. // When nothing's filled in, returns one placeholder entry so // Werger still has a group to attach to; when every sense is a // filled template sense, stays empty (matches trans.visible()). glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane, but other fields are filled — still gets a // gloss group since dfn.getOutput() emits {{mane?}} for it. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // A completely empty entry (nothing filled in dfn at all, no // şablon chosen either) still gets a placeholder Werger section // to fill in later. Only // skip an individual placeholder gloss below when some other // sense actually has real content, making that particular // placeholder redundant. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it. If some other sense already has real // content, this placeholder is redundant — skip it. If the // whole entry is empty, keep it so Werger still gets a // section to fill in. if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, cavkani: { id: "cavkani", name: "çavkanî", question_fmt: "Çavkaniyên din (ne jêgirtin) lê zêde bike", visible: function (values) { return !!values.pos; }, // Fills the insert-dropdown from the members of [[Kategorî:Çavkanî]]. refreshTplSelect: function () { var sel = $("#wiktku-start-cavkani .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(catSrcTemplates || [], function (_, name) { sel.append($("<option></option>").val(name).text(name)); }); markTemplateOptions(sel, function (opt) { return opt.val(); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-cavkani-wrap").length) return null; var wrap = $("<div class='wiktku-cavkani-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-cavkani-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-cavkani-text") .attr("rows", 4) .attr("placeholder", "Şablonekî ji lîsteyê hilbijêre an rasterast binivîse…"); // Template insert dropdown, populated from [[Kategorî:Çavkanî]] — // options refreshed once the category members are fetched. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var status = $("<span class='wiktku-cavkani-status'></span>"); sel.on("change", function () { var name = $(this).val(); if (!name) return; insertAtCursor(ta[0], "\n* {{" + name + "}}"); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(status).append(ta); stepDiv.append(wrap); // build() runs again for every new beş (see the "+ Beş zêde bike" // handler), after the initial page-wide pass — so this select needs // its own init or it stays a plain, unsearchable native <select>. initSelects(wrap); if (catSrcTemplates) { steps.cavkani.refreshTplSelect(); } else { status.text("Şablon tên barkirin…"); fetchCatSrcTemplates().then(function () { steps.cavkani.refreshTplSelect(); status.text(""); }, function () { status.text("Şablon nehatin barkirin."); }); } return ta; }, output: function () { var text = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); if (!text) return ""; return "\n==== Çavkanî ====\n" + text + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); // This array only controls DOM build order — nothing else keys off it // (see the comment above stepIdToGroup). Mane tab order: Mane (senses, // with malûmatên pêşketî nested inside each, see steps.dfn.build) → // Wêne → Bi zaravayên din → Werger, so dfn/resim/zarava/trans sit // adjacent to each other in that order. var ordered_steps = [ steps.lang, steps.pos, steps.posparams, steps.cinsiyet, steps.jimar, steps.lektur, steps.tr, // Mane tab, in reading order: the senses, then the two things that // belong to the entry as a whole rather than to one sense. steps.dfn, steps.tewandin, steps.alfabeyendin, steps.zarava, steps.trans, // Etîmolojî tab. steps.etym, steps.dunde, // Eleqedar tab — three lists of the same shape. steps.je, steps.tekildar, steps.binereherwiha, // Bilêvkirin isn't part of any STEP_GROUPS tab, but still needs a // slot here because this array is what builds the DOM. steps.pron, // Beşên din, behind the picker. steps.resim, steps.bnrh, steps.bikaranin, steps.formalt, steps.hevmane, steps.dijmane, steps.jornav, steps.jernav, steps.cavkani, steps.xwendin]; // ── Step-group tabs ────────────────────────────────────────────────────── // Four tabs: "Mane" holds the senses (whose own blocks carry Nimûne, // Jêgirtin, Hevmane and Dijmane — see steps.dfn.allGroups), Tewandin, // alfabeyendin, zarava and trans; "Etîmolojî" and "Eleqedar" split out // the two other topical clusters; everything else lives behind the // "Beşên din" picker. "mane" stays first as the default-active tab // since Mane is required content. Tewandin keeps its own free-text // {{ku-tewîn-nav}} field and does NOT absorb the Cins/zayend form // parameters (m=/n=/p=), which stay on the headword template. var STEP_GROUPS = [ { id: "mane", label: "Mane", steps: ["dfn", "tewandin", "alfabeyendin", "zarava", "trans"] }, { id: "etimoloji", label: "Etîmolojî", steps: ["etym", "dunde"] }, { id: "eleqedar", label: "Eleqedar", steps: ["je", "tekildar", "binereherwiha"] }, { id: "besendin", label: "Beşên din", steps: ["resim", "formalt", "hevmane", "dijmane", "jornav", "jernav", "bikaranin", "cavkani", "xwendin", "bnrh"] }, ]; // Steps that live behind the "Beşên din" picker — only these need an // explicit "open" before they're shown, even when their tab is active. // Derived from the group above so it can't drift out of sync. var BESENDIN_STEP_IDS = STEP_GROUPS[3].steps; // Reverse lookup: step id -> index into STEP_GROUPS (undefined for // ungrouped steps — now only lang/pos/posparams/cinsiyet/lektur/tr, // which stay always-visible since they're required to get to everything // else). var stepIdToGroup = {}; $.each(STEP_GROUPS, function (gi, g) { $.each(g.steps, function (_, sid) { stepIdToGroup[sid] = gi; }); }); // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "posparams", "cinsiyet", "jimar", "lektur", "tr", "resim", "dfn", "tewandin", "formalt", "bikaranin", "alfabeyendin", "hevmane", "dijmane", "jornav", "jernav", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans", "cavkani", "xwendin" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; // ── Bilêvkirin as a standalone section ─────────────────────────────── // Pronunciation belongs to the word, not to one part of speech, so it // sits beside Navdêr/Lêker in the tab bar rather than inside any of them. // Modelled as a flag rather than an entry in `sections` since // activeSection is used as an array index in many places — viewing // Bilêvkirin leaves activeSection pointing at the POS section you were on. var viewingPron = false; // is it the tab currently on screen // Which STEP_GROUPS tab is currently shown. Lives out here (like // activeSection above) so refresh() — which is not nested inside build() // — can read it and so renderGroupTabs()/updateGroupTabIndicators() below // can be called from refresh() too. Both operate on the tab bar via its // #wiktku-group-tabs id rather than a closured element reference, for the // same reason. var activeGroup = 0; // Unsaved-changes / autosave state. Lives out here (same reason as // activeGroup above) so destroy() — which runs on final submit and on // switching to the source editor, and is not nested inside build() — // can clear the timers and the beforeunload warning. build() assigns // into these; it doesn't re-declare them. var formDirty = false; var autosaveDebounceTimer = null; var autosaveInterval = null; /** Scrolls so #wiktku-group-tabs sits exactly at its sticky position, * instead of leaving the reader stranded wherever they'd scrolled to * under the previous tab's content. Deferred a frame: switching tabs * just changed the DOM (often shortening the page), and the browser * clamps window.scrollY to the new max scroll on its own schedule — * reading it/measuring the element immediately can race that * clamp and land on a stale position. */ function scrollToGroupTabs() { var el = document.getElementById("wiktku-group-tabs"); if (!el) return; window.requestAnimationFrame(function () { var rect = el.getBoundingClientRect(); var stickyTop = parseFloat(window.getComputedStyle(el).top) || 0; window.scrollTo({ top: Math.max(0, window.scrollY + rect.top - stickyTop), behavior: "smooth" }); }); } /** Re-renders the step-group tab bar to reflect the current activeGroup. */ function renderGroupTabs() { var groupTabsDiv = $("#wiktku-group-tabs"); if (!groupTabsDiv.length) return; groupTabsDiv.empty(); $.each(STEP_GROUPS, function (i, g) { var tab = $("<span></span>") .addClass("wiktku-group-tab") .attr("data-group-idx", i) .text(g.label) .toggleClass("wiktku-tab-active", i === activeGroup); (function (idx) { tab.on("click", function () { if (idx === activeGroup) return; activeGroup = idx; renderGroupTabs(); if (idx === BESENDIN_GROUP_IDX) renderBesenDinPicker(); refresh(); scrollToGroupTabs(); }); }(i)); groupTabsDiv.append(tab); }); } /** * Toggles a "needs attention" dot on any group tab that still has a * required, unfilled field hidden inside it — so switching tabs doesn't * leave the person wondering why "Bişîne" stays disabled. */ function updateGroupTabIndicators(values) { var tabs = $("#wiktku-group-tabs .wiktku-group-tab"); if (!tabs.length) return; $.each(STEP_GROUPS, function (i, g) { var missing = false; $.each(g.steps, function (_, sid) { var step = steps[sid]; if (!step || !step.required) return; var val = values[sid]; if (val === "" || (step.multiple && $.isArray(val) && val.join("") === "")) { missing = true; } }); tabs.eq(i).toggleClass("wiktku-tab-missing", missing && i !== activeGroup); }); } // "Beşên din" reveals one field at a time via a picker rather than // stacking them all. Per-section state, snapshotted in // saveCurrentSection() and restored in restoreSection() below, and // auto-seeded from any field that already has content (so a returning // draft doesn't hide something already filled in). var openedOtherSections = {}; var BESENDIN_SET = {}; $.each(BESENDIN_STEP_IDS, function (_, sid) { BESENDIN_SET[sid] = true; }); // "besendin"'s index in STEP_GROUPS. Derived rather than hardcoded — // this was a literal 2 and silently pointed at the wrong tab the moment // Etîmolojî and Eleqedar were inserted ahead of it. var BESENDIN_GROUP_IDX = (function () { for (var i = 0; i < STEP_GROUPS.length; i++) { if (STEP_GROUPS[i].id === "besendin") return i; } return STEP_GROUPS.length - 1; }()); /** Re-renders the "Beşên din" picker to list only the not-yet-opened sections. */ function renderBesenDinPicker() { var wrap = $("#wiktku-besendin-picker"); if (!wrap.length) return; wrap.empty(); var pickerValues = getValues(); var unopened = $.grep(BESENDIN_STEP_IDS, function (sid) { if (openedOtherSections[sid]) return false; // Don't offer a section that would open onto nothing: several of // these are gated (Bi zaravayên din / Werger need lang=ku, most // need a pos). refresh() would hide it again straight away, so // picking it would read as a broken dropdown. var step = steps[sid]; if (step && typeof step.visible === "function") { try { if (!step.visible(pickerValues)) return false; } catch (e) { /* a step whose visible() needs DOM we lack yet — offer it */ } } return true; }); if (!unopened.length) return; // everything's open — nothing left to pick var sel = $("<select class='wiktku-besendin-select'></select>"); sel.attr("data-placeholder", "— beşek hilbijêre —"); sel.append($("<option value=''>— beşek hilbijêre —</option>")); $.each(unopened, function (_, sid) { var step = steps[sid]; if (!step) return; sel.append($("<option></option>").val(sid).text(capitalize(step.name))); }); sel.on("change", function () { var sid = $(this).val(); if (!sid) return; openedOtherSections[sid] = true; // Newly opened section moves right under the picker, ahead of // whatever's already open, instead of wherever it happened to // sit in the fixed step order. $("#wiktku-start-" + sid).insertAfter(wrap); renderBesenDinPicker(); refresh(); }); wrap.append(sel); initSelects(wrap); } /** Marks any BESENDIN_STEP_IDS field that already has real content as * "opened", so restoring a draft doesn't bury filled-in sections behind * the picker. Reuses each step's own output() as the emptiness check — * it already knows what "empty" means per field, and it reads the DOM * the restore just populated. Call this AFTER the DOM has the restored * values in it. */ function seedOpenedFromContent() { var values = getValues(); $.each(BESENDIN_STEP_IDS, function (_, sid) { if (openedOtherSections[sid]) return; var step = steps[sid]; if (!step || typeof step.output !== "function") return; try { if (step.output(values)) openedOtherSections[sid] = true; } catch (e) { /* a step whose output() needs more state than we have yet — skip it */ } }); } function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } // Rebuilds the dfn DOM from a previously snapshotted senses array. function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing tab bar + list so build() recreates them cleanly. stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); // The picker is collapsed behind a link by default; a restored // sense that already uses a template has to show it, or the // chosen template is invisible and looks lost. var reveal = block.data("revealTplRow"); if (typeof reveal === "function") reveal(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // dfnArea is the only thing actually saved, so split it back into // tercime/îzah for editing (mirrors syncNonKuToMane's join format). var maneParts = splitTercimeIzah(sense.mane); block.find(".wiktku-dfn-tercime").val(maneParts ? maneParts.tercime : (sense.mane || "")); block.find(".wiktku-dfn-izah").val(maneParts ? maneParts.izah : ""); // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Same for the mane-box mode (plain vs tercime+îzah), since this // also depends on tplSelect's (and lang's) value. var updateMane = block.data("updateManeMode"); if (updateMane) updateMane(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found var useModifiers = !!MODIFIER_SUBGROUPS[cls]; // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true, useModifiers); }); subList.append(useModifiers ? makeModifierLi(ta) : $("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text).each(function () { highlightLinebreak(this); }); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder entries — accepts current array shape or a legacy // single object (older saved sections) for backwards compat. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote).each(function () { highlightLinebreak(this); }); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederCatTpl) { // Legacy format from before the şablon search switched rows to // manual mode directly — convert it the same way now, so it's // editable like any other free-form source. var catSelEl = li.find(".wiktku-dfn-quote-src-sel"); catSelEl.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val("{{" + j.jederCatTpl + "}}"); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); // Restoring a draft opens the first sense's tab by default. steps.dfn.setOpenSense(stepDiv, list.find("li.wiktku-dfn-sense").first()); } // Snapshots simple (non-dfn) per-section steps from the DOM into obj. function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } if (id === "cavkani") { snap.cavkani = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); return; } if (id === "posparams") { snap.posparams = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); return; } if (id === "resim") { // One entry per row, including blank ones, so a mid-edit draft // (e.g. a filename typed but no caption yet) survives a cache // restore instead of being silently dropped. snap.resim = $("#wiktku-start-resim li.wiktku-resim-item").map(function () { return { file: $.trim($(this).find(".wiktku-resim-file").val()), caption: $.trim($(this).find(".wiktku-resim-caption").val()), alt: $.trim($(this).find(".wiktku-resim-alt").val()) }; }).get(); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); // Which "Beşên din" sub-sections this section has already opened // via the picker — per-section, like everything else here. snap.openedOtherSections = $.extend({}, openedOtherSections); sections[activeSection] = snap; } // Restores a previously saved snapshot into the form DOM. function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); $("#wiktku-start-cavkani .wiktku-cavkani-text").val(snap.cavkani || ""); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); steps.posparams.build(ppDiv); var savedTa = snap.posparams || ""; ppDiv.find(".wiktku-posparams-text").val(savedTa); // Re-parse saved textarea to restore helper widget states. if (savedTa) { var cMatch = savedTa.match(/\|c=([^|}\s]+)/); var jMatch = savedTa.match(/\|j=([^|}\s]+)/); var trMatch = savedTa.match(/\|tr=([^|}\s]+)/); // Write into the shared hidden field (not the visible // select, which has no <option>s yet) — syncHelpers() // below reads it back to restore the dropdown once the // gender/number options for this language are populated. if (cMatch) $("#wiktku-start-cinsiyet-field").val(cMatch[1]); if (jMatch) $("#wiktku-start-jimar-field").val(jMatch[1]); if (trMatch) ppDiv.find(".wiktku-posparams-field[data-pp-key='tr']").val(trMatch[1]); // For lêker, c= holds the verb-type code instead of a // gender — split it back across the two dropdowns it is // now assembled from ("x-gh" → form "x" + base "gh"). if (cMatch && /^lêker/.test(snap.pos || "")) { var lekturParts = /^(?:([xphb])-)?(n?gh)$/.exec(cMatch[1]); if (lekturParts) { ppDiv.find(".wiktku-posparams-lektur-sel").val(lekturParts[2]); ppDiv.find(".wiktku-posparams-lekturform-sel").val(lekturParts[1] || ""); } } // Restore checked optional params. "form" is stored as // "erê" rather than "1" (see rebuildTa), so it needs its // own check here. ppDiv.find(".wiktku-posparams-opt-panel input[type='checkbox']").each(function () { var key = $(this).val(); var expected = key === "form" ? "erê" : "1"; $(this).prop("checked", savedTa.indexOf("|" + key + "=" + expected) !== -1); }); } steps.posparams.syncHelpers(ppDiv); return; } if (id === "resim") { var resimDiv = $("#wiktku-start-resim"); resimDiv.find(".wiktku-resim-wrap").remove(); steps.resim.build(resimDiv); // Accept both the new array-of-rows format and the older // single {file, caption} object saved before multi-image // support existed. var resimSnap = snap.resim; var rows = $.isArray(resimSnap) ? resimSnap : (resimSnap ? [resimSnap] : []); if (rows.length) { var list = resimDiv.find("ol.wiktku-resim-list"); list.empty(); $.each(rows, function (_, r) { var item = steps.resim.buildItem(resimDiv); item.find(".wiktku-resim-file").val(r.file || ""); item.find(".wiktku-resim-caption").val(r.caption || ""); item.find(".wiktku-resim-alt").val(r.alt || ""); list.append(item); }); // Always keep a blank trailing row, same as Nimûne/Dûnde. var lastItem = list.children("li.wiktku-resim-item").last(); if ($.trim(lastItem.find(".wiktku-resim-file").val())) { list.append(steps.resim.buildItem(resimDiv)); } } return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Tell the pickers about the programmatic value change. fields.filter("select").trigger("wiktku:refresh"); }); // Restore which "Beşên din" sub-sections were already opened for // this section, then seed in anything the DOM restore above just // filled in but that wasn't marked opened yet. openedOtherSections = $.extend({}, snap.openedOtherSections || {}); seedOpenedFromContent(); renderBesenDinPicker(); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); // Bilêvkirin is NOT emitted here — it is one shared field for the // whole word, so emitting it per section duplicated it. getWikitext() // prints it once, above the POS sections. steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.tewandin.output(values); entry += steps.bikaranin.output(values); entry += steps.alfabeyendin.output(values); entry += steps.formalt.output(values); entry += steps.hevmane.output(values); entry += steps.dijmane.output(values); entry += steps.jornav.output(values); entry += steps.jernav.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); entry += steps.cavkani.output(values); entry += steps.xwendin.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { // Each hop through here can be reached asynchronously: the dfn // step waits on mw.loader.using("ext.gadget.linkify") before // calling back, so from that point on the submit handler's own // try/catch is no longer on the stack. Guard every hop instead, // or a throw after linkify loads vanishes into an unhandled // rejection and the form just sits there looking busy. try { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } catch (e) { if (typeof onSubmitError === "function") onSubmitError(e); else throw e; } } processSection(0); } // Assembles wikitext for all sections plus the shared lang header. function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var bnrh = steps.bnrh.output(sharedValues); var entry = steps.lang.output(sharedValues); // One pronunciation per word, printed once between the language // header and the POS sections — see steps.pron.output. entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // bnr-h goes before the language section — only prepended when // generating fresh wikitext (not addLangMode, which handles it separately). if (!addLangMode && bnrh) entry = bnrh + entry; // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { if (s.mane) return s.mane; // Template sense (e.g. {{guharto|ku|somepage}}) — same // construction as the tplCall built in getOutput, so the // summary shows what actually gets written to the entry // instead of going blank. if (s.tpl && s.tplTitle) { return s.tplNoLang ? "{{" + s.tpl + "|" + s.tplTitle + "}}" : "{{" + s.tpl + "|" + sharedValues.lang + "|" + s.tplTitle + "}}"; } return ""; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; // Set by build() to its submitFailed(). Lives out here because the // wikitext-assembly functions below are outside build()'s closure but // still need a way to report a failure to the person rather than dying // silently in the console. var onSubmitError = null; // Whether Mane/Bi zaravayên din/Werger has anything in it — kept // outside refresh() so the click handler can read the latest value. var wiktkuContentGateOk = true; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues, placeholderText) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>").text(placeholderText || "")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice.label); if (choice.sortKey !== undefined) { // This is a language choice {code, label, sortKey} — show code. displayText = capitalize(choice.label) + " (" + choice.code + ")"; } var option = $(mw.html.element("option", { value: choice.code }, displayText)); if (disabledValues[choice.code]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } // Keys to disable for a key menu: already-taken or explicitly disabled. function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); populateMenus(input, step.keys, getDisabledKeys(step)); // Keep the key menus mutually exclusive: whatever one row selects is // disabled in every other row. Recomputed from the DOM on each change. input.on("change", function () { var all = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield"); var taken = {}; all.each(function () { var v = $(this).val(); if (v) taken[v] = true; }); all.not(this).each(function () { var self = $(this), own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (code) $(this).prop("disabled", !!taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }); // Return the wrapper; the select lives inside it and still fires change. return wrapNativeSelect(input); } // Adds another text field to the list if the last one now has text. function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); if (step.placeholder) { nextInput.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = step.modifiers ? makeModifierLi(nextInput).prepend(nextKeyInput || "") : $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) initSelects(nextItem); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } // Shows/hides steps based on whether their prerequisites are met, and // updates placeholders where applicable. function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); steps.cavkani.refreshTplSelect(); // Re-render any step's question label that depends on current values // (e.g. dfn's Werger-section reminder, which only applies to ku). $.each(steps, function (stepId, step) { if (typeof step.question_fmt === "function") { $("#wiktku-start-" + stepId + " .wiktku-start-step-question") .text(step.question_fmt(values)); } }); // Sync every sense block's mane-box mode (plain mane vs tercime+îzah) // to the current language, in case lang changes after blocks exist. $("#wiktku-start-dfn li.wiktku-dfn-sense").each(function () { var updateMane = $(this).data("updateManeMode"); if (updateMane) updateMane(); }); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Re-sync the "<label> bi <ziman>…" placeholder on every always-visible // sub-field list (etîket, kategorî, hevmane, …), since the language may // not have been chosen yet when these lists were first built, or may // have changed since. $("#wiktku-start-dfn .wiktku-dfn-sublist").each(function () { var upd = $(this).data("updatePlaceholders"); if (typeof upd === "function") upd(); }); // Same idea for word-list steps (jê, têkildar, binêre herwiha, …) // whose placeholder is a function of the current language. $.each(steps, function (stepId, step) { if (typeof step.placeholder === "function") { $("#wiktku-start-" + stepId + " textarea.wiktku-start-step-field") .attr("placeholder", step.placeholder()); } }); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // Insert after the quote textarea's resize-wrap (if the manual // resize handle has already been attached to it), not after the // bare textarea -- otherwise this lands *inside* that wrap, // between the textarea and its own grip, breaking jêgirtin's // handle and nesting the tr/t boxes inside it. var quoteTa = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap = quoteTa.closest(".wiktku-resize-wrap"); (quoteResizeWrap.length ? quoteResizeWrap : quoteTa).after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // See the tr-field branch above for why this targets the // resize-wrap instead of the bare textarea. var quoteTa2 = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap2 = quoteTa2.closest(".wiktku-resize-wrap"); (quoteResizeWrap2.length ? quoteResizeWrap2 : quoteTa2).after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { var groupIdx = stepIdToGroup[stepId]; var hiddenByTab = (groupIdx !== undefined && groupIdx !== activeGroup) || // Beşên din picker: stays hidden even while its tab is // active until explicitly opened from the dropdown. (BESENDIN_SET[stepId] && !openedOtherSections[stepId]); // Bilêvkirin is its own section now, so the two views are // mutually exclusive: on it, only pron shows (plus Ziman, which // is shared and stays above every section); off it, pron is // hidden no matter which tab is active. pron is deliberately // ungrouped — stepIdToGroup has no entry for it — so without // this branch it would show on all four tabs at once. if (stepId === "pron") { hiddenByTab = hiddenByTab || !viewingPron; } else if (viewingPron && stepId !== "lang") { hiddenByTab = true; } if (hiddenByTab || (typeof(step.visible) === "function" && !step.visible(values))) { $("#wiktku-start-" + stepId).hide(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } // After build, sync the posparams helper widgets whenever pos or lang changes. if (step.id === "posparams" && typeof step.syncHelpers === "function") { step.syncHelpers(stepDiv); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } stepDiv.slideDown(); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); // The four content tabs belong to a POS section — Bilêvkirin has no // sub-tabs of its own, so the bar goes away while it's on screen. $("#wiktku-group-tabs").toggle(!!values.pos && !viewingPron); var besenDinActive = activeGroup === BESENDIN_GROUP_IDX && !viewingPron; $("#wiktku-besendin-picker").toggle(besenDinActive); // The option list is filtered by each step's visible(), which depends // on lang/pos — so it has to be rebuilt when those change, not just // when a section is opened. Safe to call from here: rendering the // picker doesn't itself call refresh(), only picking an option does. if (besenDinActive) renderBesenDinPicker(); updateGroupTabIndicators(values); continueBtn.setDisabled(!canContinue); // Soft gate: stays a real, clickable OOUI button — a hard // setDisabled(true) here would swallow the click entirely, leaving // no way to tell the person why nothing happened. The CSS-only // "looks disabled" class lets the click handler still run and show // wiktkuNotify's explanation. wiktkuContentGateOk = !canContinue || hasMinRequiredContent(values); continueBtn.$element.toggleClass("wiktku-btn-soft-disabled", !wiktkuContentGateOk); } function destroy() { if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); if (autosaveInterval) clearInterval(autosaveInterval); formDirty = false; $(window).off("beforeunload.wiktkuUnsaved"); $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard").slideDown(); // #editform was kept laid-out but off-screen (see build()) instead of // display:none, precisely so the editor never had to size itself // against a zero-width/height box. Just bring it back on-screen — // no slideDown needed since it was never actually collapsed. $("#editform").removeClass("wiktku-offscreen"); // Belt-and-braces: if WikiEditor/CodeMirror/mobile's auto-grow still // cached a stale size from some earlier point, nudge them to // recalculate now that the box is genuinely visible. $(window).trigger("resize"); if (window.CodeMirror) { var cm = $("#wpTextbox1").data("CodeMirror") || $("#wpTextbox1").data("cmInstance"); if (cm && typeof cm.refresh === "function") cm.refresh(); } $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and navz. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; // Inserts a new "== {{ziman|code}} ==" section at the correct sorted // position: navz, then ku/hac/sdh/lki/ckb/zza, then alphabetical by name. function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections — just write the new section. // Add \n\n only when there is real non-whitespace content above. var trimmed = existing.replace(/\s+$/, ""); return trimmed ? trimmed + "\n\n" + wikitext : wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // (?![\s\S]) matches only true end-of-string, since a bare "$" with // /m would stop at the section's first line break instead. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections, each separated by exactly \n\n. // Trim trailing whitespace off each section's content first so we // control the spacing precisely. var joined = sections.map(function (s) { return s.content.replace(/\s+$/, ""); }).join("\n\n"); // Only add a separator after the preamble when it has real content. var preambleTrimmed = preamble.replace(/\s+$/, ""); var prefix = preambleTrimmed ? preambleTrimmed + "\n\n" : ""; return prefix + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê zimanekî nû li rûpelê îlawe bikî. Eger ev ziman jixwe hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bike, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Muhtewaya rûpelê paqij bike (her tiştî jê bibe û rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); // Tab bar for switching between step-groups (topics) within a section. // renderGroupTabs()/updateGroupTabIndicators() (which populate and // maintain it) live outside build() — see near "var activeSection". var groupTabsDiv = $("<div id='wiktku-group-tabs'></div>"); // Both tab bars are sticky (CSS). group-tabs' sticky "top" has to sit // right below section-tabs' actual rendered height, which isn't a // fixed number since the bar can wrap onto a second line. Measured // here and published as a CSS custom property the stylesheet reads // back; recomputed on content changes and window resize. // // Vector 2022 has its own sticky header (.vector-sticky-header) that // pins to the real top:0 once you scroll past the page title, which // would otherwise sit directly behind (and hide) our section-tabs. // Fixed by measuring how much of the viewport Vector's header // currently occupies and offsetting both our bars below it, via // --wiktku-siteheader-h. Vector's header slides in/out with scroll // position, so this is re-measured on scroll too, not just resize. function siteHeaderOffset() { var el = document.querySelector(".vector-sticky-header"); if (!el) return 0; var rect = el.getBoundingClientRect(); // Present in the DOM at all times on Vector 2022, but only // actually occupying screen space once scrolled into place — // before that it sits translated above the viewport (negative/ // zero rect), which must not add a phantom gap under our bars. if (rect.bottom <= 0 || rect.top > 4) return 0; return Math.max(0, rect.bottom); } var stickyOffsetQueued = false; function syncStickyTabsOffset() { var h = sectionTabsDiv.is(":visible") ? (sectionTabsDiv.outerHeight() || 0) : 0; startForm.css("--wiktku-stabs-h", h + "px"); startForm.css("--wiktku-siteheader-h", siteHeaderOffset() + "px"); } function queueStickyTabsOffsetSync() { if (stickyOffsetQueued) return; stickyOffsetQueued = true; window.requestAnimationFrame(function () { stickyOffsetQueued = false; syncStickyTabsOffset(); }); } $(window).on("resize.wiktkuStickyTabs scroll.wiktkuStickyTabs", queueStickyTabsOffsetSync); // "Beşên din" picker — sits right under the group tab bar, only // shown while that tab is active (toggled in refresh(), see // BESENDIN_GROUP_IDX); renderBesenDinPicker() fills it. var besenDinPickerDiv = $("<div id='wiktku-besendin-picker' class='wiktku-besendin-picker'></div>"); /** Puts the form back in a usable state after a failed submit and * says what happened. Without this the button stays disabled and * the spinner spins forever on any exception — the person is left * staring at a form that looks busy but is dead, with the reason * visible only in the browser console. */ function submitFailed(err) { spinner.hide(); continueBtn.setDisabled(false); continueBtn.$element.removeClass("wiktku-btn-sending"); var detail = (err && (err.message || err.toString())) || "sedem nediyar"; mw.notify( "Şandin bi ser neket: " + detail + " — tiştê ku te nivîsî winda nebûye. Heke ev dubare bibe, " + "bi 'Edîtora çavkaniyê veke' berdewam bike.", { type: "error", tag: "wiktku-submit", autoHide: false } ); // Deliberately console.error as well: the notification is for the // person, this is for whoever they report the bug to. if (window.console && console.error) console.error("[wiktku] submit failed", err); } onSubmitError = submitFailed; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); continueBtn.$element.addClass("wiktku-btn-sending"); spinner.show(); try { getWikitext(function (wikitext) { try { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page — write fresh content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // ── bnr-h merge ────────────────────────────────────────── // If the user filled bnr-h inputs, either merge into the // existing {{bnr-h|…}} call or prepend a new one. var bnrhOut = steps.bnrh.output(getValues()); if (bnrhOut) { var newPages = bnrhOut.replace(/^\{\{bnr-h\|/, "").replace(/\}\}\n?$/, "").split("|"); var bnrhRe = /\{\{bnr-h\|([^}]*)\}\}/i; if (bnrhRe.test(existing)) { existing = existing.replace(bnrhRe, function (_, inner) { var existingPages = inner.split("|").map(function (p) { return p.trim(); }); $.each(newPages, function (_, p) { p = p.trim(); if (p && existingPages.indexOf(p) === -1) existingPages.push(p); }); return "{{bnr-h|" + existingPages.join("|") + "}}"; }); } else { existing = bnrhOut + existing; } } // If this language's section already exists (whitespace // differences aside), merge into it; otherwise insert new. var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); } catch (e) { // Thrown while writing the result into #wpTextbox1. submitFailed(e); } }); } catch (e) { // Catches anything thrown synchronously inside getWikitext. submitFailed(e); } }); // Tracks whether groupTabsDiv has been inserted yet. var groupTabsInserted = false; $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); var nameH3 = $("<h3></h3>").addClass("wiktku-start-step-name"); var nameLabel = $("<label></label>") .attr("for", "wiktku-start-" + step.id + "-field") .text(name); nameH3.append(nameLabel); stepDiv.append(nameH3); if (step.question_fmt) { // question_fmt can be a plain string, or a function of the // current values (used by steps whose question text depends // on e.g. the chosen language) — refresh() keeps it in sync // afterwards via the .wiktku-start-step-question class. var questionText = typeof step.question_fmt === "function" ? step.question_fmt(getValues()) : step.question_fmt; stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, questionText))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); // initSelects() runs over the whole form once it is in the DOM. stepDiv.append(input); } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.placeholder) { input.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append(step.modifiers ? makeModifierLi(input) : $("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Section tabs (switch between POS sections) sit above the // per-section fields, starting at "pos". if (step.id === "pos") { startForm.append(sectionTabsDiv); } // Step-group tabs sit just before the first grouped step in // ordered_steps. Derived from stepIdToGroup so this keeps // working no matter how STEP_GROUPS/ordered_steps get reordered. if (!groupTabsInserted && stepIdToGroup[step.id] !== undefined) { startForm.append(groupTabsDiv); startForm.append(besenDinPickerDiv); groupTabsInserted = true; } startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); /** Adds a new, empty POS section and switches to it. */ function addPosSection() { saveCurrentSection(); viewingPron = false; sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); return; } if (id === "resim") { $("#wiktku-start-resim .wiktku-resim-wrap").remove(); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); stepDiv.find("select.wiktku-start-step-field").trigger("wiktku:refresh"); }); // Fresh section — no "Beşên din" sub-section has been opened yet. openedOtherSections = {}; renderBesenDinPicker(); renderSectionTabs(); refresh(); } addSectionBtn.on("click", addPosSection); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); syncStickyTabsOffset(); return; } sectionTabsDiv.show(); // Bilêvkirin leads the bar, ahead of the POS sections. var pronTab = $("<span></span>") .addClass("wiktku-section-tab wiktku-section-tab-pron") .text("Bilêvkirin") .toggleClass("wiktku-tab-active", viewingPron); pronTab.on("click", function () { if (viewingPron) return; saveCurrentSection(); viewingPron = true; refresh(); renderSectionTabs(); }); sectionTabsDiv.append(pronTab); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection && !viewingPron); (function (idx) { tab.on("click", function () { if (idx === activeSection && !viewingPron) return; // Leaving Bilêvkirin doesn't need a save — its field // is shared and never part of a section snapshot. if (!viewingPron) saveCurrentSection(); viewingPron = false; activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); syncStickyTabsOffset(); } renderSectionTabs(); /** * Re-populates a dynamically-growing "multiple" field list (bnrh, je, * tekildar, …) from a saved array of strings. Sets each value via * .val() + a triggered "input" event rather than touching the DOM * structure directly, so the normal refreshForTextField() growth * logic adds exactly as many rows as needed — the same thing that * happens when a person types into the last (empty) row. */ function restoreMultiField(id, values) { var container = $("#wiktku-start-" + id); $.each(values || [], function (i, v) { var field = container.find(".wiktku-start-step-field").eq(i); if (!field.length || !v) return; field.val(v).trigger("input"); }); } /** * Restores a full cached draft: shared lang/pron/bnrh fields, then * every section (via the same restoreSection()/refresh()/ * renderSectionTabs() sequence already used when switching tabs). * @param cached {{lang: string, pron: string, bnrh: Array, sections: Array, activeSection: number}} */ function restoreFromCache(cached) { if (cached.lang) { $("#wiktku-start-lang-field").val(cached.lang); $("#wiktku-start-lang-field").trigger("wiktku:refresh"); } // Rebuild dependent steps (pos, pron wrap, etc.) now that lang is set. refresh(); if (cached.pron !== undefined) { $("#wiktku-start-pron .wiktku-pron-text").val(cached.pron); } if (cached.bnrh) { restoreMultiField("bnrh", cached.bnrh); } sections = (cached.sections && cached.sections.length) ? cached.sections : [{}]; activeSection = (typeof cached.activeSection === "number" && cached.activeSection >= 0 && cached.activeSection < sections.length) ? cached.activeSection : 0; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); updateLastSavedIndicator(cached.savedAt || null); formDirty = false; wiktkuNotify("Danûstandina berê ya qeydkirî ji cache hate barkirin.", { type: "info", tag: "wiktku-cache-restore" }); } // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); // A new cureyê rêzimanî means any previously chosen cinsiyet/ // cureyê lêkerê no longer applies — clear both selections (and // the shared hidden cinsiyet field, since rebuildTa()/syncHelpers() // fall back to it) before wiping the textarea, so nothing stale // gets carried over into the rebuilt template. var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-cinsiyet-sel").val(""); ppDiv.find(".wiktku-posparams-jimar-sel").val(""); ppDiv.find(".wiktku-posparams-lektur-sel").prop("selectedIndex", 0); ppDiv.find(".wiktku-posparams-lekturform-sel").prop("selectedIndex", 0); $("#wiktku-start-cinsiyet-field").val(""); $("#wiktku-start-jimar-field").val(""); ppDiv.find(".wiktku-posparams-text").val(""); // refresh() runs steps.posparams.syncHelpers(), which toggles the // param rows for the new pos and — since the textarea is now // empty — calls rebuildTa() to repopulate it. refresh(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { // Immediate feedback that the click registered continueBtn.$element.addClass("wiktku-btn-flash"); setTimeout(function () { continueBtn.$element.removeClass("wiktku-btn-flash"); }, 500); // Ziman/Cureyê rêzimanî already block submission via the real // OOUI setDisabled (see canContinue in refresh()) — this is a // second, softer check that still lets the click through so we // can explain why, instead of the button just silently doing nothing. if (!wiktkuContentGateOk) { wiktkuNotify( "Berî şandinê, tiştekî binivîse: Mane, Bi zaravayên din, an jî Werger — kêmasî yek ji van sê beşan divê tijî be.", { type: "warn", tag: "wiktku-mincontent" } ); return; } wiktkuNotify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", flags: [ "destructive" ], }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Cache save/clear buttons ───────────────────────────────────────── // Manual, page-scoped save of the entire wizard (all sections, not // just the active one) via [[MediaWiki:Gadget-StorageUtils.js]]'s // ObjectStorage. Restoring happens silently on load at the end of // build(), once the full language list is available. // // Saving also happens automatically (debounced while typing, plus a // periodic fallback) — see "Autosave" below — since relying on the // person to remember to click "Li cache qeyd bike" before an // accidental tab close/reload defeats the point of having a cache // at all. function buildCacheSnapshot() { return { lang: getValues().lang || "", pron: $("#wiktku-start-pron .wiktku-pron-text").val() || "", // bnrh is shared (page-level), same as lang/pron above — not // per-section, so it doesn't live in sections[]. bnrh: getValuesForStep("bnrh"), sections: sections, activeSection: activeSection, savedAt: Date.now() }; } // ── Last-saved indicator ───────────────────────────────────────────── var lastSavedEl = $("<span id='wiktku-last-saved'></span>"); function formatSavedTime(ts) { try { return new Date(ts).toLocaleTimeString(mw.config.get("wgUserLanguage"), { hour: "2-digit", minute: "2-digit" }); } catch (e) { return new Date(ts).toLocaleTimeString(); } } function updateLastSavedIndicator(ts) { lastSavedEl.text(ts ? ("Cache: qeydkirî di saet " + formatSavedTime(ts) + " de") : ""); } // ── Dirty-state tracking + autosave ────────────────────────────────── // formDirty mirrors "does the live form differ from what's in cache". // Anything the person types/selects sets it; a successful save (auto // or manual) clears it; destroy() (final submit, or switching to the // source editor) also clears it since the wizard's job is over at // that point either way. formDirty/autosaveDebounceTimer/autosaveInterval // are declared in the outer scope (near activeGroup) — assigned here, // not re-declared — so destroy() can reach them too. var AUTOSAVE_DEBOUNCE_MS = 8000; // save shortly after typing pauses var AUTOSAVE_INTERVAL_MS = 60000; // …and at least this often regardless function performAutosave() { if (!formDirty) return; saveCurrentSection(); try { formCache.Set(buildCacheSnapshot()); formDirty = false; updateLastSavedIndicator(Date.now()); } catch (e) { // Silent on autosave failure (storage blocked/full, etc.) — the // manual button still surfaces a proper error if the person // tries it directly, no need to interrupt typing with a toast. } } function scheduleAutosave() { formDirty = true; if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = setTimeout(performAutosave, AUTOSAVE_DEBOUNCE_MS); } startForm.on("input change", "input, textarea, select", scheduleAutosave); autosaveInterval = setInterval(performAutosave, AUTOSAVE_INTERVAL_MS); // Warn on accidental tab close/reload while there's anything unsaved. $(window).on("beforeunload.wiktkuUnsaved", function (e) { if (!formDirty) return undefined; e.preventDefault(); e.returnValue = ""; return ""; }); var saveCacheBtn = new OO.ui.ButtonWidget({ label: "Li cache qeyd bike", title: "Halê vê formê yê niha (ziman, bilêvkirin û hemû beş) li cache (localStorage) qeyd bike, da ku eger rûpel bêyî xwestin were girtin an ji nû ve were barkirin, tu karibî berdewam bikî." }); saveCacheBtn.on("click", function () { saveCurrentSection(); // ObjectStorage.Set() doesn't return a success/failure value, so // the only way to detect a real failure (storage blocked, quota // exceeded, JSON.stringify choking on something unexpected) is to // catch it here rather than inspect a (nonexistent) return value. try { var snapshot = buildCacheSnapshot(); formCache.Set(snapshot); formDirty = false; updateLastSavedIndicator(snapshot.savedAt); wiktkuNotify("Halê formê li cache hate qeydkirin.", { type: "success", tag: "wiktku-cache-save" }); } catch (e) { mw.notify("Qeydkirina li cache bi ser neket.", { type: "error", tag: "wiktku-cache-save" }); } }); var clearCacheBtn = new OO.ui.ButtonWidget({ label: "Cache paqij bike", flags: [ "destructive" ], title: "Datayên qeydkirî yên vê rûpelê ji cache jê bibe (forma ku niha xuya dike naguherîne)." }); clearCacheBtn.on("click", function () { formCache.Set({}); // The live form still has whatever the person typed — it's just no // longer backed up anywhere, so treat this like a fresh unsaved edit. formDirty = true; updateLastSavedIndicator(null); wiktkuNotify("Cache hate paqijkirin.", { type: "success", tag: "wiktku-cache-clear" }); }); // ── "⋯" overflow ───────────────────────────────────────────── // One primary action and one secondary stay on the bar; everything // else moves in here, to avoid four same-weight buttons crowding // (and wrapping to three rows on a phone). var moreBtn = $("<button type='button' class='wiktku-more-btn' title='Vebijarkên din'>⋯</button>"); var moreMenu = $("<div class='wiktku-more-menu'></div>").hide(); /** Moves an existing OOUI button into the overflow menu, keeping its * handlers — the widgets already carry the behaviour, so this is * purely about where they are shown. */ function intoMenu(btn, extraClass) { var row = $("<div class='wiktku-more-item'></div>"); if (extraClass) row.addClass(extraClass); btn.$element.on("click", function () { moreMenu.hide(); }); row.append(btn.$element); moreMenu.append(row); } intoMenu(saveCacheBtn); intoMenu(clearCacheBtn, "wiktku-more-item-danger"); moreMenu.append($("<div class='wiktku-more-sep'></div>")); moreMenu.append($("<div class='wiktku-more-item wiktku-more-note'></div>").append(lastSavedEl)); moreBtn.on("click", function (e) { e.preventDefault(); e.stopPropagation(); var open = moreMenu.is(":visible"); moreMenu.toggle(!open); if (!open) { setTimeout(function () { $(document).one("click.wiktkuMore", function () { moreMenu.hide(); }); }, 0); } }); var moreWrap = $("<span class='wiktku-more-wrap'></span>").append(moreBtn).append(moreMenu); footer.append(moreWrap); // Icon-only settings button — opens the Tercîh dialog. Plain OOUI // icon names depend on which icon-pack module happens to be loaded, // so this uses the actual Codex "settings" (color-subtle) SVG from // Commons directly, the same way the spinner above hotlinks its gif. var prefsBtn = $("<button></button>", { type: "button", "class": "wiktku-prefs-btn", title: "Tercîh — sazkariyên vê amûrê biguherîne" }); prefsBtn.on("click", function (e) { e.preventDefault(); wiktkuOpenPrefsDialog(); }); // The gear is icon-only on the bar; inside a text menu it needs a // label like everything else around it. prefsBtn.on("click", function () { moreMenu.hide(); }); moreMenu.prepend($("<div class='wiktku-more-sep'></div>")); moreMenu.prepend($("<div class='wiktku-more-item wiktku-more-item-prefs'></div>") .append(prefsBtn) .append($("<span class='wiktku-more-item-label'></span>").text("Tercîh"))); startForm.append(footer); // NOTE: deliberately NOT .hide() (display:none). WikiEditor/CodeMirror/ // the mobile editor's auto-grow logic measure #wpTextbox1's real // dimensions during their own init, which happens while the wizard is // up. A display:none ancestor reports 0 for offsetWidth/offsetHeight/ // scrollHeight, so those scripts bake in a near-zero height that never // gets recalculated later — slideDown() in destroy() only animates the // outer box, it doesn't re-trigger their sizing. Pushing #editform // off-screen instead keeps it laid out (real width/height available to // measure) without being visible, so the editbox opens at full size. $("#editform").addClass("wiktku-offscreen").before(startForm); // renderGroupTabs() looks up #wiktku-group-tabs via a live DOM // selector, so it must run after startForm is actually in the document. renderGroupTabs(); renderBesenDinPicker(); // One pass over the whole form: every select that hasn't already been // initialised, and isn't opted out with .wiktku-plain-select, gets // the searchable picker. initSelects(startForm); refresh(); // Give every draggable textarea a custom resize grip (works // consistently on Safari/iOS, unlike the native corner grip — see // the "Manual drag-to-resize handle" comment in styles.css), and // keep applying it to textareas added later on (new sense blocks, // quote-source fields, nimûne rows, …). wiktkuInitManualResize(startForm); new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { $(mutation.addedNodes).each(function () { if (this.nodeType !== 1) return; wiktkuInitManualResize(this); }); }); }).observe(startForm[0], { childList: true, subtree: true }); // Now that the full language list is loaded, silently restore any // draft the editor previously saved for this page. var cachedDraft = formCache.Get(); if (cachedDraft && cachedDraft.sections && cachedDraft.sections.length) { restoreFromCache(cachedDraft); } } mw.loader.using(["oojs-ui-core"], function () { function wiktkuProceedWithData(wiktkuData) { var d = wiktkuData || {}; // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Jimar (number) code definitions — same shape as the wiki's // own Lua number-type table (code -> {cat, display[, req]}). if (d.numberLabels) $.extend(NUMBER_LABELS, d.numberLabels); // Populate lang choices (pinned list). if (d.langChoices) steps.lang.choices = choicesFromObject(d.langChoices, true); // Populate langsByCode and merge full language list from d.ziman. // d.ziman is a {code: name} object with all known languages. $.each(steps.lang.choices, function (i, choice) { if (choice.sortKey === undefined) choice.sortKey = choice.label; langsByCode[choice.code] = choice; }); if (d.ziman) { var pinnedCodes = {}; $.each(steps.lang.choices, function (i, c) { pinnedCodes[c.code] = true; }); var extraChoices = []; $.each(d.ziman, function (code, name) { if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; if (pinnedCodes[code]) return; var choice = { code: code, label: name, sortKey: name }; extraChoices.push(choice); langsByCode[code] = choice; }); extraChoices.sort(function (a, b) { return a.sortKey.localeCompare(b.sortKey, userLang); }); steps.lang.choices = steps.lang.choices.concat(extraChoices); } // Keep the full merged list around for trans/dunde/zarava — those // should still be able to reference any language even when the // Tercîh panel restricts the main "ziman" step below — then, if // the user set a restriction there, narrow steps.lang.choices // itself to just those codes. var wiktkuFullLangChoices = steps.lang.choices; if (wiktkuPrefs.langCodes && wiktkuPrefs.langCodes.length) { var wiktkuAllowedLangSet = {}; $.each(wiktkuPrefs.langCodes, function (i, code) { wiktkuAllowedLangSet[code] = true; }); var wiktkuRestrictedChoices = $.grep(wiktkuFullLangChoices, function (c) { return !!wiktkuAllowedLangSet[c.code]; }); // Fall back to the full list instead of showing an empty // dropdown if none of the saved codes matched anything // (typo'd code, data.json changed since, …). steps.lang.choices = wiktkuRestrictedChoices.length ? wiktkuRestrictedChoices : wiktkuFullLangChoices; } // Populate POS choices — also a plain {code: label} object in data.json. if (d.posChoices) steps.pos.choices = choicesFromObject(d.posChoices, false); // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the full language list // (not the possibly Tercîh-restricted steps.lang.choices). steps.trans.keys = wiktkuFullLangChoices; steps.dunde.keys = wiktkuFullLangChoices; steps.zarava.keys = getZaravaKeys(wiktkuFullLangChoices); build(); } // data.json ships inside this package module, so it is already parsed // and in memory — no action=raw round trip, and no Testing switch to // forget to flip back before deploying. wiktkuProceedWithData(require("./start/data.json")); }); }); //</nowiki> 0p3ofesboinnvrmmuk9m8rr5xb7r3d3 6333854 6333853 2026-08-15T17:33:07Z Wikihez 7344 6333854 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. // implicit dependencies: StorageUtils (ObjectStorage) //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var addLangMode = mw.util.getParamValue("wiktkuaddlang") === "1"; // ── Tercîh (user settings) panel stored via mw.storage (localStorage), globally var WIKTKU_PREFS_KEY = "wiktku_start_prefs"; var WIKTKU_PREFS_DEFAULTS = { // [] = show the full language list in the "ziman" step; otherwise // only these codes are shown there (data.json codes, not names). langCodes: [], // true = never auto-open on a new/empty page — only via the // "+Ziman/beşeke din" portlet link. onlyOnClick: false, // "auto" | "p-cactions" | "p-tb" | "p-views" — where the // "+Ziman/beşeke din" portlet link is added. portlet: "auto", // true = suppress routine/informational mw.notify toasts (page // loading, cache auto-restored, cache saved/cleared, "tê şandin…"). // Errors and direct results of an explicit action (like saving // Tercîh itself) always show regardless of this setting. quiet: false }; function wiktkuLoadPrefs() { if (!(window.mw && mw.storage)) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var raw; try { raw = mw.storage.get(WIKTKU_PREFS_KEY); } catch (e) { raw = null; } if (!raw) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var parsed; try { parsed = JSON.parse(raw); } catch (e) { parsed = {}; } return $.extend({}, WIKTKU_PREFS_DEFAULTS, parsed); } function wiktkuSavePrefs(prefs) { if (!(window.mw && mw.storage)) return false; try { mw.storage.set(WIKTKU_PREFS_KEY, JSON.stringify(prefs)); return true; } catch (e) { return false; } } var wiktkuPrefs = wiktkuLoadPrefs(); // Routine/informational notices go through here so "quiet mode" can // suppress them; errors and explicit-action confirmations (like the // Tercîh save toast) call mw.notify directly instead, and always show. function wiktkuNotify(message, options) { if (wiktkuPrefs.quiet) return; mw.notify(message, options); } // Lazily built the first time it's opened; reused after that (see // wiktkuOpenPrefsDialog below, defined once we know OOUI is available). var wiktkuPrefsWindowManager = null; var wiktkuPrefsDialog = null; function wiktkuOpenPrefsDialog() { mw.loader.using(["oojs-ui-core", "oojs-ui-windows"], function () { function WiktkuPrefsDialog(config) { WiktkuPrefsDialog.super.call(this, config); } if (!wiktkuPrefsDialog) { OO.inheritClass(WiktkuPrefsDialog, OO.ui.ProcessDialog); WiktkuPrefsDialog.static.name = "wiktkuPrefsDialog"; WiktkuPrefsDialog.static.title = "Tercîhên min"; WiktkuPrefsDialog.static.actions = [ { action: "save", label: "Qeyd bike", flags: ["primary", "progressive"] }, { action: "cancel", label: "Betal bike", flags: "safe" } ]; WiktkuPrefsDialog.prototype.initialize = function () { WiktkuPrefsDialog.super.prototype.initialize.call(this); this.langCodesInput = new OO.ui.TextInputWidget({ placeholder: "ku, zza, ckb (vala bihêle ji bo hemû zimanan)" }); this.onlyOnClickCheckbox = new OO.ui.CheckboxInputWidget({}); this.quietCheckbox = new OO.ui.CheckboxInputWidget({}); this.portletDropdown = new OO.ui.DropdownInputWidget({ options: [ { data: "auto", label: "Otomatîk (li gorî rûyê wîkiyê)" }, { data: "p-cactions", label: "p-cactions - Li qismê Amûran" }, { data: "left-navigation", label: "left-navigation - Li qismê Gotar-Gotûbêj" }, { data: "p-tb", label: "p-tb - Li qismê Giştî" }, { data: "p-views", label: "p-views - Li qismê Bixwîne" } ] }); var fieldset = new OO.ui.FieldsetLayout({ label: "Eyar" }); fieldset.addItems([ new OO.ui.FieldLayout(this.langCodesInput, { label: "Kodên zimanan ku tê xuyakirin li qismê \"ziman\"", align: "top", help: "Kodan bi virgulê (,) ji hev veqetîne. Vala bihêle da ku hemû ziman were nîşandan.", helpInline: true }), new OO.ui.FieldLayout(this.onlyOnClickCheckbox, { label: "Tenê veke wextê \"+Ziman/beşeke din\" were tikandin", align: "inline", help: "Eger were hilbijartin, ev amûr êdî otomatîk li ser rûpelên nû/vala dest pê nake — divê meriv her carê pêl \"+Ziman/beşeke din\" bike.", helpInline: true }), new OO.ui.FieldLayout(this.portletDropdown, { label: "Cihê lînka \"+Ziman/beşeke din\"", align: "top", help: "\"Otomatîk\" li gorî rûyê wîkiyê hildibijêre.", helpInline: true }), new OO.ui.FieldLayout(this.quietCheckbox, { label: "Moda bêdeng (kêmtir agahdarî nîşan bide)", align: "inline", help: "Agahdariyên normal nîşan nede. Xeta her tim tên xuyakirin.", helpInline: true }) ]); this.$body.addClass("wiktku-prefs-dialog-body").append(fieldset.$element); }; WiktkuPrefsDialog.prototype.getSetupProcess = function (data) { return WiktkuPrefsDialog.super.prototype.getSetupProcess.call(this, data) .next(function () { this.langCodesInput.setValue(wiktkuPrefs.langCodes.join(", ")); this.onlyOnClickCheckbox.setSelected(!!wiktkuPrefs.onlyOnClick); this.portletDropdown.setValue(wiktkuPrefs.portlet || "auto"); this.quietCheckbox.setSelected(!!wiktkuPrefs.quiet); }, this); }; WiktkuPrefsDialog.prototype.getActionProcess = function (action) { var dialog = this; if (action === "save") { return new OO.ui.Process(function () { var codes = dialog.langCodesInput.getValue() .split(/[,\s]+/) .map(function (c) { return c.trim().toLowerCase(); }) .filter(function (c) { return !!c; }); wiktkuPrefs = { langCodes: codes, onlyOnClick: dialog.onlyOnClickCheckbox.isSelected(), portlet: dialog.portletDropdown.getValue() || "auto", quiet: dialog.quietCheckbox.isSelected() }; wiktkuSavePrefs(wiktkuPrefs); mw.notify( "Tercîh hatin qeydkirin. Rûpelê ji nû ve bar bike (F5).", { type: "success", tag: "wiktku-prefs-save" } ); dialog.close({ action: "save" }); }); } if (action === "cancel") { return new OO.ui.Process(function () { dialog.close({ action: "cancel" }); }); } return WiktkuPrefsDialog.super.prototype.getActionProcess.call(this, action); }; wiktkuPrefsWindowManager = new OO.ui.WindowManager(); $(document.body).append(wiktkuPrefsWindowManager.$element); wiktkuPrefsDialog = new WiktkuPrefsDialog(); wiktkuPrefsWindowManager.addWindows([wiktkuPrefsDialog]); } wiktkuPrefsWindowManager.openWindow(wiktkuPrefsDialog); }); } var targetContainer; var skin = mw.config.get('skin'); if (wiktkuPrefs.portlet && wiktkuPrefs.portlet !== "auto") { targetContainer = wiktkuPrefs.portlet; } else if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Li vê rûpelê, ziman an jî beşeke nû zêde bike"); // If "onlyOnClick" is set, the wizard should ONLY ever open via the // "+Ziman/beşeke din" link — never automatically var wiktkuNewPageDetected = $(".mw-newarticletext, .mw-newarticletextanon").length > 0; if (wiktkuPrefs.onlyOnClick ? !addLangMode : (!addLangMode && !wiktkuNewPageDetected)) { return; } // ── Shared helpers ─────────────────────────────────────────────────── // Generic text/UI utilities live in their own package file now — see the // header of util.js for why. Aliased to bare names here so the ~400 call // sites below read exactly as they did when these were local functions. var wiktkuUtil = require("./start/util.js"); var capitalize = wiktkuUtil.capitalize; var decapitalize = wiktkuUtil.decapitalize; var escapeRegExp = wiktkuUtil.escapeRegExp; var stripWikilinks = wiktkuUtil.stripWikilinks; var splitTercimeIzah = wiktkuUtil.splitTercimeIzah; var insertAtCursor = wiktkuUtil.insertAtCursor; var foldDiacritics = wiktkuUtil.foldDiacritics; var wrapNativeSelect = wiktkuUtil.wrapNativeSelect; var initSelects = wiktkuUtil.initSelects; var wiktkuInitManualResize = wiktkuUtil.initManualResize; function langHeaderSource(codePattern) { return "\n?==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } var catSrcTemplates = null; var catSrcTemplatesPromise = null; function fetchCatSrcTemplates() { if (catSrcTemplatesPromise) return catSrcTemplatesPromise; catSrcTemplatesPromise = new mw.Api().get({ action: "query", list: "categorymembers", cmtitle: "Kategorî:Çavkanî", cmnamespace: 10, cmlimit: "max", formatversion: 2 }).then(function (data) { var members = (data.query && data.query.categorymembers) || []; catSrcTemplates = $.map(members, function (m) { // Pêşgira navî ya "Şablon:" rake. return m.title.replace(/^[^:]+:/, ""); }); catSrcTemplates.sort(function (a, b) { return a.localeCompare(b, userLang); }); return catSrcTemplates; }, function () { catSrcTemplates = []; return catSrcTemplates; }); return catSrcTemplatesPromise; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var formCache = new ObjectStorage("wiktku_start_draft_" + mw.config.get("wgPageName"), 1); var langsByCode = {}; // Looks up the display label for a language code, falling back to the // code itself if it isn't known yet (e.g. langsByCode not loaded). function getLangLabel(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; // Converts a {code: label} object (langChoices/posChoices in data.json) // into the {code, label[, sortKey]} array the rest of the script uses. // isLang: true adds a sortKey and shows "(code)" after the label — // language choices only. function choicesFromObject(obj, isLang) { var result = []; $.each(obj || {}, function (code, label) { var choice = { code: code, label: label }; if (isLang) choice.sortKey = label; result.push(choice); }); return result; } function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c.code] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Number codes (y, s, d, p, p+, tp, j, j+, j/nj, nj, nj+, hj!, hj?) from // data.json's "numberLabels". Same {code: {cat, display[, req]}} shape as // the wiki's Lua number-type table; "display" can contain HTML (<abbr>) // or wikilinks, so it's only used as-is in wikitext output, never dropped // straight into an <option> (see stripMarkupForOption below). var NUMBER_LABELS = {}; // Distinguishes the Jimar dropdown (j= param) from the Cîns dropdown // (c= param): a code that's a key in NUMBER_LABELS is a number code, // everything else is a gender code. Compound codes like "m-p"/"n-p" are // gender+plural pairs and correctly stay on the gender side. function isNumberCode(code) { return Object.prototype.hasOwnProperty.call(NUMBER_LABELS, code); } // Strips the bit of markup "display" is allowed to contain so it's safe // to use as plain <option> text (options can't render HTML or wikilinks): // <abbr title="X">Y</abbr> -> "Y (X)", [[a|b]] -> "b", [[a]] -> "a". function stripMarkupForOption(html) { if (!html) return ""; return $.trim( String(html) .replace(/<abbr[^>]*title="([^"]*)"[^>]*>([\s\S]*?)<\/abbr>/gi, "$2 ($1)") .replace(/\[\[[^\]|]*\|([^\]]*)\]\]/g, "$1") .replace(/\[\[([^\]]*)\]\]/g, "$1") .replace(/<[^>]+>/g, "") ); } // Builds the Jimar dropdown's <option> text for one code: "j — jimarbar". function numberOptionLabel(code) { var def = NUMBER_LABELS[code]; if (!def) return code; var text = stripMarkupForOption(def.display); return text ? (code + " — " + text) : code; } // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } // ── Template explanations ──────────────────────────────────────────── // Every place a template can be picked shows the same row: a status // dot, the name, a link to the template page, and an ⓘ. This is the ⓘ. // // Text comes from the template's own TemplateData where it has any, so // the explanation stays right without anyone maintaining a second copy // by hand — with the desc already in data.json as the fallback for // templates that have none. var wiktkuTplDataCache = {}; // name -> {desc, params[]} or null when absent /** Fetches TemplateData for one template. Resolves to null if the * template has none (a plain, undocumented template — very common). */ function fetchTemplateData(name) { if (Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, name)) { return $.Deferred().resolve(wiktkuTplDataCache[name]).promise(); } return new mw.Api().get({ action: "templatedata", titles: "Şablon:" + name, redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; var first = null; $.each(pages, function (_, p) { if (!first) first = p; }); var out = null; if (first) { var desc = first.description; // TemplateData descriptions are language maps when the // template is documented in more than one language. if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(first.params || {}, function (key, p) { var label = p && p.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(p && p.required) }); }); out = { desc: desc || "", params: params }; } wiktkuTplDataCache[name] = out; return out; }, function () { // No TemplateData, or the API is unhappy — cache the miss so a // repeated ⓘ click doesn't re-request it every time. wiktkuTplDataCache[name] = null; return null; }); } /** Fetches TemplateData for many templates in one request and fills the * cache; resolves either way, a template with no TemplateData caches as null. */ function prefetchTemplateData(names) { var missing = $.grep(names || [], function (n) { return n && !Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n); }); if (!missing.length) return $.Deferred().resolve().promise(); // The API caps a titles list at 50 for normal users. missing = missing.slice(0, 50); return new mw.Api().get({ action: "templatedata", titles: $.map(missing, function (n) { return "Şablon:" + n; }).join("|"), redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; $.each(pages, function (_, page) { if (!page || !page.title) return; var name = String(page.title).replace(/^[^:]+:/, ""); var desc = page.description; if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(page.params || {}, function (key, prm) { var label = prm && prm.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(prm && prm.required) }); }); wiktkuTplDataCache[name] = { desc: desc || "", params: params }; }); // Anything the API didn't answer for simply has none — cache the // miss so the per-row ⓘ doesn't re-request it one at a time. $.each(missing, function (_, n) { if (!Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n)) wiktkuTplDataCache[n] = null; }); }, function () { $.each(missing, function (_, n) { wiktkuTplDataCache[n] = null; }); }); } /** Rewrites each tagged <option> in `sel` as "name — description", using * TemplateData. Only fills rows that have no description yet, so the * hand-written ones in data.json (which carry usage examples the API * does not) are left exactly as they are. */ function applyTplDescriptions(sel) { if (!sel || !sel.length) return; var changed = false; sel.find("option[data-tpl]").each(function () { var opt = $(this); var name = opt.attr("data-tpl"); if (opt.text().indexOf(" — ") !== -1) return; // already described var td = wiktkuTplDataCache[name]; var desc = (td && td.desc) || localTplDesc(name); if (!desc) return; // One line: TemplateData descriptions can run to a paragraph. desc = $.trim(String(desc).split("\n")[0]); if (desc.length > 90) desc = desc.slice(0, 90) + "…"; opt.text(name + " — " + desc); changed = true; }); // The picker caches option text for searching, so it has to re-read. if (changed) sel.trigger("wiktku:refresh"); } /** Hand-written fallback description, from data.json. * * This is the escape hatch for templates with no TemplateData on the * wiki: add a "desc" to the entry in data.json and it shows up in the * dropdown and in the ⓘ immediately, no code change. TemplateData is * still the better place — VisualEditor and every other tool reads it * too — but this keeps the picker useful in the meantime. * * Works for any pool: pronTpls, etymTpls, tplDefs, jederDefs. */ function localTplDesc(name) { var pools = [steps.pron.pronTpls, steps.etym.etymTpls, steps.dfn.tplDefs, steps.dfn.jederDefs]; var found = ""; $.each(pools, function (_, pool) { if (pool && pool[name] && pool[name].desc) { found = pool[name].desc; return false; } }); return found; } /** Opens the inline explanation panel for `name`, anchored under the * picker it was opened from. */ function showTemplateInfo(name, anchorWrap) { $(".wiktku-tpl-info").remove(); var panel = $("<div class='wiktku-tpl-info'></div>"); panel.append($("<div class='wiktku-tpl-info-name'></div>").text("{{" + name + "}}")); var body = $("<div class='wiktku-tpl-info-desc'></div>").text("Tê barkirin…"); panel.append(body); var params = $("<div class='wiktku-tpl-info-params'></div>"); panel.append(params); panel.append($("<a class='wiktku-tpl-info-link' target='_blank' rel='noopener'></a>") .attr("href", wiktkuUtil.tplPageUrl(name)) .text("Rûpela şablonê veke →")); var close = $("<button type='button' class='wiktku-tpl-info-close' title='Bigire'>✕</button>"); close.on("click", function () { panel.remove(); }); panel.prepend(close); $(anchorWrap).after(panel); fetchTemplateData(name).then(function (td) { var desc = (td && td.desc) || localTplDesc(name); body.text(desc || "Ji bo vê şablonê ravek nehatiye nivîsandin."); if (td && td.params && td.params.length) { params.append($("<div class='wiktku-tpl-info-params-title'></div>").text("Parametre:")); var listEl = $("<ul></ul>"); $.each(td.params, function (_, p) { var line = p.name + (p.label ? " — " + p.label : "") + (p.required ? " (pêwîst)" : ""); listEl.append($("<li></li>").text(line)); }); params.append(listEl); } }); } /** Marks a picker's <option>s as template rows so the searchable widget * renders them with the dot / 🔗 / ⓘ affordances, and wires the ⓘ * handler for that picker. `nameOf` maps an <option> to a template * name — the pickers store different things in value= (a snippet for * the insert dropdowns, the bare name for the sense selector). */ function markTemplateOptions(sel, nameOf) { if (!sel || !sel.length) return; var names = []; sel.find("option").each(function () { var opt = $(this); var name = nameOf(opt); if (!name) return; opt.attr("data-tpl", name); // Deprecated/typo templates are the "special cases only" ones. opt.attr("data-tpl-status", /kevnbûyî|şaşnivîs|kêmpeyda/i.test(opt.text()) ? "yellow" : "green"); names.push(name); }); sel.data("wiktkuTplInfo", showTemplateInfo); // Fill in the descriptions. Matters most for the Mane picker, whose // entries in data.json are names with no desc at all — "rastnivîs", // "ku-Latn", "guharto" on their own. One request covers every // template in the picker, cached for the per-row ⓘ as well. prefetchTemplateData(names).always(function () { applyTplDescriptions(sel); }); } /** Pulls the template name out of a snippet like "* {{ku-IPA}}" or * "{{ji|SOURCELANG|CODE|…}}". */ function tplNameFromSnippet(snippet) { var m = /\{\{\s*([^|}\n]+)/.exec(snippet || ""); return m ? $.trim(m[1]) : ""; } // True if a sense has content beyond mane worth keeping (etîket, word // lists, nimûne, jêder) — so it's still emitted with {{mane?}} if empty. function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } // A technically-"complete" entry (Ziman + Cureyê rêzimanî filled) with // nothing in Mane, Bi zaravayên din or Werger is still meaningfully // empty, so this is checked separately at submit-click time with its // own message. function hasMinRequiredContent(values) { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasMane = dfnSenses.some(function (s) { return (s.tpl && s.tplTitle) || (!s.tpl && (s.mane !== "" || senseHasExtraContent(s))); }); if (hasMane) return true; if (values.lang === "ku") { var hasWerger = false; $("#wiktku-start-trans .wiktku-trans-group").each(function () { if (steps.trans.getGroupTranslations($(this)).length) hasWerger = true; }); if (hasWerger) return true; var hasZarava = false; $("#wiktku-start-zarava .wiktku-zarava-group").each(function () { if (steps.zarava.getGroupTranslations($(this)).length) hasZarava = true; }); if (hasZarava) return true; } return false; } // Bolds the *first* occurrence of the page name function boldPageNameOnce(text) { if (!text || !pageNameRe) return text; var re = new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "i"); return text.replace(re, "'''$1'''"); } // Converts literal line breaks typed into a nimûne/jêgirtin box into // wikitext <br> tags, function nlToBr(text) { return text ? text.replace(/\r\n|\r|\n/g, "<br>") : text; } function escapeHtmlForBackdrop(str) { return String(str) .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;"); } // Mirrors a textarea's text, with a small highlighted marker placed // right after each line that's followed by an actual typed/pasted // linebreak. Rendered into a transparent backdrop layer behind the // textarea (see ensureLinebreakBackdrop()), so only the point of the // break is marked instead of the whole box. function buildLinebreakBackdropHtml(text) { var lines = text.split(/\r\n|\r|\n/); return $.map(lines, function (line, i) { var isLast = i === lines.length - 1; return escapeHtmlForBackdrop(line) + (isLast ? "" : "<mark class='wiktku-linebreak-mark'>↵</mark>\n"); }).join(""); } // Copies the metrics that affect where text wraps/lands (font, line // height, padding, border) from the real textarea onto its backdrop, // via computed style rather than shared CSS classes — most of the // box's own rules are written as "textarea.foo", which a <div> with // the same class wouldn't match. Re-run on every update in case a // responsive breakpoint changed the textarea's own font-size. function syncLinebreakBackdropMetrics(textarea, backdrop) { var cs = window.getComputedStyle(textarea[0]); backdrop.css({ "box-sizing": cs.boxSizing, "padding-top": cs.paddingTop, "padding-right": cs.paddingRight, "padding-bottom": cs.paddingBottom, "padding-left": cs.paddingLeft, "border-width": cs.borderWidth, "border-style": "solid", "font-family": cs.fontFamily, "font-size": cs.fontSize, "font-weight": cs.fontWeight, "line-height": cs.lineHeight, "letter-spacing": cs.letterSpacing }); } // Lazily wraps a textarea in its own positioning anchor (independent // of .wiktku-resize-wrap, so this doesn't depend on load order versus // wiktkuMakeManualResizable) and inserts the transparent backdrop // layer used to mark the exact point of a linebreak. Safe to call // more than once on the same textarea — the backdrop is cached. function ensureLinebreakBackdrop(textarea) { var existing = textarea.data("wiktkuLinebreakBackdrop"); if (existing) return existing; textarea.wrap("<div class='wiktku-linebreak-wrap'></div>"); var backdrop = $("<div aria-hidden='true'></div>").addClass("wiktku-linebreak-backdrop"); textarea.before(backdrop); textarea.data("wiktkuLinebreakBackdrop", backdrop); textarea.on("scroll.wiktkuLinebreak", function () { backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); }); return backdrop; } // Flags a nimûne/jêgirtin textarea (via CSS class, for the border // tint + tooltip) while it contains a typed/pasted linebreak, so the // user notices before it's silently turned into <br> on output. // Marks only the exact point of the break via a mirrored backdrop, // rather than tinting the whole box. function highlightLinebreak(el) { var textarea = $(el); var text = textarea.val(); var hasBreak = /\r|\n/.test(text); textarea .toggleClass("wiktku-has-linebreak", hasBreak) .attr("title", hasBreak ? "Xeta nû dê wek <br> bê nivîsandin" : ""); if (!hasBreak) { var cached = textarea.data("wiktkuLinebreakBackdrop"); if (cached) cached.hide(); textarea.removeClass("wiktku-has-linebreak-source"); return; } var backdrop = ensureLinebreakBackdrop(textarea); textarea.addClass("wiktku-has-linebreak-source"); syncLinebreakBackdropMetrics(textarea, backdrop); backdrop.html(buildLinebreakBackdropHtml(text)).show(); backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); } // Each nimûne item can be { text, tr, t }: text, transliteration, translation. function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{nimûne?|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = nlToBr(boldPageNameOnce(text)); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + nlToBr(n.tr); // Translation as third positional param (no key needed). if (n.t) tpl += "|" + nlToBr(n.t); } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 60 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } // Formats jêder (citation) entries into "#* {{jêder…|…}}" lines; skips // entries with no quote text. Falls back to the generic {{jêder}} // template when no specific template was chosen. function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; var quote = nlToBr(boldPageNameOnce(jeder.quote)); var quoteTr = nlToBr(jeder.quoteTr); var quoteT = nlToBr(jeder.quoteT); if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + quote; if (quoteTr) cite += "|tr=" + quoteTr; if (quoteT) cite += "|tercime=" + quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + quote; if (quoteTr) out += "|tr=" + quoteTr; if (quoteT) out += "|tercime=" + quoteT; // A şablon picked from Kategorî:Çavkanî is transcluded as the // source param (e.g. |{{Kovara X}}); manual text is used as-is. var srcParam = jeder.jederCatTpl ? ("{{" + jeder.jederCatTpl + "}}") : (jeder.jederManual ? jeder.jederManual : "çavkanî?"); // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } // True if a sense has at least one jêder entry with quote text. function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } // Builds "{{tplName|lang|part1|part2|…}}" from a sense field (kategori, // etiket), wrapped inline (" {{…}} ") or on its own line ("\n#: {{…}}"). function buildSenseTpl(sense, field, lang, tplName) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return call } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } // ── Inline modifier system ─────────────────────────────────────────────── // Appends a ⊕ button to a word input <li>. Clicking it shows a compact // modifier picker; selecting one prompts for the value and appends // <modifier:value> to the textarea's current content. 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îf" }, { 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: qualifier (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" }, { key: "qq", label: "qq: qualifier (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î" } ]; // Sub-groups (inside a sense/definition block) that get the same ⊕ // modifier button as makeWordListStep fields. var MODIFIER_SUBGROUPS = { "wiktku-dfn-alternativ": true, "wiktku-dfn-hevmane": true, "wiktku-dfn-dijmane": true, "wiktku-dfn-koordine": true, "wiktku-dfn-jornav": true, "wiktku-dfn-jernav": true }; /** * Wraps a freshly-created textarea in a <li> with a ⊕ modifier button. * `ta` — the jQuery textarea element. * Returns the <li>. */ function makeModifierLi(ta) { var li = $("<li class='wiktku-word-li'></li>"); var btn = $("<button type='button' class='wiktku-mod-btn' title='Modifiyerê lê zêde bike'>⊕</button>"); var picker = $("<div class='wiktku-mod-picker'></div>").hide(); // Which modifier keys are already present in the textarea's current // text — e.g. "<t:...>" → "t" used. Each modifier can only be // applied once per word, so its pill gets disabled once used. function usedKeys() { var used = {}; var re = /<([a-zA-Z]+):/g; var val = ta.val() || ""; var m; while ((m = re.exec(val)) !== null) used[m[1]] = true; return used; } $.each(WORD_MODIFIERS, function (_, mod) { var pill = $("<button type='button' class='wiktku-mod-pill'></button>").text(mod.label); pill.attr("title", mod.hint); pill.data("mod-key", mod.key); pill.on("click", function (e) { e.preventDefault(); if (pill.prop("disabled")) return; // already used on this word picker.hide(); // Show a tiny inline input for the modifier value. var valWrap = $("<span class='wiktku-mod-val-wrap'></span>"); var valInp = $("<input type='text' class='wiktku-mod-val-input'>") .attr("placeholder", mod.hint + "…") .attr("size", 20); var confirm = $("<button type='button' class='wiktku-mod-confirm'>✓</button>"); var cancel = $("<button type='button' class='wiktku-mod-cancel'>✕</button>"); function applyModifier() { var v = $.trim(valInp.val()); if (v) { ta.val(ta.val() + "<" + mod.key + ":" + v + ">"); ta.trigger("input"); } valWrap.remove(); ta.focus(); } confirm.on("click", applyModifier); cancel.on("click", function () { valWrap.remove(); ta.focus(); }); valInp.on("keydown", function (e) { if (e.which === 13) { e.preventDefault(); applyModifier(); } if (e.which === 27) { valWrap.remove(); ta.focus(); } }); valWrap.append(valInp).append(confirm).append(cancel); li.append(valWrap); valInp.focus(); }); picker.append(pill); }); btn.on("click", function (e) { e.preventDefault(); // Close any other open pickers in the same list. li.closest("ol, ul").find(".wiktku-mod-picker").not(picker).hide(); // Grey out modifiers already used on this word — refreshed on // every open since the text (and thus what's "used") can change. var used = usedKeys(); picker.find(".wiktku-mod-pill").each(function () { var isUsed = !!used[$(this).data("mod-key")]; $(this).prop("disabled", isUsed).toggleClass("wiktku-mod-pill-used", isUsed); }); picker.toggle(); }); // Close picker when focus leaves the li entirely. li.on("focusout", function () { setTimeout(function () { if (!$.contains(li[0], document.activeElement)) picker.hide(); }, 150); }); li.append(ta).append(btn).append(picker); return li; } function makeWordListStep(id, name, question_fmt) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, modifiers: true, // Function instead of a plain string so it can name the current // language — computed fresh at build time and re-applied by // refresh() whenever the language changes. placeholder: function () { var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return "Kelîme" + (langLabel ? " bi " + langLabel : "") + "…"; }, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); var header = capitalize(name); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: {}, visible: function (values) { if (!values.lang) return false; // addLangMode: skip pron only if this lang already has a section. if (addLangMode) { // Clearing the page makes existing content irrelevant. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, // Fills the insert-dropdown from pronTpls, filtered by language. refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); // Reassures the user this field is optional — the dropdown // below writes the template for them, no syntax needed up front. wrap.append( $("<p class='wiktku-step-hint'></p>").text( "Ev qad ne mecbûrî ye. Heke tu nizanî kîjan şablonî hilbijêrî, vale bihêle — an ji pêşkêşkariya jêrîn şablonekî hilbijêre, ew ê bixweber li vir were nivîsandin." ) ); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike "); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); // Clear the picker's search box sel.trigger("wiktku:refresh"); ta.focus(); return; } // The noLang templates (ku-IPA, ku-kîte, zza-IPA, zza-kîte) // auto-generate content from a Lua module reading the page // title, so show a live preview and require confirmation // before inserting. var tplLabel = selectedOption.text(); $(this).val(""); sel.trigger("wiktku:refresh"); steps.pron.showTplPreview(stepDiv, ta, snippet, tplLabel); }); wrap.append(sel).append(ta); stepDiv.append(wrap); steps.pron.buildIpaPalette(wrap, ta); initSelects(wrap); return ta; }, // ── IPA character palette ────────────────────────────────── // Modelled on fr.wiktionary's: every character is a button that // drops itself in at the cursor. Two sub-tabs, because the full // IPA chart is ~180 symbols and roughly twenty of them ever // appear in Kurmancî — "IPA (kurdî)" opens by default and the // full chart is one click away for loanwords and other // languages. Grouped with a label down the left so it reads as // a chart rather than one long line of glyphs. IPA_KU: [ { label: "Kît/stres", chars: ["ˈ", "ˌ", "ː"] }, { label: "Bêdeng", chars: ["d͡ʒ", "t͡ʃ", "ʒ", "ʃ", "ɫ", "ŋ", "ɾ", "r", "ʋ", "ħ", "ʕ", "ɣ", "χ", "ʔ"] }, { label: "Dengdêr", chars: ["ɑː", "eː", "ɛ", "ɪ", "iː", "ɯ", "ʊ", "uː", "yː", "ø", "œ"] } ], IPA_FULL: [ { label: "Bêdeng 1", chars: ["m", "ɱ", "n", "ɳ", "ɲ", "ŋ", "ɴ", "p", "b", "t", "d", "t̪", "d̪", "ʈ", "ɖ", "c", "ɟ", "k", "ɡ", "q", "ɢ", "ʡ", "ʔ"] }, { label: "Bêdeng 2", chars: ["ɸ", "β", "f", "v", "θ", "ð", "s", "z", "ʃ", "ʒ", "ʂ", "ʐ", "ɕ", "ʑ", "ç", "ʝ", "x", "ɣ", "χ", "ʁ", "ħ", "ʕ", "h", "ɦ", "ʜ", "ʢ", "ɧ"] }, { label: "Bêdeng 3", chars: ["ʋ", "ɹ", "ɻ", "j", "ɥ", "ɰ", "ʍ", "w", "ʙ", "ⱱ", "ɾ", "ɽ", "r", "ʀ", "ɺ", "l", "ɫ", "ɬ", "ɮ", "ɭ", "ʎ", "ʟ"] }, { label: "Bêdeng 4", chars: ["ɓ", "ɗ", "ᶑ", "ʄ", "ɠ", "ʛ", "ʘ", "ǀ", "ǃ", "ǂ", "ǁ"] }, { label: "Dengdêr", chars: ["i", "y", "ɪ", "ʏ", "ɨ", "ʉ", "ɯ", "u", "ʊ", "e", "ø", "ɘ", "ɵ", "ɤ", "o", "ə", "ɚ", "ɛ", "œ", "ɜ", "ɝ", "ɞ", "ʌ", "ɔ", "æ", "ɶ", "ɐ", "a", "ɑ", "ɒ"] }, { label: "Suprasegmental", chars: ["ˈ", "ˌ", "ː", "ˑ", "ʼ", "ˀ", "ˤ", "ᵝ", "ᵊ", "ˠ", "ʰ", "ʱ", "ʲ", "ˡ", "ⁿ", "ᵑ", "ʷ", "ᶣ", "˞", "‿"] }, { label: "Dîakrîtîk", chars: ["̚", "̪", "̺", "̻", "̼", "̬", "̊", "̥", "̞", "̝", "̘", "̙", "̽", "̟", "̠", "̈", "̤", "̹", "̜", "̍", "̩", "̆", "̯", "̃", "̰", "͡", "͜"] }, { label: "Ton", chars: ["̋", "́", "̄", "̀", "̏", "̌", "̂", "˥", "˦", "˧", "˨", "˩", "ꜛ", "ꜜ", "↗", "↘", "‖"] } ], /** Builds the two-sub-tab character palette under the textarea. */ buildIpaPalette: function (wrap, ta) { if (wrap.find(".wiktku-ipa-palette").length) return; var panel = $("<div class='wiktku-ipa-panel'></div>").hide(); var toggle = $("<a href='#' class='wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tîpên bilêvkirinê</span>")); toggle.on("click", function (e) { e.preventDefault(); var open = panel.is(":visible"); panel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); wrap.append($("<div class='wiktku-adv-toggle-row'></div>").append(toggle)); // Sub-tab bar, with the two template buttons pinned right. var subTabs = $("<div class='wiktku-ipa-subtabs'></div>"); var kuTab = $("<span class='wiktku-ipa-subtab wiktku-tab-active'>IPA (kurdî)</span>"); var fullTab = $("<span class='wiktku-ipa-subtab'>IPA</span>"); subTabs.append(kuTab).append(fullTab); var tplBtns = $("<span class='wiktku-ipa-tplbtns'></span>"); $.each([ { label: "{{ku-IPA|+}}", snippet: "{{ku-IPA|}}", back: 2 }, { label: "{{IPA|+}}", snippet: "{{IPA|ku|}}", back: 2 } ], function (_, t) { var b = $("<button type='button' class='wiktku-ipa-tplbtn'></button>").text(t.label); b.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], t.snippet); // Park the cursor inside the braces, where the value goes. var pos = ta[0].selectionStart - t.back; ta[0].selectionStart = ta[0].selectionEnd = pos; ta.focus(); }); tplBtns.append(b); }); subTabs.append(tplBtns); panel.append(subTabs); function buildGrid(groups) { var grid = $("<div class='wiktku-ipa-grid'></div>"); $.each(groups, function (_, g) { var row = $("<div class='wiktku-ipa-row'></div>"); row.append($("<span class='wiktku-ipa-rowlabel'></span>").text(g.label)); var keys = $("<span class='wiktku-ipa-keys'></span>"); $.each(g.chars, function (_, ch) { var btn = $("<button type='button' class='wiktku-ipa-key'></button>"); // A combining mark on its own renders as a stray // accent floating over whatever precedes it, so // show it on a dotted circle — but insert only // the mark itself. var combining = /^[̀-ͯ҃-҉]$/.test(ch); btn.text(combining ? "◌" + ch : ch); if (combining) btn.addClass("wiktku-ipa-key-combining"); btn.attr("title", ch); btn.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], ch); ta.focus(); }); keys.append(btn); }); row.append(keys); grid.append(row); }); return grid; } var kuGrid = buildGrid(steps.pron.IPA_KU); var fullGrid = buildGrid(steps.pron.IPA_FULL).hide(); panel.append(kuGrid).append(fullGrid); kuTab.on("click", function () { kuTab.addClass("wiktku-tab-active"); fullTab.removeClass("wiktku-tab-active"); kuGrid.show(); fullGrid.hide(); }); fullTab.on("click", function () { fullTab.addClass("wiktku-tab-active"); kuTab.removeClass("wiktku-tab-active"); fullGrid.show(); kuGrid.hide(); }); panel.addClass("wiktku-ipa-palette"); wrap.append(panel); }, /** Inline preview + confirm panel for a "noLang" (auto-content) * pronunciation template — fetches what the snippet expands to * for this page and only inserts it if the user confirms. */ showTplPreview: function (stepDiv, ta, snippet, tplLabel) { // Only one preview panel open at a time. stepDiv.find(".wiktku-pron-preview").remove(); var panel = $("<div class='wiktku-pron-preview'></div>"); panel.append($("<div class='wiktku-pron-preview-label'></div>") .text("Pêşdîtina " + tplLabel + ":")); var body = $("<div class='wiktku-pron-preview-body'></div>").text("Tê barkirin…"); panel.append(body); var actions = $("<div class='wiktku-pron-preview-actions'></div>"); var confirmBtn = $("<button type='button' class='wiktku-pron-preview-confirm'>✓ Tevlî bike</button>") .prop("disabled", true); var cancelBtn = $("<button type='button' class='wiktku-pron-preview-cancel'>✕ Betal bike</button>"); actions.append(confirmBtn).append(cancelBtn); panel.append(actions); ta.before(panel); confirmBtn.on("click", function () { insertAtCursor(ta[0], snippet); panel.remove(); ta.focus(); }); cancelBtn.on("click", function () { panel.remove(); }); // action=parse, not action=expandtemplates. expandtemplates // returns *expanded wikitext*, so the preview read as // [[IPA]]<sup>([[Wîkîferheng:IPA kurmancî|kilîd]])</sup>: // <span class="IPA">/-{kshhe}-/</span>[[Kategorî:…]] — which // is exactly what the person is trying to avoid having to // read. parse hands back the rendered HTML the page will // actually show. // // Drop the leading "* " first: it is wikitext list syntax // wrapping the template, and keeping it would render the // preview as a bulleted list rather than the line itself. new mw.Api().post({ action: "parse", title: pageName, text: snippet.replace(/^\*\s*/, ""), prop: "text", wrapoutputclass: "", disablelimitreport: 1, disableeditsection: 1, contentmodel: "wikitext", formatversion: 2 }).done(function (data) { var html = (data && data.parse && data.parse.text) || ""; if ($.trim($("<div>").html(html).text())) { body.html(html); // Category links render as nothing but still exist; // and any real link inside a preview should not // navigate away from a half-filled form. body.find("a").attr("target", "_blank").attr("rel", "noopener"); } else { body.text("(vala — ji bo vê rûpelê tiştek nehate afirandin)"); } confirmBtn.prop("disabled", false); }).fail(function () { body.text("Pêşdîtin nehate barkirin — tu dikarî hîn jî wê tevlî bikî."); confirmBtn.prop("disabled", false); }); }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line; }).join("\n"); // "===" heading under Ziman and above the POS sections; the // field is shared across sections, so it's emitted once by // getWikitext() rather than per-POS-section (would otherwise // print the pronunciation twice for a two-POS entry). return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var capitalizedPos = capitalize(pos); // "form" opt-param (checked in posparams) marks this as a // form-of/inflected entry — the section title becomes // "Formeke <pos>ê" instead of the plain pos name. The // template call itself still uses the unchanged pos name. var isForm = $("#wiktku-posparams-opt-form").is(":checked"); var header = isForm ? "\n=== Formeke " + pos + "ê ===\n" : "\n=== " + capitalizedPos + " ===\n"; // Image line (between header and template call) var imageLine = steps.resim.output(values); // Read the live wikitext from the posparams textarea. // Fall back to a plain {{pos|lang}} if the step hasn't been built yet. var tplLine = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); if (!tplLine) { tplLine = "{{" + pos + "|" + (values.lang || "") + "}}"; } return header + imageLine + tplLine + "\n"; } }, // cinsiyet (gender) — shown for navdêr/serenav only, with choices built // from metadata[lang].g since not every language has grammatical gender. cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams // Single source of truth for the selected gender code. The visible // dropdown lives inside the posparams step (see steps.posparams), // but it must always read/write THIS hidden field — not a field of // its own — since getValuesForStep("cinsiyet") reads from here. build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-cinsiyet-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // jimar (grammatical number) — same hidden-field pattern as cinsiyet // above, but writes into its own j= template parameter instead of // sharing c=. Shown for navdêr/serenav only, with choices built from // whichever of metadata[lang].g are number codes (see isNumberCode). jimar: { id: "jimar", name: "jimar", question_fmt: 'Jimara "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-jimar-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // Lêker transitivity — hidden step, handled inside posparams lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function () { return false; }, choices: [ { code: "gh", label: "gerguhêz" }, { code: "x-gh", label: "xwerû-gerguhêz" }, { code: "p-gh", label: "pêkhatî-gerguhêz" }, { code: "h-gh", label: "hevedudanî-gerguhêz" }, { code: "b-gh", label: "biwêjî-gerguhêz" }, { code: "ngh", label: "negerguhêz" }, { code: "x-ngh", label: "xwerû-negerguhêz" }, { code: "p-ngh", label: "pêkhatî-negerguhêz" }, { code: "h-ngh", label: "hevedudanî-negerguhêz" }, { code: "b-ngh", label: "biwêjî-negerguhêz" } ], output: function () { return ""; } }, // tr — hidden step, handled inside posparams tr: { id: "tr", name: "transliterasyon", question_fmt: "Transliterasyona vê kelîmeyê", multiple: false, narrow: true, visible: function () { return false; } }, posparams: { id: "posparams", // Fused onto the "pos" card visually (see #wiktku-start-posparams // in styles.css) so the two read as ONE question — this name is // only a no-CSS/no-JS fallback, since the h3 that would show it // is hidden by CSS. name: "taybetmendî", // Shows what's actually being asked for: gender for nouns, verb // type for verbs, a generic fallback otherwise. question_fmt: function (values) { var pos = values.pos || ""; // Cinsiyet/Jimar fields below are self-labelled, so no title needed here. if (pos === "navdêr" || pos === "serenav") return ""; if (/^lêker/.test(pos)) return "Cureyê lêkerê"; return "Taybetmendî"; }, visible: function (values) { return !!(values.lang && values.pos); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-posparams-wrap").length) return null; var wrap = $("<div class='wiktku-posparams-wrap'></div>"); var helpers = $("<div class='wiktku-posparams-helpers'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-posparams-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-posparams-text") .attr("rows", 2); var _rebuilding = false; function safeRebuild() { if (_rebuilding) return; _rebuilding = true; steps.posparams.rebuildTa(stepDiv); _rebuilding = false; refresh(); } // Generic text-input row factory function makeTextRow(key, labelText, placeholder) { var row = $("<div class='wiktku-posparams-row'></div>") .attr("id", "wiktku-posparams-row-" + key).hide(); var inp = $("<input type='text'>") .addClass("wiktku-start-narrow wiktku-posparams-field") .attr("data-pp-key", key) .attr("placeholder", placeholder || ""); inp.on("input", safeRebuild); row.append($("<label></label>").text(labelText + ": ")).append(inp); return row; } // cinsiyet var cinsiyetRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-c'></div>") .append($("<label></label>").text("Cinsiyet: ")).hide(); var cinsiyetSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-cinsiyet-sel") .append($("<option value=''>— hilbijêre —</option>")); // Writes into the real, shared #wiktku-start-cinsiyet-field (owned by // steps.cinsiyet) rather than a field of its own — see the comment // on steps.cinsiyet.build for why that matters. cinsiyetSel.on("change", function () { $("#wiktku-start-cinsiyet-field").val($(this).val()).trigger("change"); safeRebuild(); }); cinsiyetRow.append(cinsiyetSel); // jimar (number) — second dropdown next to Cinsiyet, writes // into the shared hidden #wiktku-start-jimar-field, into its // own j= param instead of sharing c=. Options + tooltip are // built in syncHelpers once the language's number codes are known. var jimarRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-jimar'></div>") .append($("<label></label>").text("Jimar: ")).hide(); var jimarSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-jimar-sel") .append($("<option value=''>— hilbijêre —</option>")); jimarSel.on("change", function () { $("#wiktku-start-jimar-field").val($(this).val()).trigger("change"); safeRebuild(); }); jimarRow.append(jimarSel); // lektur: two plain questions (transitivity + structural form) // instead of one 10-option dropdown. Emitted code: base alone // ("gh"), or prefix + "-" + base ("x-gh"). var lekturRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lektur'></div>") .append($("<label></label>").text("Lêker derbasdar e? ")).hide(); var lekturSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lektur-sel") .append($("<option value=''>— hilbijêre —</option>")) .append($("<option value='gh'>gerguhêz (bireser digire)</option>")) .append($("<option value='ngh'>negerguhêz (bireser nagire)</option>")); lekturSel.on("change", safeRebuild); lekturRow.append(lekturSel); // Second half of the same question — the structural form. // Blank = xwerû/sade, which is the common case. var lekturFormRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lekturform'></div>") .append($("<label></label>").text("Şiklê lêkerê: ")).hide(); var lekturFormSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lekturform-sel") .append($("<option value=''>sade (asayî)</option>")) .append($("<option value='x'>xwerû</option>")) .append($("<option value='p'>pêkhatî</option>")) .append($("<option value='h'>hevedudanî</option>")) .append($("<option value='b'>biwêjî</option>")); lekturFormSel.on("change", safeRebuild); lekturFormRow.append(lekturFormSel); helpers.append(cinsiyetRow).append(jimarRow).append(lekturRow).append(lekturFormRow); // ── Everything below here is "Tercîhên pêşketî" ────────────── // These rows live inside a collapsed panel, so the default // view of this card is two dropdowns instead of twenty-odd fields. // Transliteration is a primary field, not an advanced one, for // any language not written in Latin script: for those, an // entry without it is incomplete. syncHelpers already gates // the row on needsTransliteration(lang), so for Kurmancî and // other Latin-script languages it simply never appears. helpers.append(makeTextRow("tr", "Transliterasyon (tr)", "Transliterasyon…")); var advPanel = $("<div class='wiktku-posparams-adv-panel'></div>").hide(); advPanel .append(makeTextRow("cuda", "nîşankirina alternatîv", "cuda…")) .append(makeTextRow("ts", "Transkrîpsiyon (ts)", "Transkrîpsiyon…")) .append(makeTextRow("m", "Forma mê (m)", "Forma mê…")) .append(makeTextRow("mtr", "Translit. mê (mtr)", "Transliterasyona mê…")) .append(makeTextRow("n", "Forma nêr (n)", "Forma nêr…")) .append(makeTextRow("ntr", "Translit. nêr (ntr)", "Transliterasyona nêr…")) .append(makeTextRow("p", "Forma pirjimar (p)", "Forma pirjimar…")) .append(makeTextRow("ptr", "Translit. pirjimar", "Transliterasyona pirjimar…")) .append(makeTextRow("y", "Forma yekjimar (y)", "Forma yekjimar…")) .append(makeTextRow("ytr", "Translit. yekjimar", "Transliterasyona yekjimar…")) .append(makeTextRow("sûp", "Forma sûperlatîv (sûp)", "Forma sûperlatîv…")) .append(makeTextRow("sûptr", "Translit. sûperlatîv", "Transliterasyona sûperlatîv…")) .append(makeTextRow("komp", "Forma komparatîv (komp)", "Forma komparatîv…")) .append(makeTextRow("komptr", "Translit. komparatîv", "Transliterasyona komparatîv…")) .append(makeTextRow("gir", "Forma girdêk (gir)", "gir=…")) .append(makeTextRow("girtr", "Translit. gir", "girtr=…")) .append(makeTextRow("hûr", "Forma hûrek (hûr)", "hûr=…")) .append(makeTextRow("hûrtr", "Translit. hûr", "hûrtr=…")) .append(makeTextRow("hanja", "Forma hanja", "hanja=…")) .append(makeTextRow("hanjaTr","Translit. hanja", "hanjaTr=…")) // Lêker rehên demê (only shown when pos is lêker — see syncHelpers) .append(makeTextRow("niha", "Rehê dema niha (niha)", "Rehê dema niha…")) .append(makeTextRow("nihatr", "Translit. rehê dema niha", "Transliterasyona rehê dema niha…")) .append(makeTextRow("borî", "Rehê dema borî (borî)", "Rehê dema borî…")) .append(makeTextRow("borîtr", "Translit. rehê dema borî", "Transliterasyona rehê dema borî…")) .append(makeTextRow("subj", "Rehê dema bilanî (subj)", "Rehê dema bilanî…")) .append(makeTextRow("subjtr", "Translit. rehê dema bilanî", "Transliterasyona rehê dema bilanî…")); // Optional boolean params — nested inside the advanced panel // (they were already the most niche thing on the card). var optPanel = $("<div class='wiktku-posparams-opt-panel'></div>"); $.each([ { key: "form", label: "form — ev made forma tewandî ye" }, { key: "formaalt", label: "formaalt — vê madeyê bike forma alternatîv" }, { key: "nekatcure", label: "nekatcure — sinifa rêzimanî kategorîze neke" }, { key: "nekatcins", label: "nekatcins — kategoriya cinsiyetê neyîne" }, { key: "nekatçendterm", label: "nekatçendterm — kategoriya çend-term neyîne" }, { key: "serlînkneke", label: "serlînkneke — sernavê madeyê lînk neke" }, { key: "nekatpalîndrom", label: "nekatpalîndrom — kategoriya palîndromê neyîne" }, { key: "neformtr", label: "neformtr — transliterasyona forman neyîne" } ], function (_, p) { var cb = $("<input type='checkbox'>") .attr("id", "wiktku-posparams-opt-" + p.key).val(p.key).on("change", safeRebuild); var lbl = $("<label></label>").attr("for", "wiktku-posparams-opt-" + p.key).text(" " + p.label); optPanel.append($("<div class='wiktku-posparams-opt-row'></div>").append(cb).append(lbl)); }); advPanel.append(optPanel); var optToggle = $("<a href='#' class='wiktku-posparams-opt-toggle wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tercîhên pêşketî</span>")); optToggle.on("click", function (e) { e.preventDefault(); var open = advPanel.is(":visible"); advPanel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); helpers.append($("<div class='wiktku-adv-toggle-row'></div>") .append(optToggle)); helpers.append(advPanel); wrap.append(helpers).append(ta); // Typing directly in textarea keeps cinsiyet/jimar hidden // fields in sync, but does NOT call refresh() — preserves // manual edits. ta.on("input", function () { var text = $(this).val(); var cMatch = text.match(/\|c=([^|}\s]+)/); $("#wiktku-start-cinsiyet-field").val(cMatch ? cMatch[1] : ""); var jMatch = text.match(/\|j=([^|}\s]+)/); $("#wiktku-start-jimar-field").val(jMatch ? jMatch[1] : ""); }); stepDiv.append(wrap); return null; }, /** Reads all helper widget values and rewrites the textarea. * Called only by safeRebuild (user interaction) — never by syncHelpers, * so manual textarea edits are never overwritten by a refresh cycle. */ rebuildTa: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; if (!pos || !lang) return; var cinsiyet = stepDiv.find(".wiktku-posparams-cinsiyet-sel").val() || ""; var jimar = stepDiv.find(".wiktku-posparams-jimar-sel").val() || ""; // Two dropdowns, one code: "gh" / "ngh" on their own, or // prefixed with the structural form ("x-gh", "b-ngh", …). var lekturBase = stepDiv.find(".wiktku-posparams-lektur-sel").val() || ""; var lekturForm = stepDiv.find(".wiktku-posparams-lekturform-sel").val() || ""; var lektur = lekturBase ? (lekturForm ? lekturForm + "-" + lekturBase : lekturBase) : ""; function v(key) { return $.trim(stepDiv.find(".wiktku-posparams-field[data-pp-key='" + key + "']").val()); } var out = "{{" + pos + "|" + lang; if (pos === "navdêr" || pos === "serenav") { out += cinsiyet ? "|c=" + cinsiyet : (lang === "ku" ? "|c=?" : ""); // Number is its own j= param, separate from c= (which // holds gender, including compounds like m-p/n-p). if (jimar) out += "|j=" + jimar; } else if (/^lêker/.test(pos) && lektur) { out += "|c=" + lektur; } if (v("cuda")) out += "|" + v("cuda"); if (v("tr")) out += "|tr=" + v("tr"); if (v("ts")) out += "|ts=" + v("ts"); $.each(["m","n","p","y"], function (_, k) { if (v(k)) out += "|" + k + "=" + v(k); if (v(k+"tr")) out += "|" + k + "tr=" + v(k+"tr"); }); if (v("sûp")) out += "|sûp=" + v("sûp"); if (v("sûptr")) out += "|sûptr=" + v("sûptr"); if (v("komp")) out += "|komp=" + v("komp"); if (v("komptr")) out += "|komptr=" + v("komptr"); if (v("gir")) out += "|gir=" + v("gir"); if (v("girtr")) out += "|girtr=" + v("girtr"); if (v("hûr")) out += "|hûr=" + v("hûr"); if (v("hûrtr")) out += "|hûrtr=" + v("hûrtr"); if (v("hanja")) out += "|hanja=" + v("hanja"); if (v("hanjaTr")) out += "|hanjaTr=" + v("hanjaTr"); if (v("niha")) out += "|niha=" + v("niha"); if (v("nihatr")) out += "|nihatr=" + v("nihatr"); if (v("borî")) out += "|borî=" + v("borî"); if (v("borîtr")) out += "|borîtr=" + v("borîtr"); if (v("subj")) out += "|subj=" + v("subj"); if (v("subjtr")) out += "|subjtr=" + v("subjtr"); stepDiv.find(".wiktku-posparams-opt-panel input:checked").each(function () { var key = $(this).val(); // "form" marks this entry as a form-of/inflected entry — it // takes "erê" rather than the plain "1" the other boolean // opt params use. out += "|" + key + "=" + (key === "form" ? "erê" : "1"); }); out += "}}"; stepDiv.find(".wiktku-posparams-text").val(out); $("#wiktku-start-cinsiyet-field").val(cinsiyet); $("#wiktku-start-jimar-field").val(jimar); }, /** Called from refresh() — controls row visibility only. * Does NOT rewrite textarea so user edits are preserved. * Rebuilds only when textarea is empty (first pos selection). */ syncHelpers: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; var needsTr = needsTransliteration(lang); var isNom = pos === "navdêr" || pos === "serenav" || pos === "rengdêr"; var isAdj = pos === "rengdêr"; var isTîp = pos === "tîp"; var isJa = lang === "ja"; var isLeker = /^lêker/.test(pos); // metadata[lang].g lists gender AND number codes together — // split them here (see isNumberCode) so Cîns only ever offers // gender codes (and gender+plural compounds like m-p/n-p, // which aren't NUMBER_LABELS keys) and Jimar only offers number codes. var meta = metadata[lang]; var allCodes = (meta && meta.g) || []; var genderCodes = $.grep(allCodes, function (c) { return !isNumberCode(c); }); var jimarCodes = $.grep(allCodes, function (c) { return isNumberCode(c); }); var showC = (pos === "navdêr" || pos === "serenav") && genderCodes.length > 0; var cRow = stepDiv.find("#wiktku-posparams-row-c"); cRow.toggle(showC); if (showC) { var sel = cRow.find(".wiktku-posparams-cinsiyet-sel"); // Prefer the select's own current value (normal in-session // use); fall back to the shared hidden field, which is how // a cache/section restore communicates a saved gender // before this select has any <option>s to hold it. var prev = sel.val() || $("#wiktku-start-cinsiyet-field").val() || ""; sel.find("option[value!='']").remove(); $.each(genderCodes, function (_, code) { sel.append($("<option></option>").val(code).text(genderLabel(code))); }); if (prev) sel.val(prev); } var showJimar = (pos === "navdêr" || pos === "serenav") && jimarCodes.length > 0; var jimarRowEl = stepDiv.find("#wiktku-posparams-row-jimar"); jimarRowEl.toggle(showJimar); if (showJimar) { var jimarSelEl = jimarRowEl.find(".wiktku-posparams-jimar-sel"); var prevJimar = jimarSelEl.val() || $("#wiktku-start-jimar-field").val() || ""; jimarSelEl.find("option[value!='']").remove(); $.each(jimarCodes, function (_, code) { var def = NUMBER_LABELS[code] || {}; var opt = $("<option></option>").val(code).text(numberOptionLabel(code)); // The explanation (cat, e.g. "dualia tantum") shows as a // hover tooltip — <option> can't hold richer markup. if (def.cat) opt.attr("title", def.cat); jimarSelEl.append(opt); }); if (prevJimar) jimarSelEl.val(prevJimar); } stepDiv.find("#wiktku-posparams-row-lektur").toggle(isLeker); // Only ask for the structural form once gerguhêz/negerguhêz is answered. stepDiv.find("#wiktku-posparams-row-lekturform") .toggle(isLeker && !!stepDiv.find(".wiktku-posparams-lektur-sel").val()); stepDiv.find("#wiktku-posparams-row-tr").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-ts").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-m").toggle(isNom); stepDiv.find("#wiktku-posparams-row-mtr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-n").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ntr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-p").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ptr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-y").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ytr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-sûp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-sûptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-komp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-komptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-gir").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-girtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hûr").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-hûrtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hanja").toggle(isJa); stepDiv.find("#wiktku-posparams-row-hanjaTr").toggle(isJa); stepDiv.find("#wiktku-posparams-row-niha").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-nihatr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-borî").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-borîtr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-subj").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-subjtr").toggle(isLeker && needsTr); if (!$.trim(stepDiv.find(".wiktku-posparams-text").val())) { steps.posparams.rebuildTa(stepDiv); } }, output: function () { return ""; } // pos.output reads the textarea directly }, dfn: { id: "dfn", name: "Mane", // Field types that live behind "Malûmatên pêşketî". Kept as one // list so the collapse CSS, the count badge and the allGroups // adv: flags below can't drift apart. ADV_SUBGROUPS: [ "wiktku-dfn-etiket", "wiktku-dfn-kategori", "wiktku-dfn-alternativ", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ], question_fmt: function (values) { var base = "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin!"; if (values.lang === "ku") { return base + " Ji bo tercimeyan beşa 'Werger' bi kar bîne!"; } return base; }, multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, // Builds one sense block (<li>): mane textarea, nimûne list, and // sub-lists for alternatîv/hevmane/dijmane/etc. buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Tercime + Îzah boxes (non-ku alternative to the plain mane box) — // Non-ku entries get a direct translation plus a {{îzah|…}}-wrapped // gloss instead of a Kurdish-style gloss. Rather than teach every // consumer (getSenses/getOutput/linkify) a second data shape, these // boxes just write their combined text into dfnArea and re-fire its // "input" event, so dfnArea stays the single source of truth. var tercimeArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-tercime-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-tercime") .attr("rows", 2) .attr("placeholder", "Tercimeyên rasterast ên kurmancî… Ji bo school-a îngilîzî li vir 'mekteb, medrese' binivîse"); var izahArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-izah-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-izah") .attr("rows", 3) .attr("placeholder", "Îzaha kurmancî… Ji bo school-a îngilîzî li vir 'cihê tehsîlgirtinê' binivîse"); var nonKuWrap = $("<div class='wiktku-dfn-nonku-wrap'></div>") .append(tercimeArea).append(izahArea) .hide(); function syncNonKuToMane() { var t = $.trim(tercimeArea.val()); var iz = $.trim(izahArea.val()); // if tercime is blank, use îzah as definition var combined = t ? (iz ? t + " {{îzah|" + iz + "}}" : t) : iz; dfnArea.val(combined); // Re-fires onDfnInput, as if this were typed directly into // the mane textarea. dfnArea.trigger("input"); } tercimeArea.on("input", syncNonKuToMane); izahArea.on("input", syncNonKuToMane); // Switches between the plain mane box and the tercime+îzah pair — // only for non-ku entries with no tplSelect selected. function updateManeMode() { var lang = getValues().lang || ""; var isTpl = !!tplSelect.val(); if (lang && lang !== "ku" && !isTpl) { dfnArea.hide(); nonKuWrap.show(); } else { nonKuWrap.hide(); if (!isTpl) dfnArea.show(); } } // Store on the block so refresh() can re-sync every block when // lang changes, and restoreDfn() can re-sync after restoring. block.data("updateManeMode", updateManeMode); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || {}; // Cache of all non-placeholder option elements, so updateTplOptions // can detach/re-attach them without losing the full list. var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.attr("data-placeholder", "Li şablonekê bigere"); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (name, tpl) { // Shows "name — tpl.desc" when a tplDefs entry has a desc // in data.json, same pattern as steps.pron's template picker. var opt = $("<option></option>") .val(name) .text(tpl.desc ? name + " — " + tpl.desc : name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); // Same status-dot / 🔗 / ⓘ row treatment as every other // template picker. This one carries the bare name in value=, // so the name mapper is the identity rather than a snippet // parse; descriptions come from each template's TemplateData. markTemplateOptions(tplSelect, function (opt) { return opt.val(); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible // ones — native <select> won't reliably hide options any other way. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); // Options that were detached when the descriptions arrived // missed that pass, so describe whatever is attached now. // The cache is warm by this point, so this is synchronous. applyTplDescriptions(tplSelect); tplSelect.trigger("wiktku:refresh"); if (currentVal && !currentStillValid) { tplSelect.val(""); tplTitleInput.hide().val(""); updateManeMode(); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpela hedefê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // Şablon senses have no plain gloss, so hide alternatîv/hevmane/ // dijmane/etc. Etîket, Nimûne and Jêgirtin stay visible either way. function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); nonKuWrap.hide(); tplTitleInput.show().focus(); } else { tplTitleInput.hide().val(""); updateManeMode(); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); // The template picker is an alternative to writing a // definition, not a step before it — so the box comes first // and this sits under it as a quiet link. It only expands // for the minority of senses that are a pointer at another // word (guharto, şaşnivîs, kevnbûyî) rather than a meaning. var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput) .hide(); var tplLink = $("<a href='#' class='wiktku-dfn-tpl-link'></a>") .text("Ev ne pênase ye — şablonek bi kar bîne"); tplLink.on("click", function (e) { e.preventDefault(); tplRow.show(); $(this).hide(); tplRow.find("input.wiktku-ac-input").first().focus(); }); /** Opens the picker without a click — used on restore, when a * sense already has a template and hiding it would make the * chosen value invisible. */ function revealTplRow() { tplRow.show(); tplLink.hide(); } block.data("revealTplRow", revealTplRow); block.append(dfnArea); block.append(nonKuWrap); block.append(tplLink); block.append(tplRow); // Apply lang filter on initial build. updateTplOptions(); updateManeMode(); // — Sub-field groups. — // The four most-used groups (Nimûne, Jêgirtin, Hevmane, Dijmane) // stay open; the rest sit behind the "Malûmatên pêşketî" toggle // (adv: true → .wiktku-dfn-subgroup-adv, keyed off by the collapse CSS). // Jêgirtin isn't in this array — it's a compound widget built // after the loop — but it's inserted right after Nimûne so the // visible order matches the list above. var allGroups = [ { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "wekî etîket lê xuya nabe tenê kategorîze dike", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê", adv: true }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in", adv: true }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e", adv: true }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e", adv: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); if (g.adv) groupDiv.addClass("wiktku-dfn-subgroup-adv"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } // The placeholder names the current language, but that's // often not chosen yet when this block is first built — // so keep a function around that refresh() (and onSubInput, // for newly-grown fields) can call again once lang is set // or changes. function subPlaceholder() { if (g.noLangSuffix) return g.label + "…"; var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return g.label + (langLabel ? " bi " + langLabel : "") + "…"; } function updateSubPlaceholders() { list.find("> li > textarea.wiktku-dfn-subfield").attr("placeholder", subPlaceholder()); } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": ") .append($("<span></span>").addClass("wiktku-dfn-sublabel-hint").text(g.izah)); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var useModifiers = !!MODIFIER_SUBGROUPS[g.cls]; list.data("updatePlaceholders", updateSubPlaceholders); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", subPlaceholder()); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow, useModifiers); }); list.append(useModifiers ? makeModifierLi(firstInput) : $("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder group — growing list, same structure as Nimûne. — (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text("Jêgirtin")) .append(": "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<textarea></textarea>") .addClass("wiktku-dfn-subfield wiktku-dfn-quote-citoid-input") .attr("rows", 1) .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi otomatîk tijî bike", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); // Fetches citation data from Citoid and fills this citation's // şablon + fields — only rebuilds fields on template change, // and never overwrites values the user already typed. function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoid.fetchJederFields(query).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only rebuild if switching şablon, so a repeat fetch // doesn't clear fields already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel wiktku-plain-select"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); srcSel.append($("<option></option>").val("__category__").text("Ji Kategorî:Çavkanî şablonekê hilbijêre")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); // Citoid is only useful before a source is chosen — // hide it once a selection is made, restore on reset. if (chosen) { citoidWrap.hide(); } else { citoidWrap.show(); return; } if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } if (chosen === "__category__") { // Search widget over the members of [[Kategorî:Çavkanî]]. // Picking a şablon here immediately switches the row to // "Bi destê xwe binivîsim" mode with {{Şablon}} pre-filled, var catWrap = $("<span></span>").addClass("wiktku-native-select-wrap wiktku-dfn-quote-src-cat"); var catInput = $("<input type='search' autocomplete='off'>") .addClass("wiktku-start-narrow wiktku-dfn-quote-src-cat-input") .attr("placeholder", "Li navê şablonê bigere…"); var catResults = $("<ul></ul>").addClass("wiktku-ac-results wiktku-dfn-quote-src-cat-results").hide(); var catStatus = $("<span></span>").addClass("wiktku-dfn-quote-src-cat-status").text("Şablon tên barkirin…"); var showCatResults = function (query) { var q = $.trim(query).toLowerCase(); catResults.empty(); var list = catSrcTemplates || []; var matched = q ? $.grep(list, function (name) { return name.toLowerCase().indexOf(q) !== -1; }) : list; if (!matched.length) { catResults.hide(); return; } $.each(matched.slice(0, 50), function (_, name) { var li = $("<li></li>").text(name).attr("data-value", name); var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; e.preventDefault(); selectCatTpl(name); }); li.on("mousedown", function (e) { e.preventDefault(); selectCatTpl(name); }); catResults.append(li); }); catResults.show(); }; // Wraps the chosen şablon as {{Name}}, drops it into the // manual textarea, and switches the row into manual mode // so the user can keep editing it (add params, etc.). var selectCatTpl = function (name) { catResults.hide(); srcSel.val("__manual__"); srcSel.trigger("change"); srcFields.find(".wiktku-dfn-quote-src-manual") .val("{{" + name + "}}") .trigger("focus"); }; catInput.on("input", function () { showCatResults($(this).val()); }); catInput.on("focus", function () { showCatResults($(this).val()); }); catInput.on("blur", function () { setTimeout(function () { catResults.hide(); }, 200); }); catWrap.append(catInput).append(catResults).append(catStatus); srcFields.append(catWrap); fetchCatSrcTemplates().then(function () { catStatus.text(""); }, function () { catStatus.text("Şablon nehatin barkirin."); }); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (key, label) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", key) .attr("placeholder", label + "…"); // "Sernav" / "Sernavê orjînal" (title fields, e.g. for // kitêb/kovar/malper) get a taller, draggable box; every // other field in the template stays as-is. Field labels // come from the on-wiki jederDefs data, so match on the // (diacritic-folded) label text rather than a fixed key. var foldedLabel = foldDiacritics(label); if (/^sernav$/.test(foldedLabel) || /orjin/.test(foldedLabel)) { inp.addClass("wiktku-dfn-quote-src-input--title"); } row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); jederGroupDiv.append(jederLbl).append(jederList); // Straight after Nimûne rather than last: Jêgirtin is the // same kind of thing (an attested use of the word) and the // two belong together — see the allGroups comment above. var nimuneGroup = block.find(".wiktku-dfn-nimune-group"); if (nimuneGroup.length) jederGroupDiv.insertAfter(nimuneGroup); else block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); // ── "Malûmatên pêşketî" — per sense, after Dijmane ─────── // One toggle per sense rather than one for the whole step: // the fields behind it (Etîket, Kategorî, Jornav…) belong to // a single meaning, so a global switch flipped them for every // sense at once and gave a count that answered "across all // senses" — not a question anybody was asking. (function () { block.addClass("wiktku-sense-adv-hidden"); var advRow = $("<div class='wiktku-adv-toggle-row wiktku-sense-adv-row'></div>"); var advToggle = $("<a href='#' class='wiktku-adv-toggle'></a>").attr("aria-expanded", "false"); var advLabel = $("<span class='wiktku-adv-toggle-text'></span>"); advToggle.append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")).append(advLabel); function syncAdv() { var hidden = block.hasClass("wiktku-sense-adv-hidden"); advLabel.text(hidden ? "Malûmatên pêşketî nîşan bide" : "Malûmatên pêşketî veşêre"); advToggle.attr("aria-expanded", hidden ? "false" : "true") .toggleClass("wiktku-adv-open", !hidden); } advToggle.on("click", function (e) { e.preventDefault(); block.toggleClass("wiktku-sense-adv-hidden"); syncAdv(); }); block.data("syncSenseAdv", syncAdv); advRow.append(advToggle); // After the last always-visible group (Dijmane) and before // the advanced ones, which sit below it in DOM order. var lastPrimary = block.find(".wiktku-dfn-dijmane-group"); if (lastPrimary.length) advRow.insertAfter(lastPrimary); else block.append(advRow); syncAdv(); }()); return block; }, /** Shows only `block` among the sense list; hides every other one. */ setOpenSense: function (stepDiv, block) { stepDiv.find("li.wiktku-dfn-sense").each(function () { $(this).toggleClass("wiktku-sense-collapsed", !$(this).is(block)); }); steps.dfn.renderSenseTabs(stepDiv); }, /** Rebuilds the "Mane 1 / Mane 2 / + Mane zêde bike" tab row from the current sense list. */ renderSenseTabs: function (stepDiv) { var tabsDiv = stepDiv.find(".wiktku-dfn-sense-tabs"); if (!tabsDiv.length) return; tabsDiv.empty(); stepDiv.find("li.wiktku-dfn-sense").each(function (i) { var li = $(this); var tab = $("<span class='wiktku-dfn-sense-tab'></span>") .text("Mane " + (i + 1)) .toggleClass("wiktku-tab-active", !li.hasClass("wiktku-sense-collapsed")); tab.on("click", function () { steps.dfn.setOpenSense(stepDiv, li); }); tabsDiv.append(tab); }); var addBtn = $("<button type='button' class='wiktku-add-sense'></button>") .append($("<span class='wiktku-add-sense-plus'>+</span>")) .append(document.createTextNode("Mane zêde bike")); addBtn.on("click", function (e) { e.preventDefault(); steps.dfn.addSense(stepDiv); }); tabsDiv.append(addBtn); }, onDfnInput: function (stepDiv, block, textarea) { refresh(); }, /** Appends a sense, opens it, and hides the others. */ addSense: function (stepDiv) { var list = stepDiv.find("ol.wiktku-dfn-list"); var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); initSelects(newBlock); steps.dfn.setOpenSense(stepDiv, newBlock); newBlock.find("textarea.wiktku-dfn-mane").first().focus(); refresh(); return newBlock; }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow, modifiers) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow, modifiers); }); list.append(modifiers ? makeModifierLi(next) : $("<li></li>").append(next)); // New field starts with no placeholder — give it (and any // others in the list) the current one. var updatePlaceholders = list.data("updatePlaceholders"); if (typeof updatePlaceholders === "function") updatePlaceholders(); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: {}, posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; // One reassurance, shown once for the whole Mane step: the // "an jî şablonek hilbijêre" dropdown inside each sense is // optional — plain text is the normal path. if (!stepDiv.find(".wiktku-dfn-tpl-hint").length) { stepDiv.append( $("<p class='wiktku-step-hint wiktku-dfn-tpl-hint'></p>").text( "Ji bo her maneyekê, dropdown-a \"an jî şablonek hilbijêre\" ne mecbûrî ye — bi gelemperî tu tenê maneyê bi tîpên asayî dinivîsî. Ew şablon tenê ji bo rewşên taybet in (mînak: guherto, kevnbûyî, şaşnivîs); heke tu nizanî kîjan divê, vale bihêle." ) ); } var tabsDiv = $("<div class='wiktku-dfn-sense-tabs'></div>"); stepDiv.append(tabsDiv); var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); steps.dfn.renderSenseTabs(stepDiv); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName === "__category__") { // Reachable only if the user opened the category search but // never picked a şablon — picking one switches the row to // __manual__ (see selectCatTpl above), so there's nothing // meaningful to save here. } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: readList("wiktku-dfn-etiket"), kategori: readList("wiktku-dfn-kategori"), nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense var izahLines = []; // parallel — raw îzah gloss for that same sense // True only once some sense's *actual* dfn text (post tercime/îzah // split) is non-empty. var hasLinkableMane = false; $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("# " + (tplKatTpl ? tplKatTpl + " " : "") + (tplLabelTpl ? tplLabelTpl + " " : "") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(""); // template senses have no îzah return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty // Pull the îzah gloss (if any) out of the combined tercime+îzah // string — it's spliced back in separately below, after its // own linkify pass (see izahLines / the second linkifyText call). var izahRaw = null; var tercimeIzah = splitTercimeIzah(dfn); if (tercimeIzah) { dfn = tercimeIzah.tercime; izahRaw = stripWikilinks(tercimeIzah.izah); } if (dfn) { dfn = stripWikilinks(dfn); // Sentence-case + trailing period are for ku definitions, // which are written as full glosses. if (lang === "ku") { if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } // Real prose — this is what makes the sense worth running // through the main linkify pass. hasLinkableMane = true; } else if (izahRaw === null) { // No mane at all — this is just the "{{mane?|lang}}" // placeholder, a bare template call with no plain words // in it. Do NOT count it as linkable: sending nothing but // bracketed templates through the main linkify pass hangs // the linkify gadget (see the hasLinkableMane/hasIzah // check below). dfn = lang === "ku" ? "{{mane?|" + lang + "}}" : ""; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var out = "# " + (katTpl ? katTpl + " " : "") + (labelTpl ? labelTpl + " " : "") + dfn; var idx = defLines.length; var hasThisIzah = izahRaw !== null && $.trim(izahRaw) !== ""; // Bare {{...}} token — like {{wiktku-cite-N}}, this survives // linkify's first pass untouched (it treats template calls as // opaque), then gets swapped for {{îzah|…}} once the actual // gloss text has been linkified in its own separate pass. if (hasThisIzah) { out += (dfn ? " " : "") + "{{wiktku-izah-" + idx + "}}"; } function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(hasThisIzah ? izahRaw : ""); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } // Runs text through the linkify gadget if it's loaded, otherwise // just passes it through unchanged. Shared by both linkify passes // below (main mane text, and — separately — îzah glosses). function linkifyText(t, cb) { if (typeof $.kuLinkify === "function") { $.kuLinkify(t, cb); } else { cb(t); } } var hasIzah = izahLines.some(function (t) { return t && $.trim(t) !== ""; }); var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with nimûne?. text = "# {{mane?|" + lang + "}}\n#* {{nimûne?|" + lang + "}}\n"; callback(text); return; } // Runs the îzah-only linkify pass against `base` (either the raw // text, when there's no linkable mane to run the main pass on // first, or the already-linkified main text). Shared by both // branches below so the token-splice logic only lives once. function runIzahPass(base) { var izahJoined = $.map(izahLines, function (raw, idx) { if (!raw) return undefined; return "{{wiktku-izah-open-" + idx + "}}" + raw + "{{wiktku-izah-close-" + idx + "}}"; }).join("\n"); linkifyText(izahJoined, function (izahLinked) { var izahByIdx = {}; var re = /\{\{wiktku-izah-open-(\d+)\}\}([\s\S]*?)\{\{wiktku-izah-close-\1\}\}/g; var m; while ((m = re.exec(izahLinked)) !== null) { izahByIdx[parseInt(m[1], 10)] = m[2]; } var withIzah = base.replace(/\{\{wiktku-izah-(\d+)\}\}/g, function (_, n) { var linked = izahByIdx[parseInt(n, 10)]; return linked !== undefined ? "{{îzah|" + linked + "}}" : ""; }); callback(restoreCites(withIzah)); }); } if (!hasLinkableMane) { if (!hasIzah) { // All filled senses are template senses (or otherwise have // no plain text at all) — nothing here needs linkify. callback(restoreCites(text)); return; } // There's no plain mane text anywhere (e.g. tercime left blank // with only îzah filled in), so every defLine is just a bare // template call with nothing to word-link. Sending a line // like "# {{wiktku-izah-0}}" through the main linkify pass // gives it no plain words to work with, makes the linkify // gadget hang — so skip that pass entirely and run only // the îzah pass, splicing straight into the unlinkified text. var loadIzahOnly = function () { runIzahPass(text); }; mw.loader.using("ext.gadget.linkify", loadIzahOnly, loadIzahOnly); return; } var didTryToLoad = function () { // First pass: the main definition text (mane), same as before. linkifyText(text, function (mainLinked) { if (!hasIzah) { callback(restoreCites(mainLinked)); return; } // Second pass: îzah glosses, linkified via their own // separate call. Each gloss is wrapped in its own // {{wiktku-izah-open/close-N}} pair; like the existing // {{wiktku-cite-N}} tokens, these sit inside double // braces so linkify leaves the tokens themselves alone — // only the raw gloss text between each pair gets linked. runIzahPass(mainLinked); }); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, tewandin: { id: "tewandin", name: "tewandin", question_fmt: 'Tewandina "' + pageName + '" binivîse', visible: function (values) { return values.lang && values.pos; }, build: function (stepDiv) { if (stepDiv.find(".wiktku-tewandin-wrap").length) return null; var wrap = $("<div class='wiktku-tewandin-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-tewandin-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-tewandin-text") .attr("rows", 4) .attr("placeholder", "{{ku-tewîn-nav|nêr}}"); wrap.append(ta); stepDiv.append(wrap); function autoPopulate() { if (!ta.length) return; var vals = getValues(); var c = vals.cinsiyet || ""; var p = vals.pos || ""; if (!pageName.includes(" ") && c && GENDER_BASE_LABELS[c] && (p === "navdêr" || p === "serenav") && vals.lang === "ku" && c !== "mndudil") { var label = (c === "mnmane") ? "mê û nêr" : GENDER_BASE_LABELS[c]; var out = "{{ku-tewîn-nav|" + label; if (p === "serenav") out += "|y"; out += "}}"; if (!$.trim(ta.val())) ta.val(out); } } setTimeout(function () { autoPopulate(); $("#wiktku-start-form").on("change.tewandin", "#wiktku-start-lang-field, #wiktku-start-cinsiyet-field, #wiktku-start-pos-field", autoPopulate); }, 0); return ta; }, output: function () { var manualText = $.trim($("#wiktku-start-tewandin .wiktku-tewandin-text").val()); if (manualText) { return "\n==== Tewandin ====\n" + manualText + "\n"; } return ""; } }, // resim — one or more images resim: { id: "resim", name: "resim", question_fmt: "Resmekê lê zêde bike", visible: function (values) { return !!(values.lang && values.pos); }, /** Builds one image row: filename + caption + alt text. */ buildItem: function (stepDiv) { var item = $("<li class='wiktku-resim-item'></li>"); var fileRow = $("<div class='wiktku-posparams-row'></div>"); var fileInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-file") .attr("placeholder", "navê_dosyayê.jpg"); fileRow.append($("<label></label>").text("Navê dosyayê: ")).append(fileInp); var capRow = $("<div class='wiktku-posparams-row'></div>"); var capInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-caption") .attr("placeholder", "Danasîna resimê…"); capRow.append($("<label></label>").text("Danasîn: ")).append(capInp); // Alt text: what a screen reader announces for this image var altRow = $("<div class='wiktku-posparams-row'></div>"); var altInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-alt") .attr("placeholder", "Ji bo kesên nabînin, çi tê dîtin? (ne mecbûrî)"); altRow.append($("<label></label>").text("Nivîsa alternatîf: ")).append(altInp); // Auto-fill the caption with the plain page name when a filename // is typed fileInp.on("input", function () { var file = $.trim($(this).val()); var curCap = $.trim(capInp.val()); var isDefault = !curCap || curCap === pageName; if (file && isDefault) { capInp.val(pageName); } else if (!file && isDefault) { capInp.val(""); } steps.resim.onFileInput(stepDiv, item, this); }); item.append(fileRow).append(capRow).append(altRow); return item; }, /** Grows the image list when the last row's filename gets content. */ onFileInput: function (stepDiv, item, input) { var val = $.trim($(input).val()); var list = stepDiv.find("ol.wiktku-resim-list"); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { list.append(steps.resim.buildItem(stepDiv)); } }, build: function (stepDiv) { if (stepDiv.find(".wiktku-resim-wrap").length) return null; var wrap = $("<div class='wiktku-resim-wrap'></div>"); var list = $("<ol class='wiktku-resim-list'></ol>"); list.append(steps.resim.buildItem(stepDiv)); wrap.append(list); stepDiv.append(wrap); return null; }, /** Reads every filled row from the DOM into an array of {file, caption, alt} * objects — blank rows (missing filename or caption) are skipped. * Non-Kurdish captions get wrapped in {{zim|lang|…}} here, unless * the user already typed their own {{zim|…}} template. Alt text is * optional and left as plain text either way. */ getImages: function (values) { var lang = (values && values.lang) || getValues().lang || ""; var images = []; $("#wiktku-start-resim li.wiktku-resim-item").each(function () { var file = $.trim($(this).find(".wiktku-resim-file").val()); var caption = $.trim($(this).find(".wiktku-resim-caption").val()); var alt = $.trim($(this).find(".wiktku-resim-alt").val()); if (!file || !caption) return; // Strip leading "Wêne:" or "File:" if the user typed it — we add it ourselves. file = file.replace(/^(wêne|file|image)\s*:\s*/i, ""); if (lang && lang !== "ku" && !/^\{\{zim\s*\|/i.test(caption)) { caption = "{{zim|" + lang + "|" + caption + "}}"; } images.push({ file: file, caption: caption, alt: alt }); }); return images; }, output: function (values) { var images = steps.resim.getImages(values); if (!images.length) return ""; return images.map(function (img) { var altPart = img.alt ? "|alt=" + img.alt : ""; return "[[Wêne:" + img.file + "|thumb" + altPart + "|" + img.caption + "]]"; }).join("\n") + "\n"; } }, // bnr-h — {{bnr-h|Page1|Page2|…}} prepended before the lang section (shared, not per-section) bnrh: { id: "bnrh", name: "binêre herwiha (bnr-h)", question_fmt: "Şablona bnr-h li qismê herî jor a rûpelê", //visible: function (values) { return !!values.lang; }, multiple: true, narrow: true, placeholder: "Ji bo 'test' bnr 'Test', 'teşt'", output: function (values) { var pages = $.grep(values.bnrh || [], function (p) { return !!$.trim(p); }); if (!pages.length) return ""; return "{{bnr-h|" + pages.map(function (p) { return $.trim(p); }).join("|") + "}}\n"; } }, bikaranin: { id: "bikaranin", name: "Notên bikaranînê", question_fmt: "Notên bikaranînê yên li ser vê kelîmeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, output: function (values) { var text = $.trim(values.bikaranin || ""); if (!text) return ""; return "\n==== Notên bikaranînê ====\n" + text + "\n"; }, }, xwendin: { id: "xwendin", name: "Bêhtir bixwîne", question_fmt: "Lînkên derveyî eleqedarî vê madeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: function (values) { if (!values || !values.lang) { return `* {{wpedî}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; } const ziman = values.lang === "ku" ? "" : `|ziman=${values.lang}`; return `* {{wpedî${ziman}}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; }, output: function (values) { var text = $.trim(values.xwendin || ""); if (!text) return ""; return "\n==== Bêhtir bixwîne ====\n" + text + "\n"; }, }, alfabeyendin: { id: "alfabeyendin", name: "Bi alfabeyên din", question_fmt: function (values) { var base = "Nivîsîna vê kelîmeyê bi alfabeyên din" var langLabel = values.lang ? getLangLabel(values.lang) : ""; if (langLabel) { return base + " ên " + langLabel; } return base; }, visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: "Ji bo kurmancî: * {{ku-ar|şiklê alfaba erebî}}", output: function (values) { var text = $.trim(values.alfabeyendin || ""); if (!text) return ""; return "\n==== Bi alfabeyên din ====\n" + text + "\n"; }, }, formalt: makeWordListStep("formalt", "formên alternatîv", "Formên alternatîv ên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), hevmane: makeWordListStep("hevmane", "hevmane", "Hevmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), dijmane: makeWordListStep("dijmane", "dijmane", "Dijmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jornav: makeWordListStep("jornav", "jornav", "Jornavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jernav: makeWordListStep("jernav", "jêrnav", "Jêrnavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse"), binereherwiha: makeWordListStep("binereherwiha", "herwiha binêre", "Kelîmeyên din ên eleqedar binivîse"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: {}, visible: function (values) { return values.lang && values.pos; }, // Fills the insert-dropdown from the current etymTpls object. refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(ta); stepDiv.append(wrap); initSelects(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder. // Skip it only when every filled sense is a şablon sense // a completely empty entry with no şablon chosen still gets the placeholder var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasFilledTplSense = dfnSenses.some(function (s) { return !!s.tpl && !!s.tplTitle; }); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (hasFilledTplSense && !hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: function (values) { return {"navz": true, [values.lang]: true} }, // Language dropdown + growing word-input list; a new row appends // when the dropdown gets a value. Mirrors steps.trans, but flat. buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/build below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Attach the searchable picker now the select is in the DOM. initSelects(list); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", question_fmt: "'"+ pageName + "' di zaravayên din de çawa tê gotin?", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: {}, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zaravayekî bigere"); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; // A completely empty entry still gets a placeholder section // to fill in later; an individual placeholder gloss is only // skipped once some other sense already has real content. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", question_fmt: "Tercimeyên vê maneyê bi zimanên din binivîse", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide only when every sense is a filled template sense (no plain // gloss to attach translations to). A mix, or nothing filled in // yet, still shows Werger. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, // Language dropdown + growing word-input list, scoped to one gloss's // group (each gloss has its own group and row list). buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/buildGroup below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, // Builds (or fetches) the .wiktku-trans-group for one gloss. buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, // Syncs one .wiktku-trans-group per current gloss, keyed by // data-gloss-pos so groups stay matched across rebuilds. build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, // Reads all translation rows, grouped by gloss position. getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, // Builds the numbered "{ index, gloss }" list, one per dfn sense // with a real mane (skips template senses). index is 1-based and // matches the sense's position in the "#" definition list. // When nothing's filled in, returns one placeholder entry so // Werger still has a group to attach to; when every sense is a // filled template sense, stays empty (matches trans.visible()). glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane, but other fields are filled — still gets a // gloss group since dfn.getOutput() emits {{mane?}} for it. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // A completely empty entry (nothing filled in dfn at all, no // şablon chosen either) still gets a placeholder Werger section // to fill in later. Only // skip an individual placeholder gloss below when some other // sense actually has real content, making that particular // placeholder redundant. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it. If some other sense already has real // content, this placeholder is redundant — skip it. If the // whole entry is empty, keep it so Werger still gets a // section to fill in. if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, cavkani: { id: "cavkani", name: "çavkanî", question_fmt: "Çavkaniyên din (ne jêgirtin) lê zêde bike", visible: function (values) { return !!values.pos; }, // Fills the insert-dropdown from the members of [[Kategorî:Çavkanî]]. refreshTplSelect: function () { var sel = $("#wiktku-start-cavkani .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(catSrcTemplates || [], function (_, name) { sel.append($("<option></option>").val(name).text(name)); }); markTemplateOptions(sel, function (opt) { return opt.val(); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-cavkani-wrap").length) return null; var wrap = $("<div class='wiktku-cavkani-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-cavkani-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-cavkani-text") .attr("rows", 4) .attr("placeholder", "Şablonekî ji lîsteyê hilbijêre an rasterast binivîse…"); // Template insert dropdown, populated from [[Kategorî:Çavkanî]] — // options refreshed once the category members are fetched. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var status = $("<span class='wiktku-cavkani-status'></span>"); sel.on("change", function () { var name = $(this).val(); if (!name) return; insertAtCursor(ta[0], "\n* {{" + name + "}}"); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(status).append(ta); stepDiv.append(wrap); // build() runs again for every new beş (see the "+ Beş zêde bike" // handler), after the initial page-wide pass — so this select needs // its own init or it stays a plain, unsearchable native <select>. initSelects(wrap); if (catSrcTemplates) { steps.cavkani.refreshTplSelect(); } else { status.text("Şablon tên barkirin…"); fetchCatSrcTemplates().then(function () { steps.cavkani.refreshTplSelect(); status.text(""); }, function () { status.text("Şablon nehatin barkirin."); }); } return ta; }, output: function () { var text = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); if (!text) return ""; return "\n==== Çavkanî ====\n" + text + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); // This array only controls DOM build order — nothing else keys off it // (see the comment above stepIdToGroup). Mane tab order: Mane (senses, // with malûmatên pêşketî nested inside each, see steps.dfn.build) → // Wêne → Bi zaravayên din → Werger, so dfn/resim/zarava/trans sit // adjacent to each other in that order. var ordered_steps = [ steps.lang, steps.pos, steps.posparams, steps.cinsiyet, steps.jimar, steps.lektur, steps.tr, // Mane tab, in reading order: the senses, then the two things that // belong to the entry as a whole rather than to one sense. steps.dfn, steps.tewandin, steps.alfabeyendin, steps.zarava, steps.trans, // Etîmolojî tab. steps.etym, steps.dunde, // Eleqedar tab — three lists of the same shape. steps.je, steps.tekildar, steps.binereherwiha, // Bilêvkirin isn't part of any STEP_GROUPS tab, but still needs a // slot here because this array is what builds the DOM. steps.pron, // Beşên din, behind the picker. steps.resim, steps.bnrh, steps.bikaranin, steps.formalt, steps.hevmane, steps.dijmane, steps.jornav, steps.jernav, steps.cavkani, steps.xwendin]; // ── Step-group tabs ────────────────────────────────────────────────────── // Four tabs: "Mane" holds the senses (whose own blocks carry Nimûne, // Jêgirtin, Hevmane and Dijmane — see steps.dfn.allGroups), Tewandin, // alfabeyendin, zarava and trans; "Etîmolojî" and "Eleqedar" split out // the two other topical clusters; everything else lives behind the // "Beşên din" picker. "mane" stays first as the default-active tab // since Mane is required content. Tewandin keeps its own free-text // {{ku-tewîn-nav}} field and does NOT absorb the Cins/zayend form // parameters (m=/n=/p=), which stay on the headword template. var STEP_GROUPS = [ { id: "mane", label: "Mane", steps: ["dfn", "tewandin", "alfabeyendin", "zarava", "trans"] }, { id: "etimoloji", label: "Etîmolojî", steps: ["etym", "dunde"] }, { id: "eleqedar", label: "Eleqedar", steps: ["je", "tekildar", "binereherwiha"] }, { id: "besendin", label: "Beşên din", steps: ["resim", "formalt", "hevmane", "dijmane", "jornav", "jernav", "bikaranin", "cavkani", "xwendin", "bnrh"] }, ]; // Steps that live behind the "Beşên din" picker — only these need an // explicit "open" before they're shown, even when their tab is active. // Derived from the group above so it can't drift out of sync. var BESENDIN_STEP_IDS = STEP_GROUPS[3].steps; // Reverse lookup: step id -> index into STEP_GROUPS (undefined for // ungrouped steps — now only lang/pos/posparams/cinsiyet/lektur/tr, // which stay always-visible since they're required to get to everything // else). var stepIdToGroup = {}; $.each(STEP_GROUPS, function (gi, g) { $.each(g.steps, function (_, sid) { stepIdToGroup[sid] = gi; }); }); // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "posparams", "cinsiyet", "jimar", "lektur", "tr", "resim", "dfn", "tewandin", "formalt", "bikaranin", "alfabeyendin", "hevmane", "dijmane", "jornav", "jernav", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans", "cavkani", "xwendin" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; // ── Bilêvkirin as a standalone section ─────────────────────────────── // Pronunciation belongs to the word, not to one part of speech, so it // sits beside Navdêr/Lêker in the tab bar rather than inside any of them. // Modelled as a flag rather than an entry in `sections` since // activeSection is used as an array index in many places — viewing // Bilêvkirin leaves activeSection pointing at the POS section you were on. var viewingPron = false; // is it the tab currently on screen // Which STEP_GROUPS tab is currently shown. Lives out here (like // activeSection above) so refresh() — which is not nested inside build() // — can read it and so renderGroupTabs()/updateGroupTabIndicators() below // can be called from refresh() too. Both operate on the tab bar via its // #wiktku-group-tabs id rather than a closured element reference, for the // same reason. var activeGroup = 0; // Unsaved-changes / autosave state. Lives out here (same reason as // activeGroup above) so destroy() — which runs on final submit and on // switching to the source editor, and is not nested inside build() — // can clear the timers and the beforeunload warning. build() assigns // into these; it doesn't re-declare them. var formDirty = false; var autosaveDebounceTimer = null; var autosaveInterval = null; /** Re-renders the step-group tab bar to reflect the current activeGroup. */ function renderGroupTabs() { var groupTabsDiv = $("#wiktku-group-tabs"); if (!groupTabsDiv.length) return; groupTabsDiv.empty(); $.each(STEP_GROUPS, function (i, g) { var tab = $("<span></span>") .addClass("wiktku-group-tab") .attr("data-group-idx", i) .text(g.label) .toggleClass("wiktku-tab-active", i === activeGroup); (function (idx) { tab.on("click", function () { if (idx === activeGroup) return; activeGroup = idx; renderGroupTabs(); if (idx === BESENDIN_GROUP_IDX) renderBesenDinPicker(); refresh(); // Switching tabs can shorten the page (e.g. leaving a long // "Beşên din" field), and the browser may clamp the scroll // position on its own timing before our measurement runs. // Deferring one frame lets that settle first, so the // offsetTop read below is the final, post-refresh one. window.requestAnimationFrame(function () { var bar = document.getElementById("wiktku-group-tabs"); if (!bar) return; var form = document.getElementById("wiktku-start-form"); var stabsH = form ? (parseFloat(form.style.getPropertyValue("--wiktku-stabs-h")) || 0) : 0; var siteHeaderH = form ? (parseFloat(form.style.getPropertyValue("--wiktku-siteheader-h")) || 0) : 0; var top = bar.getBoundingClientRect().top + window.pageYOffset - stabsH - siteHeaderH; $("html, body").animate({ scrollTop: Math.max(0, top) }, 200); }); }); }(i)); groupTabsDiv.append(tab); }); } /** * Toggles a "needs attention" dot on any group tab that still has a * required, unfilled field hidden inside it — so switching tabs doesn't * leave the person wondering why "Bişîne" stays disabled. */ function updateGroupTabIndicators(values) { var tabs = $("#wiktku-group-tabs .wiktku-group-tab"); if (!tabs.length) return; $.each(STEP_GROUPS, function (i, g) { var missing = false; $.each(g.steps, function (_, sid) { var step = steps[sid]; if (!step || !step.required) return; var val = values[sid]; if (val === "" || (step.multiple && $.isArray(val) && val.join("") === "")) { missing = true; } }); tabs.eq(i).toggleClass("wiktku-tab-missing", missing && i !== activeGroup); }); } // "Beşên din" reveals one field at a time via a picker rather than // stacking them all. Per-section state, snapshotted in // saveCurrentSection() and restored in restoreSection() below, and // auto-seeded from any field that already has content (so a returning // draft doesn't hide something already filled in). var openedOtherSections = {}; var BESENDIN_SET = {}; $.each(BESENDIN_STEP_IDS, function (_, sid) { BESENDIN_SET[sid] = true; }); // "besendin"'s index in STEP_GROUPS. Derived rather than hardcoded — // this was a literal 2 and silently pointed at the wrong tab the moment // Etîmolojî and Eleqedar were inserted ahead of it. var BESENDIN_GROUP_IDX = (function () { for (var i = 0; i < STEP_GROUPS.length; i++) { if (STEP_GROUPS[i].id === "besendin") return i; } return STEP_GROUPS.length - 1; }()); /** Re-renders the "Beşên din" picker to list only the not-yet-opened sections. */ function renderBesenDinPicker() { var wrap = $("#wiktku-besendin-picker"); if (!wrap.length) return; wrap.empty(); var pickerValues = getValues(); var unopened = $.grep(BESENDIN_STEP_IDS, function (sid) { if (openedOtherSections[sid]) return false; // Don't offer a section that would open onto nothing: several of // these are gated (Bi zaravayên din / Werger need lang=ku, most // need a pos). refresh() would hide it again straight away, so // picking it would read as a broken dropdown. var step = steps[sid]; if (step && typeof step.visible === "function") { try { if (!step.visible(pickerValues)) return false; } catch (e) { /* a step whose visible() needs DOM we lack yet — offer it */ } } return true; }); if (!unopened.length) return; // everything's open — nothing left to pick var sel = $("<select class='wiktku-besendin-select'></select>"); sel.attr("data-placeholder", "— beşek hilbijêre —"); sel.append($("<option value=''>— beşek hilbijêre —</option>")); $.each(unopened, function (_, sid) { var step = steps[sid]; if (!step) return; sel.append($("<option></option>").val(sid).text(capitalize(step.name))); }); sel.on("change", function () { var sid = $(this).val(); if (!sid) return; openedOtherSections[sid] = true; // Newly opened section moves right under the picker, ahead of // whatever's already open, instead of wherever it happened to // sit in the fixed step order. $("#wiktku-start-" + sid).insertAfter(wrap); renderBesenDinPicker(); refresh(); }); wrap.append(sel); initSelects(wrap); } /** Marks any BESENDIN_STEP_IDS field that already has real content as * "opened", so restoring a draft doesn't bury filled-in sections behind * the picker. Reuses each step's own output() as the emptiness check — * it already knows what "empty" means per field, and it reads the DOM * the restore just populated. Call this AFTER the DOM has the restored * values in it. */ function seedOpenedFromContent() { var values = getValues(); $.each(BESENDIN_STEP_IDS, function (_, sid) { if (openedOtherSections[sid]) return; var step = steps[sid]; if (!step || typeof step.output !== "function") return; try { if (step.output(values)) openedOtherSections[sid] = true; } catch (e) { /* a step whose output() needs more state than we have yet — skip it */ } }); } function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } // Rebuilds the dfn DOM from a previously snapshotted senses array. function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing tab bar + list so build() recreates them cleanly. stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); // The picker is collapsed behind a link by default; a restored // sense that already uses a template has to show it, or the // chosen template is invisible and looks lost. var reveal = block.data("revealTplRow"); if (typeof reveal === "function") reveal(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // dfnArea is the only thing actually saved, so split it back into // tercime/îzah for editing (mirrors syncNonKuToMane's join format). var maneParts = splitTercimeIzah(sense.mane); block.find(".wiktku-dfn-tercime").val(maneParts ? maneParts.tercime : (sense.mane || "")); block.find(".wiktku-dfn-izah").val(maneParts ? maneParts.izah : ""); // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Same for the mane-box mode (plain vs tercime+îzah), since this // also depends on tplSelect's (and lang's) value. var updateMane = block.data("updateManeMode"); if (updateMane) updateMane(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found var useModifiers = !!MODIFIER_SUBGROUPS[cls]; // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true, useModifiers); }); subList.append(useModifiers ? makeModifierLi(ta) : $("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text).each(function () { highlightLinebreak(this); }); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder entries — accepts current array shape or a legacy // single object (older saved sections) for backwards compat. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote).each(function () { highlightLinebreak(this); }); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederCatTpl) { // Legacy format from before the şablon search switched rows to // manual mode directly — convert it the same way now, so it's // editable like any other free-form source. var catSelEl = li.find(".wiktku-dfn-quote-src-sel"); catSelEl.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val("{{" + j.jederCatTpl + "}}"); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); // Restoring a draft opens the first sense's tab by default. steps.dfn.setOpenSense(stepDiv, list.find("li.wiktku-dfn-sense").first()); } // Snapshots simple (non-dfn) per-section steps from the DOM into obj. function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } if (id === "cavkani") { snap.cavkani = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); return; } if (id === "posparams") { snap.posparams = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); return; } if (id === "resim") { // One entry per row, including blank ones, so a mid-edit draft // (e.g. a filename typed but no caption yet) survives a cache // restore instead of being silently dropped. snap.resim = $("#wiktku-start-resim li.wiktku-resim-item").map(function () { return { file: $.trim($(this).find(".wiktku-resim-file").val()), caption: $.trim($(this).find(".wiktku-resim-caption").val()), alt: $.trim($(this).find(".wiktku-resim-alt").val()) }; }).get(); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); // Which "Beşên din" sub-sections this section has already opened // via the picker — per-section, like everything else here. snap.openedOtherSections = $.extend({}, openedOtherSections); sections[activeSection] = snap; } // Restores a previously saved snapshot into the form DOM. function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); $("#wiktku-start-cavkani .wiktku-cavkani-text").val(snap.cavkani || ""); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); steps.posparams.build(ppDiv); var savedTa = snap.posparams || ""; ppDiv.find(".wiktku-posparams-text").val(savedTa); // Re-parse saved textarea to restore helper widget states. if (savedTa) { var cMatch = savedTa.match(/\|c=([^|}\s]+)/); var jMatch = savedTa.match(/\|j=([^|}\s]+)/); var trMatch = savedTa.match(/\|tr=([^|}\s]+)/); // Write into the shared hidden field (not the visible // select, which has no <option>s yet) — syncHelpers() // below reads it back to restore the dropdown once the // gender/number options for this language are populated. if (cMatch) $("#wiktku-start-cinsiyet-field").val(cMatch[1]); if (jMatch) $("#wiktku-start-jimar-field").val(jMatch[1]); if (trMatch) ppDiv.find(".wiktku-posparams-field[data-pp-key='tr']").val(trMatch[1]); // For lêker, c= holds the verb-type code instead of a // gender — split it back across the two dropdowns it is // now assembled from ("x-gh" → form "x" + base "gh"). if (cMatch && /^lêker/.test(snap.pos || "")) { var lekturParts = /^(?:([xphb])-)?(n?gh)$/.exec(cMatch[1]); if (lekturParts) { ppDiv.find(".wiktku-posparams-lektur-sel").val(lekturParts[2]); ppDiv.find(".wiktku-posparams-lekturform-sel").val(lekturParts[1] || ""); } } // Restore checked optional params. "form" is stored as // "erê" rather than "1" (see rebuildTa), so it needs its // own check here. ppDiv.find(".wiktku-posparams-opt-panel input[type='checkbox']").each(function () { var key = $(this).val(); var expected = key === "form" ? "erê" : "1"; $(this).prop("checked", savedTa.indexOf("|" + key + "=" + expected) !== -1); }); } steps.posparams.syncHelpers(ppDiv); return; } if (id === "resim") { var resimDiv = $("#wiktku-start-resim"); resimDiv.find(".wiktku-resim-wrap").remove(); steps.resim.build(resimDiv); // Accept both the new array-of-rows format and the older // single {file, caption} object saved before multi-image // support existed. var resimSnap = snap.resim; var rows = $.isArray(resimSnap) ? resimSnap : (resimSnap ? [resimSnap] : []); if (rows.length) { var list = resimDiv.find("ol.wiktku-resim-list"); list.empty(); $.each(rows, function (_, r) { var item = steps.resim.buildItem(resimDiv); item.find(".wiktku-resim-file").val(r.file || ""); item.find(".wiktku-resim-caption").val(r.caption || ""); item.find(".wiktku-resim-alt").val(r.alt || ""); list.append(item); }); // Always keep a blank trailing row, same as Nimûne/Dûnde. var lastItem = list.children("li.wiktku-resim-item").last(); if ($.trim(lastItem.find(".wiktku-resim-file").val())) { list.append(steps.resim.buildItem(resimDiv)); } } return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Tell the pickers about the programmatic value change. fields.filter("select").trigger("wiktku:refresh"); }); // Restore which "Beşên din" sub-sections were already opened for // this section, then seed in anything the DOM restore above just // filled in but that wasn't marked opened yet. openedOtherSections = $.extend({}, snap.openedOtherSections || {}); seedOpenedFromContent(); renderBesenDinPicker(); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); // Bilêvkirin is NOT emitted here — it is one shared field for the // whole word, so emitting it per section duplicated it. getWikitext() // prints it once, above the POS sections. steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.tewandin.output(values); entry += steps.bikaranin.output(values); entry += steps.alfabeyendin.output(values); entry += steps.formalt.output(values); entry += steps.hevmane.output(values); entry += steps.dijmane.output(values); entry += steps.jornav.output(values); entry += steps.jernav.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); entry += steps.cavkani.output(values); entry += steps.xwendin.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { // Each hop through here can be reached asynchronously: the dfn // step waits on mw.loader.using("ext.gadget.linkify") before // calling back, so from that point on the submit handler's own // try/catch is no longer on the stack. Guard every hop instead, // or a throw after linkify loads vanishes into an unhandled // rejection and the form just sits there looking busy. try { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } catch (e) { if (typeof onSubmitError === "function") onSubmitError(e); else throw e; } } processSection(0); } // Assembles wikitext for all sections plus the shared lang header. function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var bnrh = steps.bnrh.output(sharedValues); var entry = steps.lang.output(sharedValues); // One pronunciation per word, printed once between the language // header and the POS sections — see steps.pron.output. entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // bnr-h goes before the language section — only prepended when // generating fresh wikitext (not addLangMode, which handles it separately). if (!addLangMode && bnrh) entry = bnrh + entry; // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { if (s.mane) return s.mane; // Template sense (e.g. {{guharto|ku|somepage}}) — same // construction as the tplCall built in getOutput, so the // summary shows what actually gets written to the entry // instead of going blank. if (s.tpl && s.tplTitle) { return s.tplNoLang ? "{{" + s.tpl + "|" + s.tplTitle + "}}" : "{{" + s.tpl + "|" + sharedValues.lang + "|" + s.tplTitle + "}}"; } return ""; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; // Set by build() to its submitFailed(). Lives out here because the // wikitext-assembly functions below are outside build()'s closure but // still need a way to report a failure to the person rather than dying // silently in the console. var onSubmitError = null; // Whether Mane/Bi zaravayên din/Werger has anything in it — kept // outside refresh() so the click handler can read the latest value. var wiktkuContentGateOk = true; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues, placeholderText) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>").text(placeholderText || "")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice.label); if (choice.sortKey !== undefined) { // This is a language choice {code, label, sortKey} — show code. displayText = capitalize(choice.label) + " (" + choice.code + ")"; } var option = $(mw.html.element("option", { value: choice.code }, displayText)); if (disabledValues[choice.code]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } // Keys to disable for a key menu: already-taken or explicitly disabled. function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); populateMenus(input, step.keys, getDisabledKeys(step)); // Keep the key menus mutually exclusive: whatever one row selects is // disabled in every other row. Recomputed from the DOM on each change. input.on("change", function () { var all = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield"); var taken = {}; all.each(function () { var v = $(this).val(); if (v) taken[v] = true; }); all.not(this).each(function () { var self = $(this), own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (code) $(this).prop("disabled", !!taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }); // Return the wrapper; the select lives inside it and still fires change. return wrapNativeSelect(input); } // Adds another text field to the list if the last one now has text. function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); if (step.placeholder) { nextInput.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = step.modifiers ? makeModifierLi(nextInput).prepend(nextKeyInput || "") : $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) initSelects(nextItem); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } // Shows/hides steps based on whether their prerequisites are met, and // updates placeholders where applicable. function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); steps.cavkani.refreshTplSelect(); // Re-render any step's question label that depends on current values // (e.g. dfn's Werger-section reminder, which only applies to ku). $.each(steps, function (stepId, step) { if (typeof step.question_fmt === "function") { $("#wiktku-start-" + stepId + " .wiktku-start-step-question") .text(step.question_fmt(values)); } }); // Sync every sense block's mane-box mode (plain mane vs tercime+îzah) // to the current language, in case lang changes after blocks exist. $("#wiktku-start-dfn li.wiktku-dfn-sense").each(function () { var updateMane = $(this).data("updateManeMode"); if (updateMane) updateMane(); }); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Re-sync the "<label> bi <ziman>…" placeholder on every always-visible // sub-field list (etîket, kategorî, hevmane, …), since the language may // not have been chosen yet when these lists were first built, or may // have changed since. $("#wiktku-start-dfn .wiktku-dfn-sublist").each(function () { var upd = $(this).data("updatePlaceholders"); if (typeof upd === "function") upd(); }); // Same idea for word-list steps (jê, têkildar, binêre herwiha, …) // whose placeholder is a function of the current language. $.each(steps, function (stepId, step) { if (typeof step.placeholder === "function") { $("#wiktku-start-" + stepId + " textarea.wiktku-start-step-field") .attr("placeholder", step.placeholder()); } }); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // Insert after the quote textarea's resize-wrap (if the manual // resize handle has already been attached to it), not after the // bare textarea -- otherwise this lands *inside* that wrap, // between the textarea and its own grip, breaking jêgirtin's // handle and nesting the tr/t boxes inside it. var quoteTa = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap = quoteTa.closest(".wiktku-resize-wrap"); (quoteResizeWrap.length ? quoteResizeWrap : quoteTa).after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // See the tr-field branch above for why this targets the // resize-wrap instead of the bare textarea. var quoteTa2 = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap2 = quoteTa2.closest(".wiktku-resize-wrap"); (quoteResizeWrap2.length ? quoteResizeWrap2 : quoteTa2).after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { var groupIdx = stepIdToGroup[stepId]; var hiddenByTab = (groupIdx !== undefined && groupIdx !== activeGroup) || // Beşên din picker: stays hidden even while its tab is // active until explicitly opened from the dropdown. (BESENDIN_SET[stepId] && !openedOtherSections[stepId]); // Bilêvkirin is its own section now, so the two views are // mutually exclusive: on it, only pron shows (plus Ziman, which // is shared and stays above every section); off it, pron is // hidden no matter which tab is active. pron is deliberately // ungrouped — stepIdToGroup has no entry for it — so without // this branch it would show on all four tabs at once. if (stepId === "pron") { hiddenByTab = hiddenByTab || !viewingPron; } else if (viewingPron && stepId !== "lang") { hiddenByTab = true; } if (hiddenByTab || (typeof(step.visible) === "function" && !step.visible(values))) { $("#wiktku-start-" + stepId).hide(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } // After build, sync the posparams helper widgets whenever pos or lang changes. if (step.id === "posparams" && typeof step.syncHelpers === "function") { step.syncHelpers(stepDiv); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } stepDiv.slideDown(); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); // The four content tabs belong to a POS section — Bilêvkirin has no // sub-tabs of its own, so the bar goes away while it's on screen. $("#wiktku-group-tabs").toggle(!!values.pos && !viewingPron); var besenDinActive = activeGroup === BESENDIN_GROUP_IDX && !viewingPron; $("#wiktku-besendin-picker").toggle(besenDinActive); // The option list is filtered by each step's visible(), which depends // on lang/pos — so it has to be rebuilt when those change, not just // when a section is opened. Safe to call from here: rendering the // picker doesn't itself call refresh(), only picking an option does. if (besenDinActive) renderBesenDinPicker(); updateGroupTabIndicators(values); continueBtn.setDisabled(!canContinue); // Soft gate: stays a real, clickable OOUI button — a hard // setDisabled(true) here would swallow the click entirely, leaving // no way to tell the person why nothing happened. The CSS-only // "looks disabled" class lets the click handler still run and show // wiktkuNotify's explanation. wiktkuContentGateOk = !canContinue || hasMinRequiredContent(values); continueBtn.$element.toggleClass("wiktku-btn-soft-disabled", !wiktkuContentGateOk); } function destroy() { if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); if (autosaveInterval) clearInterval(autosaveInterval); formDirty = false; $(window).off("beforeunload.wiktkuUnsaved"); $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard").slideDown(); // #editform was kept laid-out but off-screen (see build()) instead of // display:none, precisely so the editor never had to size itself // against a zero-width/height box. Just bring it back on-screen — // no slideDown needed since it was never actually collapsed. $("#editform").removeClass("wiktku-offscreen"); // Belt-and-braces: if WikiEditor/CodeMirror/mobile's auto-grow still // cached a stale size from some earlier point, nudge them to // recalculate now that the box is genuinely visible. $(window).trigger("resize"); if (window.CodeMirror) { var cm = $("#wpTextbox1").data("CodeMirror") || $("#wpTextbox1").data("cmInstance"); if (cm && typeof cm.refresh === "function") cm.refresh(); } $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and navz. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; // Inserts a new "== {{ziman|code}} ==" section at the correct sorted // position: navz, then ku/hac/sdh/lki/ckb/zza, then alphabetical by name. function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections — just write the new section. // Add \n\n only when there is real non-whitespace content above. var trimmed = existing.replace(/\s+$/, ""); return trimmed ? trimmed + "\n\n" + wikitext : wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // (?![\s\S]) matches only true end-of-string, since a bare "$" with // /m would stop at the section's first line break instead. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections, each separated by exactly \n\n. // Trim trailing whitespace off each section's content first so we // control the spacing precisely. var joined = sections.map(function (s) { return s.content.replace(/\s+$/, ""); }).join("\n\n"); // Only add a separator after the preamble when it has real content. var preambleTrimmed = preamble.replace(/\s+$/, ""); var prefix = preambleTrimmed ? preambleTrimmed + "\n\n" : ""; return prefix + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê zimanekî nû li rûpelê îlawe bikî. Eger ev ziman jixwe hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bike, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Muhtewaya rûpelê paqij bike (her tiştî jê bibe û rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); // Tab bar for switching between step-groups (topics) within a section. // renderGroupTabs()/updateGroupTabIndicators() (which populate and // maintain it) live outside build() — see near "var activeSection". var groupTabsDiv = $("<div id='wiktku-group-tabs'></div>"); // Both tab bars are sticky (CSS). group-tabs' sticky "top" has to sit // right below section-tabs' actual rendered height, which isn't a // fixed number since the bar can wrap onto a second line. Measured // here and published as a CSS custom property the stylesheet reads // back; recomputed on content changes and window resize. // // Vector 2022 has its own sticky header (.vector-sticky-header) that // pins to the real top:0 once you scroll past the page title, which // would otherwise sit directly behind (and hide) our section-tabs. // Fixed by measuring how much of the viewport Vector's header // currently occupies and offsetting both our bars below it, via // --wiktku-siteheader-h. Vector's header slides in/out with scroll // position, so this is re-measured on scroll too, not just resize. function siteHeaderOffset() { var el = document.querySelector(".vector-sticky-header"); if (!el) return 0; var rect = el.getBoundingClientRect(); // Present in the DOM at all times on Vector 2022, but only // actually occupying screen space once scrolled into place — // before that it sits translated above the viewport (negative/ // zero rect), which must not add a phantom gap under our bars. if (rect.bottom <= 0 || rect.top > 4) return 0; return Math.max(0, rect.bottom); } var stickyOffsetQueued = false; function syncStickyTabsOffset() { var h = sectionTabsDiv.is(":visible") ? (sectionTabsDiv.outerHeight() || 0) : 0; startForm.css("--wiktku-stabs-h", h + "px"); startForm.css("--wiktku-siteheader-h", siteHeaderOffset() + "px"); } function queueStickyTabsOffsetSync() { if (stickyOffsetQueued) return; stickyOffsetQueued = true; window.requestAnimationFrame(function () { stickyOffsetQueued = false; syncStickyTabsOffset(); }); } $(window).on("resize.wiktkuStickyTabs scroll.wiktkuStickyTabs", queueStickyTabsOffsetSync); // "Beşên din" picker — sits right under the group tab bar, only // shown while that tab is active (toggled in refresh(), see // BESENDIN_GROUP_IDX); renderBesenDinPicker() fills it. var besenDinPickerDiv = $("<div id='wiktku-besendin-picker' class='wiktku-besendin-picker'></div>"); /** Puts the form back in a usable state after a failed submit and * says what happened. Without this the button stays disabled and * the spinner spins forever on any exception — the person is left * staring at a form that looks busy but is dead, with the reason * visible only in the browser console. */ function submitFailed(err) { spinner.hide(); continueBtn.setDisabled(false); continueBtn.$element.removeClass("wiktku-btn-sending"); var detail = (err && (err.message || err.toString())) || "sedem nediyar"; mw.notify( "Şandin bi ser neket: " + detail + " — tiştê ku te nivîsî winda nebûye. Heke ev dubare bibe, " + "bi 'Edîtora çavkaniyê veke' berdewam bike.", { type: "error", tag: "wiktku-submit", autoHide: false } ); // Deliberately console.error as well: the notification is for the // person, this is for whoever they report the bug to. if (window.console && console.error) console.error("[wiktku] submit failed", err); } onSubmitError = submitFailed; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); continueBtn.$element.addClass("wiktku-btn-sending"); spinner.show(); try { getWikitext(function (wikitext) { try { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page — write fresh content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // ── bnr-h merge ────────────────────────────────────────── // If the user filled bnr-h inputs, either merge into the // existing {{bnr-h|…}} call or prepend a new one. var bnrhOut = steps.bnrh.output(getValues()); if (bnrhOut) { var newPages = bnrhOut.replace(/^\{\{bnr-h\|/, "").replace(/\}\}\n?$/, "").split("|"); var bnrhRe = /\{\{bnr-h\|([^}]*)\}\}/i; if (bnrhRe.test(existing)) { existing = existing.replace(bnrhRe, function (_, inner) { var existingPages = inner.split("|").map(function (p) { return p.trim(); }); $.each(newPages, function (_, p) { p = p.trim(); if (p && existingPages.indexOf(p) === -1) existingPages.push(p); }); return "{{bnr-h|" + existingPages.join("|") + "}}"; }); } else { existing = bnrhOut + existing; } } // If this language's section already exists (whitespace // differences aside), merge into it; otherwise insert new. var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); } catch (e) { // Thrown while writing the result into #wpTextbox1. submitFailed(e); } }); } catch (e) { // Catches anything thrown synchronously inside getWikitext. submitFailed(e); } }); // Tracks whether groupTabsDiv has been inserted yet. var groupTabsInserted = false; $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); var nameH3 = $("<h3></h3>").addClass("wiktku-start-step-name"); var nameLabel = $("<label></label>") .attr("for", "wiktku-start-" + step.id + "-field") .text(name); nameH3.append(nameLabel); stepDiv.append(nameH3); if (step.question_fmt) { // question_fmt can be a plain string, or a function of the // current values (used by steps whose question text depends // on e.g. the chosen language) — refresh() keeps it in sync // afterwards via the .wiktku-start-step-question class. var questionText = typeof step.question_fmt === "function" ? step.question_fmt(getValues()) : step.question_fmt; stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, questionText))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); // initSelects() runs over the whole form once it is in the DOM. stepDiv.append(input); } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.placeholder) { input.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append(step.modifiers ? makeModifierLi(input) : $("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Section tabs (switch between POS sections) sit above the // per-section fields, starting at "pos". if (step.id === "pos") { startForm.append(sectionTabsDiv); } // Step-group tabs sit just before the first grouped step in // ordered_steps. Derived from stepIdToGroup so this keeps // working no matter how STEP_GROUPS/ordered_steps get reordered. if (!groupTabsInserted && stepIdToGroup[step.id] !== undefined) { startForm.append(groupTabsDiv); startForm.append(besenDinPickerDiv); groupTabsInserted = true; } startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); /** Adds a new, empty POS section and switches to it. */ function addPosSection() { saveCurrentSection(); viewingPron = false; sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); return; } if (id === "resim") { $("#wiktku-start-resim .wiktku-resim-wrap").remove(); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); stepDiv.find("select.wiktku-start-step-field").trigger("wiktku:refresh"); }); // Fresh section — no "Beşên din" sub-section has been opened yet. openedOtherSections = {}; renderBesenDinPicker(); renderSectionTabs(); refresh(); } addSectionBtn.on("click", addPosSection); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); syncStickyTabsOffset(); return; } sectionTabsDiv.show(); // Bilêvkirin leads the bar, ahead of the POS sections. var pronTab = $("<span></span>") .addClass("wiktku-section-tab wiktku-section-tab-pron") .text("Bilêvkirin") .toggleClass("wiktku-tab-active", viewingPron); pronTab.on("click", function () { if (viewingPron) return; saveCurrentSection(); viewingPron = true; refresh(); renderSectionTabs(); }); sectionTabsDiv.append(pronTab); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection && !viewingPron); (function (idx) { tab.on("click", function () { if (idx === activeSection && !viewingPron) return; // Leaving Bilêvkirin doesn't need a save — its field // is shared and never part of a section snapshot. if (!viewingPron) saveCurrentSection(); viewingPron = false; activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); syncStickyTabsOffset(); } renderSectionTabs(); /** * Re-populates a dynamically-growing "multiple" field list (bnrh, je, * tekildar, …) from a saved array of strings. Sets each value via * .val() + a triggered "input" event rather than touching the DOM * structure directly, so the normal refreshForTextField() growth * logic adds exactly as many rows as needed — the same thing that * happens when a person types into the last (empty) row. */ function restoreMultiField(id, values) { var container = $("#wiktku-start-" + id); $.each(values || [], function (i, v) { var field = container.find(".wiktku-start-step-field").eq(i); if (!field.length || !v) return; field.val(v).trigger("input"); }); } /** * Restores a full cached draft: shared lang/pron/bnrh fields, then * every section (via the same restoreSection()/refresh()/ * renderSectionTabs() sequence already used when switching tabs). * @param cached {{lang: string, pron: string, bnrh: Array, sections: Array, activeSection: number}} */ function restoreFromCache(cached) { if (cached.lang) { $("#wiktku-start-lang-field").val(cached.lang); $("#wiktku-start-lang-field").trigger("wiktku:refresh"); } // Rebuild dependent steps (pos, pron wrap, etc.) now that lang is set. refresh(); if (cached.pron !== undefined) { $("#wiktku-start-pron .wiktku-pron-text").val(cached.pron); } if (cached.bnrh) { restoreMultiField("bnrh", cached.bnrh); } sections = (cached.sections && cached.sections.length) ? cached.sections : [{}]; activeSection = (typeof cached.activeSection === "number" && cached.activeSection >= 0 && cached.activeSection < sections.length) ? cached.activeSection : 0; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); updateLastSavedIndicator(cached.savedAt || null); formDirty = false; wiktkuNotify("Danûstandina berê ya qeydkirî ji cache hate barkirin.", { type: "info", tag: "wiktku-cache-restore" }); } // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); // A new cureyê rêzimanî means any previously chosen cinsiyet/ // cureyê lêkerê no longer applies — clear both selections (and // the shared hidden cinsiyet field, since rebuildTa()/syncHelpers() // fall back to it) before wiping the textarea, so nothing stale // gets carried over into the rebuilt template. var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-cinsiyet-sel").val(""); ppDiv.find(".wiktku-posparams-jimar-sel").val(""); ppDiv.find(".wiktku-posparams-lektur-sel").prop("selectedIndex", 0); ppDiv.find(".wiktku-posparams-lekturform-sel").prop("selectedIndex", 0); $("#wiktku-start-cinsiyet-field").val(""); $("#wiktku-start-jimar-field").val(""); ppDiv.find(".wiktku-posparams-text").val(""); // refresh() runs steps.posparams.syncHelpers(), which toggles the // param rows for the new pos and — since the textarea is now // empty — calls rebuildTa() to repopulate it. refresh(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { // Immediate feedback that the click registered continueBtn.$element.addClass("wiktku-btn-flash"); setTimeout(function () { continueBtn.$element.removeClass("wiktku-btn-flash"); }, 500); // Ziman/Cureyê rêzimanî already block submission via the real // OOUI setDisabled (see canContinue in refresh()) — this is a // second, softer check that still lets the click through so we // can explain why, instead of the button just silently doing nothing. if (!wiktkuContentGateOk) { wiktkuNotify( "Berî şandinê, tiştekî binivîse: Mane, Bi zaravayên din, an jî Werger — kêmasî yek ji van sê beşan divê tijî be.", { type: "warn", tag: "wiktku-mincontent" } ); return; } wiktkuNotify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", flags: [ "destructive" ], }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Cache save/clear buttons ───────────────────────────────────────── // Manual, page-scoped save of the entire wizard (all sections, not // just the active one) via [[MediaWiki:Gadget-StorageUtils.js]]'s // ObjectStorage. Restoring happens silently on load at the end of // build(), once the full language list is available. // // Saving also happens automatically (debounced while typing, plus a // periodic fallback) — see "Autosave" below — since relying on the // person to remember to click "Li cache qeyd bike" before an // accidental tab close/reload defeats the point of having a cache // at all. function buildCacheSnapshot() { return { lang: getValues().lang || "", pron: $("#wiktku-start-pron .wiktku-pron-text").val() || "", // bnrh is shared (page-level), same as lang/pron above — not // per-section, so it doesn't live in sections[]. bnrh: getValuesForStep("bnrh"), sections: sections, activeSection: activeSection, savedAt: Date.now() }; } // ── Last-saved indicator ───────────────────────────────────────────── var lastSavedEl = $("<span id='wiktku-last-saved'></span>"); function formatSavedTime(ts) { try { return new Date(ts).toLocaleTimeString(mw.config.get("wgUserLanguage"), { hour: "2-digit", minute: "2-digit" }); } catch (e) { return new Date(ts).toLocaleTimeString(); } } function updateLastSavedIndicator(ts) { lastSavedEl.text(ts ? ("Cache: qeydkirî di saet " + formatSavedTime(ts) + " de") : ""); } // ── Dirty-state tracking + autosave ────────────────────────────────── // formDirty mirrors "does the live form differ from what's in cache". // Anything the person types/selects sets it; a successful save (auto // or manual) clears it; destroy() (final submit, or switching to the // source editor) also clears it since the wizard's job is over at // that point either way. formDirty/autosaveDebounceTimer/autosaveInterval // are declared in the outer scope (near activeGroup) — assigned here, // not re-declared — so destroy() can reach them too. var AUTOSAVE_DEBOUNCE_MS = 8000; // save shortly after typing pauses var AUTOSAVE_INTERVAL_MS = 60000; // …and at least this often regardless function performAutosave() { if (!formDirty) return; saveCurrentSection(); try { formCache.Set(buildCacheSnapshot()); formDirty = false; updateLastSavedIndicator(Date.now()); } catch (e) { // Silent on autosave failure (storage blocked/full, etc.) — the // manual button still surfaces a proper error if the person // tries it directly, no need to interrupt typing with a toast. } } function scheduleAutosave() { formDirty = true; if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = setTimeout(performAutosave, AUTOSAVE_DEBOUNCE_MS); } startForm.on("input change", "input, textarea, select", scheduleAutosave); autosaveInterval = setInterval(performAutosave, AUTOSAVE_INTERVAL_MS); // Warn on accidental tab close/reload while there's anything unsaved. $(window).on("beforeunload.wiktkuUnsaved", function (e) { if (!formDirty) return undefined; e.preventDefault(); e.returnValue = ""; return ""; }); var saveCacheBtn = new OO.ui.ButtonWidget({ label: "Li cache qeyd bike", title: "Halê vê formê yê niha (ziman, bilêvkirin û hemû beş) li cache (localStorage) qeyd bike, da ku eger rûpel bêyî xwestin were girtin an ji nû ve were barkirin, tu karibî berdewam bikî." }); saveCacheBtn.on("click", function () { saveCurrentSection(); // ObjectStorage.Set() doesn't return a success/failure value, so // the only way to detect a real failure (storage blocked, quota // exceeded, JSON.stringify choking on something unexpected) is to // catch it here rather than inspect a (nonexistent) return value. try { var snapshot = buildCacheSnapshot(); formCache.Set(snapshot); formDirty = false; updateLastSavedIndicator(snapshot.savedAt); wiktkuNotify("Halê formê li cache hate qeydkirin.", { type: "success", tag: "wiktku-cache-save" }); } catch (e) { mw.notify("Qeydkirina li cache bi ser neket.", { type: "error", tag: "wiktku-cache-save" }); } }); var clearCacheBtn = new OO.ui.ButtonWidget({ label: "Cache paqij bike", flags: [ "destructive" ], title: "Datayên qeydkirî yên vê rûpelê ji cache jê bibe (forma ku niha xuya dike naguherîne)." }); clearCacheBtn.on("click", function () { formCache.Set({}); // The live form still has whatever the person typed — it's just no // longer backed up anywhere, so treat this like a fresh unsaved edit. formDirty = true; updateLastSavedIndicator(null); wiktkuNotify("Cache hate paqijkirin.", { type: "success", tag: "wiktku-cache-clear" }); }); // ── "⋯" overflow ───────────────────────────────────────────── // One primary action and one secondary stay on the bar; everything // else moves in here, to avoid four same-weight buttons crowding // (and wrapping to three rows on a phone). var moreBtn = $("<button type='button' class='wiktku-more-btn' title='Vebijarkên din'>⋯</button>"); var moreMenu = $("<div class='wiktku-more-menu'></div>").hide(); /** Moves an existing OOUI button into the overflow menu, keeping its * handlers — the widgets already carry the behaviour, so this is * purely about where they are shown. */ function intoMenu(btn, extraClass) { var row = $("<div class='wiktku-more-item'></div>"); if (extraClass) row.addClass(extraClass); btn.$element.on("click", function () { moreMenu.hide(); }); row.append(btn.$element); moreMenu.append(row); } intoMenu(saveCacheBtn); intoMenu(clearCacheBtn, "wiktku-more-item-danger"); moreMenu.append($("<div class='wiktku-more-sep'></div>")); moreMenu.append($("<div class='wiktku-more-item wiktku-more-note'></div>").append(lastSavedEl)); moreBtn.on("click", function (e) { e.preventDefault(); e.stopPropagation(); var open = moreMenu.is(":visible"); moreMenu.toggle(!open); if (!open) { setTimeout(function () { $(document).one("click.wiktkuMore", function () { moreMenu.hide(); }); }, 0); } }); var moreWrap = $("<span class='wiktku-more-wrap'></span>").append(moreBtn).append(moreMenu); footer.append(moreWrap); // Icon-only settings button — opens the Tercîh dialog. Plain OOUI // icon names depend on which icon-pack module happens to be loaded, // so this uses the actual Codex "settings" (color-subtle) SVG from // Commons directly, the same way the spinner above hotlinks its gif. var prefsBtn = $("<button></button>", { type: "button", "class": "wiktku-prefs-btn", title: "Tercîh — sazkariyên vê amûrê biguherîne" }); prefsBtn.on("click", function (e) { e.preventDefault(); wiktkuOpenPrefsDialog(); }); // The gear is icon-only on the bar; inside a text menu it needs a // label like everything else around it. prefsBtn.on("click", function () { moreMenu.hide(); }); moreMenu.prepend($("<div class='wiktku-more-sep'></div>")); moreMenu.prepend($("<div class='wiktku-more-item wiktku-more-item-prefs'></div>") .append(prefsBtn) .append($("<span class='wiktku-more-item-label'></span>").text("Tercîh"))); startForm.append(footer); // NOTE: deliberately NOT .hide() (display:none). WikiEditor/CodeMirror/ // the mobile editor's auto-grow logic measure #wpTextbox1's real // dimensions during their own init, which happens while the wizard is // up. A display:none ancestor reports 0 for offsetWidth/offsetHeight/ // scrollHeight, so those scripts bake in a near-zero height that never // gets recalculated later — slideDown() in destroy() only animates the // outer box, it doesn't re-trigger their sizing. Pushing #editform // off-screen instead keeps it laid out (real width/height available to // measure) without being visible, so the editbox opens at full size. $("#editform").addClass("wiktku-offscreen").before(startForm); // renderGroupTabs() looks up #wiktku-group-tabs via a live DOM // selector, so it must run after startForm is actually in the document. renderGroupTabs(); renderBesenDinPicker(); // One pass over the whole form: every select that hasn't already been // initialised, and isn't opted out with .wiktku-plain-select, gets // the searchable picker. initSelects(startForm); refresh(); // Give every draggable textarea a custom resize grip (works // consistently on Safari/iOS, unlike the native corner grip — see // the "Manual drag-to-resize handle" comment in styles.css), and // keep applying it to textareas added later on (new sense blocks, // quote-source fields, nimûne rows, …). wiktkuInitManualResize(startForm); new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { $(mutation.addedNodes).each(function () { if (this.nodeType !== 1) return; wiktkuInitManualResize(this); }); }); }).observe(startForm[0], { childList: true, subtree: true }); // Now that the full language list is loaded, silently restore any // draft the editor previously saved for this page. var cachedDraft = formCache.Get(); if (cachedDraft && cachedDraft.sections && cachedDraft.sections.length) { restoreFromCache(cachedDraft); } } mw.loader.using(["oojs-ui-core"], function () { function wiktkuProceedWithData(wiktkuData) { var d = wiktkuData || {}; // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Jimar (number) code definitions — same shape as the wiki's // own Lua number-type table (code -> {cat, display[, req]}). if (d.numberLabels) $.extend(NUMBER_LABELS, d.numberLabels); // Populate lang choices (pinned list). if (d.langChoices) steps.lang.choices = choicesFromObject(d.langChoices, true); // Populate langsByCode and merge full language list from d.ziman. // d.ziman is a {code: name} object with all known languages. $.each(steps.lang.choices, function (i, choice) { if (choice.sortKey === undefined) choice.sortKey = choice.label; langsByCode[choice.code] = choice; }); if (d.ziman) { var pinnedCodes = {}; $.each(steps.lang.choices, function (i, c) { pinnedCodes[c.code] = true; }); var extraChoices = []; $.each(d.ziman, function (code, name) { if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; if (pinnedCodes[code]) return; var choice = { code: code, label: name, sortKey: name }; extraChoices.push(choice); langsByCode[code] = choice; }); extraChoices.sort(function (a, b) { return a.sortKey.localeCompare(b.sortKey, userLang); }); steps.lang.choices = steps.lang.choices.concat(extraChoices); } // Keep the full merged list around for trans/dunde/zarava — those // should still be able to reference any language even when the // Tercîh panel restricts the main "ziman" step below — then, if // the user set a restriction there, narrow steps.lang.choices // itself to just those codes. var wiktkuFullLangChoices = steps.lang.choices; if (wiktkuPrefs.langCodes && wiktkuPrefs.langCodes.length) { var wiktkuAllowedLangSet = {}; $.each(wiktkuPrefs.langCodes, function (i, code) { wiktkuAllowedLangSet[code] = true; }); var wiktkuRestrictedChoices = $.grep(wiktkuFullLangChoices, function (c) { return !!wiktkuAllowedLangSet[c.code]; }); // Fall back to the full list instead of showing an empty // dropdown if none of the saved codes matched anything // (typo'd code, data.json changed since, …). steps.lang.choices = wiktkuRestrictedChoices.length ? wiktkuRestrictedChoices : wiktkuFullLangChoices; } // Populate POS choices — also a plain {code: label} object in data.json. if (d.posChoices) steps.pos.choices = choicesFromObject(d.posChoices, false); // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the full language list // (not the possibly Tercîh-restricted steps.lang.choices). steps.trans.keys = wiktkuFullLangChoices; steps.dunde.keys = wiktkuFullLangChoices; steps.zarava.keys = getZaravaKeys(wiktkuFullLangChoices); build(); } // data.json ships inside this package module, so it is already parsed // and in memory — no action=raw round trip, and no Testing switch to // forget to flip back before deploying. wiktkuProceedWithData(require("./start/data.json")); }); }); //</nowiki> hzxuxawhn9etn9slqw1xez2bslzs8zt 6333855 6333854 2026-08-15T17:45:30Z Wikihez 7344 6333855 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. // implicit dependencies: StorageUtils (ObjectStorage) //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var addLangMode = mw.util.getParamValue("wiktkuaddlang") === "1"; // ── Tercîh (user settings) panel stored via mw.storage (localStorage), globally var WIKTKU_PREFS_KEY = "wiktku_start_prefs"; var WIKTKU_PREFS_DEFAULTS = { // [] = show the full language list in the "ziman" step; otherwise // only these codes are shown there (data.json codes, not names). langCodes: [], // true = never auto-open on a new/empty page — only via the // "+Ziman/beşeke din" portlet link. onlyOnClick: false, // "auto" | "p-cactions" | "p-tb" | "p-views" — where the // "+Ziman/beşeke din" portlet link is added. portlet: "auto", // true = suppress routine/informational mw.notify toasts (page // loading, cache auto-restored, cache saved/cleared, "tê şandin…"). // Errors and direct results of an explicit action (like saving // Tercîh itself) always show regardless of this setting. quiet: false }; function wiktkuLoadPrefs() { if (!(window.mw && mw.storage)) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var raw; try { raw = mw.storage.get(WIKTKU_PREFS_KEY); } catch (e) { raw = null; } if (!raw) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var parsed; try { parsed = JSON.parse(raw); } catch (e) { parsed = {}; } return $.extend({}, WIKTKU_PREFS_DEFAULTS, parsed); } function wiktkuSavePrefs(prefs) { if (!(window.mw && mw.storage)) return false; try { mw.storage.set(WIKTKU_PREFS_KEY, JSON.stringify(prefs)); return true; } catch (e) { return false; } } var wiktkuPrefs = wiktkuLoadPrefs(); // Routine/informational notices go through here so "quiet mode" can // suppress them; errors and explicit-action confirmations (like the // Tercîh save toast) call mw.notify directly instead, and always show. function wiktkuNotify(message, options) { if (wiktkuPrefs.quiet) return; mw.notify(message, options); } // Lazily built the first time it's opened; reused after that (see // wiktkuOpenPrefsDialog below, defined once we know OOUI is available). var wiktkuPrefsWindowManager = null; var wiktkuPrefsDialog = null; function wiktkuOpenPrefsDialog() { mw.loader.using(["oojs-ui-core", "oojs-ui-windows"], function () { function WiktkuPrefsDialog(config) { WiktkuPrefsDialog.super.call(this, config); } if (!wiktkuPrefsDialog) { OO.inheritClass(WiktkuPrefsDialog, OO.ui.ProcessDialog); WiktkuPrefsDialog.static.name = "wiktkuPrefsDialog"; WiktkuPrefsDialog.static.title = "Tercîhên min"; WiktkuPrefsDialog.static.actions = [ { action: "save", label: "Qeyd bike", flags: ["primary", "progressive"] }, { action: "cancel", label: "Betal bike", flags: "safe" } ]; WiktkuPrefsDialog.prototype.initialize = function () { WiktkuPrefsDialog.super.prototype.initialize.call(this); this.langCodesInput = new OO.ui.TextInputWidget({ placeholder: "ku, zza, ckb (vala bihêle ji bo hemû zimanan)" }); this.onlyOnClickCheckbox = new OO.ui.CheckboxInputWidget({}); this.quietCheckbox = new OO.ui.CheckboxInputWidget({}); this.portletDropdown = new OO.ui.DropdownInputWidget({ options: [ { data: "auto", label: "Otomatîk (li gorî rûyê wîkiyê)" }, { data: "p-cactions", label: "p-cactions - Li qismê Amûran" }, { data: "left-navigation", label: "left-navigation - Li qismê Gotar-Gotûbêj" }, { data: "p-tb", label: "p-tb - Li qismê Giştî" }, { data: "p-views", label: "p-views - Li qismê Bixwîne" } ] }); var fieldset = new OO.ui.FieldsetLayout({ label: "Eyar" }); fieldset.addItems([ new OO.ui.FieldLayout(this.langCodesInput, { label: "Kodên zimanan ku tê xuyakirin li qismê \"ziman\"", align: "top", help: "Kodan bi virgulê (,) ji hev veqetîne. Vala bihêle da ku hemû ziman were nîşandan.", helpInline: true }), new OO.ui.FieldLayout(this.onlyOnClickCheckbox, { label: "Tenê veke wextê \"+Ziman/beşeke din\" were tikandin", align: "inline", help: "Eger were hilbijartin, ev amûr êdî otomatîk li ser rûpelên nû/vala dest pê nake — divê meriv her carê pêl \"+Ziman/beşeke din\" bike.", helpInline: true }), new OO.ui.FieldLayout(this.portletDropdown, { label: "Cihê lînka \"+Ziman/beşeke din\"", align: "top", help: "\"Otomatîk\" li gorî rûyê wîkiyê hildibijêre.", helpInline: true }), new OO.ui.FieldLayout(this.quietCheckbox, { label: "Moda bêdeng (kêmtir agahdarî nîşan bide)", align: "inline", help: "Agahdariyên normal nîşan nede. Xeta her tim tên xuyakirin.", helpInline: true }) ]); this.$body.addClass("wiktku-prefs-dialog-body").append(fieldset.$element); }; WiktkuPrefsDialog.prototype.getSetupProcess = function (data) { return WiktkuPrefsDialog.super.prototype.getSetupProcess.call(this, data) .next(function () { this.langCodesInput.setValue(wiktkuPrefs.langCodes.join(", ")); this.onlyOnClickCheckbox.setSelected(!!wiktkuPrefs.onlyOnClick); this.portletDropdown.setValue(wiktkuPrefs.portlet || "auto"); this.quietCheckbox.setSelected(!!wiktkuPrefs.quiet); }, this); }; WiktkuPrefsDialog.prototype.getActionProcess = function (action) { var dialog = this; if (action === "save") { return new OO.ui.Process(function () { var codes = dialog.langCodesInput.getValue() .split(/[,\s]+/) .map(function (c) { return c.trim().toLowerCase(); }) .filter(function (c) { return !!c; }); wiktkuPrefs = { langCodes: codes, onlyOnClick: dialog.onlyOnClickCheckbox.isSelected(), portlet: dialog.portletDropdown.getValue() || "auto", quiet: dialog.quietCheckbox.isSelected() }; wiktkuSavePrefs(wiktkuPrefs); mw.notify( "Tercîh hatin qeydkirin. Rûpelê ji nû ve bar bike (F5).", { type: "success", tag: "wiktku-prefs-save" } ); dialog.close({ action: "save" }); }); } if (action === "cancel") { return new OO.ui.Process(function () { dialog.close({ action: "cancel" }); }); } return WiktkuPrefsDialog.super.prototype.getActionProcess.call(this, action); }; wiktkuPrefsWindowManager = new OO.ui.WindowManager(); $(document.body).append(wiktkuPrefsWindowManager.$element); wiktkuPrefsDialog = new WiktkuPrefsDialog(); wiktkuPrefsWindowManager.addWindows([wiktkuPrefsDialog]); } wiktkuPrefsWindowManager.openWindow(wiktkuPrefsDialog); }); } var targetContainer; var skin = mw.config.get('skin'); if (wiktkuPrefs.portlet && wiktkuPrefs.portlet !== "auto") { targetContainer = wiktkuPrefs.portlet; } else if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Li vê rûpelê, ziman an jî beşeke nû zêde bike"); // If "onlyOnClick" is set, the wizard should ONLY ever open via the // "+Ziman/beşeke din" link — never automatically var wiktkuNewPageDetected = $(".mw-newarticletext, .mw-newarticletextanon").length > 0; if (wiktkuPrefs.onlyOnClick ? !addLangMode : (!addLangMode && !wiktkuNewPageDetected)) { return; } // ── Shared helpers ─────────────────────────────────────────────────── // Generic text/UI utilities live in their own package file now — see the // header of util.js for why. Aliased to bare names here so the ~400 call // sites below read exactly as they did when these were local functions. var wiktkuUtil = require("./start/util.js"); var capitalize = wiktkuUtil.capitalize; var decapitalize = wiktkuUtil.decapitalize; var escapeRegExp = wiktkuUtil.escapeRegExp; var stripWikilinks = wiktkuUtil.stripWikilinks; var splitTercimeIzah = wiktkuUtil.splitTercimeIzah; var insertAtCursor = wiktkuUtil.insertAtCursor; var foldDiacritics = wiktkuUtil.foldDiacritics; var wrapNativeSelect = wiktkuUtil.wrapNativeSelect; var initSelects = wiktkuUtil.initSelects; var wiktkuInitManualResize = wiktkuUtil.initManualResize; function langHeaderSource(codePattern) { return "\n?==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } // Trash icon (OOjs UI's "trash" glyph, simplified) shared by the Mane // sense tabs and the Beş (POS section) tabs, so deleting a tab looks // and behaves the same in both places. Kept as a <button> separate from // the tab's own click target — and given its own click handler that // stops propagation — specifically because clicking directly on a tab // switches to it; without a distinct hit-target for delete, a stray // click meant to open a sense/section would delete it instead. function makeTrashButton(title) { return $("<button type='button' class='wiktku-trash-btn'></button>") .attr("title", title) .attr("aria-label", title) .html( "<svg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'>" + "<path d='M7 3a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v1h4v2h-1.05l-.9 11.1A2 2 0 0 1 13.06 19H6.94a2 2 0 0 1-1.99-1.9L4.05 6H3V4h4V3zm2 1h2V4H9v0zM6.06 6l.88 11h6.12l.88-11H6.06zM8 8h1.5v7H8V8zm2.5 0H12v7h-1.5V8z'/>" + "</svg>" ); } function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } var catSrcTemplates = null; var catSrcTemplatesPromise = null; function fetchCatSrcTemplates() { if (catSrcTemplatesPromise) return catSrcTemplatesPromise; catSrcTemplatesPromise = new mw.Api().get({ action: "query", list: "categorymembers", cmtitle: "Kategorî:Çavkanî", cmnamespace: 10, cmlimit: "max", formatversion: 2 }).then(function (data) { var members = (data.query && data.query.categorymembers) || []; catSrcTemplates = $.map(members, function (m) { // Pêşgira navî ya "Şablon:" rake. return m.title.replace(/^[^:]+:/, ""); }); catSrcTemplates.sort(function (a, b) { return a.localeCompare(b, userLang); }); return catSrcTemplates; }, function () { catSrcTemplates = []; return catSrcTemplates; }); return catSrcTemplatesPromise; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var formCache = new ObjectStorage("wiktku_start_draft_" + mw.config.get("wgPageName"), 1); var langsByCode = {}; // Looks up the display label for a language code, falling back to the // code itself if it isn't known yet (e.g. langsByCode not loaded). function getLangLabel(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; // Converts a {code: label} object (langChoices/posChoices in data.json) // into the {code, label[, sortKey]} array the rest of the script uses. // isLang: true adds a sortKey and shows "(code)" after the label — // language choices only. function choicesFromObject(obj, isLang) { var result = []; $.each(obj || {}, function (code, label) { var choice = { code: code, label: label }; if (isLang) choice.sortKey = label; result.push(choice); }); return result; } function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c.code] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Number codes (y, s, d, p, p+, tp, j, j+, j/nj, nj, nj+, hj!, hj?) from // data.json's "numberLabels". Same {code: {cat, display[, req]}} shape as // the wiki's Lua number-type table; "display" can contain HTML (<abbr>) // or wikilinks, so it's only used as-is in wikitext output, never dropped // straight into an <option> (see stripMarkupForOption below). var NUMBER_LABELS = {}; // Distinguishes the Jimar dropdown (j= param) from the Cîns dropdown // (c= param): a code that's a key in NUMBER_LABELS is a number code, // everything else is a gender code. Compound codes like "m-p"/"n-p" are // gender+plural pairs and correctly stay on the gender side. function isNumberCode(code) { return Object.prototype.hasOwnProperty.call(NUMBER_LABELS, code); } // Strips the bit of markup "display" is allowed to contain so it's safe // to use as plain <option> text (options can't render HTML or wikilinks): // <abbr title="X">Y</abbr> -> "Y (X)", [[a|b]] -> "b", [[a]] -> "a". function stripMarkupForOption(html) { if (!html) return ""; return $.trim( String(html) .replace(/<abbr[^>]*title="([^"]*)"[^>]*>([\s\S]*?)<\/abbr>/gi, "$2 ($1)") .replace(/\[\[[^\]|]*\|([^\]]*)\]\]/g, "$1") .replace(/\[\[([^\]]*)\]\]/g, "$1") .replace(/<[^>]+>/g, "") ); } // Builds the Jimar dropdown's <option> text for one code: "j — jimarbar". function numberOptionLabel(code) { var def = NUMBER_LABELS[code]; if (!def) return code; var text = stripMarkupForOption(def.display); return text ? (code + " — " + text) : code; } // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } // ── Template explanations ──────────────────────────────────────────── // Every place a template can be picked shows the same row: a status // dot, the name, a link to the template page, and an ⓘ. This is the ⓘ. // // Text comes from the template's own TemplateData where it has any, so // the explanation stays right without anyone maintaining a second copy // by hand — with the desc already in data.json as the fallback for // templates that have none. var wiktkuTplDataCache = {}; // name -> {desc, params[]} or null when absent /** Fetches TemplateData for one template. Resolves to null if the * template has none (a plain, undocumented template — very common). */ function fetchTemplateData(name) { if (Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, name)) { return $.Deferred().resolve(wiktkuTplDataCache[name]).promise(); } return new mw.Api().get({ action: "templatedata", titles: "Şablon:" + name, redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; var first = null; $.each(pages, function (_, p) { if (!first) first = p; }); var out = null; if (first) { var desc = first.description; // TemplateData descriptions are language maps when the // template is documented in more than one language. if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(first.params || {}, function (key, p) { var label = p && p.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(p && p.required) }); }); out = { desc: desc || "", params: params }; } wiktkuTplDataCache[name] = out; return out; }, function () { // No TemplateData, or the API is unhappy — cache the miss so a // repeated ⓘ click doesn't re-request it every time. wiktkuTplDataCache[name] = null; return null; }); } /** Fetches TemplateData for many templates in one request and fills the * cache; resolves either way, a template with no TemplateData caches as null. */ function prefetchTemplateData(names) { var missing = $.grep(names || [], function (n) { return n && !Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n); }); if (!missing.length) return $.Deferred().resolve().promise(); // The API caps a titles list at 50 for normal users. missing = missing.slice(0, 50); return new mw.Api().get({ action: "templatedata", titles: $.map(missing, function (n) { return "Şablon:" + n; }).join("|"), redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; $.each(pages, function (_, page) { if (!page || !page.title) return; var name = String(page.title).replace(/^[^:]+:/, ""); var desc = page.description; if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(page.params || {}, function (key, prm) { var label = prm && prm.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(prm && prm.required) }); }); wiktkuTplDataCache[name] = { desc: desc || "", params: params }; }); // Anything the API didn't answer for simply has none — cache the // miss so the per-row ⓘ doesn't re-request it one at a time. $.each(missing, function (_, n) { if (!Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n)) wiktkuTplDataCache[n] = null; }); }, function () { $.each(missing, function (_, n) { wiktkuTplDataCache[n] = null; }); }); } /** Rewrites each tagged <option> in `sel` as "name — description", using * TemplateData. Only fills rows that have no description yet, so the * hand-written ones in data.json (which carry usage examples the API * does not) are left exactly as they are. */ function applyTplDescriptions(sel) { if (!sel || !sel.length) return; var changed = false; sel.find("option[data-tpl]").each(function () { var opt = $(this); var name = opt.attr("data-tpl"); if (opt.text().indexOf(" — ") !== -1) return; // already described var td = wiktkuTplDataCache[name]; var desc = (td && td.desc) || localTplDesc(name); if (!desc) return; // One line: TemplateData descriptions can run to a paragraph. desc = $.trim(String(desc).split("\n")[0]); if (desc.length > 90) desc = desc.slice(0, 90) + "…"; opt.text(name + " — " + desc); changed = true; }); // The picker caches option text for searching, so it has to re-read. if (changed) sel.trigger("wiktku:refresh"); } /** Hand-written fallback description, from data.json. * * This is the escape hatch for templates with no TemplateData on the * wiki: add a "desc" to the entry in data.json and it shows up in the * dropdown and in the ⓘ immediately, no code change. TemplateData is * still the better place — VisualEditor and every other tool reads it * too — but this keeps the picker useful in the meantime. * * Works for any pool: pronTpls, etymTpls, tplDefs, jederDefs. */ function localTplDesc(name) { var pools = [steps.pron.pronTpls, steps.etym.etymTpls, steps.dfn.tplDefs, steps.dfn.jederDefs]; var found = ""; $.each(pools, function (_, pool) { if (pool && pool[name] && pool[name].desc) { found = pool[name].desc; return false; } }); return found; } /** Opens the inline explanation panel for `name`, anchored under the * picker it was opened from. */ function showTemplateInfo(name, anchorWrap) { $(".wiktku-tpl-info").remove(); var panel = $("<div class='wiktku-tpl-info'></div>"); panel.append($("<div class='wiktku-tpl-info-name'></div>").text("{{" + name + "}}")); var body = $("<div class='wiktku-tpl-info-desc'></div>").text("Tê barkirin…"); panel.append(body); var params = $("<div class='wiktku-tpl-info-params'></div>"); panel.append(params); panel.append($("<a class='wiktku-tpl-info-link' target='_blank' rel='noopener'></a>") .attr("href", wiktkuUtil.tplPageUrl(name)) .text("Rûpela şablonê veke →")); var close = $("<button type='button' class='wiktku-tpl-info-close' title='Bigire'>✕</button>"); close.on("click", function () { panel.remove(); }); panel.prepend(close); $(anchorWrap).after(panel); fetchTemplateData(name).then(function (td) { var desc = (td && td.desc) || localTplDesc(name); body.text(desc || "Ji bo vê şablonê ravek nehatiye nivîsandin."); if (td && td.params && td.params.length) { params.append($("<div class='wiktku-tpl-info-params-title'></div>").text("Parametre:")); var listEl = $("<ul></ul>"); $.each(td.params, function (_, p) { var line = p.name + (p.label ? " — " + p.label : "") + (p.required ? " (pêwîst)" : ""); listEl.append($("<li></li>").text(line)); }); params.append(listEl); } }); } /** Marks a picker's <option>s as template rows so the searchable widget * renders them with the dot / 🔗 / ⓘ affordances, and wires the ⓘ * handler for that picker. `nameOf` maps an <option> to a template * name — the pickers store different things in value= (a snippet for * the insert dropdowns, the bare name for the sense selector). */ function markTemplateOptions(sel, nameOf) { if (!sel || !sel.length) return; var names = []; sel.find("option").each(function () { var opt = $(this); var name = nameOf(opt); if (!name) return; opt.attr("data-tpl", name); // Deprecated/typo templates are the "special cases only" ones. opt.attr("data-tpl-status", /kevnbûyî|şaşnivîs|kêmpeyda/i.test(opt.text()) ? "yellow" : "green"); names.push(name); }); sel.data("wiktkuTplInfo", showTemplateInfo); // Fill in the descriptions. Matters most for the Mane picker, whose // entries in data.json are names with no desc at all — "rastnivîs", // "ku-Latn", "guharto" on their own. One request covers every // template in the picker, cached for the per-row ⓘ as well. prefetchTemplateData(names).always(function () { applyTplDescriptions(sel); }); } /** Pulls the template name out of a snippet like "* {{ku-IPA}}" or * "{{ji|SOURCELANG|CODE|…}}". */ function tplNameFromSnippet(snippet) { var m = /\{\{\s*([^|}\n]+)/.exec(snippet || ""); return m ? $.trim(m[1]) : ""; } // True if a sense has content beyond mane worth keeping (etîket, word // lists, nimûne, jêder) — so it's still emitted with {{mane?}} if empty. function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } // A technically-"complete" entry (Ziman + Cureyê rêzimanî filled) with // nothing in Mane, Bi zaravayên din or Werger is still meaningfully // empty, so this is checked separately at submit-click time with its // own message. function hasMinRequiredContent(values) { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasMane = dfnSenses.some(function (s) { return (s.tpl && s.tplTitle) || (!s.tpl && (s.mane !== "" || senseHasExtraContent(s))); }); if (hasMane) return true; if (values.lang === "ku") { var hasWerger = false; $("#wiktku-start-trans .wiktku-trans-group").each(function () { if (steps.trans.getGroupTranslations($(this)).length) hasWerger = true; }); if (hasWerger) return true; var hasZarava = false; $("#wiktku-start-zarava .wiktku-zarava-group").each(function () { if (steps.zarava.getGroupTranslations($(this)).length) hasZarava = true; }); if (hasZarava) return true; } return false; } // Bolds the *first* occurrence of the page name function boldPageNameOnce(text) { if (!text || !pageNameRe) return text; var re = new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "i"); return text.replace(re, "'''$1'''"); } // Converts literal line breaks typed into a nimûne/jêgirtin box into // wikitext <br> tags, function nlToBr(text) { return text ? text.replace(/\r\n|\r|\n/g, "<br>") : text; } function escapeHtmlForBackdrop(str) { return String(str) .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;"); } // Mirrors a textarea's text, with a small highlighted marker placed // right after each line that's followed by an actual typed/pasted // linebreak. Rendered into a transparent backdrop layer behind the // textarea (see ensureLinebreakBackdrop()), so only the point of the // break is marked instead of the whole box. function buildLinebreakBackdropHtml(text) { var lines = text.split(/\r\n|\r|\n/); return $.map(lines, function (line, i) { var isLast = i === lines.length - 1; return escapeHtmlForBackdrop(line) + (isLast ? "" : "<mark class='wiktku-linebreak-mark'>↵</mark>\n"); }).join(""); } // Copies the metrics that affect where text wraps/lands (font, line // height, padding, border) from the real textarea onto its backdrop, // via computed style rather than shared CSS classes — most of the // box's own rules are written as "textarea.foo", which a <div> with // the same class wouldn't match. Re-run on every update in case a // responsive breakpoint changed the textarea's own font-size. function syncLinebreakBackdropMetrics(textarea, backdrop) { var cs = window.getComputedStyle(textarea[0]); backdrop.css({ "box-sizing": cs.boxSizing, "padding-top": cs.paddingTop, "padding-right": cs.paddingRight, "padding-bottom": cs.paddingBottom, "padding-left": cs.paddingLeft, "border-width": cs.borderWidth, "border-style": "solid", "font-family": cs.fontFamily, "font-size": cs.fontSize, "font-weight": cs.fontWeight, "line-height": cs.lineHeight, "letter-spacing": cs.letterSpacing }); } // Lazily wraps a textarea in its own positioning anchor (independent // of .wiktku-resize-wrap, so this doesn't depend on load order versus // wiktkuMakeManualResizable) and inserts the transparent backdrop // layer used to mark the exact point of a linebreak. Safe to call // more than once on the same textarea — the backdrop is cached. function ensureLinebreakBackdrop(textarea) { var existing = textarea.data("wiktkuLinebreakBackdrop"); if (existing) return existing; textarea.wrap("<div class='wiktku-linebreak-wrap'></div>"); var backdrop = $("<div aria-hidden='true'></div>").addClass("wiktku-linebreak-backdrop"); textarea.before(backdrop); textarea.data("wiktkuLinebreakBackdrop", backdrop); textarea.on("scroll.wiktkuLinebreak", function () { backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); }); return backdrop; } // Flags a nimûne/jêgirtin textarea (via CSS class, for the border // tint + tooltip) while it contains a typed/pasted linebreak, so the // user notices before it's silently turned into <br> on output. // Marks only the exact point of the break via a mirrored backdrop, // rather than tinting the whole box. function highlightLinebreak(el) { var textarea = $(el); var text = textarea.val(); var hasBreak = /\r|\n/.test(text); textarea .toggleClass("wiktku-has-linebreak", hasBreak) .attr("title", hasBreak ? "Xeta nû dê wek <br> bê nivîsandin" : ""); if (!hasBreak) { var cached = textarea.data("wiktkuLinebreakBackdrop"); if (cached) cached.hide(); textarea.removeClass("wiktku-has-linebreak-source"); return; } var backdrop = ensureLinebreakBackdrop(textarea); textarea.addClass("wiktku-has-linebreak-source"); syncLinebreakBackdropMetrics(textarea, backdrop); backdrop.html(buildLinebreakBackdropHtml(text)).show(); backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); } // Each nimûne item can be { text, tr, t }: text, transliteration, translation. function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{nimûne?|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = nlToBr(boldPageNameOnce(text)); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + nlToBr(n.tr); // Translation as third positional param (no key needed). if (n.t) tpl += "|" + nlToBr(n.t); } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 60 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } // Formats jêder (citation) entries into "#* {{jêder…|…}}" lines; skips // entries with no quote text. Falls back to the generic {{jêder}} // template when no specific template was chosen. function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; var quote = nlToBr(boldPageNameOnce(jeder.quote)); var quoteTr = nlToBr(jeder.quoteTr); var quoteT = nlToBr(jeder.quoteT); if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + quote; if (quoteTr) cite += "|tr=" + quoteTr; if (quoteT) cite += "|tercime=" + quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + quote; if (quoteTr) out += "|tr=" + quoteTr; if (quoteT) out += "|tercime=" + quoteT; // A şablon picked from Kategorî:Çavkanî is transcluded as the // source param (e.g. |{{Kovara X}}); manual text is used as-is. var srcParam = jeder.jederCatTpl ? ("{{" + jeder.jederCatTpl + "}}") : (jeder.jederManual ? jeder.jederManual : "çavkanî?"); // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } // True if a sense has at least one jêder entry with quote text. function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } // Builds "{{tplName|lang|part1|part2|…}}" from a sense field (kategori, // etiket), wrapped inline (" {{…}} ") or on its own line ("\n#: {{…}}"). function buildSenseTpl(sense, field, lang, tplName) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return call } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } // ── Inline modifier system ─────────────────────────────────────────────── // Appends a ⊕ button to a word input <li>. Clicking it shows a compact // modifier picker; selecting one prompts for the value and appends // <modifier:value> to the textarea's current content. 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îf" }, { 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: qualifier (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" }, { key: "qq", label: "qq: qualifier (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î" } ]; // Sub-groups (inside a sense/definition block) that get the same ⊕ // modifier button as makeWordListStep fields. var MODIFIER_SUBGROUPS = { "wiktku-dfn-alternativ": true, "wiktku-dfn-hevmane": true, "wiktku-dfn-dijmane": true, "wiktku-dfn-koordine": true, "wiktku-dfn-jornav": true, "wiktku-dfn-jernav": true }; /** * Wraps a freshly-created textarea in a <li> with a ⊕ modifier button. * `ta` — the jQuery textarea element. * Returns the <li>. */ function makeModifierLi(ta) { var li = $("<li class='wiktku-word-li'></li>"); var btn = $("<button type='button' class='wiktku-mod-btn' title='Modifiyerê lê zêde bike'>⊕</button>"); var picker = $("<div class='wiktku-mod-picker'></div>").hide(); // Which modifier keys are already present in the textarea's current // text — e.g. "<t:...>" → "t" used. Each modifier can only be // applied once per word, so its pill gets disabled once used. function usedKeys() { var used = {}; var re = /<([a-zA-Z]+):/g; var val = ta.val() || ""; var m; while ((m = re.exec(val)) !== null) used[m[1]] = true; return used; } $.each(WORD_MODIFIERS, function (_, mod) { var pill = $("<button type='button' class='wiktku-mod-pill'></button>").text(mod.label); pill.attr("title", mod.hint); pill.data("mod-key", mod.key); pill.on("click", function (e) { e.preventDefault(); if (pill.prop("disabled")) return; // already used on this word picker.hide(); // Show a tiny inline input for the modifier value. var valWrap = $("<span class='wiktku-mod-val-wrap'></span>"); var valInp = $("<input type='text' class='wiktku-mod-val-input'>") .attr("placeholder", mod.hint + "…") .attr("size", 20); var confirm = $("<button type='button' class='wiktku-mod-confirm'>✓</button>"); var cancel = $("<button type='button' class='wiktku-mod-cancel'>✕</button>"); function applyModifier() { var v = $.trim(valInp.val()); if (v) { ta.val(ta.val() + "<" + mod.key + ":" + v + ">"); ta.trigger("input"); } valWrap.remove(); ta.focus(); } confirm.on("click", applyModifier); cancel.on("click", function () { valWrap.remove(); ta.focus(); }); valInp.on("keydown", function (e) { if (e.which === 13) { e.preventDefault(); applyModifier(); } if (e.which === 27) { valWrap.remove(); ta.focus(); } }); valWrap.append(valInp).append(confirm).append(cancel); li.append(valWrap); valInp.focus(); }); picker.append(pill); }); btn.on("click", function (e) { e.preventDefault(); // Close any other open pickers in the same list. li.closest("ol, ul").find(".wiktku-mod-picker").not(picker).hide(); // Grey out modifiers already used on this word — refreshed on // every open since the text (and thus what's "used") can change. var used = usedKeys(); picker.find(".wiktku-mod-pill").each(function () { var isUsed = !!used[$(this).data("mod-key")]; $(this).prop("disabled", isUsed).toggleClass("wiktku-mod-pill-used", isUsed); }); picker.toggle(); }); // Close picker when focus leaves the li entirely. li.on("focusout", function () { setTimeout(function () { if (!$.contains(li[0], document.activeElement)) picker.hide(); }, 150); }); li.append(ta).append(btn).append(picker); return li; } function makeWordListStep(id, name, question_fmt) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, modifiers: true, // Function instead of a plain string so it can name the current // language — computed fresh at build time and re-applied by // refresh() whenever the language changes. placeholder: function () { var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return "Kelîme" + (langLabel ? " bi " + langLabel : "") + "…"; }, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); var header = capitalize(name); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: {}, visible: function (values) { if (!values.lang) return false; // addLangMode: skip pron only if this lang already has a section. if (addLangMode) { // Clearing the page makes existing content irrelevant. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, // Fills the insert-dropdown from pronTpls, filtered by language. refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); // Reassures the user this field is optional — the dropdown // below writes the template for them, no syntax needed up front. wrap.append( $("<p class='wiktku-step-hint'></p>").text( "Ev qad ne mecbûrî ye. Heke tu nizanî kîjan şablonî hilbijêrî, vale bihêle — an ji pêşkêşkariya jêrîn şablonekî hilbijêre, ew ê bixweber li vir were nivîsandin." ) ); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike "); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); // Clear the picker's search box sel.trigger("wiktku:refresh"); ta.focus(); return; } // The noLang templates (ku-IPA, ku-kîte, zza-IPA, zza-kîte) // auto-generate content from a Lua module reading the page // title, so show a live preview and require confirmation // before inserting. var tplLabel = selectedOption.text(); $(this).val(""); sel.trigger("wiktku:refresh"); steps.pron.showTplPreview(stepDiv, ta, snippet, tplLabel); }); wrap.append(sel).append(ta); stepDiv.append(wrap); steps.pron.buildIpaPalette(wrap, ta); initSelects(wrap); return ta; }, // ── IPA character palette ────────────────────────────────── // Modelled on fr.wiktionary's: every character is a button that // drops itself in at the cursor. Two sub-tabs, because the full // IPA chart is ~180 symbols and roughly twenty of them ever // appear in Kurmancî — "IPA (kurdî)" opens by default and the // full chart is one click away for loanwords and other // languages. Grouped with a label down the left so it reads as // a chart rather than one long line of glyphs. IPA_KU: [ { label: "Kît/stres", chars: ["ˈ", "ˌ", "ː"] }, { label: "Bêdeng", chars: ["d͡ʒ", "t͡ʃ", "ʒ", "ʃ", "ɫ", "ŋ", "ɾ", "r", "ʋ", "ħ", "ʕ", "ɣ", "χ", "ʔ"] }, { label: "Dengdêr", chars: ["ɑː", "eː", "ɛ", "ɪ", "iː", "ɯ", "ʊ", "uː", "yː", "ø", "œ"] } ], IPA_FULL: [ { label: "Bêdeng 1", chars: ["m", "ɱ", "n", "ɳ", "ɲ", "ŋ", "ɴ", "p", "b", "t", "d", "t̪", "d̪", "ʈ", "ɖ", "c", "ɟ", "k", "ɡ", "q", "ɢ", "ʡ", "ʔ"] }, { label: "Bêdeng 2", chars: ["ɸ", "β", "f", "v", "θ", "ð", "s", "z", "ʃ", "ʒ", "ʂ", "ʐ", "ɕ", "ʑ", "ç", "ʝ", "x", "ɣ", "χ", "ʁ", "ħ", "ʕ", "h", "ɦ", "ʜ", "ʢ", "ɧ"] }, { label: "Bêdeng 3", chars: ["ʋ", "ɹ", "ɻ", "j", "ɥ", "ɰ", "ʍ", "w", "ʙ", "ⱱ", "ɾ", "ɽ", "r", "ʀ", "ɺ", "l", "ɫ", "ɬ", "ɮ", "ɭ", "ʎ", "ʟ"] }, { label: "Bêdeng 4", chars: ["ɓ", "ɗ", "ᶑ", "ʄ", "ɠ", "ʛ", "ʘ", "ǀ", "ǃ", "ǂ", "ǁ"] }, { label: "Dengdêr", chars: ["i", "y", "ɪ", "ʏ", "ɨ", "ʉ", "ɯ", "u", "ʊ", "e", "ø", "ɘ", "ɵ", "ɤ", "o", "ə", "ɚ", "ɛ", "œ", "ɜ", "ɝ", "ɞ", "ʌ", "ɔ", "æ", "ɶ", "ɐ", "a", "ɑ", "ɒ"] }, { label: "Suprasegmental", chars: ["ˈ", "ˌ", "ː", "ˑ", "ʼ", "ˀ", "ˤ", "ᵝ", "ᵊ", "ˠ", "ʰ", "ʱ", "ʲ", "ˡ", "ⁿ", "ᵑ", "ʷ", "ᶣ", "˞", "‿"] }, { label: "Dîakrîtîk", chars: ["̚", "̪", "̺", "̻", "̼", "̬", "̊", "̥", "̞", "̝", "̘", "̙", "̽", "̟", "̠", "̈", "̤", "̹", "̜", "̍", "̩", "̆", "̯", "̃", "̰", "͡", "͜"] }, { label: "Ton", chars: ["̋", "́", "̄", "̀", "̏", "̌", "̂", "˥", "˦", "˧", "˨", "˩", "ꜛ", "ꜜ", "↗", "↘", "‖"] } ], /** Builds the two-sub-tab character palette under the textarea. */ buildIpaPalette: function (wrap, ta) { if (wrap.find(".wiktku-ipa-palette").length) return; var panel = $("<div class='wiktku-ipa-panel'></div>").hide(); var toggle = $("<a href='#' class='wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tîpên bilêvkirinê</span>")); toggle.on("click", function (e) { e.preventDefault(); var open = panel.is(":visible"); panel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); wrap.append($("<div class='wiktku-adv-toggle-row'></div>").append(toggle)); // Sub-tab bar, with the two template buttons pinned right. var subTabs = $("<div class='wiktku-ipa-subtabs'></div>"); var kuTab = $("<span class='wiktku-ipa-subtab wiktku-tab-active'>IPA (kurdî)</span>"); var fullTab = $("<span class='wiktku-ipa-subtab'>IPA</span>"); subTabs.append(kuTab).append(fullTab); var tplBtns = $("<span class='wiktku-ipa-tplbtns'></span>"); $.each([ { label: "{{ku-IPA|+}}", snippet: "{{ku-IPA|}}", back: 2 }, { label: "{{IPA|+}}", snippet: "{{IPA|ku|}}", back: 2 } ], function (_, t) { var b = $("<button type='button' class='wiktku-ipa-tplbtn'></button>").text(t.label); b.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], t.snippet); // Park the cursor inside the braces, where the value goes. var pos = ta[0].selectionStart - t.back; ta[0].selectionStart = ta[0].selectionEnd = pos; ta.focus(); }); tplBtns.append(b); }); subTabs.append(tplBtns); panel.append(subTabs); function buildGrid(groups) { var grid = $("<div class='wiktku-ipa-grid'></div>"); $.each(groups, function (_, g) { var row = $("<div class='wiktku-ipa-row'></div>"); row.append($("<span class='wiktku-ipa-rowlabel'></span>").text(g.label)); var keys = $("<span class='wiktku-ipa-keys'></span>"); $.each(g.chars, function (_, ch) { var btn = $("<button type='button' class='wiktku-ipa-key'></button>"); // A combining mark on its own renders as a stray // accent floating over whatever precedes it, so // show it on a dotted circle — but insert only // the mark itself. var combining = /^[̀-ͯ҃-҉]$/.test(ch); btn.text(combining ? "◌" + ch : ch); if (combining) btn.addClass("wiktku-ipa-key-combining"); btn.attr("title", ch); btn.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], ch); ta.focus(); }); keys.append(btn); }); row.append(keys); grid.append(row); }); return grid; } var kuGrid = buildGrid(steps.pron.IPA_KU); var fullGrid = buildGrid(steps.pron.IPA_FULL).hide(); panel.append(kuGrid).append(fullGrid); kuTab.on("click", function () { kuTab.addClass("wiktku-tab-active"); fullTab.removeClass("wiktku-tab-active"); kuGrid.show(); fullGrid.hide(); }); fullTab.on("click", function () { fullTab.addClass("wiktku-tab-active"); kuTab.removeClass("wiktku-tab-active"); fullGrid.show(); kuGrid.hide(); }); panel.addClass("wiktku-ipa-palette"); wrap.append(panel); }, /** Inline preview + confirm panel for a "noLang" (auto-content) * pronunciation template — fetches what the snippet expands to * for this page and only inserts it if the user confirms. */ showTplPreview: function (stepDiv, ta, snippet, tplLabel) { // Only one preview panel open at a time. stepDiv.find(".wiktku-pron-preview").remove(); var panel = $("<div class='wiktku-pron-preview'></div>"); panel.append($("<div class='wiktku-pron-preview-label'></div>") .text("Pêşdîtina " + tplLabel + ":")); var body = $("<div class='wiktku-pron-preview-body'></div>").text("Tê barkirin…"); panel.append(body); var actions = $("<div class='wiktku-pron-preview-actions'></div>"); var confirmBtn = $("<button type='button' class='wiktku-pron-preview-confirm'>✓ Tevlî bike</button>") .prop("disabled", true); var cancelBtn = $("<button type='button' class='wiktku-pron-preview-cancel'>✕ Betal bike</button>"); actions.append(confirmBtn).append(cancelBtn); panel.append(actions); ta.before(panel); confirmBtn.on("click", function () { insertAtCursor(ta[0], snippet); panel.remove(); ta.focus(); }); cancelBtn.on("click", function () { panel.remove(); }); // action=parse, not action=expandtemplates. expandtemplates // returns *expanded wikitext*, so the preview read as // [[IPA]]<sup>([[Wîkîferheng:IPA kurmancî|kilîd]])</sup>: // <span class="IPA">/-{kshhe}-/</span>[[Kategorî:…]] — which // is exactly what the person is trying to avoid having to // read. parse hands back the rendered HTML the page will // actually show. // // Drop the leading "* " first: it is wikitext list syntax // wrapping the template, and keeping it would render the // preview as a bulleted list rather than the line itself. new mw.Api().post({ action: "parse", title: pageName, text: snippet.replace(/^\*\s*/, ""), prop: "text", wrapoutputclass: "", disablelimitreport: 1, disableeditsection: 1, contentmodel: "wikitext", formatversion: 2 }).done(function (data) { var html = (data && data.parse && data.parse.text) || ""; if ($.trim($("<div>").html(html).text())) { body.html(html); // Category links render as nothing but still exist; // and any real link inside a preview should not // navigate away from a half-filled form. body.find("a").attr("target", "_blank").attr("rel", "noopener"); } else { body.text("(vala — ji bo vê rûpelê tiştek nehate afirandin)"); } confirmBtn.prop("disabled", false); }).fail(function () { body.text("Pêşdîtin nehate barkirin — tu dikarî hîn jî wê tevlî bikî."); confirmBtn.prop("disabled", false); }); }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line; }).join("\n"); // "===" heading under Ziman and above the POS sections; the // field is shared across sections, so it's emitted once by // getWikitext() rather than per-POS-section (would otherwise // print the pronunciation twice for a two-POS entry). return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var capitalizedPos = capitalize(pos); // "form" opt-param (checked in posparams) marks this as a // form-of/inflected entry — the section title becomes // "Formeke <pos>ê" instead of the plain pos name. The // template call itself still uses the unchanged pos name. var isForm = $("#wiktku-posparams-opt-form").is(":checked"); var header = isForm ? "\n=== Formeke " + pos + "ê ===\n" : "\n=== " + capitalizedPos + " ===\n"; // Image line (between header and template call) var imageLine = steps.resim.output(values); // Read the live wikitext from the posparams textarea. // Fall back to a plain {{pos|lang}} if the step hasn't been built yet. var tplLine = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); if (!tplLine) { tplLine = "{{" + pos + "|" + (values.lang || "") + "}}"; } return header + imageLine + tplLine + "\n"; } }, // cinsiyet (gender) — shown for navdêr/serenav only, with choices built // from metadata[lang].g since not every language has grammatical gender. cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams // Single source of truth for the selected gender code. The visible // dropdown lives inside the posparams step (see steps.posparams), // but it must always read/write THIS hidden field — not a field of // its own — since getValuesForStep("cinsiyet") reads from here. build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-cinsiyet-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // jimar (grammatical number) — same hidden-field pattern as cinsiyet // above, but writes into its own j= template parameter instead of // sharing c=. Shown for navdêr/serenav only, with choices built from // whichever of metadata[lang].g are number codes (see isNumberCode). jimar: { id: "jimar", name: "jimar", question_fmt: 'Jimara "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-jimar-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // Lêker transitivity — hidden step, handled inside posparams lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function () { return false; }, choices: [ { code: "gh", label: "gerguhêz" }, { code: "x-gh", label: "xwerû-gerguhêz" }, { code: "p-gh", label: "pêkhatî-gerguhêz" }, { code: "h-gh", label: "hevedudanî-gerguhêz" }, { code: "b-gh", label: "biwêjî-gerguhêz" }, { code: "ngh", label: "negerguhêz" }, { code: "x-ngh", label: "xwerû-negerguhêz" }, { code: "p-ngh", label: "pêkhatî-negerguhêz" }, { code: "h-ngh", label: "hevedudanî-negerguhêz" }, { code: "b-ngh", label: "biwêjî-negerguhêz" } ], output: function () { return ""; } }, // tr — hidden step, handled inside posparams tr: { id: "tr", name: "transliterasyon", question_fmt: "Transliterasyona vê kelîmeyê", multiple: false, narrow: true, visible: function () { return false; } }, posparams: { id: "posparams", // Fused onto the "pos" card visually (see #wiktku-start-posparams // in styles.css) so the two read as ONE question — this name is // only a no-CSS/no-JS fallback, since the h3 that would show it // is hidden by CSS. name: "taybetmendî", // Shows what's actually being asked for: gender for nouns, verb // type for verbs, a generic fallback otherwise. question_fmt: function (values) { var pos = values.pos || ""; // Cinsiyet/Jimar fields below are self-labelled, so no title needed here. if (pos === "navdêr" || pos === "serenav") return ""; if (/^lêker/.test(pos)) return "Cureyê lêkerê"; return "Taybetmendî"; }, visible: function (values) { return !!(values.lang && values.pos); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-posparams-wrap").length) return null; var wrap = $("<div class='wiktku-posparams-wrap'></div>"); var helpers = $("<div class='wiktku-posparams-helpers'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-posparams-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-posparams-text") .attr("rows", 2); var _rebuilding = false; function safeRebuild() { if (_rebuilding) return; _rebuilding = true; steps.posparams.rebuildTa(stepDiv); _rebuilding = false; refresh(); } // Generic text-input row factory function makeTextRow(key, labelText, placeholder) { var row = $("<div class='wiktku-posparams-row'></div>") .attr("id", "wiktku-posparams-row-" + key).hide(); var inp = $("<input type='text'>") .addClass("wiktku-start-narrow wiktku-posparams-field") .attr("data-pp-key", key) .attr("placeholder", placeholder || ""); inp.on("input", safeRebuild); row.append($("<label></label>").text(labelText + ": ")).append(inp); return row; } // cinsiyet var cinsiyetRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-c'></div>") .append($("<label></label>").text("Cinsiyet: ")).hide(); var cinsiyetSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-cinsiyet-sel") .append($("<option value=''>— hilbijêre —</option>")); // Writes into the real, shared #wiktku-start-cinsiyet-field (owned by // steps.cinsiyet) rather than a field of its own — see the comment // on steps.cinsiyet.build for why that matters. cinsiyetSel.on("change", function () { $("#wiktku-start-cinsiyet-field").val($(this).val()).trigger("change"); safeRebuild(); }); cinsiyetRow.append(cinsiyetSel); // jimar (number) — second dropdown next to Cinsiyet, writes // into the shared hidden #wiktku-start-jimar-field, into its // own j= param instead of sharing c=. Options + tooltip are // built in syncHelpers once the language's number codes are known. var jimarRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-jimar'></div>") .append($("<label></label>").text("Jimar: ")).hide(); var jimarSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-jimar-sel") .append($("<option value=''>— hilbijêre —</option>")); jimarSel.on("change", function () { $("#wiktku-start-jimar-field").val($(this).val()).trigger("change"); safeRebuild(); }); jimarRow.append(jimarSel); // lektur: two plain questions (transitivity + structural form) // instead of one 10-option dropdown. Emitted code: base alone // ("gh"), or prefix + "-" + base ("x-gh"). var lekturRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lektur'></div>") .append($("<label></label>").text("Lêker derbasdar e? ")).hide(); var lekturSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lektur-sel") .append($("<option value=''>— hilbijêre —</option>")) .append($("<option value='gh'>gerguhêz (bireser digire)</option>")) .append($("<option value='ngh'>negerguhêz (bireser nagire)</option>")); lekturSel.on("change", safeRebuild); lekturRow.append(lekturSel); // Second half of the same question — the structural form. // Blank = xwerû/sade, which is the common case. var lekturFormRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lekturform'></div>") .append($("<label></label>").text("Şiklê lêkerê: ")).hide(); var lekturFormSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lekturform-sel") .append($("<option value=''>sade (asayî)</option>")) .append($("<option value='x'>xwerû</option>")) .append($("<option value='p'>pêkhatî</option>")) .append($("<option value='h'>hevedudanî</option>")) .append($("<option value='b'>biwêjî</option>")); lekturFormSel.on("change", safeRebuild); lekturFormRow.append(lekturFormSel); helpers.append(cinsiyetRow).append(jimarRow).append(lekturRow).append(lekturFormRow); // ── Everything below here is "Tercîhên pêşketî" ────────────── // These rows live inside a collapsed panel, so the default // view of this card is two dropdowns instead of twenty-odd fields. // Transliteration is a primary field, not an advanced one, for // any language not written in Latin script: for those, an // entry without it is incomplete. syncHelpers already gates // the row on needsTransliteration(lang), so for Kurmancî and // other Latin-script languages it simply never appears. helpers.append(makeTextRow("tr", "Transliterasyon (tr)", "Transliterasyon…")); var advPanel = $("<div class='wiktku-posparams-adv-panel'></div>").hide(); advPanel .append(makeTextRow("cuda", "nîşankirina alternatîv", "cuda…")) .append(makeTextRow("ts", "Transkrîpsiyon (ts)", "Transkrîpsiyon…")) .append(makeTextRow("m", "Forma mê (m)", "Forma mê…")) .append(makeTextRow("mtr", "Translit. mê (mtr)", "Transliterasyona mê…")) .append(makeTextRow("n", "Forma nêr (n)", "Forma nêr…")) .append(makeTextRow("ntr", "Translit. nêr (ntr)", "Transliterasyona nêr…")) .append(makeTextRow("p", "Forma pirjimar (p)", "Forma pirjimar…")) .append(makeTextRow("ptr", "Translit. pirjimar", "Transliterasyona pirjimar…")) .append(makeTextRow("y", "Forma yekjimar (y)", "Forma yekjimar…")) .append(makeTextRow("ytr", "Translit. yekjimar", "Transliterasyona yekjimar…")) .append(makeTextRow("sûp", "Forma sûperlatîv (sûp)", "Forma sûperlatîv…")) .append(makeTextRow("sûptr", "Translit. sûperlatîv", "Transliterasyona sûperlatîv…")) .append(makeTextRow("komp", "Forma komparatîv (komp)", "Forma komparatîv…")) .append(makeTextRow("komptr", "Translit. komparatîv", "Transliterasyona komparatîv…")) .append(makeTextRow("gir", "Forma girdêk (gir)", "gir=…")) .append(makeTextRow("girtr", "Translit. gir", "girtr=…")) .append(makeTextRow("hûr", "Forma hûrek (hûr)", "hûr=…")) .append(makeTextRow("hûrtr", "Translit. hûr", "hûrtr=…")) .append(makeTextRow("hanja", "Forma hanja", "hanja=…")) .append(makeTextRow("hanjaTr","Translit. hanja", "hanjaTr=…")) // Lêker rehên demê (only shown when pos is lêker — see syncHelpers) .append(makeTextRow("niha", "Rehê dema niha (niha)", "Rehê dema niha…")) .append(makeTextRow("nihatr", "Translit. rehê dema niha", "Transliterasyona rehê dema niha…")) .append(makeTextRow("borî", "Rehê dema borî (borî)", "Rehê dema borî…")) .append(makeTextRow("borîtr", "Translit. rehê dema borî", "Transliterasyona rehê dema borî…")) .append(makeTextRow("subj", "Rehê dema bilanî (subj)", "Rehê dema bilanî…")) .append(makeTextRow("subjtr", "Translit. rehê dema bilanî", "Transliterasyona rehê dema bilanî…")); // Optional boolean params — nested inside the advanced panel // (they were already the most niche thing on the card). var optPanel = $("<div class='wiktku-posparams-opt-panel'></div>"); $.each([ { key: "form", label: "form — ev made forma tewandî ye" }, { key: "formaalt", label: "formaalt — vê madeyê bike forma alternatîv" }, { key: "nekatcure", label: "nekatcure — sinifa rêzimanî kategorîze neke" }, { key: "nekatcins", label: "nekatcins — kategoriya cinsiyetê neyîne" }, { key: "nekatçendterm", label: "nekatçendterm — kategoriya çend-term neyîne" }, { key: "serlînkneke", label: "serlînkneke — sernavê madeyê lînk neke" }, { key: "nekatpalîndrom", label: "nekatpalîndrom — kategoriya palîndromê neyîne" }, { key: "neformtr", label: "neformtr — transliterasyona forman neyîne" } ], function (_, p) { var cb = $("<input type='checkbox'>") .attr("id", "wiktku-posparams-opt-" + p.key).val(p.key).on("change", safeRebuild); var lbl = $("<label></label>").attr("for", "wiktku-posparams-opt-" + p.key).text(" " + p.label); optPanel.append($("<div class='wiktku-posparams-opt-row'></div>").append(cb).append(lbl)); }); advPanel.append(optPanel); var optToggle = $("<a href='#' class='wiktku-posparams-opt-toggle wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tercîhên pêşketî</span>")); optToggle.on("click", function (e) { e.preventDefault(); var open = advPanel.is(":visible"); advPanel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); helpers.append($("<div class='wiktku-adv-toggle-row'></div>") .append(optToggle)); helpers.append(advPanel); wrap.append(helpers).append(ta); // Typing directly in textarea keeps cinsiyet/jimar hidden // fields in sync, but does NOT call refresh() — preserves // manual edits. ta.on("input", function () { var text = $(this).val(); var cMatch = text.match(/\|c=([^|}\s]+)/); $("#wiktku-start-cinsiyet-field").val(cMatch ? cMatch[1] : ""); var jMatch = text.match(/\|j=([^|}\s]+)/); $("#wiktku-start-jimar-field").val(jMatch ? jMatch[1] : ""); }); stepDiv.append(wrap); return null; }, /** Reads all helper widget values and rewrites the textarea. * Called only by safeRebuild (user interaction) — never by syncHelpers, * so manual textarea edits are never overwritten by a refresh cycle. */ rebuildTa: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; if (!pos || !lang) return; var cinsiyet = stepDiv.find(".wiktku-posparams-cinsiyet-sel").val() || ""; var jimar = stepDiv.find(".wiktku-posparams-jimar-sel").val() || ""; // Two dropdowns, one code: "gh" / "ngh" on their own, or // prefixed with the structural form ("x-gh", "b-ngh", …). var lekturBase = stepDiv.find(".wiktku-posparams-lektur-sel").val() || ""; var lekturForm = stepDiv.find(".wiktku-posparams-lekturform-sel").val() || ""; var lektur = lekturBase ? (lekturForm ? lekturForm + "-" + lekturBase : lekturBase) : ""; function v(key) { return $.trim(stepDiv.find(".wiktku-posparams-field[data-pp-key='" + key + "']").val()); } var out = "{{" + pos + "|" + lang; if (pos === "navdêr" || pos === "serenav") { out += cinsiyet ? "|c=" + cinsiyet : (lang === "ku" ? "|c=?" : ""); // Number is its own j= param, separate from c= (which // holds gender, including compounds like m-p/n-p). if (jimar) out += "|j=" + jimar; } else if (/^lêker/.test(pos) && lektur) { out += "|c=" + lektur; } if (v("cuda")) out += "|" + v("cuda"); if (v("tr")) out += "|tr=" + v("tr"); if (v("ts")) out += "|ts=" + v("ts"); $.each(["m","n","p","y"], function (_, k) { if (v(k)) out += "|" + k + "=" + v(k); if (v(k+"tr")) out += "|" + k + "tr=" + v(k+"tr"); }); if (v("sûp")) out += "|sûp=" + v("sûp"); if (v("sûptr")) out += "|sûptr=" + v("sûptr"); if (v("komp")) out += "|komp=" + v("komp"); if (v("komptr")) out += "|komptr=" + v("komptr"); if (v("gir")) out += "|gir=" + v("gir"); if (v("girtr")) out += "|girtr=" + v("girtr"); if (v("hûr")) out += "|hûr=" + v("hûr"); if (v("hûrtr")) out += "|hûrtr=" + v("hûrtr"); if (v("hanja")) out += "|hanja=" + v("hanja"); if (v("hanjaTr")) out += "|hanjaTr=" + v("hanjaTr"); if (v("niha")) out += "|niha=" + v("niha"); if (v("nihatr")) out += "|nihatr=" + v("nihatr"); if (v("borî")) out += "|borî=" + v("borî"); if (v("borîtr")) out += "|borîtr=" + v("borîtr"); if (v("subj")) out += "|subj=" + v("subj"); if (v("subjtr")) out += "|subjtr=" + v("subjtr"); stepDiv.find(".wiktku-posparams-opt-panel input:checked").each(function () { var key = $(this).val(); // "form" marks this entry as a form-of/inflected entry — it // takes "erê" rather than the plain "1" the other boolean // opt params use. out += "|" + key + "=" + (key === "form" ? "erê" : "1"); }); out += "}}"; stepDiv.find(".wiktku-posparams-text").val(out); $("#wiktku-start-cinsiyet-field").val(cinsiyet); $("#wiktku-start-jimar-field").val(jimar); }, /** Called from refresh() — controls row visibility only. * Does NOT rewrite textarea so user edits are preserved. * Rebuilds only when textarea is empty (first pos selection). */ syncHelpers: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; var needsTr = needsTransliteration(lang); var isNom = pos === "navdêr" || pos === "serenav" || pos === "rengdêr"; var isAdj = pos === "rengdêr"; var isTîp = pos === "tîp"; var isJa = lang === "ja"; var isLeker = /^lêker/.test(pos); // metadata[lang].g lists gender AND number codes together — // split them here (see isNumberCode) so Cîns only ever offers // gender codes (and gender+plural compounds like m-p/n-p, // which aren't NUMBER_LABELS keys) and Jimar only offers number codes. var meta = metadata[lang]; var allCodes = (meta && meta.g) || []; var genderCodes = $.grep(allCodes, function (c) { return !isNumberCode(c); }); var jimarCodes = $.grep(allCodes, function (c) { return isNumberCode(c); }); var showC = (pos === "navdêr" || pos === "serenav") && genderCodes.length > 0; var cRow = stepDiv.find("#wiktku-posparams-row-c"); cRow.toggle(showC); if (showC) { var sel = cRow.find(".wiktku-posparams-cinsiyet-sel"); // Prefer the select's own current value (normal in-session // use); fall back to the shared hidden field, which is how // a cache/section restore communicates a saved gender // before this select has any <option>s to hold it. var prev = sel.val() || $("#wiktku-start-cinsiyet-field").val() || ""; sel.find("option[value!='']").remove(); $.each(genderCodes, function (_, code) { sel.append($("<option></option>").val(code).text(genderLabel(code))); }); if (prev) sel.val(prev); } var showJimar = (pos === "navdêr" || pos === "serenav") && jimarCodes.length > 0; var jimarRowEl = stepDiv.find("#wiktku-posparams-row-jimar"); jimarRowEl.toggle(showJimar); if (showJimar) { var jimarSelEl = jimarRowEl.find(".wiktku-posparams-jimar-sel"); var prevJimar = jimarSelEl.val() || $("#wiktku-start-jimar-field").val() || ""; jimarSelEl.find("option[value!='']").remove(); $.each(jimarCodes, function (_, code) { var def = NUMBER_LABELS[code] || {}; var opt = $("<option></option>").val(code).text(numberOptionLabel(code)); // The explanation (cat, e.g. "dualia tantum") shows as a // hover tooltip — <option> can't hold richer markup. if (def.cat) opt.attr("title", def.cat); jimarSelEl.append(opt); }); if (prevJimar) jimarSelEl.val(prevJimar); } stepDiv.find("#wiktku-posparams-row-lektur").toggle(isLeker); // Only ask for the structural form once gerguhêz/negerguhêz is answered. stepDiv.find("#wiktku-posparams-row-lekturform") .toggle(isLeker && !!stepDiv.find(".wiktku-posparams-lektur-sel").val()); stepDiv.find("#wiktku-posparams-row-tr").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-ts").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-m").toggle(isNom); stepDiv.find("#wiktku-posparams-row-mtr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-n").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ntr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-p").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ptr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-y").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ytr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-sûp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-sûptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-komp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-komptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-gir").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-girtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hûr").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-hûrtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hanja").toggle(isJa); stepDiv.find("#wiktku-posparams-row-hanjaTr").toggle(isJa); stepDiv.find("#wiktku-posparams-row-niha").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-nihatr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-borî").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-borîtr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-subj").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-subjtr").toggle(isLeker && needsTr); if (!$.trim(stepDiv.find(".wiktku-posparams-text").val())) { steps.posparams.rebuildTa(stepDiv); } }, output: function () { return ""; } // pos.output reads the textarea directly }, dfn: { id: "dfn", name: "Mane", // Field types that live behind "Malûmatên pêşketî". Kept as one // list so the collapse CSS, the count badge and the allGroups // adv: flags below can't drift apart. ADV_SUBGROUPS: [ "wiktku-dfn-etiket", "wiktku-dfn-kategori", "wiktku-dfn-alternativ", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ], question_fmt: function (values) { var base = "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin!"; if (values.lang === "ku") { return base + " Ji bo tercimeyan beşa 'Werger' bi kar bîne!"; } return base; }, multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, // Builds one sense block (<li>): mane textarea, nimûne list, and // sub-lists for alternatîv/hevmane/dijmane/etc. buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Tercime + Îzah boxes (non-ku alternative to the plain mane box) — // Non-ku entries get a direct translation plus a {{îzah|…}}-wrapped // gloss instead of a Kurdish-style gloss. Rather than teach every // consumer (getSenses/getOutput/linkify) a second data shape, these // boxes just write their combined text into dfnArea and re-fire its // "input" event, so dfnArea stays the single source of truth. var tercimeArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-tercime-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-tercime") .attr("rows", 2) .attr("placeholder", "Tercimeyên rasterast ên kurmancî… Ji bo school-a îngilîzî li vir 'mekteb, medrese' binivîse"); var izahArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-izah-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-izah") .attr("rows", 3) .attr("placeholder", "Îzaha kurmancî… Ji bo school-a îngilîzî li vir 'cihê tehsîlgirtinê' binivîse"); var nonKuWrap = $("<div class='wiktku-dfn-nonku-wrap'></div>") .append(tercimeArea).append(izahArea) .hide(); function syncNonKuToMane() { var t = $.trim(tercimeArea.val()); var iz = $.trim(izahArea.val()); // if tercime is blank, use îzah as definition var combined = t ? (iz ? t + " {{îzah|" + iz + "}}" : t) : iz; dfnArea.val(combined); // Re-fires onDfnInput, as if this were typed directly into // the mane textarea. dfnArea.trigger("input"); } tercimeArea.on("input", syncNonKuToMane); izahArea.on("input", syncNonKuToMane); // Switches between the plain mane box and the tercime+îzah pair — // only for non-ku entries with no tplSelect selected. function updateManeMode() { var lang = getValues().lang || ""; var isTpl = !!tplSelect.val(); if (lang && lang !== "ku" && !isTpl) { dfnArea.hide(); nonKuWrap.show(); } else { nonKuWrap.hide(); if (!isTpl) dfnArea.show(); } } // Store on the block so refresh() can re-sync every block when // lang changes, and restoreDfn() can re-sync after restoring. block.data("updateManeMode", updateManeMode); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || {}; // Cache of all non-placeholder option elements, so updateTplOptions // can detach/re-attach them without losing the full list. var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.attr("data-placeholder", "Li şablonekê bigere"); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (name, tpl) { // Shows "name — tpl.desc" when a tplDefs entry has a desc // in data.json, same pattern as steps.pron's template picker. var opt = $("<option></option>") .val(name) .text(tpl.desc ? name + " — " + tpl.desc : name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); // Same status-dot / 🔗 / ⓘ row treatment as every other // template picker. This one carries the bare name in value=, // so the name mapper is the identity rather than a snippet // parse; descriptions come from each template's TemplateData. markTemplateOptions(tplSelect, function (opt) { return opt.val(); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible // ones — native <select> won't reliably hide options any other way. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); // Options that were detached when the descriptions arrived // missed that pass, so describe whatever is attached now. // The cache is warm by this point, so this is synchronous. applyTplDescriptions(tplSelect); tplSelect.trigger("wiktku:refresh"); if (currentVal && !currentStillValid) { tplSelect.val(""); tplTitleInput.hide().val(""); updateManeMode(); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpela hedefê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // Şablon senses have no plain gloss, so hide alternatîv/hevmane/ // dijmane/etc. Etîket, Nimûne and Jêgirtin stay visible either way. function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); nonKuWrap.hide(); tplTitleInput.show().focus(); } else { tplTitleInput.hide().val(""); updateManeMode(); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); // The template picker is an alternative to writing a // definition, not a step before it — so the box comes first // and this sits under it as a quiet link. It only expands // for the minority of senses that are a pointer at another // word (guharto, şaşnivîs, kevnbûyî) rather than a meaning. var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput) .hide(); var tplLink = $("<a href='#' class='wiktku-dfn-tpl-link'></a>") .text("Ev ne pênase ye — şablonek bi kar bîne"); tplLink.on("click", function (e) { e.preventDefault(); tplRow.show(); $(this).hide(); tplRow.find("input.wiktku-ac-input").first().focus(); }); /** Opens the picker without a click — used on restore, when a * sense already has a template and hiding it would make the * chosen value invisible. */ function revealTplRow() { tplRow.show(); tplLink.hide(); } block.data("revealTplRow", revealTplRow); block.append(dfnArea); block.append(nonKuWrap); block.append(tplLink); block.append(tplRow); // Apply lang filter on initial build. updateTplOptions(); updateManeMode(); // — Sub-field groups. — // The four most-used groups (Nimûne, Jêgirtin, Hevmane, Dijmane) // stay open; the rest sit behind the "Malûmatên pêşketî" toggle // (adv: true → .wiktku-dfn-subgroup-adv, keyed off by the collapse CSS). // Jêgirtin isn't in this array — it's a compound widget built // after the loop — but it's inserted right after Nimûne so the // visible order matches the list above. var allGroups = [ { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "wekî etîket lê xuya nabe tenê kategorîze dike", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê", adv: true }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in", adv: true }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e", adv: true }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e", adv: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); if (g.adv) groupDiv.addClass("wiktku-dfn-subgroup-adv"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } // The placeholder names the current language, but that's // often not chosen yet when this block is first built — // so keep a function around that refresh() (and onSubInput, // for newly-grown fields) can call again once lang is set // or changes. function subPlaceholder() { if (g.noLangSuffix) return g.label + "…"; var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return g.label + (langLabel ? " bi " + langLabel : "") + "…"; } function updateSubPlaceholders() { list.find("> li > textarea.wiktku-dfn-subfield").attr("placeholder", subPlaceholder()); } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": ") .append($("<span></span>").addClass("wiktku-dfn-sublabel-hint").text(g.izah)); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var useModifiers = !!MODIFIER_SUBGROUPS[g.cls]; list.data("updatePlaceholders", updateSubPlaceholders); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", subPlaceholder()); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow, useModifiers); }); list.append(useModifiers ? makeModifierLi(firstInput) : $("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder group — growing list, same structure as Nimûne. — (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text("Jêgirtin")) .append(": "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<textarea></textarea>") .addClass("wiktku-dfn-subfield wiktku-dfn-quote-citoid-input") .attr("rows", 1) .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi otomatîk tijî bike", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); // Fetches citation data from Citoid and fills this citation's // şablon + fields — only rebuilds fields on template change, // and never overwrites values the user already typed. function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoid.fetchJederFields(query).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only rebuild if switching şablon, so a repeat fetch // doesn't clear fields already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel wiktku-plain-select"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); srcSel.append($("<option></option>").val("__category__").text("Ji Kategorî:Çavkanî şablonekê hilbijêre")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); // Citoid is only useful before a source is chosen — // hide it once a selection is made, restore on reset. if (chosen) { citoidWrap.hide(); } else { citoidWrap.show(); return; } if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } if (chosen === "__category__") { // Search widget over the members of [[Kategorî:Çavkanî]]. // Picking a şablon here immediately switches the row to // "Bi destê xwe binivîsim" mode with {{Şablon}} pre-filled, var catWrap = $("<span></span>").addClass("wiktku-native-select-wrap wiktku-dfn-quote-src-cat"); var catInput = $("<input type='search' autocomplete='off'>") .addClass("wiktku-start-narrow wiktku-dfn-quote-src-cat-input") .attr("placeholder", "Li navê şablonê bigere…"); var catResults = $("<ul></ul>").addClass("wiktku-ac-results wiktku-dfn-quote-src-cat-results").hide(); var catStatus = $("<span></span>").addClass("wiktku-dfn-quote-src-cat-status").text("Şablon tên barkirin…"); var showCatResults = function (query) { var q = $.trim(query).toLowerCase(); catResults.empty(); var list = catSrcTemplates || []; var matched = q ? $.grep(list, function (name) { return name.toLowerCase().indexOf(q) !== -1; }) : list; if (!matched.length) { catResults.hide(); return; } $.each(matched.slice(0, 50), function (_, name) { var li = $("<li></li>").text(name).attr("data-value", name); var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; e.preventDefault(); selectCatTpl(name); }); li.on("mousedown", function (e) { e.preventDefault(); selectCatTpl(name); }); catResults.append(li); }); catResults.show(); }; // Wraps the chosen şablon as {{Name}}, drops it into the // manual textarea, and switches the row into manual mode // so the user can keep editing it (add params, etc.). var selectCatTpl = function (name) { catResults.hide(); srcSel.val("__manual__"); srcSel.trigger("change"); srcFields.find(".wiktku-dfn-quote-src-manual") .val("{{" + name + "}}") .trigger("focus"); }; catInput.on("input", function () { showCatResults($(this).val()); }); catInput.on("focus", function () { showCatResults($(this).val()); }); catInput.on("blur", function () { setTimeout(function () { catResults.hide(); }, 200); }); catWrap.append(catInput).append(catResults).append(catStatus); srcFields.append(catWrap); fetchCatSrcTemplates().then(function () { catStatus.text(""); }, function () { catStatus.text("Şablon nehatin barkirin."); }); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (key, label) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", key) .attr("placeholder", label + "…"); // "Sernav" / "Sernavê orjînal" (title fields, e.g. for // kitêb/kovar/malper) get a taller, draggable box; every // other field in the template stays as-is. Field labels // come from the on-wiki jederDefs data, so match on the // (diacritic-folded) label text rather than a fixed key. var foldedLabel = foldDiacritics(label); if (/^sernav$/.test(foldedLabel) || /orjin/.test(foldedLabel)) { inp.addClass("wiktku-dfn-quote-src-input--title"); } row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); jederGroupDiv.append(jederLbl).append(jederList); // Straight after Nimûne rather than last: Jêgirtin is the // same kind of thing (an attested use of the word) and the // two belong together — see the allGroups comment above. var nimuneGroup = block.find(".wiktku-dfn-nimune-group"); if (nimuneGroup.length) jederGroupDiv.insertAfter(nimuneGroup); else block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); // ── "Malûmatên pêşketî" — per sense, after Dijmane ─────── // One toggle per sense rather than one for the whole step: // the fields behind it (Etîket, Kategorî, Jornav…) belong to // a single meaning, so a global switch flipped them for every // sense at once and gave a count that answered "across all // senses" — not a question anybody was asking. (function () { block.addClass("wiktku-sense-adv-hidden"); var advRow = $("<div class='wiktku-adv-toggle-row wiktku-sense-adv-row'></div>"); var advToggle = $("<a href='#' class='wiktku-adv-toggle'></a>").attr("aria-expanded", "false"); var advLabel = $("<span class='wiktku-adv-toggle-text'></span>"); advToggle.append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")).append(advLabel); function syncAdv() { var hidden = block.hasClass("wiktku-sense-adv-hidden"); advLabel.text(hidden ? "Malûmatên pêşketî nîşan bide" : "Malûmatên pêşketî veşêre"); advToggle.attr("aria-expanded", hidden ? "false" : "true") .toggleClass("wiktku-adv-open", !hidden); } advToggle.on("click", function (e) { e.preventDefault(); block.toggleClass("wiktku-sense-adv-hidden"); syncAdv(); }); block.data("syncSenseAdv", syncAdv); advRow.append(advToggle); // After the last always-visible group (Dijmane) and before // the advanced ones, which sit below it in DOM order. var lastPrimary = block.find(".wiktku-dfn-dijmane-group"); if (lastPrimary.length) advRow.insertAfter(lastPrimary); else block.append(advRow); syncAdv(); }()); return block; }, /** Shows only `block` among the sense list; hides every other one. */ setOpenSense: function (stepDiv, block) { stepDiv.find("li.wiktku-dfn-sense").each(function () { $(this).toggleClass("wiktku-sense-collapsed", !$(this).is(block)); }); steps.dfn.renderSenseTabs(stepDiv); }, /** Rebuilds the "Mane 1 / Mane 2 / + Mane zêde bike" tab row from the current sense list. */ renderSenseTabs: function (stepDiv) { var tabsDiv = stepDiv.find(".wiktku-dfn-sense-tabs"); if (!tabsDiv.length) return; tabsDiv.empty(); var senseCount = stepDiv.find("li.wiktku-dfn-sense").length; stepDiv.find("li.wiktku-dfn-sense").each(function (i) { var li = $(this); var tab = $("<span class='wiktku-dfn-sense-tab'></span>") .toggleClass("wiktku-tab-active", !li.hasClass("wiktku-sense-collapsed")); tab.append($("<span class='wiktku-tab-label'></span>").text("Mane " + (i + 1))); tab.on("click", function () { steps.dfn.setOpenSense(stepDiv, li); }); // Always keep at least one Mane — no delete button when // it's the only sense left. if (senseCount > 1) { var trash = makeTrashButton("Vê maneyê jê bibe"); trash.on("click", function (e) { // Stop this from also reaching the tab's own click // handler above (which would just re-open it). e.preventDefault(); e.stopPropagation(); if (!window.confirm("Tu dixwazî Mane " + (i + 1) + " jê bibî? Ev tişt nayê vegerandin.")) return; steps.dfn.removeSense(stepDiv, li); }); tab.append(trash); } tabsDiv.append(tab); }); var addBtn = $("<button type='button' class='wiktku-add-sense'></button>") .append($("<span class='wiktku-add-sense-plus'>+</span>")) .append(document.createTextNode("Mane zêde bike")); addBtn.on("click", function (e) { e.preventDefault(); steps.dfn.addSense(stepDiv); }); tabsDiv.append(addBtn); }, onDfnInput: function (stepDiv, block, textarea) { refresh(); }, /** Appends a sense, opens it, and hides the others. */ addSense: function (stepDiv) { var list = stepDiv.find("ol.wiktku-dfn-list"); var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); initSelects(newBlock); steps.dfn.setOpenSense(stepDiv, newBlock); newBlock.find("textarea.wiktku-dfn-mane").first().focus(); refresh(); return newBlock; }, /** Removes one sense block. Assumes the caller already confirmed * and already checked more than one sense remains. If the * removed sense was the open one, opens whichever sense ends up * taking its place (or the last one, if it was the last). */ removeSense: function (stepDiv, li) { var list = stepDiv.find("ol.wiktku-dfn-list"); var blocks = list.find("li.wiktku-dfn-sense"); var removedIdx = blocks.index(li); var wasOpen = !li.hasClass("wiktku-sense-collapsed"); li.remove(); if (wasOpen) { var remaining = list.find("li.wiktku-dfn-sense"); var next = remaining.eq(removedIdx); if (!next.length) next = remaining.last(); if (next.length) steps.dfn.setOpenSense(stepDiv, next); } steps.dfn.renderSenseTabs(stepDiv); refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow, modifiers) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow, modifiers); }); list.append(modifiers ? makeModifierLi(next) : $("<li></li>").append(next)); // New field starts with no placeholder — give it (and any // others in the list) the current one. var updatePlaceholders = list.data("updatePlaceholders"); if (typeof updatePlaceholders === "function") updatePlaceholders(); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: {}, posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; // One reassurance, shown once for the whole Mane step: the // "an jî şablonek hilbijêre" dropdown inside each sense is // optional — plain text is the normal path. if (!stepDiv.find(".wiktku-dfn-tpl-hint").length) { stepDiv.append( $("<p class='wiktku-step-hint wiktku-dfn-tpl-hint'></p>").text( "Ji bo her maneyekê, dropdown-a \"an jî şablonek hilbijêre\" ne mecbûrî ye — bi gelemperî tu tenê maneyê bi tîpên asayî dinivîsî. Ew şablon tenê ji bo rewşên taybet in (mînak: guherto, kevnbûyî, şaşnivîs); heke tu nizanî kîjan divê, vale bihêle." ) ); } var tabsDiv = $("<div class='wiktku-dfn-sense-tabs'></div>"); stepDiv.append(tabsDiv); var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); steps.dfn.renderSenseTabs(stepDiv); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName === "__category__") { // Reachable only if the user opened the category search but // never picked a şablon — picking one switches the row to // __manual__ (see selectCatTpl above), so there's nothing // meaningful to save here. } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: readList("wiktku-dfn-etiket"), kategori: readList("wiktku-dfn-kategori"), nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense var izahLines = []; // parallel — raw îzah gloss for that same sense // True only once some sense's *actual* dfn text (post tercime/îzah // split) is non-empty. var hasLinkableMane = false; $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("# " + (tplKatTpl ? tplKatTpl + " " : "") + (tplLabelTpl ? tplLabelTpl + " " : "") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(""); // template senses have no îzah return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty // Pull the îzah gloss (if any) out of the combined tercime+îzah // string — it's spliced back in separately below, after its // own linkify pass (see izahLines / the second linkifyText call). var izahRaw = null; var tercimeIzah = splitTercimeIzah(dfn); if (tercimeIzah) { dfn = tercimeIzah.tercime; izahRaw = stripWikilinks(tercimeIzah.izah); } if (dfn) { dfn = stripWikilinks(dfn); // Sentence-case + trailing period are for ku definitions, // which are written as full glosses. if (lang === "ku") { if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } // Real prose — this is what makes the sense worth running // through the main linkify pass. hasLinkableMane = true; } else if (izahRaw === null) { // No mane at all — this is just the "{{mane?|lang}}" // placeholder, a bare template call with no plain words // in it. Do NOT count it as linkable: sending nothing but // bracketed templates through the main linkify pass hangs // the linkify gadget (see the hasLinkableMane/hasIzah // check below). dfn = lang === "ku" ? "{{mane?|" + lang + "}}" : ""; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var out = "# " + (katTpl ? katTpl + " " : "") + (labelTpl ? labelTpl + " " : "") + dfn; var idx = defLines.length; var hasThisIzah = izahRaw !== null && $.trim(izahRaw) !== ""; // Bare {{...}} token — like {{wiktku-cite-N}}, this survives // linkify's first pass untouched (it treats template calls as // opaque), then gets swapped for {{îzah|…}} once the actual // gloss text has been linkified in its own separate pass. if (hasThisIzah) { out += (dfn ? " " : "") + "{{wiktku-izah-" + idx + "}}"; } function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(hasThisIzah ? izahRaw : ""); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } // Runs text through the linkify gadget if it's loaded, otherwise // just passes it through unchanged. Shared by both linkify passes // below (main mane text, and — separately — îzah glosses). function linkifyText(t, cb) { if (typeof $.kuLinkify === "function") { $.kuLinkify(t, cb); } else { cb(t); } } var hasIzah = izahLines.some(function (t) { return t && $.trim(t) !== ""; }); var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with nimûne?. text = "# {{mane?|" + lang + "}}\n#* {{nimûne?|" + lang + "}}\n"; callback(text); return; } // Runs the îzah-only linkify pass against `base` (either the raw // text, when there's no linkable mane to run the main pass on // first, or the already-linkified main text). Shared by both // branches below so the token-splice logic only lives once. function runIzahPass(base) { var izahJoined = $.map(izahLines, function (raw, idx) { if (!raw) return undefined; return "{{wiktku-izah-open-" + idx + "}}" + raw + "{{wiktku-izah-close-" + idx + "}}"; }).join("\n"); linkifyText(izahJoined, function (izahLinked) { var izahByIdx = {}; var re = /\{\{wiktku-izah-open-(\d+)\}\}([\s\S]*?)\{\{wiktku-izah-close-\1\}\}/g; var m; while ((m = re.exec(izahLinked)) !== null) { izahByIdx[parseInt(m[1], 10)] = m[2]; } var withIzah = base.replace(/\{\{wiktku-izah-(\d+)\}\}/g, function (_, n) { var linked = izahByIdx[parseInt(n, 10)]; return linked !== undefined ? "{{îzah|" + linked + "}}" : ""; }); callback(restoreCites(withIzah)); }); } if (!hasLinkableMane) { if (!hasIzah) { // All filled senses are template senses (or otherwise have // no plain text at all) — nothing here needs linkify. callback(restoreCites(text)); return; } // There's no plain mane text anywhere (e.g. tercime left blank // with only îzah filled in), so every defLine is just a bare // template call with nothing to word-link. Sending a line // like "# {{wiktku-izah-0}}" through the main linkify pass // gives it no plain words to work with, makes the linkify // gadget hang — so skip that pass entirely and run only // the îzah pass, splicing straight into the unlinkified text. var loadIzahOnly = function () { runIzahPass(text); }; mw.loader.using("ext.gadget.linkify", loadIzahOnly, loadIzahOnly); return; } var didTryToLoad = function () { // First pass: the main definition text (mane), same as before. linkifyText(text, function (mainLinked) { if (!hasIzah) { callback(restoreCites(mainLinked)); return; } // Second pass: îzah glosses, linkified via their own // separate call. Each gloss is wrapped in its own // {{wiktku-izah-open/close-N}} pair; like the existing // {{wiktku-cite-N}} tokens, these sit inside double // braces so linkify leaves the tokens themselves alone — // only the raw gloss text between each pair gets linked. runIzahPass(mainLinked); }); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, tewandin: { id: "tewandin", name: "tewandin", question_fmt: 'Tewandina "' + pageName + '" binivîse', visible: function (values) { return values.lang && values.pos; }, build: function (stepDiv) { if (stepDiv.find(".wiktku-tewandin-wrap").length) return null; var wrap = $("<div class='wiktku-tewandin-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-tewandin-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-tewandin-text") .attr("rows", 4) .attr("placeholder", "{{ku-tewîn-nav|nêr}}"); wrap.append(ta); stepDiv.append(wrap); function autoPopulate() { if (!ta.length) return; var vals = getValues(); var c = vals.cinsiyet || ""; var p = vals.pos || ""; if (!pageName.includes(" ") && c && GENDER_BASE_LABELS[c] && (p === "navdêr" || p === "serenav") && vals.lang === "ku" && c !== "mndudil") { var label = (c === "mnmane") ? "mê û nêr" : GENDER_BASE_LABELS[c]; var out = "{{ku-tewîn-nav|" + label; if (p === "serenav") out += "|y"; out += "}}"; if (!$.trim(ta.val())) ta.val(out); } } setTimeout(function () { autoPopulate(); $("#wiktku-start-form").on("change.tewandin", "#wiktku-start-lang-field, #wiktku-start-cinsiyet-field, #wiktku-start-pos-field", autoPopulate); }, 0); return ta; }, output: function () { var manualText = $.trim($("#wiktku-start-tewandin .wiktku-tewandin-text").val()); if (manualText) { return "\n==== Tewandin ====\n" + manualText + "\n"; } return ""; } }, // resim — one or more images resim: { id: "resim", name: "resim", question_fmt: "Resmekê lê zêde bike", visible: function (values) { return !!(values.lang && values.pos); }, /** Builds one image row: filename + caption + alt text. */ buildItem: function (stepDiv) { var item = $("<li class='wiktku-resim-item'></li>"); var fileRow = $("<div class='wiktku-posparams-row'></div>"); var fileInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-file") .attr("placeholder", "navê_dosyayê.jpg"); fileRow.append($("<label></label>").text("Navê dosyayê: ")).append(fileInp); var capRow = $("<div class='wiktku-posparams-row'></div>"); var capInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-caption") .attr("placeholder", "Danasîna resimê…"); capRow.append($("<label></label>").text("Danasîn: ")).append(capInp); // Alt text: what a screen reader announces for this image var altRow = $("<div class='wiktku-posparams-row'></div>"); var altInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-alt") .attr("placeholder", "Ji bo kesên nabînin, çi tê dîtin? (ne mecbûrî)"); altRow.append($("<label></label>").text("Nivîsa alternatîf: ")).append(altInp); // Auto-fill the caption with the plain page name when a filename // is typed fileInp.on("input", function () { var file = $.trim($(this).val()); var curCap = $.trim(capInp.val()); var isDefault = !curCap || curCap === pageName; if (file && isDefault) { capInp.val(pageName); } else if (!file && isDefault) { capInp.val(""); } steps.resim.onFileInput(stepDiv, item, this); }); item.append(fileRow).append(capRow).append(altRow); return item; }, /** Grows the image list when the last row's filename gets content. */ onFileInput: function (stepDiv, item, input) { var val = $.trim($(input).val()); var list = stepDiv.find("ol.wiktku-resim-list"); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { list.append(steps.resim.buildItem(stepDiv)); } }, build: function (stepDiv) { if (stepDiv.find(".wiktku-resim-wrap").length) return null; var wrap = $("<div class='wiktku-resim-wrap'></div>"); var list = $("<ol class='wiktku-resim-list'></ol>"); list.append(steps.resim.buildItem(stepDiv)); wrap.append(list); stepDiv.append(wrap); return null; }, /** Reads every filled row from the DOM into an array of {file, caption, alt} * objects — blank rows (missing filename or caption) are skipped. * Non-Kurdish captions get wrapped in {{zim|lang|…}} here, unless * the user already typed their own {{zim|…}} template. Alt text is * optional and left as plain text either way. */ getImages: function (values) { var lang = (values && values.lang) || getValues().lang || ""; var images = []; $("#wiktku-start-resim li.wiktku-resim-item").each(function () { var file = $.trim($(this).find(".wiktku-resim-file").val()); var caption = $.trim($(this).find(".wiktku-resim-caption").val()); var alt = $.trim($(this).find(".wiktku-resim-alt").val()); if (!file || !caption) return; // Strip leading "Wêne:" or "File:" if the user typed it — we add it ourselves. file = file.replace(/^(wêne|file|image)\s*:\s*/i, ""); if (lang && lang !== "ku" && !/^\{\{zim\s*\|/i.test(caption)) { caption = "{{zim|" + lang + "|" + caption + "}}"; } images.push({ file: file, caption: caption, alt: alt }); }); return images; }, output: function (values) { var images = steps.resim.getImages(values); if (!images.length) return ""; return images.map(function (img) { var altPart = img.alt ? "|alt=" + img.alt : ""; return "[[Wêne:" + img.file + "|thumb" + altPart + "|" + img.caption + "]]"; }).join("\n") + "\n"; } }, // bnr-h — {{bnr-h|Page1|Page2|…}} prepended before the lang section (shared, not per-section) bnrh: { id: "bnrh", name: "binêre herwiha (bnr-h)", question_fmt: "Şablona bnr-h li qismê herî jor a rûpelê", //visible: function (values) { return !!values.lang; }, multiple: true, narrow: true, placeholder: "Ji bo 'test' bnr 'Test', 'teşt'", output: function (values) { var pages = $.grep(values.bnrh || [], function (p) { return !!$.trim(p); }); if (!pages.length) return ""; return "{{bnr-h|" + pages.map(function (p) { return $.trim(p); }).join("|") + "}}\n"; } }, bikaranin: { id: "bikaranin", name: "Notên bikaranînê", question_fmt: "Notên bikaranînê yên li ser vê kelîmeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, output: function (values) { var text = $.trim(values.bikaranin || ""); if (!text) return ""; return "\n==== Notên bikaranînê ====\n" + text + "\n"; }, }, xwendin: { id: "xwendin", name: "Bêhtir bixwîne", question_fmt: "Lînkên derveyî eleqedarî vê madeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: function (values) { if (!values || !values.lang) { return `* {{wpedî}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; } const ziman = values.lang === "ku" ? "" : `|ziman=${values.lang}`; return `* {{wpedî${ziman}}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; }, output: function (values) { var text = $.trim(values.xwendin || ""); if (!text) return ""; return "\n==== Bêhtir bixwîne ====\n" + text + "\n"; }, }, alfabeyendin: { id: "alfabeyendin", name: "Bi alfabeyên din", question_fmt: function (values) { var base = "Nivîsîna vê kelîmeyê bi alfabeyên din" var langLabel = values.lang ? getLangLabel(values.lang) : ""; if (langLabel) { return base + " ên " + langLabel; } return base; }, visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: "Ji bo kurmancî: * {{ku-ar|şiklê alfaba erebî}}", output: function (values) { var text = $.trim(values.alfabeyendin || ""); if (!text) return ""; return "\n==== Bi alfabeyên din ====\n" + text + "\n"; }, }, formalt: makeWordListStep("formalt", "formên alternatîv", "Formên alternatîv ên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), hevmane: makeWordListStep("hevmane", "hevmane", "Hevmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), dijmane: makeWordListStep("dijmane", "dijmane", "Dijmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jornav: makeWordListStep("jornav", "jornav", "Jornavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jernav: makeWordListStep("jernav", "jêrnav", "Jêrnavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse"), binereherwiha: makeWordListStep("binereherwiha", "herwiha binêre", "Kelîmeyên din ên eleqedar binivîse"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: {}, visible: function (values) { return values.lang && values.pos; }, // Fills the insert-dropdown from the current etymTpls object. refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(ta); stepDiv.append(wrap); initSelects(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder. // Skip it only when every filled sense is a şablon sense // a completely empty entry with no şablon chosen still gets the placeholder var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasFilledTplSense = dfnSenses.some(function (s) { return !!s.tpl && !!s.tplTitle; }); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (hasFilledTplSense && !hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: function (values) { return {"navz": true, [values.lang]: true} }, // Language dropdown + growing word-input list; a new row appends // when the dropdown gets a value. Mirrors steps.trans, but flat. buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/build below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Attach the searchable picker now the select is in the DOM. initSelects(list); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", question_fmt: "'"+ pageName + "' di zaravayên din de çawa tê gotin?", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: {}, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zaravayekî bigere"); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; // A completely empty entry still gets a placeholder section // to fill in later; an individual placeholder gloss is only // skipped once some other sense already has real content. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", question_fmt: "Tercimeyên vê maneyê bi zimanên din binivîse", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide only when every sense is a filled template sense (no plain // gloss to attach translations to). A mix, or nothing filled in // yet, still shows Werger. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, // Language dropdown + growing word-input list, scoped to one gloss's // group (each gloss has its own group and row list). buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/buildGroup below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, // Builds (or fetches) the .wiktku-trans-group for one gloss. buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, // Syncs one .wiktku-trans-group per current gloss, keyed by // data-gloss-pos so groups stay matched across rebuilds. build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, // Reads all translation rows, grouped by gloss position. getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, // Builds the numbered "{ index, gloss }" list, one per dfn sense // with a real mane (skips template senses). index is 1-based and // matches the sense's position in the "#" definition list. // When nothing's filled in, returns one placeholder entry so // Werger still has a group to attach to; when every sense is a // filled template sense, stays empty (matches trans.visible()). glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane, but other fields are filled — still gets a // gloss group since dfn.getOutput() emits {{mane?}} for it. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // A completely empty entry (nothing filled in dfn at all, no // şablon chosen either) still gets a placeholder Werger section // to fill in later. Only // skip an individual placeholder gloss below when some other // sense actually has real content, making that particular // placeholder redundant. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it. If some other sense already has real // content, this placeholder is redundant — skip it. If the // whole entry is empty, keep it so Werger still gets a // section to fill in. if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, cavkani: { id: "cavkani", name: "çavkanî", question_fmt: "Çavkaniyên din (ne jêgirtin) lê zêde bike", visible: function (values) { return !!values.pos; }, // Fills the insert-dropdown from the members of [[Kategorî:Çavkanî]]. refreshTplSelect: function () { var sel = $("#wiktku-start-cavkani .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(catSrcTemplates || [], function (_, name) { sel.append($("<option></option>").val(name).text(name)); }); markTemplateOptions(sel, function (opt) { return opt.val(); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-cavkani-wrap").length) return null; var wrap = $("<div class='wiktku-cavkani-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-cavkani-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-cavkani-text") .attr("rows", 4) .attr("placeholder", "Şablonekî ji lîsteyê hilbijêre an rasterast binivîse…"); // Template insert dropdown, populated from [[Kategorî:Çavkanî]] — // options refreshed once the category members are fetched. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var status = $("<span class='wiktku-cavkani-status'></span>"); sel.on("change", function () { var name = $(this).val(); if (!name) return; insertAtCursor(ta[0], "\n* {{" + name + "}}"); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(status).append(ta); stepDiv.append(wrap); // build() runs again for every new beş (see the "+ Beş zêde bike" // handler), after the initial page-wide pass — so this select needs // its own init or it stays a plain, unsearchable native <select>. initSelects(wrap); if (catSrcTemplates) { steps.cavkani.refreshTplSelect(); } else { status.text("Şablon tên barkirin…"); fetchCatSrcTemplates().then(function () { steps.cavkani.refreshTplSelect(); status.text(""); }, function () { status.text("Şablon nehatin barkirin."); }); } return ta; }, output: function () { var text = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); if (!text) return ""; return "\n==== Çavkanî ====\n" + text + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); // This array only controls DOM build order — nothing else keys off it // (see the comment above stepIdToGroup). Mane tab order: Mane (senses, // with malûmatên pêşketî nested inside each, see steps.dfn.build) → // Wêne → Bi zaravayên din → Werger, so dfn/resim/zarava/trans sit // adjacent to each other in that order. var ordered_steps = [ steps.lang, steps.pos, steps.posparams, steps.cinsiyet, steps.jimar, steps.lektur, steps.tr, // Mane tab, in reading order: the senses, then the two things that // belong to the entry as a whole rather than to one sense. steps.dfn, steps.tewandin, steps.alfabeyendin, steps.zarava, steps.trans, // Etîmolojî tab. steps.etym, steps.dunde, // Eleqedar tab — three lists of the same shape. steps.je, steps.tekildar, steps.binereherwiha, // Bilêvkirin isn't part of any STEP_GROUPS tab, but still needs a // slot here because this array is what builds the DOM. steps.pron, // Beşên din, behind the picker. steps.resim, steps.bnrh, steps.bikaranin, steps.formalt, steps.hevmane, steps.dijmane, steps.jornav, steps.jernav, steps.cavkani, steps.xwendin]; // ── Step-group tabs ────────────────────────────────────────────────────── // Four tabs: "Mane" holds the senses (whose own blocks carry Nimûne, // Jêgirtin, Hevmane and Dijmane — see steps.dfn.allGroups), Tewandin, // alfabeyendin, zarava and trans; "Etîmolojî" and "Eleqedar" split out // the two other topical clusters; everything else lives behind the // "Beşên din" picker. "mane" stays first as the default-active tab // since Mane is required content. Tewandin keeps its own free-text // {{ku-tewîn-nav}} field and does NOT absorb the Cins/zayend form // parameters (m=/n=/p=), which stay on the headword template. var STEP_GROUPS = [ { id: "mane", label: "Mane", steps: ["dfn", "tewandin", "alfabeyendin", "zarava", "trans"] }, { id: "etimoloji", label: "Etîmolojî", steps: ["etym", "dunde"] }, { id: "eleqedar", label: "Eleqedar", steps: ["je", "tekildar", "binereherwiha"] }, { id: "besendin", label: "Beşên din", steps: ["resim", "formalt", "hevmane", "dijmane", "jornav", "jernav", "bikaranin", "cavkani", "xwendin", "bnrh"] }, ]; // Steps that live behind the "Beşên din" picker — only these need an // explicit "open" before they're shown, even when their tab is active. // Derived from the group above so it can't drift out of sync. var BESENDIN_STEP_IDS = STEP_GROUPS[3].steps; // Reverse lookup: step id -> index into STEP_GROUPS (undefined for // ungrouped steps — now only lang/pos/posparams/cinsiyet/lektur/tr, // which stay always-visible since they're required to get to everything // else). var stepIdToGroup = {}; $.each(STEP_GROUPS, function (gi, g) { $.each(g.steps, function (_, sid) { stepIdToGroup[sid] = gi; }); }); // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "posparams", "cinsiyet", "jimar", "lektur", "tr", "resim", "dfn", "tewandin", "formalt", "bikaranin", "alfabeyendin", "hevmane", "dijmane", "jornav", "jernav", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans", "cavkani", "xwendin" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; // ── Bilêvkirin as a standalone section ─────────────────────────────── // Pronunciation belongs to the word, not to one part of speech, so it // sits beside Navdêr/Lêker in the tab bar rather than inside any of them. // Modelled as a flag rather than an entry in `sections` since // activeSection is used as an array index in many places — viewing // Bilêvkirin leaves activeSection pointing at the POS section you were on. var viewingPron = false; // is it the tab currently on screen // Which STEP_GROUPS tab is currently shown. Lives out here (like // activeSection above) so refresh() — which is not nested inside build() // — can read it and so renderGroupTabs()/updateGroupTabIndicators() below // can be called from refresh() too. Both operate on the tab bar via its // #wiktku-group-tabs id rather than a closured element reference, for the // same reason. var activeGroup = 0; // Unsaved-changes / autosave state. Lives out here (same reason as // activeGroup above) so destroy() — which runs on final submit and on // switching to the source editor, and is not nested inside build() — // can clear the timers and the beforeunload warning. build() assigns // into these; it doesn't re-declare them. var formDirty = false; var autosaveDebounceTimer = null; var autosaveInterval = null; /** Re-renders the step-group tab bar to reflect the current activeGroup. */ function renderGroupTabs() { var groupTabsDiv = $("#wiktku-group-tabs"); if (!groupTabsDiv.length) return; groupTabsDiv.empty(); $.each(STEP_GROUPS, function (i, g) { var tab = $("<span></span>") .addClass("wiktku-group-tab") .attr("data-group-idx", i) .text(g.label) .toggleClass("wiktku-tab-active", i === activeGroup); (function (idx) { tab.on("click", function () { if (idx === activeGroup) return; activeGroup = idx; renderGroupTabs(); if (idx === BESENDIN_GROUP_IDX) renderBesenDinPicker(); refresh(); // Switching tabs can shorten the page (e.g. leaving a long // "Beşên din" field), and the browser may clamp the scroll // position on its own timing before our measurement runs. // Deferring one frame lets that settle first, so the // offsetTop read below is the final, post-refresh one. window.requestAnimationFrame(function () { var bar = document.getElementById("wiktku-group-tabs"); if (!bar) return; var form = document.getElementById("wiktku-start-form"); var stabsH = form ? (parseFloat(form.style.getPropertyValue("--wiktku-stabs-h")) || 0) : 0; var siteHeaderH = form ? (parseFloat(form.style.getPropertyValue("--wiktku-siteheader-h")) || 0) : 0; var top = bar.getBoundingClientRect().top + window.pageYOffset - stabsH - siteHeaderH; $("html, body").animate({ scrollTop: Math.max(0, top) }, 200); }); }); }(i)); groupTabsDiv.append(tab); }); } /** * Toggles a "needs attention" dot on any group tab that still has a * required, unfilled field hidden inside it — so switching tabs doesn't * leave the person wondering why "Bişîne" stays disabled. */ function updateGroupTabIndicators(values) { var tabs = $("#wiktku-group-tabs .wiktku-group-tab"); if (!tabs.length) return; $.each(STEP_GROUPS, function (i, g) { var missing = false; $.each(g.steps, function (_, sid) { var step = steps[sid]; if (!step || !step.required) return; var val = values[sid]; if (val === "" || (step.multiple && $.isArray(val) && val.join("") === "")) { missing = true; } }); tabs.eq(i).toggleClass("wiktku-tab-missing", missing && i !== activeGroup); }); } // "Beşên din" reveals one field at a time via a picker rather than // stacking them all. Per-section state, snapshotted in // saveCurrentSection() and restored in restoreSection() below, and // auto-seeded from any field that already has content (so a returning // draft doesn't hide something already filled in). var openedOtherSections = {}; var BESENDIN_SET = {}; $.each(BESENDIN_STEP_IDS, function (_, sid) { BESENDIN_SET[sid] = true; }); // "besendin"'s index in STEP_GROUPS. Derived rather than hardcoded — // this was a literal 2 and silently pointed at the wrong tab the moment // Etîmolojî and Eleqedar were inserted ahead of it. var BESENDIN_GROUP_IDX = (function () { for (var i = 0; i < STEP_GROUPS.length; i++) { if (STEP_GROUPS[i].id === "besendin") return i; } return STEP_GROUPS.length - 1; }()); /** Re-renders the "Beşên din" picker to list only the not-yet-opened sections. */ function renderBesenDinPicker() { var wrap = $("#wiktku-besendin-picker"); if (!wrap.length) return; wrap.empty(); var pickerValues = getValues(); var unopened = $.grep(BESENDIN_STEP_IDS, function (sid) { if (openedOtherSections[sid]) return false; // Don't offer a section that would open onto nothing: several of // these are gated (Bi zaravayên din / Werger need lang=ku, most // need a pos). refresh() would hide it again straight away, so // picking it would read as a broken dropdown. var step = steps[sid]; if (step && typeof step.visible === "function") { try { if (!step.visible(pickerValues)) return false; } catch (e) { /* a step whose visible() needs DOM we lack yet — offer it */ } } return true; }); if (!unopened.length) return; // everything's open — nothing left to pick var sel = $("<select class='wiktku-besendin-select'></select>"); sel.attr("data-placeholder", "— beşek hilbijêre —"); sel.append($("<option value=''>— beşek hilbijêre —</option>")); $.each(unopened, function (_, sid) { var step = steps[sid]; if (!step) return; sel.append($("<option></option>").val(sid).text(capitalize(step.name))); }); sel.on("change", function () { var sid = $(this).val(); if (!sid) return; openedOtherSections[sid] = true; // Newly opened section moves right under the picker, ahead of // whatever's already open, instead of wherever it happened to // sit in the fixed step order. $("#wiktku-start-" + sid).insertAfter(wrap); renderBesenDinPicker(); refresh(); }); wrap.append(sel); initSelects(wrap); } /** Marks any BESENDIN_STEP_IDS field that already has real content as * "opened", so restoring a draft doesn't bury filled-in sections behind * the picker. Reuses each step's own output() as the emptiness check — * it already knows what "empty" means per field, and it reads the DOM * the restore just populated. Call this AFTER the DOM has the restored * values in it. */ function seedOpenedFromContent() { var values = getValues(); $.each(BESENDIN_STEP_IDS, function (_, sid) { if (openedOtherSections[sid]) return; var step = steps[sid]; if (!step || typeof step.output !== "function") return; try { if (step.output(values)) openedOtherSections[sid] = true; } catch (e) { /* a step whose output() needs more state than we have yet — skip it */ } }); } function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } // Rebuilds the dfn DOM from a previously snapshotted senses array. function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing tab bar + list so build() recreates them cleanly. stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); // The picker is collapsed behind a link by default; a restored // sense that already uses a template has to show it, or the // chosen template is invisible and looks lost. var reveal = block.data("revealTplRow"); if (typeof reveal === "function") reveal(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // dfnArea is the only thing actually saved, so split it back into // tercime/îzah for editing (mirrors syncNonKuToMane's join format). var maneParts = splitTercimeIzah(sense.mane); block.find(".wiktku-dfn-tercime").val(maneParts ? maneParts.tercime : (sense.mane || "")); block.find(".wiktku-dfn-izah").val(maneParts ? maneParts.izah : ""); // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Same for the mane-box mode (plain vs tercime+îzah), since this // also depends on tplSelect's (and lang's) value. var updateMane = block.data("updateManeMode"); if (updateMane) updateMane(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found var useModifiers = !!MODIFIER_SUBGROUPS[cls]; // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true, useModifiers); }); subList.append(useModifiers ? makeModifierLi(ta) : $("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text).each(function () { highlightLinebreak(this); }); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder entries — accepts current array shape or a legacy // single object (older saved sections) for backwards compat. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote).each(function () { highlightLinebreak(this); }); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederCatTpl) { // Legacy format from before the şablon search switched rows to // manual mode directly — convert it the same way now, so it's // editable like any other free-form source. var catSelEl = li.find(".wiktku-dfn-quote-src-sel"); catSelEl.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val("{{" + j.jederCatTpl + "}}"); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); // Restoring a draft opens the first sense's tab by default. steps.dfn.setOpenSense(stepDiv, list.find("li.wiktku-dfn-sense").first()); } // Snapshots simple (non-dfn) per-section steps from the DOM into obj. function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } if (id === "cavkani") { snap.cavkani = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); return; } if (id === "posparams") { snap.posparams = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); return; } if (id === "resim") { // One entry per row, including blank ones, so a mid-edit draft // (e.g. a filename typed but no caption yet) survives a cache // restore instead of being silently dropped. snap.resim = $("#wiktku-start-resim li.wiktku-resim-item").map(function () { return { file: $.trim($(this).find(".wiktku-resim-file").val()), caption: $.trim($(this).find(".wiktku-resim-caption").val()), alt: $.trim($(this).find(".wiktku-resim-alt").val()) }; }).get(); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); // Which "Beşên din" sub-sections this section has already opened // via the picker — per-section, like everything else here. snap.openedOtherSections = $.extend({}, openedOtherSections); sections[activeSection] = snap; } // Restores a previously saved snapshot into the form DOM. function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); $("#wiktku-start-cavkani .wiktku-cavkani-text").val(snap.cavkani || ""); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); steps.posparams.build(ppDiv); var savedTa = snap.posparams || ""; ppDiv.find(".wiktku-posparams-text").val(savedTa); // Re-parse saved textarea to restore helper widget states. if (savedTa) { var cMatch = savedTa.match(/\|c=([^|}\s]+)/); var jMatch = savedTa.match(/\|j=([^|}\s]+)/); var trMatch = savedTa.match(/\|tr=([^|}\s]+)/); // Write into the shared hidden field (not the visible // select, which has no <option>s yet) — syncHelpers() // below reads it back to restore the dropdown once the // gender/number options for this language are populated. if (cMatch) $("#wiktku-start-cinsiyet-field").val(cMatch[1]); if (jMatch) $("#wiktku-start-jimar-field").val(jMatch[1]); if (trMatch) ppDiv.find(".wiktku-posparams-field[data-pp-key='tr']").val(trMatch[1]); // For lêker, c= holds the verb-type code instead of a // gender — split it back across the two dropdowns it is // now assembled from ("x-gh" → form "x" + base "gh"). if (cMatch && /^lêker/.test(snap.pos || "")) { var lekturParts = /^(?:([xphb])-)?(n?gh)$/.exec(cMatch[1]); if (lekturParts) { ppDiv.find(".wiktku-posparams-lektur-sel").val(lekturParts[2]); ppDiv.find(".wiktku-posparams-lekturform-sel").val(lekturParts[1] || ""); } } // Restore checked optional params. "form" is stored as // "erê" rather than "1" (see rebuildTa), so it needs its // own check here. ppDiv.find(".wiktku-posparams-opt-panel input[type='checkbox']").each(function () { var key = $(this).val(); var expected = key === "form" ? "erê" : "1"; $(this).prop("checked", savedTa.indexOf("|" + key + "=" + expected) !== -1); }); } steps.posparams.syncHelpers(ppDiv); return; } if (id === "resim") { var resimDiv = $("#wiktku-start-resim"); resimDiv.find(".wiktku-resim-wrap").remove(); steps.resim.build(resimDiv); // Accept both the new array-of-rows format and the older // single {file, caption} object saved before multi-image // support existed. var resimSnap = snap.resim; var rows = $.isArray(resimSnap) ? resimSnap : (resimSnap ? [resimSnap] : []); if (rows.length) { var list = resimDiv.find("ol.wiktku-resim-list"); list.empty(); $.each(rows, function (_, r) { var item = steps.resim.buildItem(resimDiv); item.find(".wiktku-resim-file").val(r.file || ""); item.find(".wiktku-resim-caption").val(r.caption || ""); item.find(".wiktku-resim-alt").val(r.alt || ""); list.append(item); }); // Always keep a blank trailing row, same as Nimûne/Dûnde. var lastItem = list.children("li.wiktku-resim-item").last(); if ($.trim(lastItem.find(".wiktku-resim-file").val())) { list.append(steps.resim.buildItem(resimDiv)); } } return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Tell the pickers about the programmatic value change. fields.filter("select").trigger("wiktku:refresh"); }); // Restore which "Beşên din" sub-sections were already opened for // this section, then seed in anything the DOM restore above just // filled in but that wasn't marked opened yet. openedOtherSections = $.extend({}, snap.openedOtherSections || {}); seedOpenedFromContent(); renderBesenDinPicker(); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); // Bilêvkirin is NOT emitted here — it is one shared field for the // whole word, so emitting it per section duplicated it. getWikitext() // prints it once, above the POS sections. steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.tewandin.output(values); entry += steps.bikaranin.output(values); entry += steps.alfabeyendin.output(values); entry += steps.formalt.output(values); entry += steps.hevmane.output(values); entry += steps.dijmane.output(values); entry += steps.jornav.output(values); entry += steps.jernav.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); entry += steps.cavkani.output(values); entry += steps.xwendin.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { // Each hop through here can be reached asynchronously: the dfn // step waits on mw.loader.using("ext.gadget.linkify") before // calling back, so from that point on the submit handler's own // try/catch is no longer on the stack. Guard every hop instead, // or a throw after linkify loads vanishes into an unhandled // rejection and the form just sits there looking busy. try { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } catch (e) { if (typeof onSubmitError === "function") onSubmitError(e); else throw e; } } processSection(0); } // Assembles wikitext for all sections plus the shared lang header. function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var bnrh = steps.bnrh.output(sharedValues); var entry = steps.lang.output(sharedValues); // One pronunciation per word, printed once between the language // header and the POS sections — see steps.pron.output. entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // bnr-h goes before the language section — only prepended when // generating fresh wikitext (not addLangMode, which handles it separately). if (!addLangMode && bnrh) entry = bnrh + entry; // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { if (s.mane) return s.mane; // Template sense (e.g. {{guharto|ku|somepage}}) — same // construction as the tplCall built in getOutput, so the // summary shows what actually gets written to the entry // instead of going blank. if (s.tpl && s.tplTitle) { return s.tplNoLang ? "{{" + s.tpl + "|" + s.tplTitle + "}}" : "{{" + s.tpl + "|" + sharedValues.lang + "|" + s.tplTitle + "}}"; } return ""; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; // Set by build() to its submitFailed(). Lives out here because the // wikitext-assembly functions below are outside build()'s closure but // still need a way to report a failure to the person rather than dying // silently in the console. var onSubmitError = null; // Whether Mane/Bi zaravayên din/Werger has anything in it — kept // outside refresh() so the click handler can read the latest value. var wiktkuContentGateOk = true; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues, placeholderText) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>").text(placeholderText || "")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice.label); if (choice.sortKey !== undefined) { // This is a language choice {code, label, sortKey} — show code. displayText = capitalize(choice.label) + " (" + choice.code + ")"; } var option = $(mw.html.element("option", { value: choice.code }, displayText)); if (disabledValues[choice.code]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } // Keys to disable for a key menu: already-taken or explicitly disabled. function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); populateMenus(input, step.keys, getDisabledKeys(step)); // Keep the key menus mutually exclusive: whatever one row selects is // disabled in every other row. Recomputed from the DOM on each change. input.on("change", function () { var all = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield"); var taken = {}; all.each(function () { var v = $(this).val(); if (v) taken[v] = true; }); all.not(this).each(function () { var self = $(this), own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (code) $(this).prop("disabled", !!taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }); // Return the wrapper; the select lives inside it and still fires change. return wrapNativeSelect(input); } // Adds another text field to the list if the last one now has text. function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); if (step.placeholder) { nextInput.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = step.modifiers ? makeModifierLi(nextInput).prepend(nextKeyInput || "") : $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) initSelects(nextItem); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } // Shows/hides steps based on whether their prerequisites are met, and // updates placeholders where applicable. function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); steps.cavkani.refreshTplSelect(); // Re-render any step's question label that depends on current values // (e.g. dfn's Werger-section reminder, which only applies to ku). $.each(steps, function (stepId, step) { if (typeof step.question_fmt === "function") { $("#wiktku-start-" + stepId + " .wiktku-start-step-question") .text(step.question_fmt(values)); } }); // Sync every sense block's mane-box mode (plain mane vs tercime+îzah) // to the current language, in case lang changes after blocks exist. $("#wiktku-start-dfn li.wiktku-dfn-sense").each(function () { var updateMane = $(this).data("updateManeMode"); if (updateMane) updateMane(); }); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Re-sync the "<label> bi <ziman>…" placeholder on every always-visible // sub-field list (etîket, kategorî, hevmane, …), since the language may // not have been chosen yet when these lists were first built, or may // have changed since. $("#wiktku-start-dfn .wiktku-dfn-sublist").each(function () { var upd = $(this).data("updatePlaceholders"); if (typeof upd === "function") upd(); }); // Same idea for word-list steps (jê, têkildar, binêre herwiha, …) // whose placeholder is a function of the current language. $.each(steps, function (stepId, step) { if (typeof step.placeholder === "function") { $("#wiktku-start-" + stepId + " textarea.wiktku-start-step-field") .attr("placeholder", step.placeholder()); } }); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // Insert after the quote textarea's resize-wrap (if the manual // resize handle has already been attached to it), not after the // bare textarea -- otherwise this lands *inside* that wrap, // between the textarea and its own grip, breaking jêgirtin's // handle and nesting the tr/t boxes inside it. var quoteTa = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap = quoteTa.closest(".wiktku-resize-wrap"); (quoteResizeWrap.length ? quoteResizeWrap : quoteTa).after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // See the tr-field branch above for why this targets the // resize-wrap instead of the bare textarea. var quoteTa2 = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap2 = quoteTa2.closest(".wiktku-resize-wrap"); (quoteResizeWrap2.length ? quoteResizeWrap2 : quoteTa2).after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { var groupIdx = stepIdToGroup[stepId]; var hiddenByTab = (groupIdx !== undefined && groupIdx !== activeGroup) || // Beşên din picker: stays hidden even while its tab is // active until explicitly opened from the dropdown. (BESENDIN_SET[stepId] && !openedOtherSections[stepId]); // Bilêvkirin is its own section now, so the two views are // mutually exclusive: on it, only pron shows (plus Ziman, which // is shared and stays above every section); off it, pron is // hidden no matter which tab is active. pron is deliberately // ungrouped — stepIdToGroup has no entry for it — so without // this branch it would show on all four tabs at once. if (stepId === "pron") { hiddenByTab = hiddenByTab || !viewingPron; } else if (viewingPron && stepId !== "lang") { hiddenByTab = true; } if (hiddenByTab || (typeof(step.visible) === "function" && !step.visible(values))) { $("#wiktku-start-" + stepId).hide(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } // After build, sync the posparams helper widgets whenever pos or lang changes. if (step.id === "posparams" && typeof step.syncHelpers === "function") { step.syncHelpers(stepDiv); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } stepDiv.slideDown(); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); // The four content tabs belong to a POS section — Bilêvkirin has no // sub-tabs of its own, so the bar goes away while it's on screen. $("#wiktku-group-tabs").toggle(!!values.pos && !viewingPron); var besenDinActive = activeGroup === BESENDIN_GROUP_IDX && !viewingPron; $("#wiktku-besendin-picker").toggle(besenDinActive); // The option list is filtered by each step's visible(), which depends // on lang/pos — so it has to be rebuilt when those change, not just // when a section is opened. Safe to call from here: rendering the // picker doesn't itself call refresh(), only picking an option does. if (besenDinActive) renderBesenDinPicker(); updateGroupTabIndicators(values); continueBtn.setDisabled(!canContinue); // Soft gate: stays a real, clickable OOUI button — a hard // setDisabled(true) here would swallow the click entirely, leaving // no way to tell the person why nothing happened. The CSS-only // "looks disabled" class lets the click handler still run and show // wiktkuNotify's explanation. wiktkuContentGateOk = !canContinue || hasMinRequiredContent(values); continueBtn.$element.toggleClass("wiktku-btn-soft-disabled", !wiktkuContentGateOk); } function destroy() { if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); if (autosaveInterval) clearInterval(autosaveInterval); formDirty = false; $(window).off("beforeunload.wiktkuUnsaved"); $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard").slideDown(); // #editform was kept laid-out but off-screen (see build()) instead of // display:none, precisely so the editor never had to size itself // against a zero-width/height box. Just bring it back on-screen — // no slideDown needed since it was never actually collapsed. $("#editform").removeClass("wiktku-offscreen"); // Belt-and-braces: if WikiEditor/CodeMirror/mobile's auto-grow still // cached a stale size from some earlier point, nudge them to // recalculate now that the box is genuinely visible. $(window).trigger("resize"); if (window.CodeMirror) { var cm = $("#wpTextbox1").data("CodeMirror") || $("#wpTextbox1").data("cmInstance"); if (cm && typeof cm.refresh === "function") cm.refresh(); } $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and navz. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; // Inserts a new "== {{ziman|code}} ==" section at the correct sorted // position: navz, then ku/hac/sdh/lki/ckb/zza, then alphabetical by name. function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections — just write the new section. // Add \n\n only when there is real non-whitespace content above. var trimmed = existing.replace(/\s+$/, ""); return trimmed ? trimmed + "\n\n" + wikitext : wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // (?![\s\S]) matches only true end-of-string, since a bare "$" with // /m would stop at the section's first line break instead. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections, each separated by exactly \n\n. // Trim trailing whitespace off each section's content first so we // control the spacing precisely. var joined = sections.map(function (s) { return s.content.replace(/\s+$/, ""); }).join("\n\n"); // Only add a separator after the preamble when it has real content. var preambleTrimmed = preamble.replace(/\s+$/, ""); var prefix = preambleTrimmed ? preambleTrimmed + "\n\n" : ""; return prefix + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê zimanekî nû li rûpelê îlawe bikî. Eger ev ziman jixwe hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bike, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Muhtewaya rûpelê paqij bike (her tiştî jê bibe û rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); // Tab bar for switching between step-groups (topics) within a section. // renderGroupTabs()/updateGroupTabIndicators() (which populate and // maintain it) live outside build() — see near "var activeSection". var groupTabsDiv = $("<div id='wiktku-group-tabs'></div>"); // Both tab bars are sticky (CSS). group-tabs' sticky "top" has to sit // right below section-tabs' actual rendered height, which isn't a // fixed number since the bar can wrap onto a second line. Measured // here and published as a CSS custom property the stylesheet reads // back; recomputed on content changes and window resize. // // Vector 2022 has its own sticky header (.vector-sticky-header) that // pins to the real top:0 once you scroll past the page title, which // would otherwise sit directly behind (and hide) our section-tabs. // Fixed by measuring how much of the viewport Vector's header // currently occupies and offsetting both our bars below it, via // --wiktku-siteheader-h. Vector's header slides in/out with scroll // position, so this is re-measured on scroll too, not just resize. function siteHeaderOffset() { var el = document.querySelector(".vector-sticky-header"); if (!el) return 0; var rect = el.getBoundingClientRect(); // Present in the DOM at all times on Vector 2022, but only // actually occupying screen space once scrolled into place — // before that it sits translated above the viewport (negative/ // zero rect), which must not add a phantom gap under our bars. if (rect.bottom <= 0 || rect.top > 4) return 0; return Math.max(0, rect.bottom); } var stickyOffsetQueued = false; function syncStickyTabsOffset() { var h = sectionTabsDiv.is(":visible") ? (sectionTabsDiv.outerHeight() || 0) : 0; startForm.css("--wiktku-stabs-h", h + "px"); startForm.css("--wiktku-siteheader-h", siteHeaderOffset() + "px"); } function queueStickyTabsOffsetSync() { if (stickyOffsetQueued) return; stickyOffsetQueued = true; window.requestAnimationFrame(function () { stickyOffsetQueued = false; syncStickyTabsOffset(); }); } $(window).on("resize.wiktkuStickyTabs scroll.wiktkuStickyTabs", queueStickyTabsOffsetSync); // "Beşên din" picker — sits right under the group tab bar, only // shown while that tab is active (toggled in refresh(), see // BESENDIN_GROUP_IDX); renderBesenDinPicker() fills it. var besenDinPickerDiv = $("<div id='wiktku-besendin-picker' class='wiktku-besendin-picker'></div>"); /** Puts the form back in a usable state after a failed submit and * says what happened. Without this the button stays disabled and * the spinner spins forever on any exception — the person is left * staring at a form that looks busy but is dead, with the reason * visible only in the browser console. */ function submitFailed(err) { spinner.hide(); continueBtn.setDisabled(false); continueBtn.$element.removeClass("wiktku-btn-sending"); var detail = (err && (err.message || err.toString())) || "sedem nediyar"; mw.notify( "Şandin bi ser neket: " + detail + " — tiştê ku te nivîsî winda nebûye. Heke ev dubare bibe, " + "bi 'Edîtora çavkaniyê veke' berdewam bike.", { type: "error", tag: "wiktku-submit", autoHide: false } ); // Deliberately console.error as well: the notification is for the // person, this is for whoever they report the bug to. if (window.console && console.error) console.error("[wiktku] submit failed", err); } onSubmitError = submitFailed; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); continueBtn.$element.addClass("wiktku-btn-sending"); spinner.show(); try { getWikitext(function (wikitext) { try { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page — write fresh content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // ── bnr-h merge ────────────────────────────────────────── // If the user filled bnr-h inputs, either merge into the // existing {{bnr-h|…}} call or prepend a new one. var bnrhOut = steps.bnrh.output(getValues()); if (bnrhOut) { var newPages = bnrhOut.replace(/^\{\{bnr-h\|/, "").replace(/\}\}\n?$/, "").split("|"); var bnrhRe = /\{\{bnr-h\|([^}]*)\}\}/i; if (bnrhRe.test(existing)) { existing = existing.replace(bnrhRe, function (_, inner) { var existingPages = inner.split("|").map(function (p) { return p.trim(); }); $.each(newPages, function (_, p) { p = p.trim(); if (p && existingPages.indexOf(p) === -1) existingPages.push(p); }); return "{{bnr-h|" + existingPages.join("|") + "}}"; }); } else { existing = bnrhOut + existing; } } // If this language's section already exists (whitespace // differences aside), merge into it; otherwise insert new. var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); } catch (e) { // Thrown while writing the result into #wpTextbox1. submitFailed(e); } }); } catch (e) { // Catches anything thrown synchronously inside getWikitext. submitFailed(e); } }); // Tracks whether groupTabsDiv has been inserted yet. var groupTabsInserted = false; $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); var nameH3 = $("<h3></h3>").addClass("wiktku-start-step-name"); var nameLabel = $("<label></label>") .attr("for", "wiktku-start-" + step.id + "-field") .text(name); nameH3.append(nameLabel); stepDiv.append(nameH3); if (step.question_fmt) { // question_fmt can be a plain string, or a function of the // current values (used by steps whose question text depends // on e.g. the chosen language) — refresh() keeps it in sync // afterwards via the .wiktku-start-step-question class. var questionText = typeof step.question_fmt === "function" ? step.question_fmt(getValues()) : step.question_fmt; stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, questionText))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); // initSelects() runs over the whole form once it is in the DOM. stepDiv.append(input); } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.placeholder) { input.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append(step.modifiers ? makeModifierLi(input) : $("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Section tabs (switch between POS sections) sit above the // per-section fields, starting at "pos". if (step.id === "pos") { startForm.append(sectionTabsDiv); } // Step-group tabs sit just before the first grouped step in // ordered_steps. Derived from stepIdToGroup so this keeps // working no matter how STEP_GROUPS/ordered_steps get reordered. if (!groupTabsInserted && stepIdToGroup[step.id] !== undefined) { startForm.append(groupTabsDiv); startForm.append(besenDinPickerDiv); groupTabsInserted = true; } startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); /** Adds a new, empty POS section and switches to it. */ function addPosSection() { saveCurrentSection(); viewingPron = false; sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); return; } if (id === "resim") { $("#wiktku-start-resim .wiktku-resim-wrap").remove(); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); stepDiv.find("select.wiktku-start-step-field").trigger("wiktku:refresh"); }); // Fresh section — no "Beşên din" sub-section has been opened yet. openedOtherSections = {}; renderBesenDinPicker(); renderSectionTabs(); refresh(); } addSectionBtn.on("click", addPosSection); /** Removes one POS section. Assumes the caller already confirmed and * already checked more than one section remains. If the removed * section was the one on screen, its in-progress DOM edits are * discarded along with it (never saved back into sections[]) and a * neighboring section is restored in its place. */ function removePosSection(idx) { sections.splice(idx, 1); if (idx === activeSection) { viewingPron = false; activeSection = Math.min(idx, sections.length - 1); restoreSection(sections[activeSection]); refresh(); } else if (idx < activeSection) { activeSection -= 1; } renderSectionTabs(); } /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); syncStickyTabsOffset(); return; } sectionTabsDiv.show(); // Bilêvkirin leads the bar, ahead of the POS sections. var pronTab = $("<span></span>") .addClass("wiktku-section-tab wiktku-section-tab-pron") .text("Bilêvkirin") .toggleClass("wiktku-tab-active", viewingPron); pronTab.on("click", function () { if (viewingPron) return; saveCurrentSection(); viewingPron = true; refresh(); renderSectionTabs(); }); sectionTabsDiv.append(pronTab); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .toggleClass("wiktku-tab-active", i === activeSection && !viewingPron); tab.append($("<span class='wiktku-tab-label'></span>").text(tabLabel)); (function (idx) { tab.on("click", function () { if (idx === activeSection && !viewingPron) return; // Leaving Bilêvkirin doesn't need a save — its field // is shared and never part of a section snapshot. if (!viewingPron) saveCurrentSection(); viewingPron = false; activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); // Always keep at least one Beş — no delete button when // it's the only section left. if (sections.length > 1) { var trash = makeTrashButton("Vê beşê jê bibe"); trash.on("click", function (e) { // Stop this from also reaching the tab's own // click handler above (which would just switch // to it instead of deleting it). e.preventDefault(); e.stopPropagation(); if (!window.confirm("Tu dixwazî \"" + tabLabel + "\" jê bibî? Ev tişt nayê vegerandin.")) return; removePosSection(idx); }); tab.append(trash); } }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); syncStickyTabsOffset(); } renderSectionTabs(); /** * Re-populates a dynamically-growing "multiple" field list (bnrh, je, * tekildar, …) from a saved array of strings. Sets each value via * .val() + a triggered "input" event rather than touching the DOM * structure directly, so the normal refreshForTextField() growth * logic adds exactly as many rows as needed — the same thing that * happens when a person types into the last (empty) row. */ function restoreMultiField(id, values) { var container = $("#wiktku-start-" + id); $.each(values || [], function (i, v) { var field = container.find(".wiktku-start-step-field").eq(i); if (!field.length || !v) return; field.val(v).trigger("input"); }); } /** * Restores a full cached draft: shared lang/pron/bnrh fields, then * every section (via the same restoreSection()/refresh()/ * renderSectionTabs() sequence already used when switching tabs). * @param cached {{lang: string, pron: string, bnrh: Array, sections: Array, activeSection: number}} */ function restoreFromCache(cached) { if (cached.lang) { $("#wiktku-start-lang-field").val(cached.lang); $("#wiktku-start-lang-field").trigger("wiktku:refresh"); } // Rebuild dependent steps (pos, pron wrap, etc.) now that lang is set. refresh(); if (cached.pron !== undefined) { $("#wiktku-start-pron .wiktku-pron-text").val(cached.pron); } if (cached.bnrh) { restoreMultiField("bnrh", cached.bnrh); } sections = (cached.sections && cached.sections.length) ? cached.sections : [{}]; activeSection = (typeof cached.activeSection === "number" && cached.activeSection >= 0 && cached.activeSection < sections.length) ? cached.activeSection : 0; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); updateLastSavedIndicator(cached.savedAt || null); formDirty = false; wiktkuNotify("Danûstandina berê ya qeydkirî ji cache hate barkirin.", { type: "info", tag: "wiktku-cache-restore" }); } // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); // A new cureyê rêzimanî means any previously chosen cinsiyet/ // cureyê lêkerê no longer applies — clear both selections (and // the shared hidden cinsiyet field, since rebuildTa()/syncHelpers() // fall back to it) before wiping the textarea, so nothing stale // gets carried over into the rebuilt template. var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-cinsiyet-sel").val(""); ppDiv.find(".wiktku-posparams-jimar-sel").val(""); ppDiv.find(".wiktku-posparams-lektur-sel").prop("selectedIndex", 0); ppDiv.find(".wiktku-posparams-lekturform-sel").prop("selectedIndex", 0); $("#wiktku-start-cinsiyet-field").val(""); $("#wiktku-start-jimar-field").val(""); ppDiv.find(".wiktku-posparams-text").val(""); // refresh() runs steps.posparams.syncHelpers(), which toggles the // param rows for the new pos and — since the textarea is now // empty — calls rebuildTa() to repopulate it. refresh(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { // Immediate feedback that the click registered continueBtn.$element.addClass("wiktku-btn-flash"); setTimeout(function () { continueBtn.$element.removeClass("wiktku-btn-flash"); }, 500); // Ziman/Cureyê rêzimanî already block submission via the real // OOUI setDisabled (see canContinue in refresh()) — this is a // second, softer check that still lets the click through so we // can explain why, instead of the button just silently doing nothing. if (!wiktkuContentGateOk) { wiktkuNotify( "Berî şandinê, tiştekî binivîse: Mane, Bi zaravayên din, an jî Werger — kêmasî yek ji van sê beşan divê tijî be.", { type: "warn", tag: "wiktku-mincontent" } ); return; } wiktkuNotify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", flags: [ "destructive" ], }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Cache save/clear buttons ───────────────────────────────────────── // Manual, page-scoped save of the entire wizard (all sections, not // just the active one) via [[MediaWiki:Gadget-StorageUtils.js]]'s // ObjectStorage. Restoring happens silently on load at the end of // build(), once the full language list is available. // // Saving also happens automatically (debounced while typing, plus a // periodic fallback) — see "Autosave" below — since relying on the // person to remember to click "Li cache qeyd bike" before an // accidental tab close/reload defeats the point of having a cache // at all. function buildCacheSnapshot() { return { lang: getValues().lang || "", pron: $("#wiktku-start-pron .wiktku-pron-text").val() || "", // bnrh is shared (page-level), same as lang/pron above — not // per-section, so it doesn't live in sections[]. bnrh: getValuesForStep("bnrh"), sections: sections, activeSection: activeSection, savedAt: Date.now() }; } // ── Last-saved indicator ───────────────────────────────────────────── var lastSavedEl = $("<span id='wiktku-last-saved'></span>"); function formatSavedTime(ts) { try { return new Date(ts).toLocaleTimeString(mw.config.get("wgUserLanguage"), { hour: "2-digit", minute: "2-digit" }); } catch (e) { return new Date(ts).toLocaleTimeString(); } } function updateLastSavedIndicator(ts) { lastSavedEl.text(ts ? ("Cache: qeydkirî di saet " + formatSavedTime(ts) + " de") : ""); } // ── Dirty-state tracking + autosave ────────────────────────────────── // formDirty mirrors "does the live form differ from what's in cache". // Anything the person types/selects sets it; a successful save (auto // or manual) clears it; destroy() (final submit, or switching to the // source editor) also clears it since the wizard's job is over at // that point either way. formDirty/autosaveDebounceTimer/autosaveInterval // are declared in the outer scope (near activeGroup) — assigned here, // not re-declared — so destroy() can reach them too. var AUTOSAVE_DEBOUNCE_MS = 8000; // save shortly after typing pauses var AUTOSAVE_INTERVAL_MS = 60000; // …and at least this often regardless function performAutosave() { if (!formDirty) return; saveCurrentSection(); try { formCache.Set(buildCacheSnapshot()); formDirty = false; updateLastSavedIndicator(Date.now()); } catch (e) { // Silent on autosave failure (storage blocked/full, etc.) — the // manual button still surfaces a proper error if the person // tries it directly, no need to interrupt typing with a toast. } } function scheduleAutosave() { formDirty = true; if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = setTimeout(performAutosave, AUTOSAVE_DEBOUNCE_MS); } startForm.on("input change", "input, textarea, select", scheduleAutosave); autosaveInterval = setInterval(performAutosave, AUTOSAVE_INTERVAL_MS); // Warn on accidental tab close/reload while there's anything unsaved. $(window).on("beforeunload.wiktkuUnsaved", function (e) { if (!formDirty) return undefined; e.preventDefault(); e.returnValue = ""; return ""; }); var saveCacheBtn = new OO.ui.ButtonWidget({ label: "Li cache qeyd bike", title: "Halê vê formê yê niha (ziman, bilêvkirin û hemû beş) li cache (localStorage) qeyd bike, da ku eger rûpel bêyî xwestin were girtin an ji nû ve were barkirin, tu karibî berdewam bikî." }); saveCacheBtn.on("click", function () { saveCurrentSection(); // ObjectStorage.Set() doesn't return a success/failure value, so // the only way to detect a real failure (storage blocked, quota // exceeded, JSON.stringify choking on something unexpected) is to // catch it here rather than inspect a (nonexistent) return value. try { var snapshot = buildCacheSnapshot(); formCache.Set(snapshot); formDirty = false; updateLastSavedIndicator(snapshot.savedAt); wiktkuNotify("Halê formê li cache hate qeydkirin.", { type: "success", tag: "wiktku-cache-save" }); } catch (e) { mw.notify("Qeydkirina li cache bi ser neket.", { type: "error", tag: "wiktku-cache-save" }); } }); var clearCacheBtn = new OO.ui.ButtonWidget({ label: "Cache paqij bike", flags: [ "destructive" ], title: "Datayên qeydkirî yên vê rûpelê ji cache jê bibe (forma ku niha xuya dike naguherîne)." }); clearCacheBtn.on("click", function () { formCache.Set({}); // The live form still has whatever the person typed — it's just no // longer backed up anywhere, so treat this like a fresh unsaved edit. formDirty = true; updateLastSavedIndicator(null); wiktkuNotify("Cache hate paqijkirin.", { type: "success", tag: "wiktku-cache-clear" }); }); // ── "⋯" overflow ───────────────────────────────────────────── // One primary action and one secondary stay on the bar; everything // else moves in here, to avoid four same-weight buttons crowding // (and wrapping to three rows on a phone). var moreBtn = $("<button type='button' class='wiktku-more-btn' title='Vebijarkên din'>⋯</button>"); var moreMenu = $("<div class='wiktku-more-menu'></div>").hide(); /** Moves an existing OOUI button into the overflow menu, keeping its * handlers — the widgets already carry the behaviour, so this is * purely about where they are shown. */ function intoMenu(btn, extraClass) { var row = $("<div class='wiktku-more-item'></div>"); if (extraClass) row.addClass(extraClass); btn.$element.on("click", function () { moreMenu.hide(); }); row.append(btn.$element); moreMenu.append(row); } intoMenu(saveCacheBtn); intoMenu(clearCacheBtn, "wiktku-more-item-danger"); moreMenu.append($("<div class='wiktku-more-sep'></div>")); moreMenu.append($("<div class='wiktku-more-item wiktku-more-note'></div>").append(lastSavedEl)); moreBtn.on("click", function (e) { e.preventDefault(); e.stopPropagation(); var open = moreMenu.is(":visible"); moreMenu.toggle(!open); if (!open) { setTimeout(function () { $(document).one("click.wiktkuMore", function () { moreMenu.hide(); }); }, 0); } }); var moreWrap = $("<span class='wiktku-more-wrap'></span>").append(moreBtn).append(moreMenu); footer.append(moreWrap); // Icon-only settings button — opens the Tercîh dialog. Plain OOUI // icon names depend on which icon-pack module happens to be loaded, // so this uses the actual Codex "settings" (color-subtle) SVG from // Commons directly, the same way the spinner above hotlinks its gif. var prefsBtn = $("<button></button>", { type: "button", "class": "wiktku-prefs-btn", title: "Tercîh — sazkariyên vê amûrê biguherîne" }); prefsBtn.on("click", function (e) { e.preventDefault(); wiktkuOpenPrefsDialog(); }); // The gear is icon-only on the bar; inside a text menu it needs a // label like everything else around it. prefsBtn.on("click", function () { moreMenu.hide(); }); moreMenu.prepend($("<div class='wiktku-more-sep'></div>")); moreMenu.prepend($("<div class='wiktku-more-item wiktku-more-item-prefs'></div>") .append(prefsBtn) .append($("<span class='wiktku-more-item-label'></span>").text("Tercîh"))); startForm.append(footer); // NOTE: deliberately NOT .hide() (display:none). WikiEditor/CodeMirror/ // the mobile editor's auto-grow logic measure #wpTextbox1's real // dimensions during their own init, which happens while the wizard is // up. A display:none ancestor reports 0 for offsetWidth/offsetHeight/ // scrollHeight, so those scripts bake in a near-zero height that never // gets recalculated later — slideDown() in destroy() only animates the // outer box, it doesn't re-trigger their sizing. Pushing #editform // off-screen instead keeps it laid out (real width/height available to // measure) without being visible, so the editbox opens at full size. $("#editform").addClass("wiktku-offscreen").before(startForm); // renderGroupTabs() looks up #wiktku-group-tabs via a live DOM // selector, so it must run after startForm is actually in the document. renderGroupTabs(); renderBesenDinPicker(); // One pass over the whole form: every select that hasn't already been // initialised, and isn't opted out with .wiktku-plain-select, gets // the searchable picker. initSelects(startForm); refresh(); // Give every draggable textarea a custom resize grip (works // consistently on Safari/iOS, unlike the native corner grip — see // the "Manual drag-to-resize handle" comment in styles.css), and // keep applying it to textareas added later on (new sense blocks, // quote-source fields, nimûne rows, …). wiktkuInitManualResize(startForm); new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { $(mutation.addedNodes).each(function () { if (this.nodeType !== 1) return; wiktkuInitManualResize(this); }); }); }).observe(startForm[0], { childList: true, subtree: true }); // Now that the full language list is loaded, silently restore any // draft the editor previously saved for this page. var cachedDraft = formCache.Get(); if (cachedDraft && cachedDraft.sections && cachedDraft.sections.length) { restoreFromCache(cachedDraft); } } mw.loader.using(["oojs-ui-core"], function () { function wiktkuProceedWithData(wiktkuData) { var d = wiktkuData || {}; // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Jimar (number) code definitions — same shape as the wiki's // own Lua number-type table (code -> {cat, display[, req]}). if (d.numberLabels) $.extend(NUMBER_LABELS, d.numberLabels); // Populate lang choices (pinned list). if (d.langChoices) steps.lang.choices = choicesFromObject(d.langChoices, true); // Populate langsByCode and merge full language list from d.ziman. // d.ziman is a {code: name} object with all known languages. $.each(steps.lang.choices, function (i, choice) { if (choice.sortKey === undefined) choice.sortKey = choice.label; langsByCode[choice.code] = choice; }); if (d.ziman) { var pinnedCodes = {}; $.each(steps.lang.choices, function (i, c) { pinnedCodes[c.code] = true; }); var extraChoices = []; $.each(d.ziman, function (code, name) { if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; if (pinnedCodes[code]) return; var choice = { code: code, label: name, sortKey: name }; extraChoices.push(choice); langsByCode[code] = choice; }); extraChoices.sort(function (a, b) { return a.sortKey.localeCompare(b.sortKey, userLang); }); steps.lang.choices = steps.lang.choices.concat(extraChoices); } // Keep the full merged list around for trans/dunde/zarava — those // should still be able to reference any language even when the // Tercîh panel restricts the main "ziman" step below — then, if // the user set a restriction there, narrow steps.lang.choices // itself to just those codes. var wiktkuFullLangChoices = steps.lang.choices; if (wiktkuPrefs.langCodes && wiktkuPrefs.langCodes.length) { var wiktkuAllowedLangSet = {}; $.each(wiktkuPrefs.langCodes, function (i, code) { wiktkuAllowedLangSet[code] = true; }); var wiktkuRestrictedChoices = $.grep(wiktkuFullLangChoices, function (c) { return !!wiktkuAllowedLangSet[c.code]; }); // Fall back to the full list instead of showing an empty // dropdown if none of the saved codes matched anything // (typo'd code, data.json changed since, …). steps.lang.choices = wiktkuRestrictedChoices.length ? wiktkuRestrictedChoices : wiktkuFullLangChoices; } // Populate POS choices — also a plain {code: label} object in data.json. if (d.posChoices) steps.pos.choices = choicesFromObject(d.posChoices, false); // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the full language list // (not the possibly Tercîh-restricted steps.lang.choices). steps.trans.keys = wiktkuFullLangChoices; steps.dunde.keys = wiktkuFullLangChoices; steps.zarava.keys = getZaravaKeys(wiktkuFullLangChoices); build(); } // data.json ships inside this package module, so it is already parsed // and in memory — no action=raw round trip, and no Testing switch to // forget to flip back before deploying. wiktkuProceedWithData(require("./start/data.json")); }); }); //</nowiki> 2h6eyy0aeg02hs5uxbz4sqlqwlwrxul 6333859 6333855 2026-08-15T17:48:18Z Wikihez 7344 6333859 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. // implicit dependencies: StorageUtils (ObjectStorage) //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var addLangMode = mw.util.getParamValue("wiktkuaddlang") === "1"; // ── Tercîh (user settings) panel stored via mw.storage (localStorage), globally var WIKTKU_PREFS_KEY = "wiktku_start_prefs"; var WIKTKU_PREFS_DEFAULTS = { // [] = show the full language list in the "ziman" step; otherwise // only these codes are shown there (data.json codes, not names). langCodes: [], // true = never auto-open on a new/empty page — only via the // "+Ziman/beşeke din" portlet link. onlyOnClick: false, // "auto" | "p-cactions" | "p-tb" | "p-views" — where the // "+Ziman/beşeke din" portlet link is added. portlet: "auto", // true = suppress routine/informational mw.notify toasts (page // loading, cache auto-restored, cache saved/cleared, "tê şandin…"). // Errors and direct results of an explicit action (like saving // Tercîh itself) always show regardless of this setting. quiet: false }; function wiktkuLoadPrefs() { if (!(window.mw && mw.storage)) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var raw; try { raw = mw.storage.get(WIKTKU_PREFS_KEY); } catch (e) { raw = null; } if (!raw) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var parsed; try { parsed = JSON.parse(raw); } catch (e) { parsed = {}; } return $.extend({}, WIKTKU_PREFS_DEFAULTS, parsed); } function wiktkuSavePrefs(prefs) { if (!(window.mw && mw.storage)) return false; try { mw.storage.set(WIKTKU_PREFS_KEY, JSON.stringify(prefs)); return true; } catch (e) { return false; } } var wiktkuPrefs = wiktkuLoadPrefs(); // Routine/informational notices go through here so "quiet mode" can // suppress them; errors and explicit-action confirmations (like the // Tercîh save toast) call mw.notify directly instead, and always show. function wiktkuNotify(message, options) { if (wiktkuPrefs.quiet) return; mw.notify(message, options); } // Lazily built the first time it's opened; reused after that (see // wiktkuOpenPrefsDialog below, defined once we know OOUI is available). var wiktkuPrefsWindowManager = null; var wiktkuPrefsDialog = null; function wiktkuOpenPrefsDialog() { mw.loader.using(["oojs-ui-core", "oojs-ui-windows"], function () { function WiktkuPrefsDialog(config) { WiktkuPrefsDialog.super.call(this, config); } if (!wiktkuPrefsDialog) { OO.inheritClass(WiktkuPrefsDialog, OO.ui.ProcessDialog); WiktkuPrefsDialog.static.name = "wiktkuPrefsDialog"; WiktkuPrefsDialog.static.title = "Tercîhên min"; WiktkuPrefsDialog.static.actions = [ { action: "save", label: "Qeyd bike", flags: ["primary", "progressive"] }, { action: "cancel", label: "Betal bike", flags: "safe" } ]; WiktkuPrefsDialog.prototype.initialize = function () { WiktkuPrefsDialog.super.prototype.initialize.call(this); this.langCodesInput = new OO.ui.TextInputWidget({ placeholder: "ku, zza, ckb (vala bihêle ji bo hemû zimanan)" }); this.onlyOnClickCheckbox = new OO.ui.CheckboxInputWidget({}); this.quietCheckbox = new OO.ui.CheckboxInputWidget({}); this.portletDropdown = new OO.ui.DropdownInputWidget({ options: [ { data: "auto", label: "Otomatîk (li gorî rûyê wîkiyê)" }, { data: "p-cactions", label: "p-cactions - Li qismê Amûran" }, { data: "left-navigation", label: "left-navigation - Li qismê Gotar-Gotûbêj" }, { data: "p-tb", label: "p-tb - Li qismê Giştî" }, { data: "p-views", label: "p-views - Li qismê Bixwîne" } ] }); var fieldset = new OO.ui.FieldsetLayout({ label: "Eyar" }); fieldset.addItems([ new OO.ui.FieldLayout(this.langCodesInput, { label: "Kodên zimanan ku tê xuyakirin li qismê \"ziman\"", align: "top", help: "Kodan bi virgulê (,) ji hev veqetîne. Vala bihêle da ku hemû ziman were nîşandan.", helpInline: true }), new OO.ui.FieldLayout(this.onlyOnClickCheckbox, { label: "Tenê veke wextê \"+Ziman/beşeke din\" were tikandin", align: "inline", help: "Eger were hilbijartin, ev amûr êdî otomatîk li ser rûpelên nû/vala dest pê nake — divê meriv her carê pêl \"+Ziman/beşeke din\" bike.", helpInline: true }), new OO.ui.FieldLayout(this.portletDropdown, { label: "Cihê lînka \"+Ziman/beşeke din\"", align: "top", help: "\"Otomatîk\" li gorî rûyê wîkiyê hildibijêre.", helpInline: true }), new OO.ui.FieldLayout(this.quietCheckbox, { label: "Moda bêdeng (kêmtir agahdarî nîşan bide)", align: "inline", help: "Agahdariyên normal nîşan nede. Xeta her tim tên xuyakirin.", helpInline: true }) ]); this.$body.addClass("wiktku-prefs-dialog-body").append(fieldset.$element); }; WiktkuPrefsDialog.prototype.getSetupProcess = function (data) { return WiktkuPrefsDialog.super.prototype.getSetupProcess.call(this, data) .next(function () { this.langCodesInput.setValue(wiktkuPrefs.langCodes.join(", ")); this.onlyOnClickCheckbox.setSelected(!!wiktkuPrefs.onlyOnClick); this.portletDropdown.setValue(wiktkuPrefs.portlet || "auto"); this.quietCheckbox.setSelected(!!wiktkuPrefs.quiet); }, this); }; WiktkuPrefsDialog.prototype.getActionProcess = function (action) { var dialog = this; if (action === "save") { return new OO.ui.Process(function () { var codes = dialog.langCodesInput.getValue() .split(/[,\s]+/) .map(function (c) { return c.trim().toLowerCase(); }) .filter(function (c) { return !!c; }); wiktkuPrefs = { langCodes: codes, onlyOnClick: dialog.onlyOnClickCheckbox.isSelected(), portlet: dialog.portletDropdown.getValue() || "auto", quiet: dialog.quietCheckbox.isSelected() }; wiktkuSavePrefs(wiktkuPrefs); mw.notify( "Tercîh hatin qeydkirin. Rûpelê ji nû ve bar bike (F5).", { type: "success", tag: "wiktku-prefs-save" } ); dialog.close({ action: "save" }); }); } if (action === "cancel") { return new OO.ui.Process(function () { dialog.close({ action: "cancel" }); }); } return WiktkuPrefsDialog.super.prototype.getActionProcess.call(this, action); }; wiktkuPrefsWindowManager = new OO.ui.WindowManager(); $(document.body).append(wiktkuPrefsWindowManager.$element); wiktkuPrefsDialog = new WiktkuPrefsDialog(); wiktkuPrefsWindowManager.addWindows([wiktkuPrefsDialog]); } wiktkuPrefsWindowManager.openWindow(wiktkuPrefsDialog); }); } var targetContainer; var skin = mw.config.get('skin'); if (wiktkuPrefs.portlet && wiktkuPrefs.portlet !== "auto") { targetContainer = wiktkuPrefs.portlet; } else if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Li vê rûpelê, ziman an jî beşeke nû zêde bike"); // If "onlyOnClick" is set, the wizard should ONLY ever open via the // "+Ziman/beşeke din" link — never automatically var wiktkuNewPageDetected = $(".mw-newarticletext, .mw-newarticletextanon").length > 0; if (wiktkuPrefs.onlyOnClick ? !addLangMode : (!addLangMode && !wiktkuNewPageDetected)) { return; } // ── Shared helpers ─────────────────────────────────────────────────── // Generic text/UI utilities live in their own package file now — see the // header of util.js for why. Aliased to bare names here so the ~400 call // sites below read exactly as they did when these were local functions. var wiktkuUtil = require("./start/util.js"); var capitalize = wiktkuUtil.capitalize; var decapitalize = wiktkuUtil.decapitalize; var escapeRegExp = wiktkuUtil.escapeRegExp; var stripWikilinks = wiktkuUtil.stripWikilinks; var splitTercimeIzah = wiktkuUtil.splitTercimeIzah; var insertAtCursor = wiktkuUtil.insertAtCursor; var foldDiacritics = wiktkuUtil.foldDiacritics; var wrapNativeSelect = wiktkuUtil.wrapNativeSelect; var initSelects = wiktkuUtil.initSelects; var wiktkuInitManualResize = wiktkuUtil.initManualResize; function langHeaderSource(codePattern) { return "\n?==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } // Trash icon (OOjs UI's "trash" glyph, simplified) shared by the Mane // sense tabs and the Beş (POS section) tabs, so deleting a tab looks // and behaves the same in both places. Kept as a <button> separate from // the tab's own click target — and given its own click handler that // stops propagation — specifically because clicking directly on a tab // switches to it; without a distinct hit-target for delete, a stray // click meant to open a sense/section would delete it instead. function makeTrashButton(title) { return $("<button type='button' class='wiktku-trash-btn'></button>") .attr("title", title) .attr("aria-label", title) .html( "<svg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'>" + "<path d='M7 3a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v1h4v2h-1.05l-.9 11.1A2 2 0 0 1 13.06 19H6.94a2 2 0 0 1-1.99-1.9L4.05 6H3V4h4V3zm2 1h2V4H9v0zM6.06 6l.88 11h6.12l.88-11H6.06zM8 8h1.5v7H8V8zm2.5 0H12v7h-1.5V8z'/>" + "</svg>" ); } function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } var catSrcTemplates = null; var catSrcTemplatesPromise = null; function fetchCatSrcTemplates() { if (catSrcTemplatesPromise) return catSrcTemplatesPromise; catSrcTemplatesPromise = new mw.Api().get({ action: "query", list: "categorymembers", cmtitle: "Kategorî:Çavkanî", cmnamespace: 10, cmlimit: "max", formatversion: 2 }).then(function (data) { var members = (data.query && data.query.categorymembers) || []; catSrcTemplates = $.map(members, function (m) { // Pêşgira navî ya "Şablon:" rake. return m.title.replace(/^[^:]+:/, ""); }); catSrcTemplates.sort(function (a, b) { return a.localeCompare(b, userLang); }); return catSrcTemplates; }, function () { catSrcTemplates = []; return catSrcTemplates; }); return catSrcTemplatesPromise; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var formCache = new ObjectStorage("wiktku_start_draft_" + mw.config.get("wgPageName"), 1); var langsByCode = {}; // Looks up the display label for a language code, falling back to the // code itself if it isn't known yet (e.g. langsByCode not loaded). function getLangLabel(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; // Converts a {code: label} object (langChoices/posChoices in data.json) // into the {code, label[, sortKey]} array the rest of the script uses. // isLang: true adds a sortKey and shows "(code)" after the label — // language choices only. function choicesFromObject(obj, isLang) { var result = []; $.each(obj || {}, function (code, label) { var choice = { code: code, label: label }; if (isLang) choice.sortKey = label; result.push(choice); }); return result; } function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c.code] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Number codes (y, s, d, p, p+, tp, j, j+, j/nj, nj, nj+, hj!, hj?) from // data.json's "numberLabels". Same {code: {cat, display[, req]}} shape as // the wiki's Lua number-type table; "display" can contain HTML (<abbr>) // or wikilinks, so it's only used as-is in wikitext output, never dropped // straight into an <option> (see stripMarkupForOption below). var NUMBER_LABELS = {}; // Distinguishes the Jimar dropdown (j= param) from the Cîns dropdown // (c= param): a code that's a key in NUMBER_LABELS is a number code, // everything else is a gender code. Compound codes like "m-p"/"n-p" are // gender+plural pairs and correctly stay on the gender side. function isNumberCode(code) { return Object.prototype.hasOwnProperty.call(NUMBER_LABELS, code); } // Strips the bit of markup "display" is allowed to contain so it's safe // to use as plain <option> text (options can't render HTML or wikilinks): // <abbr title="X">Y</abbr> -> "Y (X)", [[a|b]] -> "b", [[a]] -> "a". function stripMarkupForOption(html) { if (!html) return ""; return $.trim( String(html) .replace(/<abbr[^>]*title="([^"]*)"[^>]*>([\s\S]*?)<\/abbr>/gi, "$2 ($1)") .replace(/\[\[[^\]|]*\|([^\]]*)\]\]/g, "$1") .replace(/\[\[([^\]]*)\]\]/g, "$1") .replace(/<[^>]+>/g, "") ); } // Builds the Jimar dropdown's <option> text for one code: "j — jimarbar". function numberOptionLabel(code) { var def = NUMBER_LABELS[code]; if (!def) return code; var text = stripMarkupForOption(def.display); return text ? (code + " — " + text) : code; } // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } // ── Template explanations ──────────────────────────────────────────── // Every place a template can be picked shows the same row: a status // dot, the name, a link to the template page, and an ⓘ. This is the ⓘ. // // Text comes from the template's own TemplateData where it has any, so // the explanation stays right without anyone maintaining a second copy // by hand — with the desc already in data.json as the fallback for // templates that have none. var wiktkuTplDataCache = {}; // name -> {desc, params[]} or null when absent /** Fetches TemplateData for one template. Resolves to null if the * template has none (a plain, undocumented template — very common). */ function fetchTemplateData(name) { if (Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, name)) { return $.Deferred().resolve(wiktkuTplDataCache[name]).promise(); } return new mw.Api().get({ action: "templatedata", titles: "Şablon:" + name, redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; var first = null; $.each(pages, function (_, p) { if (!first) first = p; }); var out = null; if (first) { var desc = first.description; // TemplateData descriptions are language maps when the // template is documented in more than one language. if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(first.params || {}, function (key, p) { var label = p && p.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(p && p.required) }); }); out = { desc: desc || "", params: params }; } wiktkuTplDataCache[name] = out; return out; }, function () { // No TemplateData, or the API is unhappy — cache the miss so a // repeated ⓘ click doesn't re-request it every time. wiktkuTplDataCache[name] = null; return null; }); } /** Fetches TemplateData for many templates in one request and fills the * cache; resolves either way, a template with no TemplateData caches as null. */ function prefetchTemplateData(names) { var missing = $.grep(names || [], function (n) { return n && !Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n); }); if (!missing.length) return $.Deferred().resolve().promise(); // The API caps a titles list at 50 for normal users. missing = missing.slice(0, 50); return new mw.Api().get({ action: "templatedata", titles: $.map(missing, function (n) { return "Şablon:" + n; }).join("|"), redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; $.each(pages, function (_, page) { if (!page || !page.title) return; var name = String(page.title).replace(/^[^:]+:/, ""); var desc = page.description; if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(page.params || {}, function (key, prm) { var label = prm && prm.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(prm && prm.required) }); }); wiktkuTplDataCache[name] = { desc: desc || "", params: params }; }); // Anything the API didn't answer for simply has none — cache the // miss so the per-row ⓘ doesn't re-request it one at a time. $.each(missing, function (_, n) { if (!Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n)) wiktkuTplDataCache[n] = null; }); }, function () { $.each(missing, function (_, n) { wiktkuTplDataCache[n] = null; }); }); } /** Rewrites each tagged <option> in `sel` as "name — description", using * TemplateData. Only fills rows that have no description yet, so the * hand-written ones in data.json (which carry usage examples the API * does not) are left exactly as they are. */ function applyTplDescriptions(sel) { if (!sel || !sel.length) return; var changed = false; sel.find("option[data-tpl]").each(function () { var opt = $(this); var name = opt.attr("data-tpl"); if (opt.text().indexOf(" — ") !== -1) return; // already described var td = wiktkuTplDataCache[name]; var desc = (td && td.desc) || localTplDesc(name); if (!desc) return; // One line: TemplateData descriptions can run to a paragraph. desc = $.trim(String(desc).split("\n")[0]); if (desc.length > 90) desc = desc.slice(0, 90) + "…"; opt.text(name + " — " + desc); changed = true; }); // The picker caches option text for searching, so it has to re-read. if (changed) sel.trigger("wiktku:refresh"); } /** Hand-written fallback description, from data.json. * * This is the escape hatch for templates with no TemplateData on the * wiki: add a "desc" to the entry in data.json and it shows up in the * dropdown and in the ⓘ immediately, no code change. TemplateData is * still the better place — VisualEditor and every other tool reads it * too — but this keeps the picker useful in the meantime. * * Works for any pool: pronTpls, etymTpls, tplDefs, jederDefs. */ function localTplDesc(name) { var pools = [steps.pron.pronTpls, steps.etym.etymTpls, steps.dfn.tplDefs, steps.dfn.jederDefs]; var found = ""; $.each(pools, function (_, pool) { if (pool && pool[name] && pool[name].desc) { found = pool[name].desc; return false; } }); return found; } /** Opens the inline explanation panel for `name`, anchored under the * picker it was opened from. */ function showTemplateInfo(name, anchorWrap) { $(".wiktku-tpl-info").remove(); var panel = $("<div class='wiktku-tpl-info'></div>"); panel.append($("<div class='wiktku-tpl-info-name'></div>").text("{{" + name + "}}")); var body = $("<div class='wiktku-tpl-info-desc'></div>").text("Tê barkirin…"); panel.append(body); var params = $("<div class='wiktku-tpl-info-params'></div>"); panel.append(params); panel.append($("<a class='wiktku-tpl-info-link' target='_blank' rel='noopener'></a>") .attr("href", wiktkuUtil.tplPageUrl(name)) .text("Rûpela şablonê veke →")); var close = $("<button type='button' class='wiktku-tpl-info-close' title='Bigire'>✕</button>"); close.on("click", function () { panel.remove(); }); panel.prepend(close); $(anchorWrap).after(panel); fetchTemplateData(name).then(function (td) { var desc = (td && td.desc) || localTplDesc(name); body.text(desc || "Ji bo vê şablonê ravek nehatiye nivîsandin."); if (td && td.params && td.params.length) { params.append($("<div class='wiktku-tpl-info-params-title'></div>").text("Parametre:")); var listEl = $("<ul></ul>"); $.each(td.params, function (_, p) { var line = p.name + (p.label ? " — " + p.label : "") + (p.required ? " (pêwîst)" : ""); listEl.append($("<li></li>").text(line)); }); params.append(listEl); } }); } /** Marks a picker's <option>s as template rows so the searchable widget * renders them with the dot / 🔗 / ⓘ affordances, and wires the ⓘ * handler for that picker. `nameOf` maps an <option> to a template * name — the pickers store different things in value= (a snippet for * the insert dropdowns, the bare name for the sense selector). */ function markTemplateOptions(sel, nameOf) { if (!sel || !sel.length) return; var names = []; sel.find("option").each(function () { var opt = $(this); var name = nameOf(opt); if (!name) return; opt.attr("data-tpl", name); // Deprecated/typo templates are the "special cases only" ones. opt.attr("data-tpl-status", /kevnbûyî|şaşnivîs|kêmpeyda/i.test(opt.text()) ? "yellow" : "green"); names.push(name); }); sel.data("wiktkuTplInfo", showTemplateInfo); // Fill in the descriptions. Matters most for the Mane picker, whose // entries in data.json are names with no desc at all — "rastnivîs", // "ku-Latn", "guharto" on their own. One request covers every // template in the picker, cached for the per-row ⓘ as well. prefetchTemplateData(names).always(function () { applyTplDescriptions(sel); }); } /** Pulls the template name out of a snippet like "* {{ku-IPA}}" or * "{{ji|SOURCELANG|CODE|…}}". */ function tplNameFromSnippet(snippet) { var m = /\{\{\s*([^|}\n]+)/.exec(snippet || ""); return m ? $.trim(m[1]) : ""; } // True if a sense has content beyond mane worth keeping (etîket, word // lists, nimûne, jêder) — so it's still emitted with {{mane?}} if empty. function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } // A technically-"complete" entry (Ziman + Cureyê rêzimanî filled) with // nothing in Mane, Bi zaravayên din or Werger is still meaningfully // empty, so this is checked separately at submit-click time with its // own message. function hasMinRequiredContent(values) { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasMane = dfnSenses.some(function (s) { return (s.tpl && s.tplTitle) || (!s.tpl && (s.mane !== "" || senseHasExtraContent(s))); }); if (hasMane) return true; if (values.lang === "ku") { var hasWerger = false; $("#wiktku-start-trans .wiktku-trans-group").each(function () { if (steps.trans.getGroupTranslations($(this)).length) hasWerger = true; }); if (hasWerger) return true; var hasZarava = false; $("#wiktku-start-zarava .wiktku-zarava-group").each(function () { if (steps.zarava.getGroupTranslations($(this)).length) hasZarava = true; }); if (hasZarava) return true; } return false; } // Bolds the *first* occurrence of the page name function boldPageNameOnce(text) { if (!text || !pageNameRe) return text; var re = new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "i"); return text.replace(re, "'''$1'''"); } // Converts literal line breaks typed into a nimûne/jêgirtin box into // wikitext <br> tags, function nlToBr(text) { return text ? text.replace(/\r\n|\r|\n/g, "<br>") : text; } function escapeHtmlForBackdrop(str) { return String(str) .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;"); } // Mirrors a textarea's text, with a small highlighted marker placed // right after each line that's followed by an actual typed/pasted // linebreak. Rendered into a transparent backdrop layer behind the // textarea (see ensureLinebreakBackdrop()), so only the point of the // break is marked instead of the whole box. function buildLinebreakBackdropHtml(text) { var lines = text.split(/\r\n|\r|\n/); return $.map(lines, function (line, i) { var isLast = i === lines.length - 1; return escapeHtmlForBackdrop(line) + (isLast ? "" : "<mark class='wiktku-linebreak-mark'>↵</mark>\n"); }).join(""); } // Copies the metrics that affect where text wraps/lands (font, line // height, padding, border) from the real textarea onto its backdrop, // via computed style rather than shared CSS classes — most of the // box's own rules are written as "textarea.foo", which a <div> with // the same class wouldn't match. Re-run on every update in case a // responsive breakpoint changed the textarea's own font-size. function syncLinebreakBackdropMetrics(textarea, backdrop) { var cs = window.getComputedStyle(textarea[0]); backdrop.css({ "box-sizing": cs.boxSizing, "padding-top": cs.paddingTop, "padding-right": cs.paddingRight, "padding-bottom": cs.paddingBottom, "padding-left": cs.paddingLeft, "border-width": cs.borderWidth, "border-style": "solid", "font-family": cs.fontFamily, "font-size": cs.fontSize, "font-weight": cs.fontWeight, "line-height": cs.lineHeight, "letter-spacing": cs.letterSpacing }); } // Lazily wraps a textarea in its own positioning anchor (independent // of .wiktku-resize-wrap, so this doesn't depend on load order versus // wiktkuMakeManualResizable) and inserts the transparent backdrop // layer used to mark the exact point of a linebreak. Safe to call // more than once on the same textarea — the backdrop is cached. function ensureLinebreakBackdrop(textarea) { var existing = textarea.data("wiktkuLinebreakBackdrop"); if (existing) return existing; textarea.wrap("<div class='wiktku-linebreak-wrap'></div>"); var backdrop = $("<div aria-hidden='true'></div>").addClass("wiktku-linebreak-backdrop"); textarea.before(backdrop); textarea.data("wiktkuLinebreakBackdrop", backdrop); textarea.on("scroll.wiktkuLinebreak", function () { backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); }); return backdrop; } // Flags a nimûne/jêgirtin textarea (via CSS class, for the border // tint + tooltip) while it contains a typed/pasted linebreak, so the // user notices before it's silently turned into <br> on output. // Marks only the exact point of the break via a mirrored backdrop, // rather than tinting the whole box. function highlightLinebreak(el) { var textarea = $(el); var text = textarea.val(); var hasBreak = /\r|\n/.test(text); textarea .toggleClass("wiktku-has-linebreak", hasBreak) .attr("title", hasBreak ? "Xeta nû dê wek <br> bê nivîsandin" : ""); if (!hasBreak) { var cached = textarea.data("wiktkuLinebreakBackdrop"); if (cached) cached.hide(); textarea.removeClass("wiktku-has-linebreak-source"); return; } var backdrop = ensureLinebreakBackdrop(textarea); textarea.addClass("wiktku-has-linebreak-source"); syncLinebreakBackdropMetrics(textarea, backdrop); backdrop.html(buildLinebreakBackdropHtml(text)).show(); backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); } // Each nimûne item can be { text, tr, t }: text, transliteration, translation. function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{nimûne?|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = nlToBr(boldPageNameOnce(text)); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + nlToBr(n.tr); // Translation as third positional param (no key needed). if (n.t) tpl += "|" + nlToBr(n.t); } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 60 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } // Formats jêder (citation) entries into "#* {{jêder…|…}}" lines; skips // entries with no quote text. Falls back to the generic {{jêder}} // template when no specific template was chosen. function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; var quote = nlToBr(boldPageNameOnce(jeder.quote)); var quoteTr = nlToBr(jeder.quoteTr); var quoteT = nlToBr(jeder.quoteT); if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + quote; if (quoteTr) cite += "|tr=" + quoteTr; if (quoteT) cite += "|tercime=" + quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + quote; if (quoteTr) out += "|tr=" + quoteTr; if (quoteT) out += "|tercime=" + quoteT; // A şablon picked from Kategorî:Çavkanî is transcluded as the // source param (e.g. |{{Kovara X}}); manual text is used as-is. var srcParam = jeder.jederCatTpl ? ("{{" + jeder.jederCatTpl + "}}") : (jeder.jederManual ? jeder.jederManual : "çavkanî?"); // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } // True if a sense has at least one jêder entry with quote text. function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } // Builds "{{tplName|lang|part1|part2|…}}" from a sense field (kategori, // etiket), wrapped inline (" {{…}} ") or on its own line ("\n#: {{…}}"). function buildSenseTpl(sense, field, lang, tplName) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return call } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } // ── Inline modifier system ─────────────────────────────────────────────── // Appends a ⊕ button to a word input <li>. Clicking it shows a compact // modifier picker; selecting one prompts for the value and appends // <modifier:value> to the textarea's current content. 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îf" }, { 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: qualifier (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" }, { key: "qq", label: "qq: qualifier (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î" } ]; // Sub-groups (inside a sense/definition block) that get the same ⊕ // modifier button as makeWordListStep fields. var MODIFIER_SUBGROUPS = { "wiktku-dfn-alternativ": true, "wiktku-dfn-hevmane": true, "wiktku-dfn-dijmane": true, "wiktku-dfn-koordine": true, "wiktku-dfn-jornav": true, "wiktku-dfn-jernav": true }; /** * Wraps a freshly-created textarea in a <li> with a ⊕ modifier button. * `ta` — the jQuery textarea element. * Returns the <li>. */ function makeModifierLi(ta) { var li = $("<li class='wiktku-word-li'></li>"); var btn = $("<button type='button' class='wiktku-mod-btn' title='Modifiyerê lê zêde bike'>⊕</button>"); var picker = $("<div class='wiktku-mod-picker'></div>").hide(); // Which modifier keys are already present in the textarea's current // text — e.g. "<t:...>" → "t" used. Each modifier can only be // applied once per word, so its pill gets disabled once used. function usedKeys() { var used = {}; var re = /<([a-zA-Z]+):/g; var val = ta.val() || ""; var m; while ((m = re.exec(val)) !== null) used[m[1]] = true; return used; } $.each(WORD_MODIFIERS, function (_, mod) { var pill = $("<button type='button' class='wiktku-mod-pill'></button>").text(mod.label); pill.attr("title", mod.hint); pill.data("mod-key", mod.key); pill.on("click", function (e) { e.preventDefault(); if (pill.prop("disabled")) return; // already used on this word picker.hide(); // Show a tiny inline input for the modifier value. var valWrap = $("<span class='wiktku-mod-val-wrap'></span>"); var valInp = $("<input type='text' class='wiktku-mod-val-input'>") .attr("placeholder", mod.hint + "…") .attr("size", 20); var confirm = $("<button type='button' class='wiktku-mod-confirm'>✓</button>"); var cancel = $("<button type='button' class='wiktku-mod-cancel'>✕</button>"); function applyModifier() { var v = $.trim(valInp.val()); if (v) { ta.val(ta.val() + "<" + mod.key + ":" + v + ">"); ta.trigger("input"); } valWrap.remove(); ta.focus(); } confirm.on("click", applyModifier); cancel.on("click", function () { valWrap.remove(); ta.focus(); }); valInp.on("keydown", function (e) { if (e.which === 13) { e.preventDefault(); applyModifier(); } if (e.which === 27) { valWrap.remove(); ta.focus(); } }); valWrap.append(valInp).append(confirm).append(cancel); li.append(valWrap); valInp.focus(); }); picker.append(pill); }); btn.on("click", function (e) { e.preventDefault(); // Close any other open pickers in the same list. li.closest("ol, ul").find(".wiktku-mod-picker").not(picker).hide(); // Grey out modifiers already used on this word — refreshed on // every open since the text (and thus what's "used") can change. var used = usedKeys(); picker.find(".wiktku-mod-pill").each(function () { var isUsed = !!used[$(this).data("mod-key")]; $(this).prop("disabled", isUsed).toggleClass("wiktku-mod-pill-used", isUsed); }); picker.toggle(); }); // Close picker when focus leaves the li entirely. li.on("focusout", function () { setTimeout(function () { if (!$.contains(li[0], document.activeElement)) picker.hide(); }, 150); }); li.append(ta).append(btn).append(picker); return li; } function makeWordListStep(id, name, question_fmt) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, modifiers: true, // Function instead of a plain string so it can name the current // language — computed fresh at build time and re-applied by // refresh() whenever the language changes. placeholder: function () { var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return "Kelîme" + (langLabel ? " bi " + langLabel : "") + "…"; }, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); var header = capitalize(name); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: {}, visible: function (values) { if (!values.lang) return false; // addLangMode: skip pron only if this lang already has a section. if (addLangMode) { // Clearing the page makes existing content irrelevant. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, // Fills the insert-dropdown from pronTpls, filtered by language. refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); // Reassures the user this field is optional — the dropdown // below writes the template for them, no syntax needed up front. wrap.append( $("<p class='wiktku-step-hint'></p>").text( "Ev qad ne mecbûrî ye. Heke tu nizanî kîjan şablonî hilbijêrî, vale bihêle — an ji pêşkêşkariya jêrîn şablonekî hilbijêre, ew ê bixweber li vir were nivîsandin." ) ); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike "); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); // Clear the picker's search box sel.trigger("wiktku:refresh"); ta.focus(); return; } // The noLang templates (ku-IPA, ku-kîte, zza-IPA, zza-kîte) // auto-generate content from a Lua module reading the page // title, so show a live preview and require confirmation // before inserting. var tplLabel = selectedOption.text(); $(this).val(""); sel.trigger("wiktku:refresh"); steps.pron.showTplPreview(stepDiv, ta, snippet, tplLabel); }); wrap.append(sel).append(ta); stepDiv.append(wrap); steps.pron.buildIpaPalette(wrap, ta); initSelects(wrap); return ta; }, // ── IPA character palette ────────────────────────────────── // Modelled on fr.wiktionary's: every character is a button that // drops itself in at the cursor. Two sub-tabs, because the full // IPA chart is ~180 symbols and roughly twenty of them ever // appear in Kurmancî — "IPA (kurdî)" opens by default and the // full chart is one click away for loanwords and other // languages. Grouped with a label down the left so it reads as // a chart rather than one long line of glyphs. IPA_KU: [ { label: "Kît/stres", chars: ["ˈ", "ˌ", "ː"] }, { label: "Bêdeng", chars: ["d͡ʒ", "t͡ʃ", "ʒ", "ʃ", "ɫ", "ŋ", "ɾ", "r", "ʋ", "ħ", "ʕ", "ɣ", "χ", "ʔ"] }, { label: "Dengdêr", chars: ["ɑː", "eː", "ɛ", "ɪ", "iː", "ɯ", "ʊ", "uː", "yː", "ø", "œ"] } ], IPA_FULL: [ { label: "Bêdeng 1", chars: ["m", "ɱ", "n", "ɳ", "ɲ", "ŋ", "ɴ", "p", "b", "t", "d", "t̪", "d̪", "ʈ", "ɖ", "c", "ɟ", "k", "ɡ", "q", "ɢ", "ʡ", "ʔ"] }, { label: "Bêdeng 2", chars: ["ɸ", "β", "f", "v", "θ", "ð", "s", "z", "ʃ", "ʒ", "ʂ", "ʐ", "ɕ", "ʑ", "ç", "ʝ", "x", "ɣ", "χ", "ʁ", "ħ", "ʕ", "h", "ɦ", "ʜ", "ʢ", "ɧ"] }, { label: "Bêdeng 3", chars: ["ʋ", "ɹ", "ɻ", "j", "ɥ", "ɰ", "ʍ", "w", "ʙ", "ⱱ", "ɾ", "ɽ", "r", "ʀ", "ɺ", "l", "ɫ", "ɬ", "ɮ", "ɭ", "ʎ", "ʟ"] }, { label: "Bêdeng 4", chars: ["ɓ", "ɗ", "ᶑ", "ʄ", "ɠ", "ʛ", "ʘ", "ǀ", "ǃ", "ǂ", "ǁ"] }, { label: "Dengdêr", chars: ["i", "y", "ɪ", "ʏ", "ɨ", "ʉ", "ɯ", "u", "ʊ", "e", "ø", "ɘ", "ɵ", "ɤ", "o", "ə", "ɚ", "ɛ", "œ", "ɜ", "ɝ", "ɞ", "ʌ", "ɔ", "æ", "ɶ", "ɐ", "a", "ɑ", "ɒ"] }, { label: "Suprasegmental", chars: ["ˈ", "ˌ", "ː", "ˑ", "ʼ", "ˀ", "ˤ", "ᵝ", "ᵊ", "ˠ", "ʰ", "ʱ", "ʲ", "ˡ", "ⁿ", "ᵑ", "ʷ", "ᶣ", "˞", "‿"] }, { label: "Dîakrîtîk", chars: ["̚", "̪", "̺", "̻", "̼", "̬", "̊", "̥", "̞", "̝", "̘", "̙", "̽", "̟", "̠", "̈", "̤", "̹", "̜", "̍", "̩", "̆", "̯", "̃", "̰", "͡", "͜"] }, { label: "Ton", chars: ["̋", "́", "̄", "̀", "̏", "̌", "̂", "˥", "˦", "˧", "˨", "˩", "ꜛ", "ꜜ", "↗", "↘", "‖"] } ], /** Builds the two-sub-tab character palette under the textarea. */ buildIpaPalette: function (wrap, ta) { if (wrap.find(".wiktku-ipa-palette").length) return; var panel = $("<div class='wiktku-ipa-panel'></div>").hide(); var toggle = $("<a href='#' class='wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tîpên bilêvkirinê</span>")); toggle.on("click", function (e) { e.preventDefault(); var open = panel.is(":visible"); panel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); wrap.append($("<div class='wiktku-adv-toggle-row'></div>").append(toggle)); // Sub-tab bar, with the two template buttons pinned right. var subTabs = $("<div class='wiktku-ipa-subtabs'></div>"); var kuTab = $("<span class='wiktku-ipa-subtab wiktku-tab-active'>IPA (kurdî)</span>"); var fullTab = $("<span class='wiktku-ipa-subtab'>IPA</span>"); subTabs.append(kuTab).append(fullTab); var tplBtns = $("<span class='wiktku-ipa-tplbtns'></span>"); $.each([ { label: "{{ku-IPA|+}}", snippet: "{{ku-IPA|}}", back: 2 }, { label: "{{IPA|+}}", snippet: "{{IPA|ku|}}", back: 2 } ], function (_, t) { var b = $("<button type='button' class='wiktku-ipa-tplbtn'></button>").text(t.label); b.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], t.snippet); // Park the cursor inside the braces, where the value goes. var pos = ta[0].selectionStart - t.back; ta[0].selectionStart = ta[0].selectionEnd = pos; ta.focus(); }); tplBtns.append(b); }); subTabs.append(tplBtns); panel.append(subTabs); function buildGrid(groups) { var grid = $("<div class='wiktku-ipa-grid'></div>"); $.each(groups, function (_, g) { var row = $("<div class='wiktku-ipa-row'></div>"); row.append($("<span class='wiktku-ipa-rowlabel'></span>").text(g.label)); var keys = $("<span class='wiktku-ipa-keys'></span>"); $.each(g.chars, function (_, ch) { var btn = $("<button type='button' class='wiktku-ipa-key'></button>"); // A combining mark on its own renders as a stray // accent floating over whatever precedes it, so // show it on a dotted circle — but insert only // the mark itself. var combining = /^[̀-ͯ҃-҉]$/.test(ch); btn.text(combining ? "◌" + ch : ch); if (combining) btn.addClass("wiktku-ipa-key-combining"); btn.attr("title", ch); btn.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], ch); ta.focus(); }); keys.append(btn); }); row.append(keys); grid.append(row); }); return grid; } var kuGrid = buildGrid(steps.pron.IPA_KU); var fullGrid = buildGrid(steps.pron.IPA_FULL).hide(); panel.append(kuGrid).append(fullGrid); kuTab.on("click", function () { kuTab.addClass("wiktku-tab-active"); fullTab.removeClass("wiktku-tab-active"); kuGrid.show(); fullGrid.hide(); }); fullTab.on("click", function () { fullTab.addClass("wiktku-tab-active"); kuTab.removeClass("wiktku-tab-active"); fullGrid.show(); kuGrid.hide(); }); panel.addClass("wiktku-ipa-palette"); wrap.append(panel); }, /** Inline preview + confirm panel for a "noLang" (auto-content) * pronunciation template — fetches what the snippet expands to * for this page and only inserts it if the user confirms. */ showTplPreview: function (stepDiv, ta, snippet, tplLabel) { // Only one preview panel open at a time. stepDiv.find(".wiktku-pron-preview").remove(); var panel = $("<div class='wiktku-pron-preview'></div>"); panel.append($("<div class='wiktku-pron-preview-label'></div>") .text("Pêşdîtina " + tplLabel + ":")); var body = $("<div class='wiktku-pron-preview-body'></div>").text("Tê barkirin…"); panel.append(body); var actions = $("<div class='wiktku-pron-preview-actions'></div>"); var confirmBtn = $("<button type='button' class='wiktku-pron-preview-confirm'>✓ Tevlî bike</button>") .prop("disabled", true); var cancelBtn = $("<button type='button' class='wiktku-pron-preview-cancel'>✕ Betal bike</button>"); actions.append(confirmBtn).append(cancelBtn); panel.append(actions); ta.before(panel); confirmBtn.on("click", function () { insertAtCursor(ta[0], snippet); panel.remove(); ta.focus(); }); cancelBtn.on("click", function () { panel.remove(); }); // action=parse, not action=expandtemplates. expandtemplates // returns *expanded wikitext*, so the preview read as // [[IPA]]<sup>([[Wîkîferheng:IPA kurmancî|kilîd]])</sup>: // <span class="IPA">/-{kshhe}-/</span>[[Kategorî:…]] — which // is exactly what the person is trying to avoid having to // read. parse hands back the rendered HTML the page will // actually show. // // Drop the leading "* " first: it is wikitext list syntax // wrapping the template, and keeping it would render the // preview as a bulleted list rather than the line itself. new mw.Api().post({ action: "parse", title: pageName, text: snippet.replace(/^\*\s*/, ""), prop: "text", wrapoutputclass: "", disablelimitreport: 1, disableeditsection: 1, contentmodel: "wikitext", formatversion: 2 }).done(function (data) { var html = (data && data.parse && data.parse.text) || ""; if ($.trim($("<div>").html(html).text())) { body.html(html); // Category links render as nothing but still exist; // and any real link inside a preview should not // navigate away from a half-filled form. body.find("a").attr("target", "_blank").attr("rel", "noopener"); } else { body.text("(vala — ji bo vê rûpelê tiştek nehate afirandin)"); } confirmBtn.prop("disabled", false); }).fail(function () { body.text("Pêşdîtin nehate barkirin — tu dikarî hîn jî wê tevlî bikî."); confirmBtn.prop("disabled", false); }); }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line; }).join("\n"); // "===" heading under Ziman and above the POS sections; the // field is shared across sections, so it's emitted once by // getWikitext() rather than per-POS-section (would otherwise // print the pronunciation twice for a two-POS entry). return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var capitalizedPos = capitalize(pos); // "form" opt-param (checked in posparams) marks this as a // form-of/inflected entry — the section title becomes // "Formeke <pos>ê" instead of the plain pos name. The // template call itself still uses the unchanged pos name. var isForm = $("#wiktku-posparams-opt-form").is(":checked"); var header = isForm ? "\n=== Formeke " + pos + "ê ===\n" : "\n=== " + capitalizedPos + " ===\n"; // Image line (between header and template call) var imageLine = steps.resim.output(values); // Read the live wikitext from the posparams textarea. // Fall back to a plain {{pos|lang}} if the step hasn't been built yet. var tplLine = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); if (!tplLine) { tplLine = "{{" + pos + "|" + (values.lang || "") + "}}"; } return header + imageLine + tplLine + "\n"; } }, // cinsiyet (gender) — shown for navdêr/serenav only, with choices built // from metadata[lang].g since not every language has grammatical gender. cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams // Single source of truth for the selected gender code. The visible // dropdown lives inside the posparams step (see steps.posparams), // but it must always read/write THIS hidden field — not a field of // its own — since getValuesForStep("cinsiyet") reads from here. build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-cinsiyet-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // jimar (grammatical number) — same hidden-field pattern as cinsiyet // above, but writes into its own j= template parameter instead of // sharing c=. Shown for navdêr/serenav only, with choices built from // whichever of metadata[lang].g are number codes (see isNumberCode). jimar: { id: "jimar", name: "jimar", question_fmt: 'Jimara "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-jimar-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // Lêker transitivity — hidden step, handled inside posparams lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function () { return false; }, choices: [ { code: "gh", label: "gerguhêz" }, { code: "x-gh", label: "xwerû-gerguhêz" }, { code: "p-gh", label: "pêkhatî-gerguhêz" }, { code: "h-gh", label: "hevedudanî-gerguhêz" }, { code: "b-gh", label: "biwêjî-gerguhêz" }, { code: "ngh", label: "negerguhêz" }, { code: "x-ngh", label: "xwerû-negerguhêz" }, { code: "p-ngh", label: "pêkhatî-negerguhêz" }, { code: "h-ngh", label: "hevedudanî-negerguhêz" }, { code: "b-ngh", label: "biwêjî-negerguhêz" } ], output: function () { return ""; } }, // tr — hidden step, handled inside posparams tr: { id: "tr", name: "transliterasyon", question_fmt: "Transliterasyona vê kelîmeyê", multiple: false, narrow: true, visible: function () { return false; } }, posparams: { id: "posparams", // Fused onto the "pos" card visually (see #wiktku-start-posparams // in styles.css) so the two read as ONE question — this name is // only a no-CSS/no-JS fallback, since the h3 that would show it // is hidden by CSS. name: "taybetmendî", // Shows what's actually being asked for: gender for nouns, verb // type for verbs, a generic fallback otherwise. question_fmt: function (values) { var pos = values.pos || ""; // Cinsiyet/Jimar fields below are self-labelled, so no title needed here. if (pos === "navdêr" || pos === "serenav") return ""; if (/^lêker/.test(pos)) return "Cureyê lêkerê"; return "Taybetmendî"; }, visible: function (values) { return !!(values.lang && values.pos); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-posparams-wrap").length) return null; var wrap = $("<div class='wiktku-posparams-wrap'></div>"); var helpers = $("<div class='wiktku-posparams-helpers'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-posparams-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-posparams-text") .attr("rows", 2); var _rebuilding = false; function safeRebuild() { if (_rebuilding) return; _rebuilding = true; steps.posparams.rebuildTa(stepDiv); _rebuilding = false; refresh(); } // Generic text-input row factory function makeTextRow(key, labelText, placeholder) { var row = $("<div class='wiktku-posparams-row'></div>") .attr("id", "wiktku-posparams-row-" + key).hide(); var inp = $("<input type='text'>") .addClass("wiktku-start-narrow wiktku-posparams-field") .attr("data-pp-key", key) .attr("placeholder", placeholder || ""); inp.on("input", safeRebuild); row.append($("<label></label>").text(labelText + ": ")).append(inp); return row; } // cinsiyet var cinsiyetRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-c'></div>") .append($("<label></label>").text("Cinsiyet: ")).hide(); var cinsiyetSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-cinsiyet-sel") .append($("<option value=''>— hilbijêre —</option>")); // Writes into the real, shared #wiktku-start-cinsiyet-field (owned by // steps.cinsiyet) rather than a field of its own — see the comment // on steps.cinsiyet.build for why that matters. cinsiyetSel.on("change", function () { $("#wiktku-start-cinsiyet-field").val($(this).val()).trigger("change"); safeRebuild(); }); cinsiyetRow.append(cinsiyetSel); // jimar (number) — second dropdown next to Cinsiyet, writes // into the shared hidden #wiktku-start-jimar-field, into its // own j= param instead of sharing c=. Options + tooltip are // built in syncHelpers once the language's number codes are known. var jimarRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-jimar'></div>") .append($("<label></label>").text("Jimar: ")).hide(); var jimarSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-jimar-sel") .append($("<option value=''>— hilbijêre —</option>")); jimarSel.on("change", function () { $("#wiktku-start-jimar-field").val($(this).val()).trigger("change"); safeRebuild(); }); jimarRow.append(jimarSel); // lektur: two plain questions (transitivity + structural form) // instead of one 10-option dropdown. Emitted code: base alone // ("gh"), or prefix + "-" + base ("x-gh"). var lekturRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lektur'></div>") .append($("<label></label>").text("Lêker derbasdar e? ")).hide(); var lekturSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lektur-sel") .append($("<option value=''>— hilbijêre —</option>")) .append($("<option value='gh'>gerguhêz (bireser digire)</option>")) .append($("<option value='ngh'>negerguhêz (bireser nagire)</option>")); lekturSel.on("change", safeRebuild); lekturRow.append(lekturSel); // Second half of the same question — the structural form. // Blank = xwerû/sade, which is the common case. var lekturFormRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lekturform'></div>") .append($("<label></label>").text("Şiklê lêkerê: ")).hide(); var lekturFormSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lekturform-sel") .append($("<option value=''>sade (asayî)</option>")) .append($("<option value='x'>xwerû</option>")) .append($("<option value='p'>pêkhatî</option>")) .append($("<option value='h'>hevedudanî</option>")) .append($("<option value='b'>biwêjî</option>")); lekturFormSel.on("change", safeRebuild); lekturFormRow.append(lekturFormSel); helpers.append(cinsiyetRow).append(jimarRow).append(lekturRow).append(lekturFormRow); // ── Everything below here is "Tercîhên pêşketî" ────────────── // These rows live inside a collapsed panel, so the default // view of this card is two dropdowns instead of twenty-odd fields. // Transliteration is a primary field, not an advanced one, for // any language not written in Latin script: for those, an // entry without it is incomplete. syncHelpers already gates // the row on needsTransliteration(lang), so for Kurmancî and // other Latin-script languages it simply never appears. helpers.append(makeTextRow("tr", "Transliterasyon (tr)", "Transliterasyon…")); var advPanel = $("<div class='wiktku-posparams-adv-panel'></div>").hide(); advPanel .append(makeTextRow("cuda", "nîşankirina alternatîv", "cuda…")) .append(makeTextRow("ts", "Transkrîpsiyon (ts)", "Transkrîpsiyon…")) .append(makeTextRow("m", "Forma mê (m)", "Forma mê…")) .append(makeTextRow("mtr", "Translit. mê (mtr)", "Transliterasyona mê…")) .append(makeTextRow("n", "Forma nêr (n)", "Forma nêr…")) .append(makeTextRow("ntr", "Translit. nêr (ntr)", "Transliterasyona nêr…")) .append(makeTextRow("p", "Forma pirjimar (p)", "Forma pirjimar…")) .append(makeTextRow("ptr", "Translit. pirjimar", "Transliterasyona pirjimar…")) .append(makeTextRow("y", "Forma yekjimar (y)", "Forma yekjimar…")) .append(makeTextRow("ytr", "Translit. yekjimar", "Transliterasyona yekjimar…")) .append(makeTextRow("sûp", "Forma sûperlatîv (sûp)", "Forma sûperlatîv…")) .append(makeTextRow("sûptr", "Translit. sûperlatîv", "Transliterasyona sûperlatîv…")) .append(makeTextRow("komp", "Forma komparatîv (komp)", "Forma komparatîv…")) .append(makeTextRow("komptr", "Translit. komparatîv", "Transliterasyona komparatîv…")) .append(makeTextRow("gir", "Forma girdêk (gir)", "gir=…")) .append(makeTextRow("girtr", "Translit. gir", "girtr=…")) .append(makeTextRow("hûr", "Forma hûrek (hûr)", "hûr=…")) .append(makeTextRow("hûrtr", "Translit. hûr", "hûrtr=…")) .append(makeTextRow("hanja", "Forma hanja", "hanja=…")) .append(makeTextRow("hanjaTr","Translit. hanja", "hanjaTr=…")) // Lêker rehên demê (only shown when pos is lêker — see syncHelpers) .append(makeTextRow("niha", "Rehê dema niha (niha)", "Rehê dema niha…")) .append(makeTextRow("nihatr", "Translit. rehê dema niha", "Transliterasyona rehê dema niha…")) .append(makeTextRow("borî", "Rehê dema borî (borî)", "Rehê dema borî…")) .append(makeTextRow("borîtr", "Translit. rehê dema borî", "Transliterasyona rehê dema borî…")) .append(makeTextRow("subj", "Rehê dema bilanî (subj)", "Rehê dema bilanî…")) .append(makeTextRow("subjtr", "Translit. rehê dema bilanî", "Transliterasyona rehê dema bilanî…")); // Optional boolean params — nested inside the advanced panel // (they were already the most niche thing on the card). var optPanel = $("<div class='wiktku-posparams-opt-panel'></div>"); $.each([ { key: "form", label: "form — ev made forma tewandî ye" }, { key: "formaalt", label: "formaalt — vê madeyê bike forma alternatîv" }, { key: "nekatcure", label: "nekatcure — sinifa rêzimanî kategorîze neke" }, { key: "nekatcins", label: "nekatcins — kategoriya cinsiyetê neyîne" }, { key: "nekatçendterm", label: "nekatçendterm — kategoriya çend-term neyîne" }, { key: "serlînkneke", label: "serlînkneke — sernavê madeyê lînk neke" }, { key: "nekatpalîndrom", label: "nekatpalîndrom — kategoriya palîndromê neyîne" }, { key: "neformtr", label: "neformtr — transliterasyona forman neyîne" } ], function (_, p) { var cb = $("<input type='checkbox'>") .attr("id", "wiktku-posparams-opt-" + p.key).val(p.key).on("change", safeRebuild); var lbl = $("<label></label>").attr("for", "wiktku-posparams-opt-" + p.key).text(" " + p.label); optPanel.append($("<div class='wiktku-posparams-opt-row'></div>").append(cb).append(lbl)); }); advPanel.append(optPanel); var optToggle = $("<a href='#' class='wiktku-posparams-opt-toggle wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tercîhên pêşketî</span>")); optToggle.on("click", function (e) { e.preventDefault(); var open = advPanel.is(":visible"); advPanel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); helpers.append($("<div class='wiktku-adv-toggle-row'></div>") .append(optToggle)); helpers.append(advPanel); wrap.append(helpers).append(ta); // Typing directly in textarea keeps cinsiyet/jimar hidden // fields in sync, but does NOT call refresh() — preserves // manual edits. ta.on("input", function () { var text = $(this).val(); var cMatch = text.match(/\|c=([^|}\s]+)/); $("#wiktku-start-cinsiyet-field").val(cMatch ? cMatch[1] : ""); var jMatch = text.match(/\|j=([^|}\s]+)/); $("#wiktku-start-jimar-field").val(jMatch ? jMatch[1] : ""); }); stepDiv.append(wrap); return null; }, /** Reads all helper widget values and rewrites the textarea. * Called only by safeRebuild (user interaction) — never by syncHelpers, * so manual textarea edits are never overwritten by a refresh cycle. */ rebuildTa: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; if (!pos || !lang) return; var cinsiyet = stepDiv.find(".wiktku-posparams-cinsiyet-sel").val() || ""; var jimar = stepDiv.find(".wiktku-posparams-jimar-sel").val() || ""; // Two dropdowns, one code: "gh" / "ngh" on their own, or // prefixed with the structural form ("x-gh", "b-ngh", …). var lekturBase = stepDiv.find(".wiktku-posparams-lektur-sel").val() || ""; var lekturForm = stepDiv.find(".wiktku-posparams-lekturform-sel").val() || ""; var lektur = lekturBase ? (lekturForm ? lekturForm + "-" + lekturBase : lekturBase) : ""; function v(key) { return $.trim(stepDiv.find(".wiktku-posparams-field[data-pp-key='" + key + "']").val()); } var out = "{{" + pos + "|" + lang; if (pos === "navdêr" || pos === "serenav") { out += cinsiyet ? "|c=" + cinsiyet : (lang === "ku" ? "|c=?" : ""); // Number is its own j= param, separate from c= (which // holds gender, including compounds like m-p/n-p). if (jimar) out += "|j=" + jimar; } else if (/^lêker/.test(pos) && lektur) { out += "|c=" + lektur; } if (v("cuda")) out += "|" + v("cuda"); if (v("tr")) out += "|tr=" + v("tr"); if (v("ts")) out += "|ts=" + v("ts"); $.each(["m","n","p","y"], function (_, k) { if (v(k)) out += "|" + k + "=" + v(k); if (v(k+"tr")) out += "|" + k + "tr=" + v(k+"tr"); }); if (v("sûp")) out += "|sûp=" + v("sûp"); if (v("sûptr")) out += "|sûptr=" + v("sûptr"); if (v("komp")) out += "|komp=" + v("komp"); if (v("komptr")) out += "|komptr=" + v("komptr"); if (v("gir")) out += "|gir=" + v("gir"); if (v("girtr")) out += "|girtr=" + v("girtr"); if (v("hûr")) out += "|hûr=" + v("hûr"); if (v("hûrtr")) out += "|hûrtr=" + v("hûrtr"); if (v("hanja")) out += "|hanja=" + v("hanja"); if (v("hanjaTr")) out += "|hanjaTr=" + v("hanjaTr"); if (v("niha")) out += "|niha=" + v("niha"); if (v("nihatr")) out += "|nihatr=" + v("nihatr"); if (v("borî")) out += "|borî=" + v("borî"); if (v("borîtr")) out += "|borîtr=" + v("borîtr"); if (v("subj")) out += "|subj=" + v("subj"); if (v("subjtr")) out += "|subjtr=" + v("subjtr"); stepDiv.find(".wiktku-posparams-opt-panel input:checked").each(function () { var key = $(this).val(); // "form" marks this entry as a form-of/inflected entry — it // takes "erê" rather than the plain "1" the other boolean // opt params use. out += "|" + key + "=" + (key === "form" ? "erê" : "1"); }); out += "}}"; stepDiv.find(".wiktku-posparams-text").val(out); $("#wiktku-start-cinsiyet-field").val(cinsiyet); $("#wiktku-start-jimar-field").val(jimar); }, /** Called from refresh() — controls row visibility only. * Does NOT rewrite textarea so user edits are preserved. * Rebuilds only when textarea is empty (first pos selection). */ syncHelpers: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; var needsTr = needsTransliteration(lang); var isNom = pos === "navdêr" || pos === "serenav" || pos === "rengdêr"; var isAdj = pos === "rengdêr"; var isTîp = pos === "tîp"; var isJa = lang === "ja"; var isLeker = /^lêker/.test(pos); // Kurmancî verbs are conjugated from the present/past roots // alone — there's no separate subjunctive root the way some // other languages have — so this pair of fields is noise for // lang=ku specifically, unlike niha/borî which every lêker // language needs. var isLekerSubj = isLeker && lang !== "ku"; // metadata[lang].g lists gender AND number codes together — // split them here (see isNumberCode) so Cîns only ever offers // gender codes (and gender+plural compounds like m-p/n-p, // which aren't NUMBER_LABELS keys) and Jimar only offers number codes. var meta = metadata[lang]; var allCodes = (meta && meta.g) || []; var genderCodes = $.grep(allCodes, function (c) { return !isNumberCode(c); }); var jimarCodes = $.grep(allCodes, function (c) { return isNumberCode(c); }); var showC = (pos === "navdêr" || pos === "serenav") && genderCodes.length > 0; var cRow = stepDiv.find("#wiktku-posparams-row-c"); cRow.toggle(showC); if (showC) { var sel = cRow.find(".wiktku-posparams-cinsiyet-sel"); // Prefer the select's own current value (normal in-session // use); fall back to the shared hidden field, which is how // a cache/section restore communicates a saved gender // before this select has any <option>s to hold it. var prev = sel.val() || $("#wiktku-start-cinsiyet-field").val() || ""; sel.find("option[value!='']").remove(); $.each(genderCodes, function (_, code) { sel.append($("<option></option>").val(code).text(genderLabel(code))); }); if (prev) sel.val(prev); } var showJimar = (pos === "navdêr" || pos === "serenav") && jimarCodes.length > 0; var jimarRowEl = stepDiv.find("#wiktku-posparams-row-jimar"); jimarRowEl.toggle(showJimar); if (showJimar) { var jimarSelEl = jimarRowEl.find(".wiktku-posparams-jimar-sel"); var prevJimar = jimarSelEl.val() || $("#wiktku-start-jimar-field").val() || ""; jimarSelEl.find("option[value!='']").remove(); $.each(jimarCodes, function (_, code) { var def = NUMBER_LABELS[code] || {}; var opt = $("<option></option>").val(code).text(numberOptionLabel(code)); // The explanation (cat, e.g. "dualia tantum") shows as a // hover tooltip — <option> can't hold richer markup. if (def.cat) opt.attr("title", def.cat); jimarSelEl.append(opt); }); if (prevJimar) jimarSelEl.val(prevJimar); } stepDiv.find("#wiktku-posparams-row-lektur").toggle(isLeker); // Only ask for the structural form once gerguhêz/negerguhêz is answered. stepDiv.find("#wiktku-posparams-row-lekturform") .toggle(isLeker && !!stepDiv.find(".wiktku-posparams-lektur-sel").val()); stepDiv.find("#wiktku-posparams-row-tr").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-ts").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-m").toggle(isNom); stepDiv.find("#wiktku-posparams-row-mtr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-n").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ntr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-p").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ptr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-y").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ytr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-sûp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-sûptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-komp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-komptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-gir").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-girtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hûr").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-hûrtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hanja").toggle(isJa); stepDiv.find("#wiktku-posparams-row-hanjaTr").toggle(isJa); stepDiv.find("#wiktku-posparams-row-niha").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-nihatr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-borî").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-borîtr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-subj").toggle(isLekerSubj); stepDiv.find("#wiktku-posparams-row-subjtr").toggle(isLekerSubj && needsTr); if (!$.trim(stepDiv.find(".wiktku-posparams-text").val())) { steps.posparams.rebuildTa(stepDiv); } }, output: function () { return ""; } // pos.output reads the textarea directly }, dfn: { id: "dfn", name: "Mane", // Field types that live behind "Malûmatên pêşketî". Kept as one // list so the collapse CSS, the count badge and the allGroups // adv: flags below can't drift apart. ADV_SUBGROUPS: [ "wiktku-dfn-etiket", "wiktku-dfn-kategori", "wiktku-dfn-alternativ", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ], question_fmt: function (values) { var base = "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin!"; if (values.lang === "ku") { return base + " Ji bo tercimeyan beşa 'Werger' bi kar bîne!"; } return base; }, multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, // Builds one sense block (<li>): mane textarea, nimûne list, and // sub-lists for alternatîv/hevmane/dijmane/etc. buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Tercime + Îzah boxes (non-ku alternative to the plain mane box) — // Non-ku entries get a direct translation plus a {{îzah|…}}-wrapped // gloss instead of a Kurdish-style gloss. Rather than teach every // consumer (getSenses/getOutput/linkify) a second data shape, these // boxes just write their combined text into dfnArea and re-fire its // "input" event, so dfnArea stays the single source of truth. var tercimeArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-tercime-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-tercime") .attr("rows", 2) .attr("placeholder", "Tercimeyên rasterast ên kurmancî… Ji bo school-a îngilîzî li vir 'mekteb, medrese' binivîse"); var izahArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-izah-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-izah") .attr("rows", 3) .attr("placeholder", "Îzaha kurmancî… Ji bo school-a îngilîzî li vir 'cihê tehsîlgirtinê' binivîse"); var nonKuWrap = $("<div class='wiktku-dfn-nonku-wrap'></div>") .append(tercimeArea).append(izahArea) .hide(); function syncNonKuToMane() { var t = $.trim(tercimeArea.val()); var iz = $.trim(izahArea.val()); // if tercime is blank, use îzah as definition var combined = t ? (iz ? t + " {{îzah|" + iz + "}}" : t) : iz; dfnArea.val(combined); // Re-fires onDfnInput, as if this were typed directly into // the mane textarea. dfnArea.trigger("input"); } tercimeArea.on("input", syncNonKuToMane); izahArea.on("input", syncNonKuToMane); // Switches between the plain mane box and the tercime+îzah pair — // only for non-ku entries with no tplSelect selected. function updateManeMode() { var lang = getValues().lang || ""; var isTpl = !!tplSelect.val(); if (lang && lang !== "ku" && !isTpl) { dfnArea.hide(); nonKuWrap.show(); } else { nonKuWrap.hide(); if (!isTpl) dfnArea.show(); } } // Store on the block so refresh() can re-sync every block when // lang changes, and restoreDfn() can re-sync after restoring. block.data("updateManeMode", updateManeMode); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || {}; // Cache of all non-placeholder option elements, so updateTplOptions // can detach/re-attach them without losing the full list. var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.attr("data-placeholder", "Li şablonekê bigere"); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (name, tpl) { // Shows "name — tpl.desc" when a tplDefs entry has a desc // in data.json, same pattern as steps.pron's template picker. var opt = $("<option></option>") .val(name) .text(tpl.desc ? name + " — " + tpl.desc : name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); // Same status-dot / 🔗 / ⓘ row treatment as every other // template picker. This one carries the bare name in value=, // so the name mapper is the identity rather than a snippet // parse; descriptions come from each template's TemplateData. markTemplateOptions(tplSelect, function (opt) { return opt.val(); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible // ones — native <select> won't reliably hide options any other way. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); // Options that were detached when the descriptions arrived // missed that pass, so describe whatever is attached now. // The cache is warm by this point, so this is synchronous. applyTplDescriptions(tplSelect); tplSelect.trigger("wiktku:refresh"); if (currentVal && !currentStillValid) { tplSelect.val(""); tplTitleInput.hide().val(""); updateManeMode(); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpela hedefê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // Şablon senses have no plain gloss, so hide alternatîv/hevmane/ // dijmane/etc. Etîket, Nimûne and Jêgirtin stay visible either way. function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); nonKuWrap.hide(); tplTitleInput.show().focus(); } else { tplTitleInput.hide().val(""); updateManeMode(); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); // The template picker is an alternative to writing a // definition, not a step before it — so the box comes first // and this sits under it as a quiet link. It only expands // for the minority of senses that are a pointer at another // word (guharto, şaşnivîs, kevnbûyî) rather than a meaning. var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput) .hide(); var tplLink = $("<a href='#' class='wiktku-dfn-tpl-link'></a>") .text("Ev ne pênase ye — şablonek bi kar bîne"); tplLink.on("click", function (e) { e.preventDefault(); tplRow.show(); $(this).hide(); tplRow.find("input.wiktku-ac-input").first().focus(); }); /** Opens the picker without a click — used on restore, when a * sense already has a template and hiding it would make the * chosen value invisible. */ function revealTplRow() { tplRow.show(); tplLink.hide(); } block.data("revealTplRow", revealTplRow); block.append(dfnArea); block.append(nonKuWrap); block.append(tplLink); block.append(tplRow); // Apply lang filter on initial build. updateTplOptions(); updateManeMode(); // — Sub-field groups. — // The four most-used groups (Nimûne, Jêgirtin, Hevmane, Dijmane) // stay open; the rest sit behind the "Malûmatên pêşketî" toggle // (adv: true → .wiktku-dfn-subgroup-adv, keyed off by the collapse CSS). // Jêgirtin isn't in this array — it's a compound widget built // after the loop — but it's inserted right after Nimûne so the // visible order matches the list above. var allGroups = [ { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "wekî etîket lê xuya nabe tenê kategorîze dike", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê", adv: true }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in", adv: true }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e", adv: true }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e", adv: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); if (g.adv) groupDiv.addClass("wiktku-dfn-subgroup-adv"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } // The placeholder names the current language, but that's // often not chosen yet when this block is first built — // so keep a function around that refresh() (and onSubInput, // for newly-grown fields) can call again once lang is set // or changes. function subPlaceholder() { if (g.noLangSuffix) return g.label + "…"; var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return g.label + (langLabel ? " bi " + langLabel : "") + "…"; } function updateSubPlaceholders() { list.find("> li > textarea.wiktku-dfn-subfield").attr("placeholder", subPlaceholder()); } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": ") .append($("<span></span>").addClass("wiktku-dfn-sublabel-hint").text(g.izah)); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var useModifiers = !!MODIFIER_SUBGROUPS[g.cls]; list.data("updatePlaceholders", updateSubPlaceholders); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", subPlaceholder()); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow, useModifiers); }); list.append(useModifiers ? makeModifierLi(firstInput) : $("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder group — growing list, same structure as Nimûne. — (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text("Jêgirtin")) .append(": "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<textarea></textarea>") .addClass("wiktku-dfn-subfield wiktku-dfn-quote-citoid-input") .attr("rows", 1) .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi otomatîk tijî bike", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); // Fetches citation data from Citoid and fills this citation's // şablon + fields — only rebuilds fields on template change, // and never overwrites values the user already typed. function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoid.fetchJederFields(query).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only rebuild if switching şablon, so a repeat fetch // doesn't clear fields already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel wiktku-plain-select"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); srcSel.append($("<option></option>").val("__category__").text("Ji Kategorî:Çavkanî şablonekê hilbijêre")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); // Citoid is only useful before a source is chosen — // hide it once a selection is made, restore on reset. if (chosen) { citoidWrap.hide(); } else { citoidWrap.show(); return; } if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } if (chosen === "__category__") { // Search widget over the members of [[Kategorî:Çavkanî]]. // Picking a şablon here immediately switches the row to // "Bi destê xwe binivîsim" mode with {{Şablon}} pre-filled, var catWrap = $("<span></span>").addClass("wiktku-native-select-wrap wiktku-dfn-quote-src-cat"); var catInput = $("<input type='search' autocomplete='off'>") .addClass("wiktku-start-narrow wiktku-dfn-quote-src-cat-input") .attr("placeholder", "Li navê şablonê bigere…"); var catResults = $("<ul></ul>").addClass("wiktku-ac-results wiktku-dfn-quote-src-cat-results").hide(); var catStatus = $("<span></span>").addClass("wiktku-dfn-quote-src-cat-status").text("Şablon tên barkirin…"); var showCatResults = function (query) { var q = $.trim(query).toLowerCase(); catResults.empty(); var list = catSrcTemplates || []; var matched = q ? $.grep(list, function (name) { return name.toLowerCase().indexOf(q) !== -1; }) : list; if (!matched.length) { catResults.hide(); return; } $.each(matched.slice(0, 50), function (_, name) { var li = $("<li></li>").text(name).attr("data-value", name); var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; e.preventDefault(); selectCatTpl(name); }); li.on("mousedown", function (e) { e.preventDefault(); selectCatTpl(name); }); catResults.append(li); }); catResults.show(); }; // Wraps the chosen şablon as {{Name}}, drops it into the // manual textarea, and switches the row into manual mode // so the user can keep editing it (add params, etc.). var selectCatTpl = function (name) { catResults.hide(); srcSel.val("__manual__"); srcSel.trigger("change"); srcFields.find(".wiktku-dfn-quote-src-manual") .val("{{" + name + "}}") .trigger("focus"); }; catInput.on("input", function () { showCatResults($(this).val()); }); catInput.on("focus", function () { showCatResults($(this).val()); }); catInput.on("blur", function () { setTimeout(function () { catResults.hide(); }, 200); }); catWrap.append(catInput).append(catResults).append(catStatus); srcFields.append(catWrap); fetchCatSrcTemplates().then(function () { catStatus.text(""); }, function () { catStatus.text("Şablon nehatin barkirin."); }); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (key, label) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", key) .attr("placeholder", label + "…"); // "Sernav" / "Sernavê orjînal" (title fields, e.g. for // kitêb/kovar/malper) get a taller, draggable box; every // other field in the template stays as-is. Field labels // come from the on-wiki jederDefs data, so match on the // (diacritic-folded) label text rather than a fixed key. var foldedLabel = foldDiacritics(label); if (/^sernav$/.test(foldedLabel) || /orjin/.test(foldedLabel)) { inp.addClass("wiktku-dfn-quote-src-input--title"); } row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); jederGroupDiv.append(jederLbl).append(jederList); // Straight after Nimûne rather than last: Jêgirtin is the // same kind of thing (an attested use of the word) and the // two belong together — see the allGroups comment above. var nimuneGroup = block.find(".wiktku-dfn-nimune-group"); if (nimuneGroup.length) jederGroupDiv.insertAfter(nimuneGroup); else block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); // ── "Malûmatên pêşketî" — per sense, after Dijmane ─────── // One toggle per sense rather than one for the whole step: // the fields behind it (Etîket, Kategorî, Jornav…) belong to // a single meaning, so a global switch flipped them for every // sense at once and gave a count that answered "across all // senses" — not a question anybody was asking. (function () { block.addClass("wiktku-sense-adv-hidden"); var advRow = $("<div class='wiktku-adv-toggle-row wiktku-sense-adv-row'></div>"); var advToggle = $("<a href='#' class='wiktku-adv-toggle'></a>").attr("aria-expanded", "false"); var advLabel = $("<span class='wiktku-adv-toggle-text'></span>"); advToggle.append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")).append(advLabel); function syncAdv() { var hidden = block.hasClass("wiktku-sense-adv-hidden"); advLabel.text(hidden ? "Malûmatên pêşketî nîşan bide" : "Malûmatên pêşketî veşêre"); advToggle.attr("aria-expanded", hidden ? "false" : "true") .toggleClass("wiktku-adv-open", !hidden); } advToggle.on("click", function (e) { e.preventDefault(); block.toggleClass("wiktku-sense-adv-hidden"); syncAdv(); }); block.data("syncSenseAdv", syncAdv); advRow.append(advToggle); // After the last always-visible group (Dijmane) and before // the advanced ones, which sit below it in DOM order. var lastPrimary = block.find(".wiktku-dfn-dijmane-group"); if (lastPrimary.length) advRow.insertAfter(lastPrimary); else block.append(advRow); syncAdv(); }()); return block; }, /** Shows only `block` among the sense list; hides every other one. */ setOpenSense: function (stepDiv, block) { stepDiv.find("li.wiktku-dfn-sense").each(function () { $(this).toggleClass("wiktku-sense-collapsed", !$(this).is(block)); }); steps.dfn.renderSenseTabs(stepDiv); }, /** Rebuilds the "Mane 1 / Mane 2 / + Mane zêde bike" tab row from the current sense list. */ renderSenseTabs: function (stepDiv) { var tabsDiv = stepDiv.find(".wiktku-dfn-sense-tabs"); if (!tabsDiv.length) return; tabsDiv.empty(); var senseCount = stepDiv.find("li.wiktku-dfn-sense").length; stepDiv.find("li.wiktku-dfn-sense").each(function (i) { var li = $(this); var tab = $("<span class='wiktku-dfn-sense-tab'></span>") .toggleClass("wiktku-tab-active", !li.hasClass("wiktku-sense-collapsed")); tab.append($("<span class='wiktku-tab-label'></span>").text("Mane " + (i + 1))); tab.on("click", function () { steps.dfn.setOpenSense(stepDiv, li); }); // Always keep at least one Mane — no delete button when // it's the only sense left. if (senseCount > 1) { var trash = makeTrashButton("Vê maneyê jê bibe"); trash.on("click", function (e) { // Stop this from also reaching the tab's own click // handler above (which would just re-open it). e.preventDefault(); e.stopPropagation(); if (!window.confirm("Tu dixwazî Mane " + (i + 1) + " jê bibî? Ev tişt nayê vegerandin.")) return; steps.dfn.removeSense(stepDiv, li); }); tab.append(trash); } tabsDiv.append(tab); }); var addBtn = $("<button type='button' class='wiktku-add-sense'></button>") .append($("<span class='wiktku-add-sense-plus'>+</span>")) .append(document.createTextNode("Mane zêde bike")); addBtn.on("click", function (e) { e.preventDefault(); steps.dfn.addSense(stepDiv); }); tabsDiv.append(addBtn); }, onDfnInput: function (stepDiv, block, textarea) { refresh(); }, /** Appends a sense, opens it, and hides the others. */ addSense: function (stepDiv) { var list = stepDiv.find("ol.wiktku-dfn-list"); var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); initSelects(newBlock); steps.dfn.setOpenSense(stepDiv, newBlock); newBlock.find("textarea.wiktku-dfn-mane").first().focus(); refresh(); return newBlock; }, /** Removes one sense block. Assumes the caller already confirmed * and already checked more than one sense remains. If the * removed sense was the open one, opens whichever sense ends up * taking its place (or the last one, if it was the last). */ removeSense: function (stepDiv, li) { var list = stepDiv.find("ol.wiktku-dfn-list"); var blocks = list.find("li.wiktku-dfn-sense"); var removedIdx = blocks.index(li); var wasOpen = !li.hasClass("wiktku-sense-collapsed"); li.remove(); if (wasOpen) { var remaining = list.find("li.wiktku-dfn-sense"); var next = remaining.eq(removedIdx); if (!next.length) next = remaining.last(); if (next.length) steps.dfn.setOpenSense(stepDiv, next); } steps.dfn.renderSenseTabs(stepDiv); refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow, modifiers) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow, modifiers); }); list.append(modifiers ? makeModifierLi(next) : $("<li></li>").append(next)); // New field starts with no placeholder — give it (and any // others in the list) the current one. var updatePlaceholders = list.data("updatePlaceholders"); if (typeof updatePlaceholders === "function") updatePlaceholders(); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: {}, posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; // One reassurance, shown once for the whole Mane step: the // "an jî şablonek hilbijêre" dropdown inside each sense is // optional — plain text is the normal path. if (!stepDiv.find(".wiktku-dfn-tpl-hint").length) { stepDiv.append( $("<p class='wiktku-step-hint wiktku-dfn-tpl-hint'></p>").text( "Ji bo her maneyekê, dropdown-a \"an jî şablonek hilbijêre\" ne mecbûrî ye — bi gelemperî tu tenê maneyê bi tîpên asayî dinivîsî. Ew şablon tenê ji bo rewşên taybet in (mînak: guherto, kevnbûyî, şaşnivîs); heke tu nizanî kîjan divê, vale bihêle." ) ); } var tabsDiv = $("<div class='wiktku-dfn-sense-tabs'></div>"); stepDiv.append(tabsDiv); var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); steps.dfn.renderSenseTabs(stepDiv); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName === "__category__") { // Reachable only if the user opened the category search but // never picked a şablon — picking one switches the row to // __manual__ (see selectCatTpl above), so there's nothing // meaningful to save here. } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: readList("wiktku-dfn-etiket"), kategori: readList("wiktku-dfn-kategori"), nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense var izahLines = []; // parallel — raw îzah gloss for that same sense // True only once some sense's *actual* dfn text (post tercime/îzah // split) is non-empty. var hasLinkableMane = false; $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("# " + (tplKatTpl ? tplKatTpl + " " : "") + (tplLabelTpl ? tplLabelTpl + " " : "") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(""); // template senses have no îzah return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty // Pull the îzah gloss (if any) out of the combined tercime+îzah // string — it's spliced back in separately below, after its // own linkify pass (see izahLines / the second linkifyText call). var izahRaw = null; var tercimeIzah = splitTercimeIzah(dfn); if (tercimeIzah) { dfn = tercimeIzah.tercime; izahRaw = stripWikilinks(tercimeIzah.izah); } if (dfn) { dfn = stripWikilinks(dfn); // Sentence-case + trailing period are for ku definitions, // which are written as full glosses. if (lang === "ku") { if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } // Real prose — this is what makes the sense worth running // through the main linkify pass. hasLinkableMane = true; } else if (izahRaw === null) { // No mane at all — this is just the "{{mane?|lang}}" // placeholder, a bare template call with no plain words // in it. Do NOT count it as linkable: sending nothing but // bracketed templates through the main linkify pass hangs // the linkify gadget (see the hasLinkableMane/hasIzah // check below). dfn = lang === "ku" ? "{{mane?|" + lang + "}}" : ""; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var out = "# " + (katTpl ? katTpl + " " : "") + (labelTpl ? labelTpl + " " : "") + dfn; var idx = defLines.length; var hasThisIzah = izahRaw !== null && $.trim(izahRaw) !== ""; // Bare {{...}} token — like {{wiktku-cite-N}}, this survives // linkify's first pass untouched (it treats template calls as // opaque), then gets swapped for {{îzah|…}} once the actual // gloss text has been linkified in its own separate pass. if (hasThisIzah) { out += (dfn ? " " : "") + "{{wiktku-izah-" + idx + "}}"; } function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(hasThisIzah ? izahRaw : ""); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } // Runs text through the linkify gadget if it's loaded, otherwise // just passes it through unchanged. Shared by both linkify passes // below (main mane text, and — separately — îzah glosses). function linkifyText(t, cb) { if (typeof $.kuLinkify === "function") { $.kuLinkify(t, cb); } else { cb(t); } } var hasIzah = izahLines.some(function (t) { return t && $.trim(t) !== ""; }); var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with nimûne?. text = "# {{mane?|" + lang + "}}\n#* {{nimûne?|" + lang + "}}\n"; callback(text); return; } // Runs the îzah-only linkify pass against `base` (either the raw // text, when there's no linkable mane to run the main pass on // first, or the already-linkified main text). Shared by both // branches below so the token-splice logic only lives once. function runIzahPass(base) { var izahJoined = $.map(izahLines, function (raw, idx) { if (!raw) return undefined; return "{{wiktku-izah-open-" + idx + "}}" + raw + "{{wiktku-izah-close-" + idx + "}}"; }).join("\n"); linkifyText(izahJoined, function (izahLinked) { var izahByIdx = {}; var re = /\{\{wiktku-izah-open-(\d+)\}\}([\s\S]*?)\{\{wiktku-izah-close-\1\}\}/g; var m; while ((m = re.exec(izahLinked)) !== null) { izahByIdx[parseInt(m[1], 10)] = m[2]; } var withIzah = base.replace(/\{\{wiktku-izah-(\d+)\}\}/g, function (_, n) { var linked = izahByIdx[parseInt(n, 10)]; return linked !== undefined ? "{{îzah|" + linked + "}}" : ""; }); callback(restoreCites(withIzah)); }); } if (!hasLinkableMane) { if (!hasIzah) { // All filled senses are template senses (or otherwise have // no plain text at all) — nothing here needs linkify. callback(restoreCites(text)); return; } // There's no plain mane text anywhere (e.g. tercime left blank // with only îzah filled in), so every defLine is just a bare // template call with nothing to word-link. Sending a line // like "# {{wiktku-izah-0}}" through the main linkify pass // gives it no plain words to work with, makes the linkify // gadget hang — so skip that pass entirely and run only // the îzah pass, splicing straight into the unlinkified text. var loadIzahOnly = function () { runIzahPass(text); }; mw.loader.using("ext.gadget.linkify", loadIzahOnly, loadIzahOnly); return; } var didTryToLoad = function () { // First pass: the main definition text (mane), same as before. linkifyText(text, function (mainLinked) { if (!hasIzah) { callback(restoreCites(mainLinked)); return; } // Second pass: îzah glosses, linkified via their own // separate call. Each gloss is wrapped in its own // {{wiktku-izah-open/close-N}} pair; like the existing // {{wiktku-cite-N}} tokens, these sit inside double // braces so linkify leaves the tokens themselves alone — // only the raw gloss text between each pair gets linked. runIzahPass(mainLinked); }); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, tewandin: { id: "tewandin", name: "tewandin", question_fmt: 'Tewandina "' + pageName + '" binivîse', visible: function (values) { return values.lang && values.pos; }, build: function (stepDiv) { if (stepDiv.find(".wiktku-tewandin-wrap").length) return null; var wrap = $("<div class='wiktku-tewandin-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-tewandin-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-tewandin-text") .attr("rows", 4) .attr("placeholder", "{{ku-tewîn-nav|nêr}}"); wrap.append(ta); stepDiv.append(wrap); function autoPopulate() { if (!ta.length) return; var vals = getValues(); var c = vals.cinsiyet || ""; var p = vals.pos || ""; if (!pageName.includes(" ") && c && GENDER_BASE_LABELS[c] && (p === "navdêr" || p === "serenav") && vals.lang === "ku" && c !== "mndudil") { var label = (c === "mnmane") ? "mê û nêr" : GENDER_BASE_LABELS[c]; var out = "{{ku-tewîn-nav|" + label; if (p === "serenav") out += "|y"; out += "}}"; if (!$.trim(ta.val())) ta.val(out); } } setTimeout(function () { autoPopulate(); $("#wiktku-start-form").on("change.tewandin", "#wiktku-start-lang-field, #wiktku-start-cinsiyet-field, #wiktku-start-pos-field", autoPopulate); }, 0); return ta; }, output: function () { var manualText = $.trim($("#wiktku-start-tewandin .wiktku-tewandin-text").val()); if (manualText) { return "\n==== Tewandin ====\n" + manualText + "\n"; } return ""; } }, // resim — one or more images resim: { id: "resim", name: "resim", question_fmt: "Resmekê lê zêde bike", visible: function (values) { return !!(values.lang && values.pos); }, /** Builds one image row: filename + caption + alt text. */ buildItem: function (stepDiv) { var item = $("<li class='wiktku-resim-item'></li>"); var fileRow = $("<div class='wiktku-posparams-row'></div>"); var fileInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-file") .attr("placeholder", "navê_dosyayê.jpg"); fileRow.append($("<label></label>").text("Navê dosyayê: ")).append(fileInp); var capRow = $("<div class='wiktku-posparams-row'></div>"); var capInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-caption") .attr("placeholder", "Danasîna resimê…"); capRow.append($("<label></label>").text("Danasîn: ")).append(capInp); // Alt text: what a screen reader announces for this image var altRow = $("<div class='wiktku-posparams-row'></div>"); var altInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-alt") .attr("placeholder", "Ji bo kesên nabînin, çi tê dîtin? (ne mecbûrî)"); altRow.append($("<label></label>").text("Nivîsa alternatîf: ")).append(altInp); // Auto-fill the caption with the plain page name when a filename // is typed fileInp.on("input", function () { var file = $.trim($(this).val()); var curCap = $.trim(capInp.val()); var isDefault = !curCap || curCap === pageName; if (file && isDefault) { capInp.val(pageName); } else if (!file && isDefault) { capInp.val(""); } steps.resim.onFileInput(stepDiv, item, this); }); item.append(fileRow).append(capRow).append(altRow); return item; }, /** Grows the image list when the last row's filename gets content. */ onFileInput: function (stepDiv, item, input) { var val = $.trim($(input).val()); var list = stepDiv.find("ol.wiktku-resim-list"); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { list.append(steps.resim.buildItem(stepDiv)); } }, build: function (stepDiv) { if (stepDiv.find(".wiktku-resim-wrap").length) return null; var wrap = $("<div class='wiktku-resim-wrap'></div>"); var list = $("<ol class='wiktku-resim-list'></ol>"); list.append(steps.resim.buildItem(stepDiv)); wrap.append(list); stepDiv.append(wrap); return null; }, /** Reads every filled row from the DOM into an array of {file, caption, alt} * objects — blank rows (missing filename or caption) are skipped. * Non-Kurdish captions get wrapped in {{zim|lang|…}} here, unless * the user already typed their own {{zim|…}} template. Alt text is * optional and left as plain text either way. */ getImages: function (values) { var lang = (values && values.lang) || getValues().lang || ""; var images = []; $("#wiktku-start-resim li.wiktku-resim-item").each(function () { var file = $.trim($(this).find(".wiktku-resim-file").val()); var caption = $.trim($(this).find(".wiktku-resim-caption").val()); var alt = $.trim($(this).find(".wiktku-resim-alt").val()); if (!file || !caption) return; // Strip leading "Wêne:" or "File:" if the user typed it — we add it ourselves. file = file.replace(/^(wêne|file|image)\s*:\s*/i, ""); if (lang && lang !== "ku" && !/^\{\{zim\s*\|/i.test(caption)) { caption = "{{zim|" + lang + "|" + caption + "}}"; } images.push({ file: file, caption: caption, alt: alt }); }); return images; }, output: function (values) { var images = steps.resim.getImages(values); if (!images.length) return ""; return images.map(function (img) { var altPart = img.alt ? "|alt=" + img.alt : ""; return "[[Wêne:" + img.file + "|thumb" + altPart + "|" + img.caption + "]]"; }).join("\n") + "\n"; } }, // bnr-h — {{bnr-h|Page1|Page2|…}} prepended before the lang section (shared, not per-section) bnrh: { id: "bnrh", name: "binêre herwiha (bnr-h)", question_fmt: "Şablona bnr-h li qismê herî jor a rûpelê", //visible: function (values) { return !!values.lang; }, multiple: true, narrow: true, placeholder: "Ji bo 'test' bnr 'Test', 'teşt'", output: function (values) { var pages = $.grep(values.bnrh || [], function (p) { return !!$.trim(p); }); if (!pages.length) return ""; return "{{bnr-h|" + pages.map(function (p) { return $.trim(p); }).join("|") + "}}\n"; } }, bikaranin: { id: "bikaranin", name: "Notên bikaranînê", question_fmt: "Notên bikaranînê yên li ser vê kelîmeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, output: function (values) { var text = $.trim(values.bikaranin || ""); if (!text) return ""; return "\n==== Notên bikaranînê ====\n" + text + "\n"; }, }, xwendin: { id: "xwendin", name: "Bêhtir bixwîne", question_fmt: "Lînkên derveyî eleqedarî vê madeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: function (values) { if (!values || !values.lang) { return `* {{wpedî}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; } const ziman = values.lang === "ku" ? "" : `|ziman=${values.lang}`; return `* {{wpedî${ziman}}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; }, output: function (values) { var text = $.trim(values.xwendin || ""); if (!text) return ""; return "\n==== Bêhtir bixwîne ====\n" + text + "\n"; }, }, alfabeyendin: { id: "alfabeyendin", name: "Bi alfabeyên din", question_fmt: function (values) { var base = "Nivîsîna vê kelîmeyê bi alfabeyên din" var langLabel = values.lang ? getLangLabel(values.lang) : ""; if (langLabel) { return base + " ên " + langLabel; } return base; }, visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: "Ji bo kurmancî: * {{ku-ar|şiklê alfaba erebî}}", output: function (values) { var text = $.trim(values.alfabeyendin || ""); if (!text) return ""; return "\n==== Bi alfabeyên din ====\n" + text + "\n"; }, }, formalt: makeWordListStep("formalt", "formên alternatîv", "Formên alternatîv ên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), hevmane: makeWordListStep("hevmane", "hevmane", "Hevmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), dijmane: makeWordListStep("dijmane", "dijmane", "Dijmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jornav: makeWordListStep("jornav", "jornav", "Jornavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jernav: makeWordListStep("jernav", "jêrnav", "Jêrnavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse"), binereherwiha: makeWordListStep("binereherwiha", "herwiha binêre", "Kelîmeyên din ên eleqedar binivîse"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: {}, visible: function (values) { return values.lang && values.pos; }, // Fills the insert-dropdown from the current etymTpls object. refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(ta); stepDiv.append(wrap); initSelects(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder. // Skip it only when every filled sense is a şablon sense // a completely empty entry with no şablon chosen still gets the placeholder var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasFilledTplSense = dfnSenses.some(function (s) { return !!s.tpl && !!s.tplTitle; }); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (hasFilledTplSense && !hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: function (values) { return {"navz": true, [values.lang]: true} }, // Language dropdown + growing word-input list; a new row appends // when the dropdown gets a value. Mirrors steps.trans, but flat. buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/build below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Attach the searchable picker now the select is in the DOM. initSelects(list); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", question_fmt: "'"+ pageName + "' di zaravayên din de çawa tê gotin?", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: {}, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zaravayekî bigere"); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; // A completely empty entry still gets a placeholder section // to fill in later; an individual placeholder gloss is only // skipped once some other sense already has real content. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", question_fmt: "Tercimeyên vê maneyê bi zimanên din binivîse", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide only when every sense is a filled template sense (no plain // gloss to attach translations to). A mix, or nothing filled in // yet, still shows Werger. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, // Language dropdown + growing word-input list, scoped to one gloss's // group (each gloss has its own group and row list). buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/buildGroup below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, // Builds (or fetches) the .wiktku-trans-group for one gloss. buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, // Syncs one .wiktku-trans-group per current gloss, keyed by // data-gloss-pos so groups stay matched across rebuilds. build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, // Reads all translation rows, grouped by gloss position. getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, // Builds the numbered "{ index, gloss }" list, one per dfn sense // with a real mane (skips template senses). index is 1-based and // matches the sense's position in the "#" definition list. // When nothing's filled in, returns one placeholder entry so // Werger still has a group to attach to; when every sense is a // filled template sense, stays empty (matches trans.visible()). glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane, but other fields are filled — still gets a // gloss group since dfn.getOutput() emits {{mane?}} for it. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // A completely empty entry (nothing filled in dfn at all, no // şablon chosen either) still gets a placeholder Werger section // to fill in later. Only // skip an individual placeholder gloss below when some other // sense actually has real content, making that particular // placeholder redundant. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it. If some other sense already has real // content, this placeholder is redundant — skip it. If the // whole entry is empty, keep it so Werger still gets a // section to fill in. if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, cavkani: { id: "cavkani", name: "çavkanî", question_fmt: "Çavkaniyên din (ne jêgirtin) lê zêde bike", visible: function (values) { return !!values.pos; }, // Fills the insert-dropdown from the members of [[Kategorî:Çavkanî]]. refreshTplSelect: function () { var sel = $("#wiktku-start-cavkani .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(catSrcTemplates || [], function (_, name) { sel.append($("<option></option>").val(name).text(name)); }); markTemplateOptions(sel, function (opt) { return opt.val(); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-cavkani-wrap").length) return null; var wrap = $("<div class='wiktku-cavkani-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-cavkani-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-cavkani-text") .attr("rows", 4) .attr("placeholder", "Şablonekî ji lîsteyê hilbijêre an rasterast binivîse…"); // Template insert dropdown, populated from [[Kategorî:Çavkanî]] — // options refreshed once the category members are fetched. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var status = $("<span class='wiktku-cavkani-status'></span>"); sel.on("change", function () { var name = $(this).val(); if (!name) return; insertAtCursor(ta[0], "\n* {{" + name + "}}"); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(status).append(ta); stepDiv.append(wrap); // build() runs again for every new beş (see the "+ Beş zêde bike" // handler), after the initial page-wide pass — so this select needs // its own init or it stays a plain, unsearchable native <select>. initSelects(wrap); if (catSrcTemplates) { steps.cavkani.refreshTplSelect(); } else { status.text("Şablon tên barkirin…"); fetchCatSrcTemplates().then(function () { steps.cavkani.refreshTplSelect(); status.text(""); }, function () { status.text("Şablon nehatin barkirin."); }); } return ta; }, output: function () { var text = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); if (!text) return ""; return "\n==== Çavkanî ====\n" + text + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); // This array only controls DOM build order — nothing else keys off it // (see the comment above stepIdToGroup). Mane tab order: Mane (senses, // with malûmatên pêşketî nested inside each, see steps.dfn.build) → // Wêne → Bi zaravayên din → Werger, so dfn/resim/zarava/trans sit // adjacent to each other in that order. var ordered_steps = [ steps.lang, steps.pos, steps.posparams, steps.cinsiyet, steps.jimar, steps.lektur, steps.tr, // Mane tab, in reading order: the senses, then the two things that // belong to the entry as a whole rather than to one sense. steps.dfn, steps.tewandin, steps.alfabeyendin, steps.zarava, steps.trans, // Etîmolojî tab. steps.etym, steps.dunde, // Eleqedar tab — three lists of the same shape. steps.je, steps.tekildar, steps.binereherwiha, // Bilêvkirin isn't part of any STEP_GROUPS tab, but still needs a // slot here because this array is what builds the DOM. steps.pron, // Beşên din, behind the picker. steps.resim, steps.bnrh, steps.bikaranin, steps.formalt, steps.hevmane, steps.dijmane, steps.jornav, steps.jernav, steps.cavkani, steps.xwendin]; // ── Step-group tabs ────────────────────────────────────────────────────── // Four tabs: "Mane" holds the senses (whose own blocks carry Nimûne, // Jêgirtin, Hevmane and Dijmane — see steps.dfn.allGroups), Tewandin, // alfabeyendin, zarava and trans; "Etîmolojî" and "Eleqedar" split out // the two other topical clusters; everything else lives behind the // "Beşên din" picker. "mane" stays first as the default-active tab // since Mane is required content. Tewandin keeps its own free-text // {{ku-tewîn-nav}} field and does NOT absorb the Cins/zayend form // parameters (m=/n=/p=), which stay on the headword template. var STEP_GROUPS = [ { id: "mane", label: "Mane", steps: ["dfn", "tewandin", "alfabeyendin", "zarava", "trans"] }, { id: "etimoloji", label: "Etîmolojî", steps: ["etym", "dunde"] }, { id: "eleqedar", label: "Eleqedar", steps: ["je", "tekildar", "binereherwiha"] }, { id: "besendin", label: "Beşên din", steps: ["resim", "formalt", "hevmane", "dijmane", "jornav", "jernav", "bikaranin", "cavkani", "xwendin", "bnrh"] }, ]; // Steps that live behind the "Beşên din" picker — only these need an // explicit "open" before they're shown, even when their tab is active. // Derived from the group above so it can't drift out of sync. var BESENDIN_STEP_IDS = STEP_GROUPS[3].steps; // Reverse lookup: step id -> index into STEP_GROUPS (undefined for // ungrouped steps — now only lang/pos/posparams/cinsiyet/lektur/tr, // which stay always-visible since they're required to get to everything // else). var stepIdToGroup = {}; $.each(STEP_GROUPS, function (gi, g) { $.each(g.steps, function (_, sid) { stepIdToGroup[sid] = gi; }); }); // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "posparams", "cinsiyet", "jimar", "lektur", "tr", "resim", "dfn", "tewandin", "formalt", "bikaranin", "alfabeyendin", "hevmane", "dijmane", "jornav", "jernav", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans", "cavkani", "xwendin" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; // ── Bilêvkirin as a standalone section ─────────────────────────────── // Pronunciation belongs to the word, not to one part of speech, so it // sits beside Navdêr/Lêker in the tab bar rather than inside any of them. // Modelled as a flag rather than an entry in `sections` since // activeSection is used as an array index in many places — viewing // Bilêvkirin leaves activeSection pointing at the POS section you were on. var viewingPron = false; // is it the tab currently on screen // Which STEP_GROUPS tab is currently shown. Lives out here (like // activeSection above) so refresh() — which is not nested inside build() // — can read it and so renderGroupTabs()/updateGroupTabIndicators() below // can be called from refresh() too. Both operate on the tab bar via its // #wiktku-group-tabs id rather than a closured element reference, for the // same reason. var activeGroup = 0; // Unsaved-changes / autosave state. Lives out here (same reason as // activeGroup above) so destroy() — which runs on final submit and on // switching to the source editor, and is not nested inside build() — // can clear the timers and the beforeunload warning. build() assigns // into these; it doesn't re-declare them. var formDirty = false; var autosaveDebounceTimer = null; var autosaveInterval = null; /** Re-renders the step-group tab bar to reflect the current activeGroup. */ function renderGroupTabs() { var groupTabsDiv = $("#wiktku-group-tabs"); if (!groupTabsDiv.length) return; groupTabsDiv.empty(); $.each(STEP_GROUPS, function (i, g) { var tab = $("<span></span>") .addClass("wiktku-group-tab") .attr("data-group-idx", i) .text(g.label) .toggleClass("wiktku-tab-active", i === activeGroup); (function (idx) { tab.on("click", function () { if (idx === activeGroup) return; activeGroup = idx; renderGroupTabs(); if (idx === BESENDIN_GROUP_IDX) renderBesenDinPicker(); refresh(); // Switching tabs can shorten the page (e.g. leaving a long // "Beşên din" field), and the browser may clamp the scroll // position on its own timing before our measurement runs. // Deferring one frame lets that settle first, so the // offsetTop read below is the final, post-refresh one. window.requestAnimationFrame(function () { var bar = document.getElementById("wiktku-group-tabs"); if (!bar) return; var form = document.getElementById("wiktku-start-form"); var stabsH = form ? (parseFloat(form.style.getPropertyValue("--wiktku-stabs-h")) || 0) : 0; var siteHeaderH = form ? (parseFloat(form.style.getPropertyValue("--wiktku-siteheader-h")) || 0) : 0; var top = bar.getBoundingClientRect().top + window.pageYOffset - stabsH - siteHeaderH; $("html, body").animate({ scrollTop: Math.max(0, top) }, 200); }); }); }(i)); groupTabsDiv.append(tab); }); } /** * Toggles a "needs attention" dot on any group tab that still has a * required, unfilled field hidden inside it — so switching tabs doesn't * leave the person wondering why "Bişîne" stays disabled. */ function updateGroupTabIndicators(values) { var tabs = $("#wiktku-group-tabs .wiktku-group-tab"); if (!tabs.length) return; $.each(STEP_GROUPS, function (i, g) { var missing = false; $.each(g.steps, function (_, sid) { var step = steps[sid]; if (!step || !step.required) return; var val = values[sid]; if (val === "" || (step.multiple && $.isArray(val) && val.join("") === "")) { missing = true; } }); tabs.eq(i).toggleClass("wiktku-tab-missing", missing && i !== activeGroup); }); } // "Beşên din" reveals one field at a time via a picker rather than // stacking them all. Per-section state, snapshotted in // saveCurrentSection() and restored in restoreSection() below, and // auto-seeded from any field that already has content (so a returning // draft doesn't hide something already filled in). var openedOtherSections = {}; var BESENDIN_SET = {}; $.each(BESENDIN_STEP_IDS, function (_, sid) { BESENDIN_SET[sid] = true; }); // "besendin"'s index in STEP_GROUPS. Derived rather than hardcoded — // this was a literal 2 and silently pointed at the wrong tab the moment // Etîmolojî and Eleqedar were inserted ahead of it. var BESENDIN_GROUP_IDX = (function () { for (var i = 0; i < STEP_GROUPS.length; i++) { if (STEP_GROUPS[i].id === "besendin") return i; } return STEP_GROUPS.length - 1; }()); /** Re-renders the "Beşên din" picker to list only the not-yet-opened sections. */ function renderBesenDinPicker() { var wrap = $("#wiktku-besendin-picker"); if (!wrap.length) return; wrap.empty(); var pickerValues = getValues(); var unopened = $.grep(BESENDIN_STEP_IDS, function (sid) { if (openedOtherSections[sid]) return false; // Don't offer a section that would open onto nothing: several of // these are gated (Bi zaravayên din / Werger need lang=ku, most // need a pos). refresh() would hide it again straight away, so // picking it would read as a broken dropdown. var step = steps[sid]; if (step && typeof step.visible === "function") { try { if (!step.visible(pickerValues)) return false; } catch (e) { /* a step whose visible() needs DOM we lack yet — offer it */ } } return true; }); if (!unopened.length) return; // everything's open — nothing left to pick var sel = $("<select class='wiktku-besendin-select'></select>"); sel.attr("data-placeholder", "— beşek hilbijêre —"); sel.append($("<option value=''>— beşek hilbijêre —</option>")); $.each(unopened, function (_, sid) { var step = steps[sid]; if (!step) return; sel.append($("<option></option>").val(sid).text(capitalize(step.name))); }); sel.on("change", function () { var sid = $(this).val(); if (!sid) return; openedOtherSections[sid] = true; // Newly opened section moves right under the picker, ahead of // whatever's already open, instead of wherever it happened to // sit in the fixed step order. $("#wiktku-start-" + sid).insertAfter(wrap); renderBesenDinPicker(); refresh(); }); wrap.append(sel); initSelects(wrap); } /** Marks any BESENDIN_STEP_IDS field that already has real content as * "opened", so restoring a draft doesn't bury filled-in sections behind * the picker. Reuses each step's own output() as the emptiness check — * it already knows what "empty" means per field, and it reads the DOM * the restore just populated. Call this AFTER the DOM has the restored * values in it. */ function seedOpenedFromContent() { var values = getValues(); $.each(BESENDIN_STEP_IDS, function (_, sid) { if (openedOtherSections[sid]) return; var step = steps[sid]; if (!step || typeof step.output !== "function") return; try { if (step.output(values)) openedOtherSections[sid] = true; } catch (e) { /* a step whose output() needs more state than we have yet — skip it */ } }); } function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } // Rebuilds the dfn DOM from a previously snapshotted senses array. function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing tab bar + list so build() recreates them cleanly. stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); // The picker is collapsed behind a link by default; a restored // sense that already uses a template has to show it, or the // chosen template is invisible and looks lost. var reveal = block.data("revealTplRow"); if (typeof reveal === "function") reveal(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // dfnArea is the only thing actually saved, so split it back into // tercime/îzah for editing (mirrors syncNonKuToMane's join format). var maneParts = splitTercimeIzah(sense.mane); block.find(".wiktku-dfn-tercime").val(maneParts ? maneParts.tercime : (sense.mane || "")); block.find(".wiktku-dfn-izah").val(maneParts ? maneParts.izah : ""); // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Same for the mane-box mode (plain vs tercime+îzah), since this // also depends on tplSelect's (and lang's) value. var updateMane = block.data("updateManeMode"); if (updateMane) updateMane(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found var useModifiers = !!MODIFIER_SUBGROUPS[cls]; // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true, useModifiers); }); subList.append(useModifiers ? makeModifierLi(ta) : $("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text).each(function () { highlightLinebreak(this); }); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder entries — accepts current array shape or a legacy // single object (older saved sections) for backwards compat. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote).each(function () { highlightLinebreak(this); }); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederCatTpl) { // Legacy format from before the şablon search switched rows to // manual mode directly — convert it the same way now, so it's // editable like any other free-form source. var catSelEl = li.find(".wiktku-dfn-quote-src-sel"); catSelEl.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val("{{" + j.jederCatTpl + "}}"); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); // Restoring a draft opens the first sense's tab by default. steps.dfn.setOpenSense(stepDiv, list.find("li.wiktku-dfn-sense").first()); } // Snapshots simple (non-dfn) per-section steps from the DOM into obj. function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } if (id === "cavkani") { snap.cavkani = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); return; } if (id === "posparams") { snap.posparams = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); return; } if (id === "resim") { // One entry per row, including blank ones, so a mid-edit draft // (e.g. a filename typed but no caption yet) survives a cache // restore instead of being silently dropped. snap.resim = $("#wiktku-start-resim li.wiktku-resim-item").map(function () { return { file: $.trim($(this).find(".wiktku-resim-file").val()), caption: $.trim($(this).find(".wiktku-resim-caption").val()), alt: $.trim($(this).find(".wiktku-resim-alt").val()) }; }).get(); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); // Which "Beşên din" sub-sections this section has already opened // via the picker — per-section, like everything else here. snap.openedOtherSections = $.extend({}, openedOtherSections); sections[activeSection] = snap; } // Restores a previously saved snapshot into the form DOM. function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); $("#wiktku-start-cavkani .wiktku-cavkani-text").val(snap.cavkani || ""); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); steps.posparams.build(ppDiv); var savedTa = snap.posparams || ""; ppDiv.find(".wiktku-posparams-text").val(savedTa); // Re-parse saved textarea to restore helper widget states. if (savedTa) { var cMatch = savedTa.match(/\|c=([^|}\s]+)/); var jMatch = savedTa.match(/\|j=([^|}\s]+)/); var trMatch = savedTa.match(/\|tr=([^|}\s]+)/); // Write into the shared hidden field (not the visible // select, which has no <option>s yet) — syncHelpers() // below reads it back to restore the dropdown once the // gender/number options for this language are populated. if (cMatch) $("#wiktku-start-cinsiyet-field").val(cMatch[1]); if (jMatch) $("#wiktku-start-jimar-field").val(jMatch[1]); if (trMatch) ppDiv.find(".wiktku-posparams-field[data-pp-key='tr']").val(trMatch[1]); // For lêker, c= holds the verb-type code instead of a // gender — split it back across the two dropdowns it is // now assembled from ("x-gh" → form "x" + base "gh"). if (cMatch && /^lêker/.test(snap.pos || "")) { var lekturParts = /^(?:([xphb])-)?(n?gh)$/.exec(cMatch[1]); if (lekturParts) { ppDiv.find(".wiktku-posparams-lektur-sel").val(lekturParts[2]); ppDiv.find(".wiktku-posparams-lekturform-sel").val(lekturParts[1] || ""); } } // Restore checked optional params. "form" is stored as // "erê" rather than "1" (see rebuildTa), so it needs its // own check here. ppDiv.find(".wiktku-posparams-opt-panel input[type='checkbox']").each(function () { var key = $(this).val(); var expected = key === "form" ? "erê" : "1"; $(this).prop("checked", savedTa.indexOf("|" + key + "=" + expected) !== -1); }); } steps.posparams.syncHelpers(ppDiv); return; } if (id === "resim") { var resimDiv = $("#wiktku-start-resim"); resimDiv.find(".wiktku-resim-wrap").remove(); steps.resim.build(resimDiv); // Accept both the new array-of-rows format and the older // single {file, caption} object saved before multi-image // support existed. var resimSnap = snap.resim; var rows = $.isArray(resimSnap) ? resimSnap : (resimSnap ? [resimSnap] : []); if (rows.length) { var list = resimDiv.find("ol.wiktku-resim-list"); list.empty(); $.each(rows, function (_, r) { var item = steps.resim.buildItem(resimDiv); item.find(".wiktku-resim-file").val(r.file || ""); item.find(".wiktku-resim-caption").val(r.caption || ""); item.find(".wiktku-resim-alt").val(r.alt || ""); list.append(item); }); // Always keep a blank trailing row, same as Nimûne/Dûnde. var lastItem = list.children("li.wiktku-resim-item").last(); if ($.trim(lastItem.find(".wiktku-resim-file").val())) { list.append(steps.resim.buildItem(resimDiv)); } } return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Tell the pickers about the programmatic value change. fields.filter("select").trigger("wiktku:refresh"); }); // Restore which "Beşên din" sub-sections were already opened for // this section, then seed in anything the DOM restore above just // filled in but that wasn't marked opened yet. openedOtherSections = $.extend({}, snap.openedOtherSections || {}); seedOpenedFromContent(); renderBesenDinPicker(); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); // Bilêvkirin is NOT emitted here — it is one shared field for the // whole word, so emitting it per section duplicated it. getWikitext() // prints it once, above the POS sections. steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.tewandin.output(values); entry += steps.bikaranin.output(values); entry += steps.alfabeyendin.output(values); entry += steps.formalt.output(values); entry += steps.hevmane.output(values); entry += steps.dijmane.output(values); entry += steps.jornav.output(values); entry += steps.jernav.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); entry += steps.cavkani.output(values); entry += steps.xwendin.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { // Each hop through here can be reached asynchronously: the dfn // step waits on mw.loader.using("ext.gadget.linkify") before // calling back, so from that point on the submit handler's own // try/catch is no longer on the stack. Guard every hop instead, // or a throw after linkify loads vanishes into an unhandled // rejection and the form just sits there looking busy. try { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } catch (e) { if (typeof onSubmitError === "function") onSubmitError(e); else throw e; } } processSection(0); } // Assembles wikitext for all sections plus the shared lang header. function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var bnrh = steps.bnrh.output(sharedValues); var entry = steps.lang.output(sharedValues); // One pronunciation per word, printed once between the language // header and the POS sections — see steps.pron.output. entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // bnr-h goes before the language section — only prepended when // generating fresh wikitext (not addLangMode, which handles it separately). if (!addLangMode && bnrh) entry = bnrh + entry; // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { if (s.mane) return s.mane; // Template sense (e.g. {{guharto|ku|somepage}}) — same // construction as the tplCall built in getOutput, so the // summary shows what actually gets written to the entry // instead of going blank. if (s.tpl && s.tplTitle) { return s.tplNoLang ? "{{" + s.tpl + "|" + s.tplTitle + "}}" : "{{" + s.tpl + "|" + sharedValues.lang + "|" + s.tplTitle + "}}"; } return ""; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; // Set by build() to its submitFailed(). Lives out here because the // wikitext-assembly functions below are outside build()'s closure but // still need a way to report a failure to the person rather than dying // silently in the console. var onSubmitError = null; // Whether Mane/Bi zaravayên din/Werger has anything in it — kept // outside refresh() so the click handler can read the latest value. var wiktkuContentGateOk = true; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues, placeholderText) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>").text(placeholderText || "")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice.label); if (choice.sortKey !== undefined) { // This is a language choice {code, label, sortKey} — show code. displayText = capitalize(choice.label) + " (" + choice.code + ")"; } var option = $(mw.html.element("option", { value: choice.code }, displayText)); if (disabledValues[choice.code]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } // Keys to disable for a key menu: already-taken or explicitly disabled. function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); populateMenus(input, step.keys, getDisabledKeys(step)); // Keep the key menus mutually exclusive: whatever one row selects is // disabled in every other row. Recomputed from the DOM on each change. input.on("change", function () { var all = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield"); var taken = {}; all.each(function () { var v = $(this).val(); if (v) taken[v] = true; }); all.not(this).each(function () { var self = $(this), own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (code) $(this).prop("disabled", !!taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }); // Return the wrapper; the select lives inside it and still fires change. return wrapNativeSelect(input); } // Adds another text field to the list if the last one now has text. function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); if (step.placeholder) { nextInput.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = step.modifiers ? makeModifierLi(nextInput).prepend(nextKeyInput || "") : $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) initSelects(nextItem); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } // Shows/hides steps based on whether their prerequisites are met, and // updates placeholders where applicable. function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); steps.cavkani.refreshTplSelect(); // Re-render any step's question label that depends on current values // (e.g. dfn's Werger-section reminder, which only applies to ku). $.each(steps, function (stepId, step) { if (typeof step.question_fmt === "function") { $("#wiktku-start-" + stepId + " .wiktku-start-step-question") .text(step.question_fmt(values)); } }); // Sync every sense block's mane-box mode (plain mane vs tercime+îzah) // to the current language, in case lang changes after blocks exist. $("#wiktku-start-dfn li.wiktku-dfn-sense").each(function () { var updateMane = $(this).data("updateManeMode"); if (updateMane) updateMane(); }); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Re-sync the "<label> bi <ziman>…" placeholder on every always-visible // sub-field list (etîket, kategorî, hevmane, …), since the language may // not have been chosen yet when these lists were first built, or may // have changed since. $("#wiktku-start-dfn .wiktku-dfn-sublist").each(function () { var upd = $(this).data("updatePlaceholders"); if (typeof upd === "function") upd(); }); // Same idea for word-list steps (jê, têkildar, binêre herwiha, …) // whose placeholder is a function of the current language. $.each(steps, function (stepId, step) { if (typeof step.placeholder === "function") { $("#wiktku-start-" + stepId + " textarea.wiktku-start-step-field") .attr("placeholder", step.placeholder()); } }); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // Insert after the quote textarea's resize-wrap (if the manual // resize handle has already been attached to it), not after the // bare textarea -- otherwise this lands *inside* that wrap, // between the textarea and its own grip, breaking jêgirtin's // handle and nesting the tr/t boxes inside it. var quoteTa = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap = quoteTa.closest(".wiktku-resize-wrap"); (quoteResizeWrap.length ? quoteResizeWrap : quoteTa).after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // See the tr-field branch above for why this targets the // resize-wrap instead of the bare textarea. var quoteTa2 = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap2 = quoteTa2.closest(".wiktku-resize-wrap"); (quoteResizeWrap2.length ? quoteResizeWrap2 : quoteTa2).after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { var groupIdx = stepIdToGroup[stepId]; var hiddenByTab = (groupIdx !== undefined && groupIdx !== activeGroup) || // Beşên din picker: stays hidden even while its tab is // active until explicitly opened from the dropdown. (BESENDIN_SET[stepId] && !openedOtherSections[stepId]); // Bilêvkirin is its own section now, so the two views are // mutually exclusive: on it, only pron shows (plus Ziman, which // is shared and stays above every section); off it, pron is // hidden no matter which tab is active. pron is deliberately // ungrouped — stepIdToGroup has no entry for it — so without // this branch it would show on all four tabs at once. if (stepId === "pron") { hiddenByTab = hiddenByTab || !viewingPron; } else if (viewingPron && stepId !== "lang") { hiddenByTab = true; } if (hiddenByTab || (typeof(step.visible) === "function" && !step.visible(values))) { $("#wiktku-start-" + stepId).hide(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } // After build, sync the posparams helper widgets whenever pos or lang changes. if (step.id === "posparams" && typeof step.syncHelpers === "function") { step.syncHelpers(stepDiv); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } stepDiv.slideDown(); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); // The four content tabs belong to a POS section — Bilêvkirin has no // sub-tabs of its own, so the bar goes away while it's on screen. $("#wiktku-group-tabs").toggle(!!values.pos && !viewingPron); var besenDinActive = activeGroup === BESENDIN_GROUP_IDX && !viewingPron; $("#wiktku-besendin-picker").toggle(besenDinActive); // The option list is filtered by each step's visible(), which depends // on lang/pos — so it has to be rebuilt when those change, not just // when a section is opened. Safe to call from here: rendering the // picker doesn't itself call refresh(), only picking an option does. if (besenDinActive) renderBesenDinPicker(); updateGroupTabIndicators(values); continueBtn.setDisabled(!canContinue); // Soft gate: stays a real, clickable OOUI button — a hard // setDisabled(true) here would swallow the click entirely, leaving // no way to tell the person why nothing happened. The CSS-only // "looks disabled" class lets the click handler still run and show // wiktkuNotify's explanation. wiktkuContentGateOk = !canContinue || hasMinRequiredContent(values); continueBtn.$element.toggleClass("wiktku-btn-soft-disabled", !wiktkuContentGateOk); } function destroy() { if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); if (autosaveInterval) clearInterval(autosaveInterval); formDirty = false; $(window).off("beforeunload.wiktkuUnsaved"); $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard").slideDown(); // #editform was kept laid-out but off-screen (see build()) instead of // display:none, precisely so the editor never had to size itself // against a zero-width/height box. Just bring it back on-screen — // no slideDown needed since it was never actually collapsed. $("#editform").removeClass("wiktku-offscreen"); // Belt-and-braces: if WikiEditor/CodeMirror/mobile's auto-grow still // cached a stale size from some earlier point, nudge them to // recalculate now that the box is genuinely visible. $(window).trigger("resize"); if (window.CodeMirror) { var cm = $("#wpTextbox1").data("CodeMirror") || $("#wpTextbox1").data("cmInstance"); if (cm && typeof cm.refresh === "function") cm.refresh(); } $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and navz. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; // Inserts a new "== {{ziman|code}} ==" section at the correct sorted // position: navz, then ku/hac/sdh/lki/ckb/zza, then alphabetical by name. function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections — just write the new section. // Add \n\n only when there is real non-whitespace content above. var trimmed = existing.replace(/\s+$/, ""); return trimmed ? trimmed + "\n\n" + wikitext : wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // (?![\s\S]) matches only true end-of-string, since a bare "$" with // /m would stop at the section's first line break instead. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections, each separated by exactly \n\n. // Trim trailing whitespace off each section's content first so we // control the spacing precisely. var joined = sections.map(function (s) { return s.content.replace(/\s+$/, ""); }).join("\n\n"); // Only add a separator after the preamble when it has real content. var preambleTrimmed = preamble.replace(/\s+$/, ""); var prefix = preambleTrimmed ? preambleTrimmed + "\n\n" : ""; return prefix + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê zimanekî nû li rûpelê îlawe bikî. Eger ev ziman jixwe hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bike, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Muhtewaya rûpelê paqij bike (her tiştî jê bibe û rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); // Tab bar for switching between step-groups (topics) within a section. // renderGroupTabs()/updateGroupTabIndicators() (which populate and // maintain it) live outside build() — see near "var activeSection". var groupTabsDiv = $("<div id='wiktku-group-tabs'></div>"); // Both tab bars are sticky (CSS). group-tabs' sticky "top" has to sit // right below section-tabs' actual rendered height, which isn't a // fixed number since the bar can wrap onto a second line. Measured // here and published as a CSS custom property the stylesheet reads // back; recomputed on content changes and window resize. // // Vector 2022 has its own sticky header (.vector-sticky-header) that // pins to the real top:0 once you scroll past the page title, which // would otherwise sit directly behind (and hide) our section-tabs. // Fixed by measuring how much of the viewport Vector's header // currently occupies and offsetting both our bars below it, via // --wiktku-siteheader-h. Vector's header slides in/out with scroll // position, so this is re-measured on scroll too, not just resize. function siteHeaderOffset() { var el = document.querySelector(".vector-sticky-header"); if (!el) return 0; var rect = el.getBoundingClientRect(); // Present in the DOM at all times on Vector 2022, but only // actually occupying screen space once scrolled into place — // before that it sits translated above the viewport (negative/ // zero rect), which must not add a phantom gap under our bars. if (rect.bottom <= 0 || rect.top > 4) return 0; return Math.max(0, rect.bottom); } var stickyOffsetQueued = false; function syncStickyTabsOffset() { var h = sectionTabsDiv.is(":visible") ? (sectionTabsDiv.outerHeight() || 0) : 0; startForm.css("--wiktku-stabs-h", h + "px"); startForm.css("--wiktku-siteheader-h", siteHeaderOffset() + "px"); } function queueStickyTabsOffsetSync() { if (stickyOffsetQueued) return; stickyOffsetQueued = true; window.requestAnimationFrame(function () { stickyOffsetQueued = false; syncStickyTabsOffset(); }); } $(window).on("resize.wiktkuStickyTabs scroll.wiktkuStickyTabs", queueStickyTabsOffsetSync); // "Beşên din" picker — sits right under the group tab bar, only // shown while that tab is active (toggled in refresh(), see // BESENDIN_GROUP_IDX); renderBesenDinPicker() fills it. var besenDinPickerDiv = $("<div id='wiktku-besendin-picker' class='wiktku-besendin-picker'></div>"); /** Puts the form back in a usable state after a failed submit and * says what happened. Without this the button stays disabled and * the spinner spins forever on any exception — the person is left * staring at a form that looks busy but is dead, with the reason * visible only in the browser console. */ function submitFailed(err) { spinner.hide(); continueBtn.setDisabled(false); continueBtn.$element.removeClass("wiktku-btn-sending"); var detail = (err && (err.message || err.toString())) || "sedem nediyar"; mw.notify( "Şandin bi ser neket: " + detail + " — tiştê ku te nivîsî winda nebûye. Heke ev dubare bibe, " + "bi 'Edîtora çavkaniyê veke' berdewam bike.", { type: "error", tag: "wiktku-submit", autoHide: false } ); // Deliberately console.error as well: the notification is for the // person, this is for whoever they report the bug to. if (window.console && console.error) console.error("[wiktku] submit failed", err); } onSubmitError = submitFailed; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); continueBtn.$element.addClass("wiktku-btn-sending"); spinner.show(); try { getWikitext(function (wikitext) { try { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page — write fresh content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // ── bnr-h merge ────────────────────────────────────────── // If the user filled bnr-h inputs, either merge into the // existing {{bnr-h|…}} call or prepend a new one. var bnrhOut = steps.bnrh.output(getValues()); if (bnrhOut) { var newPages = bnrhOut.replace(/^\{\{bnr-h\|/, "").replace(/\}\}\n?$/, "").split("|"); var bnrhRe = /\{\{bnr-h\|([^}]*)\}\}/i; if (bnrhRe.test(existing)) { existing = existing.replace(bnrhRe, function (_, inner) { var existingPages = inner.split("|").map(function (p) { return p.trim(); }); $.each(newPages, function (_, p) { p = p.trim(); if (p && existingPages.indexOf(p) === -1) existingPages.push(p); }); return "{{bnr-h|" + existingPages.join("|") + "}}"; }); } else { existing = bnrhOut + existing; } } // If this language's section already exists (whitespace // differences aside), merge into it; otherwise insert new. var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); } catch (e) { // Thrown while writing the result into #wpTextbox1. submitFailed(e); } }); } catch (e) { // Catches anything thrown synchronously inside getWikitext. submitFailed(e); } }); // Tracks whether groupTabsDiv has been inserted yet. var groupTabsInserted = false; $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); var nameH3 = $("<h3></h3>").addClass("wiktku-start-step-name"); var nameLabel = $("<label></label>") .attr("for", "wiktku-start-" + step.id + "-field") .text(name); nameH3.append(nameLabel); stepDiv.append(nameH3); if (step.question_fmt) { // question_fmt can be a plain string, or a function of the // current values (used by steps whose question text depends // on e.g. the chosen language) — refresh() keeps it in sync // afterwards via the .wiktku-start-step-question class. var questionText = typeof step.question_fmt === "function" ? step.question_fmt(getValues()) : step.question_fmt; stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, questionText))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); // initSelects() runs over the whole form once it is in the DOM. stepDiv.append(input); } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.placeholder) { input.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append(step.modifiers ? makeModifierLi(input) : $("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Section tabs (switch between POS sections) sit above the // per-section fields, starting at "pos". if (step.id === "pos") { startForm.append(sectionTabsDiv); } // Step-group tabs sit just before the first grouped step in // ordered_steps. Derived from stepIdToGroup so this keeps // working no matter how STEP_GROUPS/ordered_steps get reordered. if (!groupTabsInserted && stepIdToGroup[step.id] !== undefined) { startForm.append(groupTabsDiv); startForm.append(besenDinPickerDiv); groupTabsInserted = true; } startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); /** Adds a new, empty POS section and switches to it. */ function addPosSection() { saveCurrentSection(); viewingPron = false; sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); return; } if (id === "resim") { $("#wiktku-start-resim .wiktku-resim-wrap").remove(); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); stepDiv.find("select.wiktku-start-step-field").trigger("wiktku:refresh"); }); // Fresh section — no "Beşên din" sub-section has been opened yet. openedOtherSections = {}; renderBesenDinPicker(); renderSectionTabs(); refresh(); } addSectionBtn.on("click", addPosSection); /** Removes one POS section. Assumes the caller already confirmed and * already checked more than one section remains. If the removed * section was the one on screen, its in-progress DOM edits are * discarded along with it (never saved back into sections[]) and a * neighboring section is restored in its place. */ function removePosSection(idx) { sections.splice(idx, 1); if (idx === activeSection) { viewingPron = false; activeSection = Math.min(idx, sections.length - 1); restoreSection(sections[activeSection]); refresh(); } else if (idx < activeSection) { activeSection -= 1; } renderSectionTabs(); } /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); syncStickyTabsOffset(); return; } sectionTabsDiv.show(); // Bilêvkirin leads the bar, ahead of the POS sections. var pronTab = $("<span></span>") .addClass("wiktku-section-tab wiktku-section-tab-pron") .text("Bilêvkirin") .toggleClass("wiktku-tab-active", viewingPron); pronTab.on("click", function () { if (viewingPron) return; saveCurrentSection(); viewingPron = true; refresh(); renderSectionTabs(); }); sectionTabsDiv.append(pronTab); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .toggleClass("wiktku-tab-active", i === activeSection && !viewingPron); tab.append($("<span class='wiktku-tab-label'></span>").text(tabLabel)); (function (idx) { tab.on("click", function () { if (idx === activeSection && !viewingPron) return; // Leaving Bilêvkirin doesn't need a save — its field // is shared and never part of a section snapshot. if (!viewingPron) saveCurrentSection(); viewingPron = false; activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); // Always keep at least one Beş — no delete button when // it's the only section left. if (sections.length > 1) { var trash = makeTrashButton("Vê beşê jê bibe"); trash.on("click", function (e) { // Stop this from also reaching the tab's own // click handler above (which would just switch // to it instead of deleting it). e.preventDefault(); e.stopPropagation(); if (!window.confirm("Tu dixwazî \"" + tabLabel + "\" jê bibî? Ev tişt nayê vegerandin.")) return; removePosSection(idx); }); tab.append(trash); } }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); syncStickyTabsOffset(); } renderSectionTabs(); /** * Re-populates a dynamically-growing "multiple" field list (bnrh, je, * tekildar, …) from a saved array of strings. Sets each value via * .val() + a triggered "input" event rather than touching the DOM * structure directly, so the normal refreshForTextField() growth * logic adds exactly as many rows as needed — the same thing that * happens when a person types into the last (empty) row. */ function restoreMultiField(id, values) { var container = $("#wiktku-start-" + id); $.each(values || [], function (i, v) { var field = container.find(".wiktku-start-step-field").eq(i); if (!field.length || !v) return; field.val(v).trigger("input"); }); } /** * Restores a full cached draft: shared lang/pron/bnrh fields, then * every section (via the same restoreSection()/refresh()/ * renderSectionTabs() sequence already used when switching tabs). * @param cached {{lang: string, pron: string, bnrh: Array, sections: Array, activeSection: number}} */ function restoreFromCache(cached) { if (cached.lang) { $("#wiktku-start-lang-field").val(cached.lang); $("#wiktku-start-lang-field").trigger("wiktku:refresh"); } // Rebuild dependent steps (pos, pron wrap, etc.) now that lang is set. refresh(); if (cached.pron !== undefined) { $("#wiktku-start-pron .wiktku-pron-text").val(cached.pron); } if (cached.bnrh) { restoreMultiField("bnrh", cached.bnrh); } sections = (cached.sections && cached.sections.length) ? cached.sections : [{}]; activeSection = (typeof cached.activeSection === "number" && cached.activeSection >= 0 && cached.activeSection < sections.length) ? cached.activeSection : 0; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); updateLastSavedIndicator(cached.savedAt || null); formDirty = false; wiktkuNotify("Danûstandina berê ya qeydkirî ji cache hate barkirin.", { type: "info", tag: "wiktku-cache-restore" }); } // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); // A new cureyê rêzimanî means any previously chosen cinsiyet/ // cureyê lêkerê no longer applies — clear both selections (and // the shared hidden cinsiyet field, since rebuildTa()/syncHelpers() // fall back to it) before wiping the textarea, so nothing stale // gets carried over into the rebuilt template. var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-cinsiyet-sel").val(""); ppDiv.find(".wiktku-posparams-jimar-sel").val(""); ppDiv.find(".wiktku-posparams-lektur-sel").prop("selectedIndex", 0); ppDiv.find(".wiktku-posparams-lekturform-sel").prop("selectedIndex", 0); $("#wiktku-start-cinsiyet-field").val(""); $("#wiktku-start-jimar-field").val(""); ppDiv.find(".wiktku-posparams-text").val(""); // refresh() runs steps.posparams.syncHelpers(), which toggles the // param rows for the new pos and — since the textarea is now // empty — calls rebuildTa() to repopulate it. refresh(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { // Immediate feedback that the click registered continueBtn.$element.addClass("wiktku-btn-flash"); setTimeout(function () { continueBtn.$element.removeClass("wiktku-btn-flash"); }, 500); // Ziman/Cureyê rêzimanî already block submission via the real // OOUI setDisabled (see canContinue in refresh()) — this is a // second, softer check that still lets the click through so we // can explain why, instead of the button just silently doing nothing. if (!wiktkuContentGateOk) { wiktkuNotify( "Berî şandinê, tiştekî binivîse: Mane, Bi zaravayên din, an jî Werger — kêmasî yek ji van sê beşan divê tijî be.", { type: "warn", tag: "wiktku-mincontent" } ); return; } wiktkuNotify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", flags: [ "destructive" ], }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Cache save/clear buttons ───────────────────────────────────────── // Manual, page-scoped save of the entire wizard (all sections, not // just the active one) via [[MediaWiki:Gadget-StorageUtils.js]]'s // ObjectStorage. Restoring happens silently on load at the end of // build(), once the full language list is available. // // Saving also happens automatically (debounced while typing, plus a // periodic fallback) — see "Autosave" below — since relying on the // person to remember to click "Li cache qeyd bike" before an // accidental tab close/reload defeats the point of having a cache // at all. function buildCacheSnapshot() { return { lang: getValues().lang || "", pron: $("#wiktku-start-pron .wiktku-pron-text").val() || "", // bnrh is shared (page-level), same as lang/pron above — not // per-section, so it doesn't live in sections[]. bnrh: getValuesForStep("bnrh"), sections: sections, activeSection: activeSection, savedAt: Date.now() }; } // ── Last-saved indicator ───────────────────────────────────────────── var lastSavedEl = $("<span id='wiktku-last-saved'></span>"); function formatSavedTime(ts) { try { return new Date(ts).toLocaleTimeString(mw.config.get("wgUserLanguage"), { hour: "2-digit", minute: "2-digit" }); } catch (e) { return new Date(ts).toLocaleTimeString(); } } function updateLastSavedIndicator(ts) { lastSavedEl.text(ts ? ("Cache: qeydkirî di saet " + formatSavedTime(ts) + " de") : ""); } // ── Dirty-state tracking + autosave ────────────────────────────────── // formDirty mirrors "does the live form differ from what's in cache". // Anything the person types/selects sets it; a successful save (auto // or manual) clears it; destroy() (final submit, or switching to the // source editor) also clears it since the wizard's job is over at // that point either way. formDirty/autosaveDebounceTimer/autosaveInterval // are declared in the outer scope (near activeGroup) — assigned here, // not re-declared — so destroy() can reach them too. var AUTOSAVE_DEBOUNCE_MS = 8000; // save shortly after typing pauses var AUTOSAVE_INTERVAL_MS = 60000; // …and at least this often regardless function performAutosave() { if (!formDirty) return; saveCurrentSection(); try { formCache.Set(buildCacheSnapshot()); formDirty = false; updateLastSavedIndicator(Date.now()); } catch (e) { // Silent on autosave failure (storage blocked/full, etc.) — the // manual button still surfaces a proper error if the person // tries it directly, no need to interrupt typing with a toast. } } function scheduleAutosave() { formDirty = true; if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = setTimeout(performAutosave, AUTOSAVE_DEBOUNCE_MS); } startForm.on("input change", "input, textarea, select", scheduleAutosave); autosaveInterval = setInterval(performAutosave, AUTOSAVE_INTERVAL_MS); // Warn on accidental tab close/reload while there's anything unsaved. $(window).on("beforeunload.wiktkuUnsaved", function (e) { if (!formDirty) return undefined; e.preventDefault(); e.returnValue = ""; return ""; }); var saveCacheBtn = new OO.ui.ButtonWidget({ label: "Li cache qeyd bike", title: "Halê vê formê yê niha (ziman, bilêvkirin û hemû beş) li cache (localStorage) qeyd bike, da ku eger rûpel bêyî xwestin were girtin an ji nû ve were barkirin, tu karibî berdewam bikî." }); saveCacheBtn.on("click", function () { saveCurrentSection(); // ObjectStorage.Set() doesn't return a success/failure value, so // the only way to detect a real failure (storage blocked, quota // exceeded, JSON.stringify choking on something unexpected) is to // catch it here rather than inspect a (nonexistent) return value. try { var snapshot = buildCacheSnapshot(); formCache.Set(snapshot); formDirty = false; updateLastSavedIndicator(snapshot.savedAt); wiktkuNotify("Halê formê li cache hate qeydkirin.", { type: "success", tag: "wiktku-cache-save" }); } catch (e) { mw.notify("Qeydkirina li cache bi ser neket.", { type: "error", tag: "wiktku-cache-save" }); } }); var clearCacheBtn = new OO.ui.ButtonWidget({ label: "Cache paqij bike", flags: [ "destructive" ], title: "Datayên qeydkirî yên vê rûpelê ji cache jê bibe (forma ku niha xuya dike naguherîne)." }); clearCacheBtn.on("click", function () { formCache.Set({}); // The live form still has whatever the person typed — it's just no // longer backed up anywhere, so treat this like a fresh unsaved edit. formDirty = true; updateLastSavedIndicator(null); wiktkuNotify("Cache hate paqijkirin.", { type: "success", tag: "wiktku-cache-clear" }); }); // ── "⋯" overflow ───────────────────────────────────────────── // One primary action and one secondary stay on the bar; everything // else moves in here, to avoid four same-weight buttons crowding // (and wrapping to three rows on a phone). var moreBtn = $("<button type='button' class='wiktku-more-btn' title='Vebijarkên din'>⋯</button>"); var moreMenu = $("<div class='wiktku-more-menu'></div>").hide(); /** Moves an existing OOUI button into the overflow menu, keeping its * handlers — the widgets already carry the behaviour, so this is * purely about where they are shown. */ function intoMenu(btn, extraClass) { var row = $("<div class='wiktku-more-item'></div>"); if (extraClass) row.addClass(extraClass); btn.$element.on("click", function () { moreMenu.hide(); }); row.append(btn.$element); moreMenu.append(row); } intoMenu(saveCacheBtn); intoMenu(clearCacheBtn, "wiktku-more-item-danger"); moreMenu.append($("<div class='wiktku-more-sep'></div>")); moreMenu.append($("<div class='wiktku-more-item wiktku-more-note'></div>").append(lastSavedEl)); moreBtn.on("click", function (e) { e.preventDefault(); e.stopPropagation(); var open = moreMenu.is(":visible"); moreMenu.toggle(!open); if (!open) { setTimeout(function () { $(document).one("click.wiktkuMore", function () { moreMenu.hide(); }); }, 0); } }); var moreWrap = $("<span class='wiktku-more-wrap'></span>").append(moreBtn).append(moreMenu); footer.append(moreWrap); // Icon-only settings button — opens the Tercîh dialog. Plain OOUI // icon names depend on which icon-pack module happens to be loaded, // so this uses the actual Codex "settings" (color-subtle) SVG from // Commons directly, the same way the spinner above hotlinks its gif. var prefsBtn = $("<button></button>", { type: "button", "class": "wiktku-prefs-btn", title: "Tercîh — sazkariyên vê amûrê biguherîne" }); prefsBtn.on("click", function (e) { e.preventDefault(); wiktkuOpenPrefsDialog(); }); // The gear is icon-only on the bar; inside a text menu it needs a // label like everything else around it. prefsBtn.on("click", function () { moreMenu.hide(); }); moreMenu.prepend($("<div class='wiktku-more-sep'></div>")); moreMenu.prepend($("<div class='wiktku-more-item wiktku-more-item-prefs'></div>") .append(prefsBtn) .append($("<span class='wiktku-more-item-label'></span>").text("Tercîh"))); startForm.append(footer); // NOTE: deliberately NOT .hide() (display:none). WikiEditor/CodeMirror/ // the mobile editor's auto-grow logic measure #wpTextbox1's real // dimensions during their own init, which happens while the wizard is // up. A display:none ancestor reports 0 for offsetWidth/offsetHeight/ // scrollHeight, so those scripts bake in a near-zero height that never // gets recalculated later — slideDown() in destroy() only animates the // outer box, it doesn't re-trigger their sizing. Pushing #editform // off-screen instead keeps it laid out (real width/height available to // measure) without being visible, so the editbox opens at full size. $("#editform").addClass("wiktku-offscreen").before(startForm); // renderGroupTabs() looks up #wiktku-group-tabs via a live DOM // selector, so it must run after startForm is actually in the document. renderGroupTabs(); renderBesenDinPicker(); // One pass over the whole form: every select that hasn't already been // initialised, and isn't opted out with .wiktku-plain-select, gets // the searchable picker. initSelects(startForm); refresh(); // Give every draggable textarea a custom resize grip (works // consistently on Safari/iOS, unlike the native corner grip — see // the "Manual drag-to-resize handle" comment in styles.css), and // keep applying it to textareas added later on (new sense blocks, // quote-source fields, nimûne rows, …). wiktkuInitManualResize(startForm); new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { $(mutation.addedNodes).each(function () { if (this.nodeType !== 1) return; wiktkuInitManualResize(this); }); }); }).observe(startForm[0], { childList: true, subtree: true }); // Now that the full language list is loaded, silently restore any // draft the editor previously saved for this page. var cachedDraft = formCache.Get(); if (cachedDraft && cachedDraft.sections && cachedDraft.sections.length) { restoreFromCache(cachedDraft); } } mw.loader.using(["oojs-ui-core"], function () { function wiktkuProceedWithData(wiktkuData) { var d = wiktkuData || {}; // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Jimar (number) code definitions — same shape as the wiki's // own Lua number-type table (code -> {cat, display[, req]}). if (d.numberLabels) $.extend(NUMBER_LABELS, d.numberLabels); // Populate lang choices (pinned list). if (d.langChoices) steps.lang.choices = choicesFromObject(d.langChoices, true); // Populate langsByCode and merge full language list from d.ziman. // d.ziman is a {code: name} object with all known languages. $.each(steps.lang.choices, function (i, choice) { if (choice.sortKey === undefined) choice.sortKey = choice.label; langsByCode[choice.code] = choice; }); if (d.ziman) { var pinnedCodes = {}; $.each(steps.lang.choices, function (i, c) { pinnedCodes[c.code] = true; }); var extraChoices = []; $.each(d.ziman, function (code, name) { if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; if (pinnedCodes[code]) return; var choice = { code: code, label: name, sortKey: name }; extraChoices.push(choice); langsByCode[code] = choice; }); extraChoices.sort(function (a, b) { return a.sortKey.localeCompare(b.sortKey, userLang); }); steps.lang.choices = steps.lang.choices.concat(extraChoices); } // Keep the full merged list around for trans/dunde/zarava — those // should still be able to reference any language even when the // Tercîh panel restricts the main "ziman" step below — then, if // the user set a restriction there, narrow steps.lang.choices // itself to just those codes. var wiktkuFullLangChoices = steps.lang.choices; if (wiktkuPrefs.langCodes && wiktkuPrefs.langCodes.length) { var wiktkuAllowedLangSet = {}; $.each(wiktkuPrefs.langCodes, function (i, code) { wiktkuAllowedLangSet[code] = true; }); var wiktkuRestrictedChoices = $.grep(wiktkuFullLangChoices, function (c) { return !!wiktkuAllowedLangSet[c.code]; }); // Fall back to the full list instead of showing an empty // dropdown if none of the saved codes matched anything // (typo'd code, data.json changed since, …). steps.lang.choices = wiktkuRestrictedChoices.length ? wiktkuRestrictedChoices : wiktkuFullLangChoices; } // Populate POS choices — also a plain {code: label} object in data.json. if (d.posChoices) steps.pos.choices = choicesFromObject(d.posChoices, false); // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the full language list // (not the possibly Tercîh-restricted steps.lang.choices). steps.trans.keys = wiktkuFullLangChoices; steps.dunde.keys = wiktkuFullLangChoices; steps.zarava.keys = getZaravaKeys(wiktkuFullLangChoices); build(); } // data.json ships inside this package module, so it is already parsed // and in memory — no action=raw round trip, and no Testing switch to // forget to flip back before deploying. wiktkuProceedWithData(require("./start/data.json")); }); }); //</nowiki> deohpq8avd3gttfwecpr2e9wd75vett 6333861 6333859 2026-08-15T18:08:59Z Wikihez 7344 6333861 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. // implicit dependencies: StorageUtils (ObjectStorage) //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var addLangMode = mw.util.getParamValue("wiktkuaddlang") === "1"; // ── Tercîh (user settings) panel stored via mw.storage (localStorage), globally var WIKTKU_PREFS_KEY = "wiktku_start_prefs"; var WIKTKU_PREFS_DEFAULTS = { // [] = show the full language list in the "ziman" step; otherwise // only these codes are shown there (data.json codes, not names). langCodes: [], // true = never auto-open on a new/empty page — only via the // "+Ziman/beşeke din" portlet link. onlyOnClick: false, // "auto" | "p-cactions" | "p-tb" | "p-views" — where the // "+Ziman/beşeke din" portlet link is added. portlet: "auto", // true = suppress routine/informational mw.notify toasts (page // loading, cache auto-restored, cache saved/cleared, "tê şandin…"). // Errors and direct results of an explicit action (like saving // Tercîh itself) always show regardless of this setting. quiet: false }; function wiktkuLoadPrefs() { if (!(window.mw && mw.storage)) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var raw; try { raw = mw.storage.get(WIKTKU_PREFS_KEY); } catch (e) { raw = null; } if (!raw) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var parsed; try { parsed = JSON.parse(raw); } catch (e) { parsed = {}; } return $.extend({}, WIKTKU_PREFS_DEFAULTS, parsed); } function wiktkuSavePrefs(prefs) { if (!(window.mw && mw.storage)) return false; try { mw.storage.set(WIKTKU_PREFS_KEY, JSON.stringify(prefs)); return true; } catch (e) { return false; } } var wiktkuPrefs = wiktkuLoadPrefs(); // Routine/informational notices go through here so "quiet mode" can // suppress them; errors and explicit-action confirmations (like the // Tercîh save toast) call mw.notify directly instead, and always show. function wiktkuNotify(message, options) { if (wiktkuPrefs.quiet) return; mw.notify(message, options); } // Lazily built the first time it's opened; reused after that (see // wiktkuOpenPrefsDialog below, defined once we know OOUI is available). var wiktkuPrefsWindowManager = null; var wiktkuPrefsDialog = null; function wiktkuOpenPrefsDialog() { mw.loader.using(["oojs-ui-core", "oojs-ui-windows"], function () { function WiktkuPrefsDialog(config) { WiktkuPrefsDialog.super.call(this, config); } if (!wiktkuPrefsDialog) { OO.inheritClass(WiktkuPrefsDialog, OO.ui.ProcessDialog); WiktkuPrefsDialog.static.name = "wiktkuPrefsDialog"; WiktkuPrefsDialog.static.title = "Tercîhên min"; WiktkuPrefsDialog.static.actions = [ { action: "save", label: "Qeyd bike", flags: ["primary", "progressive"] }, { action: "cancel", label: "Betal bike", flags: "safe" } ]; WiktkuPrefsDialog.prototype.initialize = function () { WiktkuPrefsDialog.super.prototype.initialize.call(this); this.langCodesInput = new OO.ui.TextInputWidget({ placeholder: "ku, zza, ckb (vala bihêle ji bo hemû zimanan)" }); this.onlyOnClickCheckbox = new OO.ui.CheckboxInputWidget({}); this.quietCheckbox = new OO.ui.CheckboxInputWidget({}); this.portletDropdown = new OO.ui.DropdownInputWidget({ options: [ { data: "auto", label: "Otomatîk (li gorî rûyê wîkiyê)" }, { data: "p-cactions", label: "p-cactions - Li qismê Amûran" }, { data: "left-navigation", label: "left-navigation - Li qismê Gotar-Gotûbêj" }, { data: "p-tb", label: "p-tb - Li qismê Giştî" }, { data: "p-views", label: "p-views - Li qismê Bixwîne" } ] }); var fieldset = new OO.ui.FieldsetLayout({ label: "Eyar" }); fieldset.addItems([ new OO.ui.FieldLayout(this.langCodesInput, { label: "Kodên zimanan ku tê xuyakirin li qismê \"ziman\"", align: "top", help: "Kodan bi virgulê (,) ji hev veqetîne. Vala bihêle da ku hemû ziman were nîşandan.", helpInline: true }), new OO.ui.FieldLayout(this.onlyOnClickCheckbox, { label: "Tenê veke wextê \"+Ziman/beşeke din\" were tikandin", align: "inline", help: "Eger were hilbijartin, ev amûr êdî otomatîk li ser rûpelên nû/vala dest pê nake — divê meriv her carê pêl \"+Ziman/beşeke din\" bike.", helpInline: true }), new OO.ui.FieldLayout(this.portletDropdown, { label: "Cihê lînka \"+Ziman/beşeke din\"", align: "top", help: "\"Otomatîk\" li gorî rûyê wîkiyê hildibijêre.", helpInline: true }), new OO.ui.FieldLayout(this.quietCheckbox, { label: "Moda bêdeng (kêmtir agahdarî nîşan bide)", align: "inline", help: "Agahdariyên normal nîşan nede. Xeta her tim tên xuyakirin.", helpInline: true }) ]); this.$body.addClass("wiktku-prefs-dialog-body").append(fieldset.$element); }; WiktkuPrefsDialog.prototype.getSetupProcess = function (data) { return WiktkuPrefsDialog.super.prototype.getSetupProcess.call(this, data) .next(function () { this.langCodesInput.setValue(wiktkuPrefs.langCodes.join(", ")); this.onlyOnClickCheckbox.setSelected(!!wiktkuPrefs.onlyOnClick); this.portletDropdown.setValue(wiktkuPrefs.portlet || "auto"); this.quietCheckbox.setSelected(!!wiktkuPrefs.quiet); }, this); }; WiktkuPrefsDialog.prototype.getActionProcess = function (action) { var dialog = this; if (action === "save") { return new OO.ui.Process(function () { var codes = dialog.langCodesInput.getValue() .split(/[,\s]+/) .map(function (c) { return c.trim().toLowerCase(); }) .filter(function (c) { return !!c; }); wiktkuPrefs = { langCodes: codes, onlyOnClick: dialog.onlyOnClickCheckbox.isSelected(), portlet: dialog.portletDropdown.getValue() || "auto", quiet: dialog.quietCheckbox.isSelected() }; wiktkuSavePrefs(wiktkuPrefs); mw.notify( "Tercîh hatin qeydkirin. Rûpelê ji nû ve bar bike (F5).", { type: "success", tag: "wiktku-prefs-save" } ); dialog.close({ action: "save" }); }); } if (action === "cancel") { return new OO.ui.Process(function () { dialog.close({ action: "cancel" }); }); } return WiktkuPrefsDialog.super.prototype.getActionProcess.call(this, action); }; wiktkuPrefsWindowManager = new OO.ui.WindowManager(); $(document.body).append(wiktkuPrefsWindowManager.$element); wiktkuPrefsDialog = new WiktkuPrefsDialog(); wiktkuPrefsWindowManager.addWindows([wiktkuPrefsDialog]); } wiktkuPrefsWindowManager.openWindow(wiktkuPrefsDialog); }); } var targetContainer; var skin = mw.config.get('skin'); if (wiktkuPrefs.portlet && wiktkuPrefs.portlet !== "auto") { targetContainer = wiktkuPrefs.portlet; } else if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Li vê rûpelê, ziman an jî beşeke nû zêde bike"); // If "onlyOnClick" is set, the wizard should ONLY ever open via the // "+Ziman/beşeke din" link — never automatically var wiktkuNewPageDetected = $(".mw-newarticletext, .mw-newarticletextanon").length > 0; if (wiktkuPrefs.onlyOnClick ? !addLangMode : (!addLangMode && !wiktkuNewPageDetected)) { return; } // ── Shared helpers ─────────────────────────────────────────────────── // Generic text/UI utilities live in their own package file now — see the // header of util.js for why. Aliased to bare names here so the ~400 call // sites below read exactly as they did when these were local functions. var wiktkuUtil = require("./start/util.js"); var capitalize = wiktkuUtil.capitalize; var decapitalize = wiktkuUtil.decapitalize; var escapeRegExp = wiktkuUtil.escapeRegExp; var stripWikilinks = wiktkuUtil.stripWikilinks; var splitTercimeIzah = wiktkuUtil.splitTercimeIzah; var insertAtCursor = wiktkuUtil.insertAtCursor; var foldDiacritics = wiktkuUtil.foldDiacritics; var wrapNativeSelect = wiktkuUtil.wrapNativeSelect; var initSelects = wiktkuUtil.initSelects; var wiktkuInitManualResize = wiktkuUtil.initManualResize; function langHeaderSource(codePattern) { return "\n?==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } // Delete button (real OOUI "trash" icon, destructive-flagged) shared by // the Mane tab bar and the Beş tab bar. One button per bar — sitting // right before "+ Mane zêde bike" / "+ Beş zêde bike", not one per tab // — deletes whichever sense/section is currently open. A trash icon on // every individual tab put the hit-target right where people click to // switch tabs, which is exactly how a stray click ended up deleting the // wrong one; a single button acting on "the one you're looking at" has // only one thing it can possibly delete. function makeTrashButton(title) { return new OO.ui.ButtonWidget({ icon: "trash", flags: ["destructive"], framed: false, invisibleLabel: true, label: title, title: title, classes: ["wiktku-trash-btn"] }); } function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } var catSrcTemplates = null; var catSrcTemplatesPromise = null; function fetchCatSrcTemplates() { if (catSrcTemplatesPromise) return catSrcTemplatesPromise; catSrcTemplatesPromise = new mw.Api().get({ action: "query", list: "categorymembers", cmtitle: "Kategorî:Çavkanî", cmnamespace: 10, cmlimit: "max", formatversion: 2 }).then(function (data) { var members = (data.query && data.query.categorymembers) || []; catSrcTemplates = $.map(members, function (m) { // Pêşgira navî ya "Şablon:" rake. return m.title.replace(/^[^:]+:/, ""); }); catSrcTemplates.sort(function (a, b) { return a.localeCompare(b, userLang); }); return catSrcTemplates; }, function () { catSrcTemplates = []; return catSrcTemplates; }); return catSrcTemplatesPromise; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var formCache = new ObjectStorage("wiktku_start_draft_" + mw.config.get("wgPageName"), 1); var langsByCode = {}; // Looks up the display label for a language code, falling back to the // code itself if it isn't known yet (e.g. langsByCode not loaded). function getLangLabel(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; // Converts a {code: label} object (langChoices/posChoices in data.json) // into the {code, label[, sortKey]} array the rest of the script uses. // isLang: true adds a sortKey and shows "(code)" after the label — // language choices only. function choicesFromObject(obj, isLang) { var result = []; $.each(obj || {}, function (code, label) { var choice = { code: code, label: label }; if (isLang) choice.sortKey = label; result.push(choice); }); return result; } function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c.code] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Number codes (y, s, d, p, p+, tp, j, j+, j/nj, nj, nj+, hj!, hj?) from // data.json's "numberLabels". Same {code: {cat, display[, req]}} shape as // the wiki's Lua number-type table; "display" can contain HTML (<abbr>) // or wikilinks, so it's only used as-is in wikitext output, never dropped // straight into an <option> (see stripMarkupForOption below). var NUMBER_LABELS = {}; // Distinguishes the Jimar dropdown (j= param) from the Cîns dropdown // (c= param): a code that's a key in NUMBER_LABELS is a number code, // everything else is a gender code. Compound codes like "m-p"/"n-p" are // gender+plural pairs and correctly stay on the gender side. function isNumberCode(code) { return Object.prototype.hasOwnProperty.call(NUMBER_LABELS, code); } // Strips the bit of markup "display" is allowed to contain so it's safe // to use as plain <option> text (options can't render HTML or wikilinks): // <abbr title="X">Y</abbr> -> "Y (X)", [[a|b]] -> "b", [[a]] -> "a". function stripMarkupForOption(html) { if (!html) return ""; return $.trim( String(html) .replace(/<abbr[^>]*title="([^"]*)"[^>]*>([\s\S]*?)<\/abbr>/gi, "$2 ($1)") .replace(/\[\[[^\]|]*\|([^\]]*)\]\]/g, "$1") .replace(/\[\[([^\]]*)\]\]/g, "$1") .replace(/<[^>]+>/g, "") ); } // Builds the Jimar dropdown's <option> text for one code: "j — jimarbar". function numberOptionLabel(code) { var def = NUMBER_LABELS[code]; if (!def) return code; var text = stripMarkupForOption(def.display); return text ? (code + " — " + text) : code; } // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } // ── Template explanations ──────────────────────────────────────────── // Every place a template can be picked shows the same row: a status // dot, the name, a link to the template page, and an ⓘ. This is the ⓘ. // // Text comes from the template's own TemplateData where it has any, so // the explanation stays right without anyone maintaining a second copy // by hand — with the desc already in data.json as the fallback for // templates that have none. var wiktkuTplDataCache = {}; // name -> {desc, params[]} or null when absent /** Fetches TemplateData for one template. Resolves to null if the * template has none (a plain, undocumented template — very common). */ function fetchTemplateData(name) { if (Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, name)) { return $.Deferred().resolve(wiktkuTplDataCache[name]).promise(); } return new mw.Api().get({ action: "templatedata", titles: "Şablon:" + name, redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; var first = null; $.each(pages, function (_, p) { if (!first) first = p; }); var out = null; if (first) { var desc = first.description; // TemplateData descriptions are language maps when the // template is documented in more than one language. if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(first.params || {}, function (key, p) { var label = p && p.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(p && p.required) }); }); out = { desc: desc || "", params: params }; } wiktkuTplDataCache[name] = out; return out; }, function () { // No TemplateData, or the API is unhappy — cache the miss so a // repeated ⓘ click doesn't re-request it every time. wiktkuTplDataCache[name] = null; return null; }); } /** Fetches TemplateData for many templates in one request and fills the * cache; resolves either way, a template with no TemplateData caches as null. */ function prefetchTemplateData(names) { var missing = $.grep(names || [], function (n) { return n && !Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n); }); if (!missing.length) return $.Deferred().resolve().promise(); // The API caps a titles list at 50 for normal users. missing = missing.slice(0, 50); return new mw.Api().get({ action: "templatedata", titles: $.map(missing, function (n) { return "Şablon:" + n; }).join("|"), redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; $.each(pages, function (_, page) { if (!page || !page.title) return; var name = String(page.title).replace(/^[^:]+:/, ""); var desc = page.description; if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(page.params || {}, function (key, prm) { var label = prm && prm.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(prm && prm.required) }); }); wiktkuTplDataCache[name] = { desc: desc || "", params: params }; }); // Anything the API didn't answer for simply has none — cache the // miss so the per-row ⓘ doesn't re-request it one at a time. $.each(missing, function (_, n) { if (!Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n)) wiktkuTplDataCache[n] = null; }); }, function () { $.each(missing, function (_, n) { wiktkuTplDataCache[n] = null; }); }); } /** Rewrites each tagged <option> in `sel` as "name — description", using * TemplateData. Only fills rows that have no description yet, so the * hand-written ones in data.json (which carry usage examples the API * does not) are left exactly as they are. */ function applyTplDescriptions(sel) { if (!sel || !sel.length) return; var changed = false; sel.find("option[data-tpl]").each(function () { var opt = $(this); var name = opt.attr("data-tpl"); if (opt.text().indexOf(" — ") !== -1) return; // already described var td = wiktkuTplDataCache[name]; var desc = (td && td.desc) || localTplDesc(name); if (!desc) return; // One line: TemplateData descriptions can run to a paragraph. desc = $.trim(String(desc).split("\n")[0]); if (desc.length > 90) desc = desc.slice(0, 90) + "…"; opt.text(name + " — " + desc); changed = true; }); // The picker caches option text for searching, so it has to re-read. if (changed) sel.trigger("wiktku:refresh"); } /** Hand-written fallback description, from data.json. * * This is the escape hatch for templates with no TemplateData on the * wiki: add a "desc" to the entry in data.json and it shows up in the * dropdown and in the ⓘ immediately, no code change. TemplateData is * still the better place — VisualEditor and every other tool reads it * too — but this keeps the picker useful in the meantime. * * Works for any pool: pronTpls, etymTpls, tplDefs, jederDefs. */ function localTplDesc(name) { var pools = [steps.pron.pronTpls, steps.etym.etymTpls, steps.dfn.tplDefs, steps.dfn.jederDefs]; var found = ""; $.each(pools, function (_, pool) { if (pool && pool[name] && pool[name].desc) { found = pool[name].desc; return false; } }); return found; } /** Opens the inline explanation panel for `name`, anchored under the * picker it was opened from. */ function showTemplateInfo(name, anchorWrap) { $(".wiktku-tpl-info").remove(); var panel = $("<div class='wiktku-tpl-info'></div>"); panel.append($("<div class='wiktku-tpl-info-name'></div>").text("{{" + name + "}}")); var body = $("<div class='wiktku-tpl-info-desc'></div>").text("Tê barkirin…"); panel.append(body); var params = $("<div class='wiktku-tpl-info-params'></div>"); panel.append(params); panel.append($("<a class='wiktku-tpl-info-link' target='_blank' rel='noopener'></a>") .attr("href", wiktkuUtil.tplPageUrl(name)) .text("Rûpela şablonê veke →")); var close = $("<button type='button' class='wiktku-tpl-info-close' title='Bigire'>✕</button>"); close.on("click", function () { panel.remove(); }); panel.prepend(close); $(anchorWrap).after(panel); fetchTemplateData(name).then(function (td) { var desc = (td && td.desc) || localTplDesc(name); body.text(desc || "Ji bo vê şablonê ravek nehatiye nivîsandin."); if (td && td.params && td.params.length) { params.append($("<div class='wiktku-tpl-info-params-title'></div>").text("Parametre:")); var listEl = $("<ul></ul>"); $.each(td.params, function (_, p) { var line = p.name + (p.label ? " — " + p.label : "") + (p.required ? " (pêwîst)" : ""); listEl.append($("<li></li>").text(line)); }); params.append(listEl); } }); } /** Marks a picker's <option>s as template rows so the searchable widget * renders them with the dot / 🔗 / ⓘ affordances, and wires the ⓘ * handler for that picker. `nameOf` maps an <option> to a template * name — the pickers store different things in value= (a snippet for * the insert dropdowns, the bare name for the sense selector). */ function markTemplateOptions(sel, nameOf) { if (!sel || !sel.length) return; var names = []; sel.find("option").each(function () { var opt = $(this); var name = nameOf(opt); if (!name) return; opt.attr("data-tpl", name); // Deprecated/typo templates are the "special cases only" ones. opt.attr("data-tpl-status", /kevnbûyî|şaşnivîs|kêmpeyda/i.test(opt.text()) ? "yellow" : "green"); names.push(name); }); sel.data("wiktkuTplInfo", showTemplateInfo); // Fill in the descriptions. Matters most for the Mane picker, whose // entries in data.json are names with no desc at all — "rastnivîs", // "ku-Latn", "guharto" on their own. One request covers every // template in the picker, cached for the per-row ⓘ as well. prefetchTemplateData(names).always(function () { applyTplDescriptions(sel); }); } /** Pulls the template name out of a snippet like "* {{ku-IPA}}" or * "{{ji|SOURCELANG|CODE|…}}". */ function tplNameFromSnippet(snippet) { var m = /\{\{\s*([^|}\n]+)/.exec(snippet || ""); return m ? $.trim(m[1]) : ""; } // True if a sense has content beyond mane worth keeping (etîket, word // lists, nimûne, jêder) — so it's still emitted with {{mane?}} if empty. function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } // A technically-"complete" entry (Ziman + Cureyê rêzimanî filled) with // nothing in Mane, Bi zaravayên din or Werger is still meaningfully // empty, so this is checked separately at submit-click time with its // own message. function hasMinRequiredContent(values) { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasMane = dfnSenses.some(function (s) { return (s.tpl && s.tplTitle) || (!s.tpl && (s.mane !== "" || senseHasExtraContent(s))); }); if (hasMane) return true; if (values.lang === "ku") { var hasWerger = false; $("#wiktku-start-trans .wiktku-trans-group").each(function () { if (steps.trans.getGroupTranslations($(this)).length) hasWerger = true; }); if (hasWerger) return true; var hasZarava = false; $("#wiktku-start-zarava .wiktku-zarava-group").each(function () { if (steps.zarava.getGroupTranslations($(this)).length) hasZarava = true; }); if (hasZarava) return true; } return false; } // Bolds the *first* occurrence of the page name function boldPageNameOnce(text) { if (!text || !pageNameRe) return text; var re = new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "i"); return text.replace(re, "'''$1'''"); } // Converts literal line breaks typed into a nimûne/jêgirtin box into // wikitext <br> tags, function nlToBr(text) { return text ? text.replace(/\r\n|\r|\n/g, "<br>") : text; } function escapeHtmlForBackdrop(str) { return String(str) .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;"); } // Mirrors a textarea's text, with a small highlighted marker placed // right after each line that's followed by an actual typed/pasted // linebreak. Rendered into a transparent backdrop layer behind the // textarea (see ensureLinebreakBackdrop()), so only the point of the // break is marked instead of the whole box. function buildLinebreakBackdropHtml(text) { var lines = text.split(/\r\n|\r|\n/); return $.map(lines, function (line, i) { var isLast = i === lines.length - 1; return escapeHtmlForBackdrop(line) + (isLast ? "" : "<mark class='wiktku-linebreak-mark'>↵</mark>\n"); }).join(""); } // Copies the metrics that affect where text wraps/lands (font, line // height, padding, border) from the real textarea onto its backdrop, // via computed style rather than shared CSS classes — most of the // box's own rules are written as "textarea.foo", which a <div> with // the same class wouldn't match. Re-run on every update in case a // responsive breakpoint changed the textarea's own font-size. function syncLinebreakBackdropMetrics(textarea, backdrop) { var cs = window.getComputedStyle(textarea[0]); backdrop.css({ "box-sizing": cs.boxSizing, "padding-top": cs.paddingTop, "padding-right": cs.paddingRight, "padding-bottom": cs.paddingBottom, "padding-left": cs.paddingLeft, "border-width": cs.borderWidth, "border-style": "solid", "font-family": cs.fontFamily, "font-size": cs.fontSize, "font-weight": cs.fontWeight, "line-height": cs.lineHeight, "letter-spacing": cs.letterSpacing }); } // Lazily wraps a textarea in its own positioning anchor (independent // of .wiktku-resize-wrap, so this doesn't depend on load order versus // wiktkuMakeManualResizable) and inserts the transparent backdrop // layer used to mark the exact point of a linebreak. Safe to call // more than once on the same textarea — the backdrop is cached. function ensureLinebreakBackdrop(textarea) { var existing = textarea.data("wiktkuLinebreakBackdrop"); if (existing) return existing; textarea.wrap("<div class='wiktku-linebreak-wrap'></div>"); var backdrop = $("<div aria-hidden='true'></div>").addClass("wiktku-linebreak-backdrop"); textarea.before(backdrop); textarea.data("wiktkuLinebreakBackdrop", backdrop); textarea.on("scroll.wiktkuLinebreak", function () { backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); }); return backdrop; } // Flags a nimûne/jêgirtin textarea (via CSS class, for the border // tint + tooltip) while it contains a typed/pasted linebreak, so the // user notices before it's silently turned into <br> on output. // Marks only the exact point of the break via a mirrored backdrop, // rather than tinting the whole box. function highlightLinebreak(el) { var textarea = $(el); var text = textarea.val(); var hasBreak = /\r|\n/.test(text); textarea .toggleClass("wiktku-has-linebreak", hasBreak) .attr("title", hasBreak ? "Xeta nû dê wek <br> bê nivîsandin" : ""); if (!hasBreak) { var cached = textarea.data("wiktkuLinebreakBackdrop"); if (cached) cached.hide(); textarea.removeClass("wiktku-has-linebreak-source"); return; } var backdrop = ensureLinebreakBackdrop(textarea); textarea.addClass("wiktku-has-linebreak-source"); syncLinebreakBackdropMetrics(textarea, backdrop); backdrop.html(buildLinebreakBackdropHtml(text)).show(); backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); } // Each nimûne item can be { text, tr, t }: text, transliteration, translation. function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{nimûne?|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = nlToBr(boldPageNameOnce(text)); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + nlToBr(n.tr); // Translation as third positional param (no key needed). if (n.t) tpl += "|" + nlToBr(n.t); } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 60 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } // Formats jêder (citation) entries into "#* {{jêder…|…}}" lines; skips // entries with no quote text. Falls back to the generic {{jêder}} // template when no specific template was chosen. function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; var quote = nlToBr(boldPageNameOnce(jeder.quote)); var quoteTr = nlToBr(jeder.quoteTr); var quoteT = nlToBr(jeder.quoteT); if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + quote; if (quoteTr) cite += "|tr=" + quoteTr; if (quoteT) cite += "|tercime=" + quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + quote; if (quoteTr) out += "|tr=" + quoteTr; if (quoteT) out += "|tercime=" + quoteT; // A şablon picked from Kategorî:Çavkanî is transcluded as the // source param (e.g. |{{Kovara X}}); manual text is used as-is. var srcParam = jeder.jederCatTpl ? ("{{" + jeder.jederCatTpl + "}}") : (jeder.jederManual ? jeder.jederManual : "çavkanî?"); // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } // True if a sense has at least one jêder entry with quote text. function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } // Builds "{{tplName|lang|part1|part2|…}}" from a sense field (kategori, // etiket), wrapped inline (" {{…}} ") or on its own line ("\n#: {{…}}"). function buildSenseTpl(sense, field, lang, tplName) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return call } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } // ── Inline modifier system ─────────────────────────────────────────────── // Appends a ⊕ button to a word input <li>. Clicking it shows a compact // modifier picker; selecting one prompts for the value and appends // <modifier:value> to the textarea's current content. 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îf" }, { 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: qualifier (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" }, { key: "qq", label: "qq: qualifier (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î" } ]; // Sub-groups (inside a sense/definition block) that get the same ⊕ // modifier button as makeWordListStep fields. var MODIFIER_SUBGROUPS = { "wiktku-dfn-alternativ": true, "wiktku-dfn-hevmane": true, "wiktku-dfn-dijmane": true, "wiktku-dfn-koordine": true, "wiktku-dfn-jornav": true, "wiktku-dfn-jernav": true }; /** * Wraps a freshly-created textarea in a <li> with a ⊕ modifier button. * `ta` — the jQuery textarea element. * Returns the <li>. */ function makeModifierLi(ta) { var li = $("<li class='wiktku-word-li'></li>"); var btn = $("<button type='button' class='wiktku-mod-btn' title='Modifiyerê lê zêde bike'>⊕</button>"); var picker = $("<div class='wiktku-mod-picker'></div>").hide(); // Which modifier keys are already present in the textarea's current // text — e.g. "<t:...>" → "t" used. Each modifier can only be // applied once per word, so its pill gets disabled once used. function usedKeys() { var used = {}; var re = /<([a-zA-Z]+):/g; var val = ta.val() || ""; var m; while ((m = re.exec(val)) !== null) used[m[1]] = true; return used; } $.each(WORD_MODIFIERS, function (_, mod) { var pill = $("<button type='button' class='wiktku-mod-pill'></button>").text(mod.label); pill.attr("title", mod.hint); pill.data("mod-key", mod.key); pill.on("click", function (e) { e.preventDefault(); if (pill.prop("disabled")) return; // already used on this word picker.hide(); // Show a tiny inline input for the modifier value. var valWrap = $("<span class='wiktku-mod-val-wrap'></span>"); var valInp = $("<input type='text' class='wiktku-mod-val-input'>") .attr("placeholder", mod.hint + "…") .attr("size", 20); var confirm = $("<button type='button' class='wiktku-mod-confirm'>✓</button>"); var cancel = $("<button type='button' class='wiktku-mod-cancel'>✕</button>"); function applyModifier() { var v = $.trim(valInp.val()); if (v) { ta.val(ta.val() + "<" + mod.key + ":" + v + ">"); ta.trigger("input"); } valWrap.remove(); ta.focus(); } confirm.on("click", applyModifier); cancel.on("click", function () { valWrap.remove(); ta.focus(); }); valInp.on("keydown", function (e) { if (e.which === 13) { e.preventDefault(); applyModifier(); } if (e.which === 27) { valWrap.remove(); ta.focus(); } }); valWrap.append(valInp).append(confirm).append(cancel); li.append(valWrap); valInp.focus(); }); picker.append(pill); }); btn.on("click", function (e) { e.preventDefault(); // Close any other open pickers in the same list. li.closest("ol, ul").find(".wiktku-mod-picker").not(picker).hide(); // Grey out modifiers already used on this word — refreshed on // every open since the text (and thus what's "used") can change. var used = usedKeys(); picker.find(".wiktku-mod-pill").each(function () { var isUsed = !!used[$(this).data("mod-key")]; $(this).prop("disabled", isUsed).toggleClass("wiktku-mod-pill-used", isUsed); }); picker.toggle(); }); // Close picker when focus leaves the li entirely. li.on("focusout", function () { setTimeout(function () { if (!$.contains(li[0], document.activeElement)) picker.hide(); }, 150); }); li.append(ta).append(btn).append(picker); return li; } function makeWordListStep(id, name, question_fmt) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, modifiers: true, // Function instead of a plain string so it can name the current // language — computed fresh at build time and re-applied by // refresh() whenever the language changes. placeholder: function () { var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return "Kelîme" + (langLabel ? " bi " + langLabel : "") + "…"; }, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); var header = capitalize(name); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: {}, visible: function (values) { if (!values.lang) return false; // addLangMode: skip pron only if this lang already has a section. if (addLangMode) { // Clearing the page makes existing content irrelevant. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, // Fills the insert-dropdown from pronTpls, filtered by language. refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); // Reassures the user this field is optional — the dropdown // below writes the template for them, no syntax needed up front. wrap.append( $("<p class='wiktku-step-hint'></p>").text( "Ev qad ne mecbûrî ye. Heke tu nizanî kîjan şablonî hilbijêrî, vale bihêle — an ji pêşkêşkariya jêrîn şablonekî hilbijêre, ew ê bixweber li vir were nivîsandin." ) ); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike "); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); // Clear the picker's search box sel.trigger("wiktku:refresh"); ta.focus(); return; } // The noLang templates (ku-IPA, ku-kîte, zza-IPA, zza-kîte) // auto-generate content from a Lua module reading the page // title, so show a live preview and require confirmation // before inserting. var tplLabel = selectedOption.text(); $(this).val(""); sel.trigger("wiktku:refresh"); steps.pron.showTplPreview(stepDiv, ta, snippet, tplLabel); }); wrap.append(sel).append(ta); stepDiv.append(wrap); steps.pron.buildIpaPalette(wrap, ta); initSelects(wrap); return ta; }, // ── IPA character palette ────────────────────────────────── // Modelled on fr.wiktionary's: every character is a button that // drops itself in at the cursor. Two sub-tabs, because the full // IPA chart is ~180 symbols and roughly twenty of them ever // appear in Kurmancî — "IPA (kurdî)" opens by default and the // full chart is one click away for loanwords and other // languages. Grouped with a label down the left so it reads as // a chart rather than one long line of glyphs. IPA_KU: [ { label: "Kît/stres", chars: ["ˈ", "ˌ", "ː"] }, { label: "Bêdeng", chars: ["d͡ʒ", "t͡ʃ", "ʒ", "ʃ", "ɫ", "ŋ", "ɾ", "r", "ʋ", "ħ", "ʕ", "ɣ", "χ", "ʔ"] }, { label: "Dengdêr", chars: ["ɑː", "eː", "ɛ", "ɪ", "iː", "ɯ", "ʊ", "uː", "yː", "ø", "œ"] } ], IPA_FULL: [ { label: "Bêdeng 1", chars: ["m", "ɱ", "n", "ɳ", "ɲ", "ŋ", "ɴ", "p", "b", "t", "d", "t̪", "d̪", "ʈ", "ɖ", "c", "ɟ", "k", "ɡ", "q", "ɢ", "ʡ", "ʔ"] }, { label: "Bêdeng 2", chars: ["ɸ", "β", "f", "v", "θ", "ð", "s", "z", "ʃ", "ʒ", "ʂ", "ʐ", "ɕ", "ʑ", "ç", "ʝ", "x", "ɣ", "χ", "ʁ", "ħ", "ʕ", "h", "ɦ", "ʜ", "ʢ", "ɧ"] }, { label: "Bêdeng 3", chars: ["ʋ", "ɹ", "ɻ", "j", "ɥ", "ɰ", "ʍ", "w", "ʙ", "ⱱ", "ɾ", "ɽ", "r", "ʀ", "ɺ", "l", "ɫ", "ɬ", "ɮ", "ɭ", "ʎ", "ʟ"] }, { label: "Bêdeng 4", chars: ["ɓ", "ɗ", "ᶑ", "ʄ", "ɠ", "ʛ", "ʘ", "ǀ", "ǃ", "ǂ", "ǁ"] }, { label: "Dengdêr", chars: ["i", "y", "ɪ", "ʏ", "ɨ", "ʉ", "ɯ", "u", "ʊ", "e", "ø", "ɘ", "ɵ", "ɤ", "o", "ə", "ɚ", "ɛ", "œ", "ɜ", "ɝ", "ɞ", "ʌ", "ɔ", "æ", "ɶ", "ɐ", "a", "ɑ", "ɒ"] }, { label: "Suprasegmental", chars: ["ˈ", "ˌ", "ː", "ˑ", "ʼ", "ˀ", "ˤ", "ᵝ", "ᵊ", "ˠ", "ʰ", "ʱ", "ʲ", "ˡ", "ⁿ", "ᵑ", "ʷ", "ᶣ", "˞", "‿"] }, { label: "Dîakrîtîk", chars: ["̚", "̪", "̺", "̻", "̼", "̬", "̊", "̥", "̞", "̝", "̘", "̙", "̽", "̟", "̠", "̈", "̤", "̹", "̜", "̍", "̩", "̆", "̯", "̃", "̰", "͡", "͜"] }, { label: "Ton", chars: ["̋", "́", "̄", "̀", "̏", "̌", "̂", "˥", "˦", "˧", "˨", "˩", "ꜛ", "ꜜ", "↗", "↘", "‖"] } ], /** Builds the two-sub-tab character palette under the textarea. */ buildIpaPalette: function (wrap, ta) { if (wrap.find(".wiktku-ipa-palette").length) return; var panel = $("<div class='wiktku-ipa-panel'></div>").hide(); var toggle = $("<a href='#' class='wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tîpên bilêvkirinê</span>")); toggle.on("click", function (e) { e.preventDefault(); var open = panel.is(":visible"); panel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); wrap.append($("<div class='wiktku-adv-toggle-row'></div>").append(toggle)); // Sub-tab bar, with the two template buttons pinned right. var subTabs = $("<div class='wiktku-ipa-subtabs'></div>"); var kuTab = $("<span class='wiktku-ipa-subtab wiktku-tab-active'>IPA (kurdî)</span>"); var fullTab = $("<span class='wiktku-ipa-subtab'>IPA</span>"); subTabs.append(kuTab).append(fullTab); var tplBtns = $("<span class='wiktku-ipa-tplbtns'></span>"); $.each([ { label: "{{ku-IPA|+}}", snippet: "{{ku-IPA|}}", back: 2 }, { label: "{{IPA|+}}", snippet: "{{IPA|ku|}}", back: 2 } ], function (_, t) { var b = $("<button type='button' class='wiktku-ipa-tplbtn'></button>").text(t.label); b.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], t.snippet); // Park the cursor inside the braces, where the value goes. var pos = ta[0].selectionStart - t.back; ta[0].selectionStart = ta[0].selectionEnd = pos; ta.focus(); }); tplBtns.append(b); }); subTabs.append(tplBtns); panel.append(subTabs); function buildGrid(groups) { var grid = $("<div class='wiktku-ipa-grid'></div>"); $.each(groups, function (_, g) { var row = $("<div class='wiktku-ipa-row'></div>"); row.append($("<span class='wiktku-ipa-rowlabel'></span>").text(g.label)); var keys = $("<span class='wiktku-ipa-keys'></span>"); $.each(g.chars, function (_, ch) { var btn = $("<button type='button' class='wiktku-ipa-key'></button>"); // A combining mark on its own renders as a stray // accent floating over whatever precedes it, so // show it on a dotted circle — but insert only // the mark itself. var combining = /^[̀-ͯ҃-҉]$/.test(ch); btn.text(combining ? "◌" + ch : ch); if (combining) btn.addClass("wiktku-ipa-key-combining"); btn.attr("title", ch); btn.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], ch); ta.focus(); }); keys.append(btn); }); row.append(keys); grid.append(row); }); return grid; } var kuGrid = buildGrid(steps.pron.IPA_KU); var fullGrid = buildGrid(steps.pron.IPA_FULL).hide(); panel.append(kuGrid).append(fullGrid); kuTab.on("click", function () { kuTab.addClass("wiktku-tab-active"); fullTab.removeClass("wiktku-tab-active"); kuGrid.show(); fullGrid.hide(); }); fullTab.on("click", function () { fullTab.addClass("wiktku-tab-active"); kuTab.removeClass("wiktku-tab-active"); fullGrid.show(); kuGrid.hide(); }); panel.addClass("wiktku-ipa-palette"); wrap.append(panel); }, /** Inline preview + confirm panel for a "noLang" (auto-content) * pronunciation template — fetches what the snippet expands to * for this page and only inserts it if the user confirms. */ showTplPreview: function (stepDiv, ta, snippet, tplLabel) { // Only one preview panel open at a time. stepDiv.find(".wiktku-pron-preview").remove(); var panel = $("<div class='wiktku-pron-preview'></div>"); panel.append($("<div class='wiktku-pron-preview-label'></div>") .text("Pêşdîtina " + tplLabel + ":")); var body = $("<div class='wiktku-pron-preview-body'></div>").text("Tê barkirin…"); panel.append(body); var actions = $("<div class='wiktku-pron-preview-actions'></div>"); var confirmBtn = $("<button type='button' class='wiktku-pron-preview-confirm'>✓ Tevlî bike</button>") .prop("disabled", true); var cancelBtn = $("<button type='button' class='wiktku-pron-preview-cancel'>✕ Betal bike</button>"); actions.append(confirmBtn).append(cancelBtn); panel.append(actions); ta.before(panel); confirmBtn.on("click", function () { insertAtCursor(ta[0], snippet); panel.remove(); ta.focus(); }); cancelBtn.on("click", function () { panel.remove(); }); // action=parse, not action=expandtemplates. expandtemplates // returns *expanded wikitext*, so the preview read as // [[IPA]]<sup>([[Wîkîferheng:IPA kurmancî|kilîd]])</sup>: // <span class="IPA">/-{kshhe}-/</span>[[Kategorî:…]] — which // is exactly what the person is trying to avoid having to // read. parse hands back the rendered HTML the page will // actually show. // // Drop the leading "* " first: it is wikitext list syntax // wrapping the template, and keeping it would render the // preview as a bulleted list rather than the line itself. new mw.Api().post({ action: "parse", title: pageName, text: snippet.replace(/^\*\s*/, ""), prop: "text", wrapoutputclass: "", disablelimitreport: 1, disableeditsection: 1, contentmodel: "wikitext", formatversion: 2 }).done(function (data) { var html = (data && data.parse && data.parse.text) || ""; if ($.trim($("<div>").html(html).text())) { body.html(html); // Category links render as nothing but still exist; // and any real link inside a preview should not // navigate away from a half-filled form. body.find("a").attr("target", "_blank").attr("rel", "noopener"); } else { body.text("(vala — ji bo vê rûpelê tiştek nehate afirandin)"); } confirmBtn.prop("disabled", false); }).fail(function () { body.text("Pêşdîtin nehate barkirin — tu dikarî hîn jî wê tevlî bikî."); confirmBtn.prop("disabled", false); }); }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line; }).join("\n"); // "===" heading under Ziman and above the POS sections; the // field is shared across sections, so it's emitted once by // getWikitext() rather than per-POS-section (would otherwise // print the pronunciation twice for a two-POS entry). return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var capitalizedPos = capitalize(pos); // "form" opt-param (checked in posparams) marks this as a // form-of/inflected entry — the section title becomes // "Formeke <pos>ê" instead of the plain pos name. The // template call itself still uses the unchanged pos name. var isForm = $("#wiktku-posparams-opt-form").is(":checked"); var header = isForm ? "\n=== Formeke " + pos + "ê ===\n" : "\n=== " + capitalizedPos + " ===\n"; // Image line (between header and template call) var imageLine = steps.resim.output(values); // Read the live wikitext from the posparams textarea. // Fall back to a plain {{pos|lang}} if the step hasn't been built yet. var tplLine = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); if (!tplLine) { tplLine = "{{" + pos + "|" + (values.lang || "") + "}}"; } return header + imageLine + tplLine + "\n"; } }, // cinsiyet (gender) — shown for navdêr/serenav only, with choices built // from metadata[lang].g since not every language has grammatical gender. cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams // Single source of truth for the selected gender code. The visible // dropdown lives inside the posparams step (see steps.posparams), // but it must always read/write THIS hidden field — not a field of // its own — since getValuesForStep("cinsiyet") reads from here. build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-cinsiyet-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // jimar (grammatical number) — same hidden-field pattern as cinsiyet // above, but writes into its own j= template parameter instead of // sharing c=. Shown for navdêr/serenav only, with choices built from // whichever of metadata[lang].g are number codes (see isNumberCode). jimar: { id: "jimar", name: "jimar", question_fmt: 'Jimara "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-jimar-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // Lêker transitivity — hidden step, handled inside posparams lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function () { return false; }, choices: [ { code: "gh", label: "gerguhêz" }, { code: "x-gh", label: "xwerû-gerguhêz" }, { code: "p-gh", label: "pêkhatî-gerguhêz" }, { code: "h-gh", label: "hevedudanî-gerguhêz" }, { code: "b-gh", label: "biwêjî-gerguhêz" }, { code: "ngh", label: "negerguhêz" }, { code: "x-ngh", label: "xwerû-negerguhêz" }, { code: "p-ngh", label: "pêkhatî-negerguhêz" }, { code: "h-ngh", label: "hevedudanî-negerguhêz" }, { code: "b-ngh", label: "biwêjî-negerguhêz" } ], output: function () { return ""; } }, // tr — hidden step, handled inside posparams tr: { id: "tr", name: "transliterasyon", question_fmt: "Transliterasyona vê kelîmeyê", multiple: false, narrow: true, visible: function () { return false; } }, posparams: { id: "posparams", // Fused onto the "pos" card visually (see #wiktku-start-posparams // in styles.css) so the two read as ONE question — this name is // only a no-CSS/no-JS fallback, since the h3 that would show it // is hidden by CSS. name: "taybetmendî", // Shows what's actually being asked for: gender for nouns, verb // type for verbs, a generic fallback otherwise. question_fmt: function (values) { var pos = values.pos || ""; // Cinsiyet/Jimar fields below are self-labelled, so no title needed here. if (pos === "navdêr" || pos === "serenav") return ""; if (/^lêker/.test(pos)) return "Cureyê lêkerê"; return "Taybetmendî"; }, visible: function (values) { return !!(values.lang && values.pos); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-posparams-wrap").length) return null; var wrap = $("<div class='wiktku-posparams-wrap'></div>"); var helpers = $("<div class='wiktku-posparams-helpers'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-posparams-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-posparams-text") .attr("rows", 2); var _rebuilding = false; function safeRebuild() { if (_rebuilding) return; _rebuilding = true; steps.posparams.rebuildTa(stepDiv); _rebuilding = false; refresh(); } // Generic text-input row factory function makeTextRow(key, labelText, placeholder) { var row = $("<div class='wiktku-posparams-row'></div>") .attr("id", "wiktku-posparams-row-" + key).hide(); var inp = $("<input type='text'>") .addClass("wiktku-start-narrow wiktku-posparams-field") .attr("data-pp-key", key) .attr("placeholder", placeholder || ""); inp.on("input", safeRebuild); row.append($("<label></label>").text(labelText + ": ")).append(inp); return row; } // cinsiyet var cinsiyetRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-c'></div>") .append($("<label></label>").text("Cinsiyet: ")).hide(); var cinsiyetSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-cinsiyet-sel") .append($("<option value=''>— hilbijêre —</option>")); // Writes into the real, shared #wiktku-start-cinsiyet-field (owned by // steps.cinsiyet) rather than a field of its own — see the comment // on steps.cinsiyet.build for why that matters. cinsiyetSel.on("change", function () { $("#wiktku-start-cinsiyet-field").val($(this).val()).trigger("change"); safeRebuild(); }); cinsiyetRow.append(cinsiyetSel); // jimar (number) — second dropdown next to Cinsiyet, writes // into the shared hidden #wiktku-start-jimar-field, into its // own j= param instead of sharing c=. Options + tooltip are // built in syncHelpers once the language's number codes are known. var jimarRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-jimar'></div>") .append($("<label></label>").text("Jimar: ")).hide(); var jimarSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-jimar-sel") .append($("<option value=''>— hilbijêre —</option>")); jimarSel.on("change", function () { $("#wiktku-start-jimar-field").val($(this).val()).trigger("change"); safeRebuild(); }); jimarRow.append(jimarSel); // lektur: two plain questions (transitivity + structural form) // instead of one 10-option dropdown. Emitted code: base alone // ("gh"), or prefix + "-" + base ("x-gh"). var lekturRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lektur'></div>") .append($("<label></label>").text("Lêker derbasdar e? ")).hide(); var lekturSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lektur-sel") .append($("<option value=''>— hilbijêre —</option>")) .append($("<option value='gh'>gerguhêz (bireser digire)</option>")) .append($("<option value='ngh'>negerguhêz (bireser nagire)</option>")); lekturSel.on("change", safeRebuild); lekturRow.append(lekturSel); // Second half of the same question — the structural form. // Blank = xwerû/sade, which is the common case. var lekturFormRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lekturform'></div>") .append($("<label></label>").text("Şiklê lêkerê: ")).hide(); var lekturFormSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lekturform-sel") .append($("<option value=''>sade (asayî)</option>")) .append($("<option value='x'>xwerû</option>")) .append($("<option value='p'>pêkhatî</option>")) .append($("<option value='h'>hevedudanî</option>")) .append($("<option value='b'>biwêjî</option>")); lekturFormSel.on("change", safeRebuild); lekturFormRow.append(lekturFormSel); helpers.append(cinsiyetRow).append(jimarRow).append(lekturRow).append(lekturFormRow); // ── Everything below here is "Tercîhên pêşketî" ────────────── // These rows live inside a collapsed panel, so the default // view of this card is two dropdowns instead of twenty-odd fields. // Transliteration is a primary field, not an advanced one, for // any language not written in Latin script: for those, an // entry without it is incomplete. syncHelpers already gates // the row on needsTransliteration(lang), so for Kurmancî and // other Latin-script languages it simply never appears. helpers.append(makeTextRow("tr", "Transliterasyon (tr)", "Transliterasyon…")); var advPanel = $("<div class='wiktku-posparams-adv-panel'></div>").hide(); advPanel .append(makeTextRow("cuda", "nîşankirina alternatîv", "cuda…")) .append(makeTextRow("ts", "Transkrîpsiyon (ts)", "Transkrîpsiyon…")) .append(makeTextRow("m", "Forma mê (m)", "Forma mê…")) .append(makeTextRow("mtr", "Translit. mê (mtr)", "Transliterasyona mê…")) .append(makeTextRow("n", "Forma nêr (n)", "Forma nêr…")) .append(makeTextRow("ntr", "Translit. nêr (ntr)", "Transliterasyona nêr…")) .append(makeTextRow("p", "Forma pirjimar (p)", "Forma pirjimar…")) .append(makeTextRow("ptr", "Translit. pirjimar", "Transliterasyona pirjimar…")) .append(makeTextRow("y", "Forma yekjimar (y)", "Forma yekjimar…")) .append(makeTextRow("ytr", "Translit. yekjimar", "Transliterasyona yekjimar…")) .append(makeTextRow("sûp", "Forma sûperlatîv (sûp)", "Forma sûperlatîv…")) .append(makeTextRow("sûptr", "Translit. sûperlatîv", "Transliterasyona sûperlatîv…")) .append(makeTextRow("komp", "Forma komparatîv (komp)", "Forma komparatîv…")) .append(makeTextRow("komptr", "Translit. komparatîv", "Transliterasyona komparatîv…")) .append(makeTextRow("gir", "Forma girdêk (gir)", "gir=…")) .append(makeTextRow("girtr", "Translit. gir", "girtr=…")) .append(makeTextRow("hûr", "Forma hûrek (hûr)", "hûr=…")) .append(makeTextRow("hûrtr", "Translit. hûr", "hûrtr=…")) .append(makeTextRow("hanja", "Forma hanja", "hanja=…")) .append(makeTextRow("hanjaTr","Translit. hanja", "hanjaTr=…")) // Lêker rehên demê (only shown when pos is lêker — see syncHelpers) .append(makeTextRow("niha", "Rehê dema niha (niha)", "Rehê dema niha…")) .append(makeTextRow("nihatr", "Translit. rehê dema niha", "Transliterasyona rehê dema niha…")) .append(makeTextRow("borî", "Rehê dema borî (borî)", "Rehê dema borî…")) .append(makeTextRow("borîtr", "Translit. rehê dema borî", "Transliterasyona rehê dema borî…")) .append(makeTextRow("subj", "Rehê dema bilanî (subj)", "Rehê dema bilanî…")) .append(makeTextRow("subjtr", "Translit. rehê dema bilanî", "Transliterasyona rehê dema bilanî…")); // Optional boolean params — nested inside the advanced panel // (they were already the most niche thing on the card). var optPanel = $("<div class='wiktku-posparams-opt-panel'></div>"); $.each([ { key: "form", label: "form — ev made forma tewandî ye" }, { key: "formaalt", label: "formaalt — vê madeyê bike forma alternatîv" }, { key: "nekatcure", label: "nekatcure — sinifa rêzimanî kategorîze neke" }, { key: "nekatcins", label: "nekatcins — kategoriya cinsiyetê neyîne" }, { key: "nekatçendterm", label: "nekatçendterm — kategoriya çend-term neyîne" }, { key: "serlînkneke", label: "serlînkneke — sernavê madeyê lînk neke" }, { key: "nekatpalîndrom", label: "nekatpalîndrom — kategoriya palîndromê neyîne" }, { key: "neformtr", label: "neformtr — transliterasyona forman neyîne" } ], function (_, p) { var cb = $("<input type='checkbox'>") .attr("id", "wiktku-posparams-opt-" + p.key).val(p.key).on("change", safeRebuild); var lbl = $("<label></label>").attr("for", "wiktku-posparams-opt-" + p.key).text(" " + p.label); optPanel.append($("<div class='wiktku-posparams-opt-row'></div>").append(cb).append(lbl)); }); advPanel.append(optPanel); var optToggle = $("<a href='#' class='wiktku-posparams-opt-toggle wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tercîhên pêşketî</span>")); optToggle.on("click", function (e) { e.preventDefault(); var open = advPanel.is(":visible"); advPanel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); helpers.append($("<div class='wiktku-adv-toggle-row'></div>") .append(optToggle)); helpers.append(advPanel); wrap.append(helpers).append(ta); // Typing directly in textarea keeps cinsiyet/jimar hidden // fields in sync, but does NOT call refresh() — preserves // manual edits. ta.on("input", function () { var text = $(this).val(); var cMatch = text.match(/\|c=([^|}\s]+)/); $("#wiktku-start-cinsiyet-field").val(cMatch ? cMatch[1] : ""); var jMatch = text.match(/\|j=([^|}\s]+)/); $("#wiktku-start-jimar-field").val(jMatch ? jMatch[1] : ""); }); stepDiv.append(wrap); return null; }, /** Reads all helper widget values and rewrites the textarea. * Called only by safeRebuild (user interaction) — never by syncHelpers, * so manual textarea edits are never overwritten by a refresh cycle. */ rebuildTa: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; if (!pos || !lang) return; var cinsiyet = stepDiv.find(".wiktku-posparams-cinsiyet-sel").val() || ""; var jimar = stepDiv.find(".wiktku-posparams-jimar-sel").val() || ""; // Two dropdowns, one code: "gh" / "ngh" on their own, or // prefixed with the structural form ("x-gh", "b-ngh", …). var lekturBase = stepDiv.find(".wiktku-posparams-lektur-sel").val() || ""; var lekturForm = stepDiv.find(".wiktku-posparams-lekturform-sel").val() || ""; var lektur = lekturBase ? (lekturForm ? lekturForm + "-" + lekturBase : lekturBase) : ""; function v(key) { return $.trim(stepDiv.find(".wiktku-posparams-field[data-pp-key='" + key + "']").val()); } var out = "{{" + pos + "|" + lang; if (pos === "navdêr" || pos === "serenav") { out += cinsiyet ? "|c=" + cinsiyet : (lang === "ku" ? "|c=?" : ""); // Number is its own j= param, separate from c= (which // holds gender, including compounds like m-p/n-p). if (jimar) out += "|j=" + jimar; } else if (/^lêker/.test(pos) && lektur) { out += "|c=" + lektur; } if (v("cuda")) out += "|" + v("cuda"); if (v("tr")) out += "|tr=" + v("tr"); if (v("ts")) out += "|ts=" + v("ts"); $.each(["m","n","p","y"], function (_, k) { if (v(k)) out += "|" + k + "=" + v(k); if (v(k+"tr")) out += "|" + k + "tr=" + v(k+"tr"); }); if (v("sûp")) out += "|sûp=" + v("sûp"); if (v("sûptr")) out += "|sûptr=" + v("sûptr"); if (v("komp")) out += "|komp=" + v("komp"); if (v("komptr")) out += "|komptr=" + v("komptr"); if (v("gir")) out += "|gir=" + v("gir"); if (v("girtr")) out += "|girtr=" + v("girtr"); if (v("hûr")) out += "|hûr=" + v("hûr"); if (v("hûrtr")) out += "|hûrtr=" + v("hûrtr"); if (v("hanja")) out += "|hanja=" + v("hanja"); if (v("hanjaTr")) out += "|hanjaTr=" + v("hanjaTr"); if (v("niha")) out += "|niha=" + v("niha"); if (v("nihatr")) out += "|nihatr=" + v("nihatr"); if (v("borî")) out += "|borî=" + v("borî"); if (v("borîtr")) out += "|borîtr=" + v("borîtr"); if (v("subj")) out += "|subj=" + v("subj"); if (v("subjtr")) out += "|subjtr=" + v("subjtr"); stepDiv.find(".wiktku-posparams-opt-panel input:checked").each(function () { var key = $(this).val(); // "form" marks this entry as a form-of/inflected entry — it // takes "erê" rather than the plain "1" the other boolean // opt params use. out += "|" + key + "=" + (key === "form" ? "erê" : "1"); }); out += "}}"; stepDiv.find(".wiktku-posparams-text").val(out); $("#wiktku-start-cinsiyet-field").val(cinsiyet); $("#wiktku-start-jimar-field").val(jimar); }, /** Called from refresh() — controls row visibility only. * Does NOT rewrite textarea so user edits are preserved. * Rebuilds only when textarea is empty (first pos selection). */ syncHelpers: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; var needsTr = needsTransliteration(lang); var isNom = pos === "navdêr" || pos === "serenav" || pos === "rengdêr"; var isAdj = pos === "rengdêr"; var isTîp = pos === "tîp"; var isJa = lang === "ja"; var isLeker = /^lêker/.test(pos); // Kurmancî verbs are conjugated from the present/past roots // alone — there's no separate subjunctive root the way some // other languages have — so this pair of fields is noise for // lang=ku specifically, unlike niha/borî which every lêker // language needs. var isLekerSubj = isLeker && lang !== "ku"; // metadata[lang].g lists gender AND number codes together — // split them here (see isNumberCode) so Cîns only ever offers // gender codes (and gender+plural compounds like m-p/n-p, // which aren't NUMBER_LABELS keys) and Jimar only offers number codes. var meta = metadata[lang]; var allCodes = (meta && meta.g) || []; var genderCodes = $.grep(allCodes, function (c) { return !isNumberCode(c); }); var jimarCodes = $.grep(allCodes, function (c) { return isNumberCode(c); }); var showC = (pos === "navdêr" || pos === "serenav") && genderCodes.length > 0; var cRow = stepDiv.find("#wiktku-posparams-row-c"); cRow.toggle(showC); if (showC) { var sel = cRow.find(".wiktku-posparams-cinsiyet-sel"); // Prefer the select's own current value (normal in-session // use); fall back to the shared hidden field, which is how // a cache/section restore communicates a saved gender // before this select has any <option>s to hold it. var prev = sel.val() || $("#wiktku-start-cinsiyet-field").val() || ""; sel.find("option[value!='']").remove(); $.each(genderCodes, function (_, code) { sel.append($("<option></option>").val(code).text(genderLabel(code))); }); if (prev) sel.val(prev); } var showJimar = (pos === "navdêr" || pos === "serenav") && jimarCodes.length > 0; var jimarRowEl = stepDiv.find("#wiktku-posparams-row-jimar"); jimarRowEl.toggle(showJimar); if (showJimar) { var jimarSelEl = jimarRowEl.find(".wiktku-posparams-jimar-sel"); var prevJimar = jimarSelEl.val() || $("#wiktku-start-jimar-field").val() || ""; jimarSelEl.find("option[value!='']").remove(); $.each(jimarCodes, function (_, code) { var def = NUMBER_LABELS[code] || {}; var opt = $("<option></option>").val(code).text(numberOptionLabel(code)); // The explanation (cat, e.g. "dualia tantum") shows as a // hover tooltip — <option> can't hold richer markup. if (def.cat) opt.attr("title", def.cat); jimarSelEl.append(opt); }); if (prevJimar) jimarSelEl.val(prevJimar); } stepDiv.find("#wiktku-posparams-row-lektur").toggle(isLeker); // Only ask for the structural form once gerguhêz/negerguhêz is answered. stepDiv.find("#wiktku-posparams-row-lekturform") .toggle(isLeker && !!stepDiv.find(".wiktku-posparams-lektur-sel").val()); stepDiv.find("#wiktku-posparams-row-tr").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-ts").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-m").toggle(isNom); stepDiv.find("#wiktku-posparams-row-mtr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-n").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ntr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-p").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ptr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-y").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ytr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-sûp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-sûptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-komp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-komptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-gir").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-girtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hûr").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-hûrtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hanja").toggle(isJa); stepDiv.find("#wiktku-posparams-row-hanjaTr").toggle(isJa); stepDiv.find("#wiktku-posparams-row-niha").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-nihatr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-borî").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-borîtr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-subj").toggle(isLekerSubj); stepDiv.find("#wiktku-posparams-row-subjtr").toggle(isLekerSubj && needsTr); if (!$.trim(stepDiv.find(".wiktku-posparams-text").val())) { steps.posparams.rebuildTa(stepDiv); } }, output: function () { return ""; } // pos.output reads the textarea directly }, dfn: { id: "dfn", name: "Mane", // Field types that live behind "Malûmatên pêşketî". Kept as one // list so the collapse CSS, the count badge and the allGroups // adv: flags below can't drift apart. ADV_SUBGROUPS: [ "wiktku-dfn-etiket", "wiktku-dfn-kategori", "wiktku-dfn-alternativ", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ], question_fmt: function (values) { var base = "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin!"; if (values.lang === "ku") { return base + " Ji bo tercimeyan beşa 'Werger' bi kar bîne!"; } return base; }, multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, // Builds one sense block (<li>): mane textarea, nimûne list, and // sub-lists for alternatîv/hevmane/dijmane/etc. buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Tercime + Îzah boxes (non-ku alternative to the plain mane box) — // Non-ku entries get a direct translation plus a {{îzah|…}}-wrapped // gloss instead of a Kurdish-style gloss. Rather than teach every // consumer (getSenses/getOutput/linkify) a second data shape, these // boxes just write their combined text into dfnArea and re-fire its // "input" event, so dfnArea stays the single source of truth. var tercimeArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-tercime-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-tercime") .attr("rows", 2) .attr("placeholder", "Tercimeyên rasterast ên kurmancî… Ji bo school-a îngilîzî li vir 'mekteb, medrese' binivîse"); var izahArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-izah-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-izah") .attr("rows", 3) .attr("placeholder", "Îzaha kurmancî… Ji bo school-a îngilîzî li vir 'cihê tehsîlgirtinê' binivîse"); var nonKuWrap = $("<div class='wiktku-dfn-nonku-wrap'></div>") .append(tercimeArea).append(izahArea) .hide(); function syncNonKuToMane() { var t = $.trim(tercimeArea.val()); var iz = $.trim(izahArea.val()); // if tercime is blank, use îzah as definition var combined = t ? (iz ? t + " {{îzah|" + iz + "}}" : t) : iz; dfnArea.val(combined); // Re-fires onDfnInput, as if this were typed directly into // the mane textarea. dfnArea.trigger("input"); } tercimeArea.on("input", syncNonKuToMane); izahArea.on("input", syncNonKuToMane); // Switches between the plain mane box and the tercime+îzah pair — // only for non-ku entries with no tplSelect selected. function updateManeMode() { var lang = getValues().lang || ""; var isTpl = !!tplSelect.val(); if (lang && lang !== "ku" && !isTpl) { dfnArea.hide(); nonKuWrap.show(); } else { nonKuWrap.hide(); if (!isTpl) dfnArea.show(); } } // Store on the block so refresh() can re-sync every block when // lang changes, and restoreDfn() can re-sync after restoring. block.data("updateManeMode", updateManeMode); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || {}; // Cache of all non-placeholder option elements, so updateTplOptions // can detach/re-attach them without losing the full list. var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.attr("data-placeholder", "Li şablonekê bigere"); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (name, tpl) { // Shows "name — tpl.desc" when a tplDefs entry has a desc // in data.json, same pattern as steps.pron's template picker. var opt = $("<option></option>") .val(name) .text(tpl.desc ? name + " — " + tpl.desc : name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); // Same status-dot / 🔗 / ⓘ row treatment as every other // template picker. This one carries the bare name in value=, // so the name mapper is the identity rather than a snippet // parse; descriptions come from each template's TemplateData. markTemplateOptions(tplSelect, function (opt) { return opt.val(); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible // ones — native <select> won't reliably hide options any other way. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); // Options that were detached when the descriptions arrived // missed that pass, so describe whatever is attached now. // The cache is warm by this point, so this is synchronous. applyTplDescriptions(tplSelect); tplSelect.trigger("wiktku:refresh"); if (currentVal && !currentStillValid) { tplSelect.val(""); tplTitleInput.hide().val(""); updateManeMode(); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpela hedefê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // Şablon senses have no plain gloss, so hide alternatîv/hevmane/ // dijmane/etc. Etîket, Nimûne and Jêgirtin stay visible either way. function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); nonKuWrap.hide(); tplTitleInput.show().focus(); } else { tplTitleInput.hide().val(""); updateManeMode(); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); // The template picker is an alternative to writing a // definition, not a step before it — so the box comes first // and this sits under it as a quiet link. It only expands // for the minority of senses that are a pointer at another // word (guharto, şaşnivîs, kevnbûyî) rather than a meaning. var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput) .hide(); var tplLink = $("<a href='#' class='wiktku-dfn-tpl-link'></a>") .text("Ev ne pênase ye — şablonek bi kar bîne"); tplLink.on("click", function (e) { e.preventDefault(); tplRow.show(); $(this).hide(); tplRow.find("input.wiktku-ac-input").first().focus(); }); /** Opens the picker without a click — used on restore, when a * sense already has a template and hiding it would make the * chosen value invisible. */ function revealTplRow() { tplRow.show(); tplLink.hide(); } block.data("revealTplRow", revealTplRow); block.append(dfnArea); block.append(nonKuWrap); block.append(tplLink); block.append(tplRow); // Apply lang filter on initial build. updateTplOptions(); updateManeMode(); // — Sub-field groups. — // The four most-used groups (Nimûne, Jêgirtin, Hevmane, Dijmane) // stay open; the rest sit behind the "Malûmatên pêşketî" toggle // (adv: true → .wiktku-dfn-subgroup-adv, keyed off by the collapse CSS). // Jêgirtin isn't in this array — it's a compound widget built // after the loop — but it's inserted right after Nimûne so the // visible order matches the list above. var allGroups = [ { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "wekî etîket lê xuya nabe tenê kategorîze dike", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê", adv: true }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in", adv: true }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e", adv: true }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e", adv: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); if (g.adv) groupDiv.addClass("wiktku-dfn-subgroup-adv"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } // The placeholder names the current language, but that's // often not chosen yet when this block is first built — // so keep a function around that refresh() (and onSubInput, // for newly-grown fields) can call again once lang is set // or changes. function subPlaceholder() { if (g.noLangSuffix) return g.label + "…"; var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return g.label + (langLabel ? " bi " + langLabel : "") + "…"; } function updateSubPlaceholders() { list.find("> li > textarea.wiktku-dfn-subfield").attr("placeholder", subPlaceholder()); } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": ") .append($("<span></span>").addClass("wiktku-dfn-sublabel-hint").text(g.izah)); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var useModifiers = !!MODIFIER_SUBGROUPS[g.cls]; list.data("updatePlaceholders", updateSubPlaceholders); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", subPlaceholder()); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow, useModifiers); }); list.append(useModifiers ? makeModifierLi(firstInput) : $("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder group — growing list, same structure as Nimûne. — (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text("Jêgirtin")) .append(": "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<textarea></textarea>") .addClass("wiktku-dfn-subfield wiktku-dfn-quote-citoid-input") .attr("rows", 1) .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi otomatîk tijî bike", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); // Fetches citation data from Citoid and fills this citation's // şablon + fields — only rebuilds fields on template change, // and never overwrites values the user already typed. function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoid.fetchJederFields(query).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only rebuild if switching şablon, so a repeat fetch // doesn't clear fields already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel wiktku-plain-select"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); srcSel.append($("<option></option>").val("__category__").text("Ji Kategorî:Çavkanî şablonekê hilbijêre")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); // Citoid is only useful before a source is chosen — // hide it once a selection is made, restore on reset. if (chosen) { citoidWrap.hide(); } else { citoidWrap.show(); return; } if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } if (chosen === "__category__") { // Search widget over the members of [[Kategorî:Çavkanî]]. // Picking a şablon here immediately switches the row to // "Bi destê xwe binivîsim" mode with {{Şablon}} pre-filled, var catWrap = $("<span></span>").addClass("wiktku-native-select-wrap wiktku-dfn-quote-src-cat"); var catInput = $("<input type='search' autocomplete='off'>") .addClass("wiktku-start-narrow wiktku-dfn-quote-src-cat-input") .attr("placeholder", "Li navê şablonê bigere…"); var catResults = $("<ul></ul>").addClass("wiktku-ac-results wiktku-dfn-quote-src-cat-results").hide(); var catStatus = $("<span></span>").addClass("wiktku-dfn-quote-src-cat-status").text("Şablon tên barkirin…"); var showCatResults = function (query) { var q = $.trim(query).toLowerCase(); catResults.empty(); var list = catSrcTemplates || []; var matched = q ? $.grep(list, function (name) { return name.toLowerCase().indexOf(q) !== -1; }) : list; if (!matched.length) { catResults.hide(); return; } $.each(matched.slice(0, 50), function (_, name) { var li = $("<li></li>").text(name).attr("data-value", name); var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; e.preventDefault(); selectCatTpl(name); }); li.on("mousedown", function (e) { e.preventDefault(); selectCatTpl(name); }); catResults.append(li); }); catResults.show(); }; // Wraps the chosen şablon as {{Name}}, drops it into the // manual textarea, and switches the row into manual mode // so the user can keep editing it (add params, etc.). var selectCatTpl = function (name) { catResults.hide(); srcSel.val("__manual__"); srcSel.trigger("change"); srcFields.find(".wiktku-dfn-quote-src-manual") .val("{{" + name + "}}") .trigger("focus"); }; catInput.on("input", function () { showCatResults($(this).val()); }); catInput.on("focus", function () { showCatResults($(this).val()); }); catInput.on("blur", function () { setTimeout(function () { catResults.hide(); }, 200); }); catWrap.append(catInput).append(catResults).append(catStatus); srcFields.append(catWrap); fetchCatSrcTemplates().then(function () { catStatus.text(""); }, function () { catStatus.text("Şablon nehatin barkirin."); }); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (key, label) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", key) .attr("placeholder", label + "…"); // "Sernav" / "Sernavê orjînal" (title fields, e.g. for // kitêb/kovar/malper) get a taller, draggable box; every // other field in the template stays as-is. Field labels // come from the on-wiki jederDefs data, so match on the // (diacritic-folded) label text rather than a fixed key. var foldedLabel = foldDiacritics(label); if (/^sernav$/.test(foldedLabel) || /orjin/.test(foldedLabel)) { inp.addClass("wiktku-dfn-quote-src-input--title"); } row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); jederGroupDiv.append(jederLbl).append(jederList); // Straight after Nimûne rather than last: Jêgirtin is the // same kind of thing (an attested use of the word) and the // two belong together — see the allGroups comment above. var nimuneGroup = block.find(".wiktku-dfn-nimune-group"); if (nimuneGroup.length) jederGroupDiv.insertAfter(nimuneGroup); else block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); // ── "Malûmatên pêşketî" — per sense, after Dijmane ─────── // One toggle per sense rather than one for the whole step: // the fields behind it (Etîket, Kategorî, Jornav…) belong to // a single meaning, so a global switch flipped them for every // sense at once and gave a count that answered "across all // senses" — not a question anybody was asking. (function () { block.addClass("wiktku-sense-adv-hidden"); var advRow = $("<div class='wiktku-adv-toggle-row wiktku-sense-adv-row'></div>"); var advToggle = $("<a href='#' class='wiktku-adv-toggle'></a>").attr("aria-expanded", "false"); var advLabel = $("<span class='wiktku-adv-toggle-text'></span>"); advToggle.append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")).append(advLabel); function syncAdv() { var hidden = block.hasClass("wiktku-sense-adv-hidden"); advLabel.text(hidden ? "Malûmatên pêşketî nîşan bide" : "Malûmatên pêşketî veşêre"); advToggle.attr("aria-expanded", hidden ? "false" : "true") .toggleClass("wiktku-adv-open", !hidden); } advToggle.on("click", function (e) { e.preventDefault(); block.toggleClass("wiktku-sense-adv-hidden"); syncAdv(); }); block.data("syncSenseAdv", syncAdv); advRow.append(advToggle); // After the last always-visible group (Dijmane) and before // the advanced ones, which sit below it in DOM order. var lastPrimary = block.find(".wiktku-dfn-dijmane-group"); if (lastPrimary.length) advRow.insertAfter(lastPrimary); else block.append(advRow); syncAdv(); }()); return block; }, /** Shows only `block` among the sense list; hides every other one. */ setOpenSense: function (stepDiv, block) { stepDiv.find("li.wiktku-dfn-sense").each(function () { $(this).toggleClass("wiktku-sense-collapsed", !$(this).is(block)); }); steps.dfn.renderSenseTabs(stepDiv); }, /** Rebuilds the "Mane 1 / Mane 2 / [trash] / + Mane zêde bike" tab row from the current sense list. */ renderSenseTabs: function (stepDiv) { var tabsDiv = stepDiv.find(".wiktku-dfn-sense-tabs"); if (!tabsDiv.length) return; tabsDiv.empty(); var blocks = stepDiv.find("li.wiktku-dfn-sense"); var openLi = null; blocks.each(function (i) { var li = $(this); var isOpen = !li.hasClass("wiktku-sense-collapsed"); if (isOpen) openLi = li; var tab = $("<span class='wiktku-dfn-sense-tab'></span>") .text("Mane " + (i + 1)) .toggleClass("wiktku-tab-active", isOpen); tab.on("click", function () { steps.dfn.setOpenSense(stepDiv, li); }); tabsDiv.append(tab); }); // One delete button for the whole bar — not one per tab — so // there's only ever a single, deliberate hit-target for a // destructive action, positioned away from the tabs people // click to switch senses. Always keep at least one Mane. if (blocks.length > 1 && openLi) { var openIdx = blocks.index(openLi); var trash = makeTrashButton("Vê maneyê jê bibe (Mane " + (openIdx + 1) + ")"); trash.on("click", function () { if (!window.confirm("Tu dixwazî Mane " + (openIdx + 1) + " jê bibî? Ev tişt nayê vegerandin.")) return; steps.dfn.removeSense(stepDiv, openLi); }); tabsDiv.append(trash.$element); } var addBtn = $("<button type='button' class='wiktku-add-sense'></button>") .append($("<span class='wiktku-add-sense-plus'>+</span>")) .append(document.createTextNode("Mane zêde bike")); addBtn.on("click", function (e) { e.preventDefault(); steps.dfn.addSense(stepDiv); }); tabsDiv.append(addBtn); }, onDfnInput: function (stepDiv, block, textarea) { refresh(); }, /** Appends a sense, opens it, and hides the others. */ addSense: function (stepDiv) { var list = stepDiv.find("ol.wiktku-dfn-list"); var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); initSelects(newBlock); steps.dfn.setOpenSense(stepDiv, newBlock); newBlock.find("textarea.wiktku-dfn-mane").first().focus(); refresh(); return newBlock; }, /** Removes one sense block. Assumes the caller already confirmed * and already checked more than one sense remains. If the * removed sense was the open one, opens whichever sense ends up * taking its place (or the last one, if it was the last). */ removeSense: function (stepDiv, li) { var list = stepDiv.find("ol.wiktku-dfn-list"); var blocks = list.find("li.wiktku-dfn-sense"); var removedIdx = blocks.index(li); var wasOpen = !li.hasClass("wiktku-sense-collapsed"); li.remove(); if (wasOpen) { var remaining = list.find("li.wiktku-dfn-sense"); var next = remaining.eq(removedIdx); if (!next.length) next = remaining.last(); if (next.length) steps.dfn.setOpenSense(stepDiv, next); } steps.dfn.renderSenseTabs(stepDiv); refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow, modifiers) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow, modifiers); }); list.append(modifiers ? makeModifierLi(next) : $("<li></li>").append(next)); // New field starts with no placeholder — give it (and any // others in the list) the current one. var updatePlaceholders = list.data("updatePlaceholders"); if (typeof updatePlaceholders === "function") updatePlaceholders(); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: {}, posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; // One reassurance, shown once for the whole Mane step: the // "an jî şablonek hilbijêre" dropdown inside each sense is // optional — plain text is the normal path. if (!stepDiv.find(".wiktku-dfn-tpl-hint").length) { stepDiv.append( $("<p class='wiktku-step-hint wiktku-dfn-tpl-hint'></p>").text( "Ji bo her maneyekê, dropdown-a \"an jî şablonek hilbijêre\" ne mecbûrî ye — bi gelemperî tu tenê maneyê bi tîpên asayî dinivîsî. Ew şablon tenê ji bo rewşên taybet in (mînak: guherto, kevnbûyî, şaşnivîs); heke tu nizanî kîjan divê, vale bihêle." ) ); } var tabsDiv = $("<div class='wiktku-dfn-sense-tabs'></div>"); stepDiv.append(tabsDiv); var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); steps.dfn.renderSenseTabs(stepDiv); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName === "__category__") { // Reachable only if the user opened the category search but // never picked a şablon — picking one switches the row to // __manual__ (see selectCatTpl above), so there's nothing // meaningful to save here. } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: readList("wiktku-dfn-etiket"), kategori: readList("wiktku-dfn-kategori"), nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense var izahLines = []; // parallel — raw îzah gloss for that same sense // True only once some sense's *actual* dfn text (post tercime/îzah // split) is non-empty. var hasLinkableMane = false; $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("# " + (tplKatTpl ? tplKatTpl + " " : "") + (tplLabelTpl ? tplLabelTpl + " " : "") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(""); // template senses have no îzah return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty // Pull the îzah gloss (if any) out of the combined tercime+îzah // string — it's spliced back in separately below, after its // own linkify pass (see izahLines / the second linkifyText call). var izahRaw = null; var tercimeIzah = splitTercimeIzah(dfn); if (tercimeIzah) { dfn = tercimeIzah.tercime; izahRaw = stripWikilinks(tercimeIzah.izah); } if (dfn) { dfn = stripWikilinks(dfn); // Sentence-case + trailing period are for ku definitions, // which are written as full glosses. if (lang === "ku") { if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } // Real prose — this is what makes the sense worth running // through the main linkify pass. hasLinkableMane = true; } else if (izahRaw === null) { // No mane at all — this is just the "{{mane?|lang}}" // placeholder, a bare template call with no plain words // in it. Do NOT count it as linkable: sending nothing but // bracketed templates through the main linkify pass hangs // the linkify gadget (see the hasLinkableMane/hasIzah // check below). dfn = lang === "ku" ? "{{mane?|" + lang + "}}" : ""; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var out = "# " + (katTpl ? katTpl + " " : "") + (labelTpl ? labelTpl + " " : "") + dfn; var idx = defLines.length; var hasThisIzah = izahRaw !== null && $.trim(izahRaw) !== ""; // Bare {{...}} token — like {{wiktku-cite-N}}, this survives // linkify's first pass untouched (it treats template calls as // opaque), then gets swapped for {{îzah|…}} once the actual // gloss text has been linkified in its own separate pass. if (hasThisIzah) { out += (dfn ? " " : "") + "{{wiktku-izah-" + idx + "}}"; } function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(hasThisIzah ? izahRaw : ""); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } // Runs text through the linkify gadget if it's loaded, otherwise // just passes it through unchanged. Shared by both linkify passes // below (main mane text, and — separately — îzah glosses). function linkifyText(t, cb) { if (typeof $.kuLinkify === "function") { $.kuLinkify(t, cb); } else { cb(t); } } var hasIzah = izahLines.some(function (t) { return t && $.trim(t) !== ""; }); var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with nimûne?. text = "# {{mane?|" + lang + "}}\n#* {{nimûne?|" + lang + "}}\n"; callback(text); return; } // Runs the îzah-only linkify pass against `base` (either the raw // text, when there's no linkable mane to run the main pass on // first, or the already-linkified main text). Shared by both // branches below so the token-splice logic only lives once. function runIzahPass(base) { var izahJoined = $.map(izahLines, function (raw, idx) { if (!raw) return undefined; return "{{wiktku-izah-open-" + idx + "}}" + raw + "{{wiktku-izah-close-" + idx + "}}"; }).join("\n"); linkifyText(izahJoined, function (izahLinked) { var izahByIdx = {}; var re = /\{\{wiktku-izah-open-(\d+)\}\}([\s\S]*?)\{\{wiktku-izah-close-\1\}\}/g; var m; while ((m = re.exec(izahLinked)) !== null) { izahByIdx[parseInt(m[1], 10)] = m[2]; } var withIzah = base.replace(/\{\{wiktku-izah-(\d+)\}\}/g, function (_, n) { var linked = izahByIdx[parseInt(n, 10)]; return linked !== undefined ? "{{îzah|" + linked + "}}" : ""; }); callback(restoreCites(withIzah)); }); } if (!hasLinkableMane) { if (!hasIzah) { // All filled senses are template senses (or otherwise have // no plain text at all) — nothing here needs linkify. callback(restoreCites(text)); return; } // There's no plain mane text anywhere (e.g. tercime left blank // with only îzah filled in), so every defLine is just a bare // template call with nothing to word-link. Sending a line // like "# {{wiktku-izah-0}}" through the main linkify pass // gives it no plain words to work with, makes the linkify // gadget hang — so skip that pass entirely and run only // the îzah pass, splicing straight into the unlinkified text. var loadIzahOnly = function () { runIzahPass(text); }; mw.loader.using("ext.gadget.linkify", loadIzahOnly, loadIzahOnly); return; } var didTryToLoad = function () { // First pass: the main definition text (mane), same as before. linkifyText(text, function (mainLinked) { if (!hasIzah) { callback(restoreCites(mainLinked)); return; } // Second pass: îzah glosses, linkified via their own // separate call. Each gloss is wrapped in its own // {{wiktku-izah-open/close-N}} pair; like the existing // {{wiktku-cite-N}} tokens, these sit inside double // braces so linkify leaves the tokens themselves alone — // only the raw gloss text between each pair gets linked. runIzahPass(mainLinked); }); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, tewandin: { id: "tewandin", name: "tewandin", question_fmt: 'Tewandina "' + pageName + '" binivîse', visible: function (values) { return values.lang && values.pos; }, build: function (stepDiv) { if (stepDiv.find(".wiktku-tewandin-wrap").length) return null; var wrap = $("<div class='wiktku-tewandin-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-tewandin-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-tewandin-text") .attr("rows", 4) .attr("placeholder", "{{ku-tewîn-nav|nêr}}"); wrap.append(ta); stepDiv.append(wrap); function autoPopulate() { if (!ta.length) return; var vals = getValues(); var c = vals.cinsiyet || ""; var p = vals.pos || ""; if (!pageName.includes(" ") && c && GENDER_BASE_LABELS[c] && (p === "navdêr" || p === "serenav") && vals.lang === "ku" && c !== "mndudil") { var label = (c === "mnmane") ? "mê û nêr" : GENDER_BASE_LABELS[c]; var out = "{{ku-tewîn-nav|" + label; if (p === "serenav") out += "|y"; out += "}}"; if (!$.trim(ta.val())) ta.val(out); } } setTimeout(function () { autoPopulate(); $("#wiktku-start-form").on("change.tewandin", "#wiktku-start-lang-field, #wiktku-start-cinsiyet-field, #wiktku-start-pos-field", autoPopulate); }, 0); return ta; }, output: function () { var manualText = $.trim($("#wiktku-start-tewandin .wiktku-tewandin-text").val()); if (manualText) { return "\n==== Tewandin ====\n" + manualText + "\n"; } return ""; } }, // resim — one or more images resim: { id: "resim", name: "resim", question_fmt: "Resmekê lê zêde bike", visible: function (values) { return !!(values.lang && values.pos); }, /** Builds one image row: filename + caption + alt text. */ buildItem: function (stepDiv) { var item = $("<li class='wiktku-resim-item'></li>"); var fileRow = $("<div class='wiktku-posparams-row'></div>"); var fileInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-file") .attr("placeholder", "navê_dosyayê.jpg"); fileRow.append($("<label></label>").text("Navê dosyayê: ")).append(fileInp); var capRow = $("<div class='wiktku-posparams-row'></div>"); var capInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-caption") .attr("placeholder", "Danasîna resimê…"); capRow.append($("<label></label>").text("Danasîn: ")).append(capInp); // Alt text: what a screen reader announces for this image var altRow = $("<div class='wiktku-posparams-row'></div>"); var altInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-alt") .attr("placeholder", "Ji bo kesên nabînin, çi tê dîtin? (ne mecbûrî)"); altRow.append($("<label></label>").text("Nivîsa alternatîf: ")).append(altInp); // Auto-fill the caption with the plain page name when a filename // is typed fileInp.on("input", function () { var file = $.trim($(this).val()); var curCap = $.trim(capInp.val()); var isDefault = !curCap || curCap === pageName; if (file && isDefault) { capInp.val(pageName); } else if (!file && isDefault) { capInp.val(""); } steps.resim.onFileInput(stepDiv, item, this); }); item.append(fileRow).append(capRow).append(altRow); return item; }, /** Grows the image list when the last row's filename gets content. */ onFileInput: function (stepDiv, item, input) { var val = $.trim($(input).val()); var list = stepDiv.find("ol.wiktku-resim-list"); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { list.append(steps.resim.buildItem(stepDiv)); } }, build: function (stepDiv) { if (stepDiv.find(".wiktku-resim-wrap").length) return null; var wrap = $("<div class='wiktku-resim-wrap'></div>"); var list = $("<ol class='wiktku-resim-list'></ol>"); list.append(steps.resim.buildItem(stepDiv)); wrap.append(list); stepDiv.append(wrap); return null; }, /** Reads every filled row from the DOM into an array of {file, caption, alt} * objects — blank rows (missing filename or caption) are skipped. * Non-Kurdish captions get wrapped in {{zim|lang|…}} here, unless * the user already typed their own {{zim|…}} template. Alt text is * optional and left as plain text either way. */ getImages: function (values) { var lang = (values && values.lang) || getValues().lang || ""; var images = []; $("#wiktku-start-resim li.wiktku-resim-item").each(function () { var file = $.trim($(this).find(".wiktku-resim-file").val()); var caption = $.trim($(this).find(".wiktku-resim-caption").val()); var alt = $.trim($(this).find(".wiktku-resim-alt").val()); if (!file || !caption) return; // Strip leading "Wêne:" or "File:" if the user typed it — we add it ourselves. file = file.replace(/^(wêne|file|image)\s*:\s*/i, ""); if (lang && lang !== "ku" && !/^\{\{zim\s*\|/i.test(caption)) { caption = "{{zim|" + lang + "|" + caption + "}}"; } images.push({ file: file, caption: caption, alt: alt }); }); return images; }, output: function (values) { var images = steps.resim.getImages(values); if (!images.length) return ""; return images.map(function (img) { var altPart = img.alt ? "|alt=" + img.alt : ""; return "[[Wêne:" + img.file + "|thumb" + altPart + "|" + img.caption + "]]"; }).join("\n") + "\n"; } }, // bnr-h — {{bnr-h|Page1|Page2|…}} prepended before the lang section (shared, not per-section) bnrh: { id: "bnrh", name: "binêre herwiha (bnr-h)", question_fmt: "Şablona bnr-h li qismê herî jor a rûpelê", //visible: function (values) { return !!values.lang; }, multiple: true, narrow: true, placeholder: "Ji bo 'test' bnr 'Test', 'teşt'", output: function (values) { var pages = $.grep(values.bnrh || [], function (p) { return !!$.trim(p); }); if (!pages.length) return ""; return "{{bnr-h|" + pages.map(function (p) { return $.trim(p); }).join("|") + "}}\n"; } }, bikaranin: { id: "bikaranin", name: "Notên bikaranînê", question_fmt: "Notên bikaranînê yên li ser vê kelîmeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, output: function (values) { var text = $.trim(values.bikaranin || ""); if (!text) return ""; return "\n==== Notên bikaranînê ====\n" + text + "\n"; }, }, xwendin: { id: "xwendin", name: "Bêhtir bixwîne", question_fmt: "Lînkên derveyî eleqedarî vê madeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: function (values) { if (!values || !values.lang) { return `* {{wpedî}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; } const ziman = values.lang === "ku" ? "" : `|ziman=${values.lang}`; return `* {{wpedî${ziman}}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; }, output: function (values) { var text = $.trim(values.xwendin || ""); if (!text) return ""; return "\n==== Bêhtir bixwîne ====\n" + text + "\n"; }, }, alfabeyendin: { id: "alfabeyendin", name: "Bi alfabeyên din", question_fmt: function (values) { var base = "Nivîsîna vê kelîmeyê bi alfabeyên din" var langLabel = values.lang ? getLangLabel(values.lang) : ""; if (langLabel) { return base + " ên " + langLabel; } return base; }, visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: "Ji bo kurmancî: * {{ku-ar|şiklê alfaba erebî}}", output: function (values) { var text = $.trim(values.alfabeyendin || ""); if (!text) return ""; return "\n==== Bi alfabeyên din ====\n" + text + "\n"; }, }, formalt: makeWordListStep("formalt", "formên alternatîv", "Formên alternatîv ên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), hevmane: makeWordListStep("hevmane", "hevmane", "Hevmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), dijmane: makeWordListStep("dijmane", "dijmane", "Dijmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jornav: makeWordListStep("jornav", "jornav", "Jornavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jernav: makeWordListStep("jernav", "jêrnav", "Jêrnavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse"), binereherwiha: makeWordListStep("binereherwiha", "herwiha binêre", "Kelîmeyên din ên eleqedar binivîse"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: {}, visible: function (values) { return values.lang && values.pos; }, // Fills the insert-dropdown from the current etymTpls object. refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(ta); stepDiv.append(wrap); initSelects(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder. // Skip it only when every filled sense is a şablon sense // a completely empty entry with no şablon chosen still gets the placeholder var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasFilledTplSense = dfnSenses.some(function (s) { return !!s.tpl && !!s.tplTitle; }); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (hasFilledTplSense && !hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: function (values) { return {"navz": true, [values.lang]: true} }, // Language dropdown + growing word-input list; a new row appends // when the dropdown gets a value. Mirrors steps.trans, but flat. buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/build below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Attach the searchable picker now the select is in the DOM. initSelects(list); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", question_fmt: "'"+ pageName + "' di zaravayên din de çawa tê gotin?", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: {}, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zaravayekî bigere"); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; // A completely empty entry still gets a placeholder section // to fill in later; an individual placeholder gloss is only // skipped once some other sense already has real content. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", question_fmt: "Tercimeyên vê maneyê bi zimanên din binivîse", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide only when every sense is a filled template sense (no plain // gloss to attach translations to). A mix, or nothing filled in // yet, still shows Werger. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, // Language dropdown + growing word-input list, scoped to one gloss's // group (each gloss has its own group and row list). buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/buildGroup below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, // Builds (or fetches) the .wiktku-trans-group for one gloss. buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, // Syncs one .wiktku-trans-group per current gloss, keyed by // data-gloss-pos so groups stay matched across rebuilds. build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, // Reads all translation rows, grouped by gloss position. getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, // Builds the numbered "{ index, gloss }" list, one per dfn sense // with a real mane (skips template senses). index is 1-based and // matches the sense's position in the "#" definition list. // When nothing's filled in, returns one placeholder entry so // Werger still has a group to attach to; when every sense is a // filled template sense, stays empty (matches trans.visible()). glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane, but other fields are filled — still gets a // gloss group since dfn.getOutput() emits {{mane?}} for it. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // A completely empty entry (nothing filled in dfn at all, no // şablon chosen either) still gets a placeholder Werger section // to fill in later. Only // skip an individual placeholder gloss below when some other // sense actually has real content, making that particular // placeholder redundant. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it. If some other sense already has real // content, this placeholder is redundant — skip it. If the // whole entry is empty, keep it so Werger still gets a // section to fill in. if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, cavkani: { id: "cavkani", name: "çavkanî", question_fmt: "Çavkaniyên din (ne jêgirtin) lê zêde bike", visible: function (values) { return !!values.pos; }, // Fills the insert-dropdown from the members of [[Kategorî:Çavkanî]]. refreshTplSelect: function () { var sel = $("#wiktku-start-cavkani .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(catSrcTemplates || [], function (_, name) { sel.append($("<option></option>").val(name).text(name)); }); markTemplateOptions(sel, function (opt) { return opt.val(); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-cavkani-wrap").length) return null; var wrap = $("<div class='wiktku-cavkani-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-cavkani-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-cavkani-text") .attr("rows", 4) .attr("placeholder", "Şablonekî ji lîsteyê hilbijêre an rasterast binivîse…"); // Template insert dropdown, populated from [[Kategorî:Çavkanî]] — // options refreshed once the category members are fetched. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var status = $("<span class='wiktku-cavkani-status'></span>"); sel.on("change", function () { var name = $(this).val(); if (!name) return; insertAtCursor(ta[0], "\n* {{" + name + "}}"); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(status).append(ta); stepDiv.append(wrap); // build() runs again for every new beş (see the "+ Beş zêde bike" // handler), after the initial page-wide pass — so this select needs // its own init or it stays a plain, unsearchable native <select>. initSelects(wrap); if (catSrcTemplates) { steps.cavkani.refreshTplSelect(); } else { status.text("Şablon tên barkirin…"); fetchCatSrcTemplates().then(function () { steps.cavkani.refreshTplSelect(); status.text(""); }, function () { status.text("Şablon nehatin barkirin."); }); } return ta; }, output: function () { var text = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); if (!text) return ""; return "\n==== Çavkanî ====\n" + text + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); // This array only controls DOM build order — nothing else keys off it // (see the comment above stepIdToGroup). Mane tab order: Mane (senses, // with malûmatên pêşketî nested inside each, see steps.dfn.build) → // Wêne → Bi zaravayên din → Werger, so dfn/resim/zarava/trans sit // adjacent to each other in that order. var ordered_steps = [ steps.lang, steps.pos, steps.posparams, steps.cinsiyet, steps.jimar, steps.lektur, steps.tr, // Mane tab, in reading order: the senses, then the two things that // belong to the entry as a whole rather than to one sense. steps.dfn, steps.tewandin, steps.alfabeyendin, steps.zarava, steps.trans, // Etîmolojî tab. steps.etym, steps.dunde, // Eleqedar tab — three lists of the same shape. steps.je, steps.tekildar, steps.binereherwiha, // Bilêvkirin isn't part of any STEP_GROUPS tab, but still needs a // slot here because this array is what builds the DOM. steps.pron, // Beşên din fields — behind the picker inside the Eleqedar tab. steps.resim, steps.bnrh, steps.bikaranin, steps.formalt, steps.hevmane, steps.dijmane, steps.jornav, steps.jernav, steps.cavkani, steps.xwendin]; // ── Step-group tabs ────────────────────────────────────────────────────── // Three tabs: "Mane" holds the senses (whose own blocks carry Nimûne, // Jêgirtin, Hevmane and Dijmane — see steps.dfn.allGroups), Tewandin, // alfabeyendin, zarava and trans; "Etîmolojî" splits out that topical // cluster; "Eleqedar" holds je/tekildar/binereherwiha plus — behind the // "Beşên din" picker, which lives inside this tab rather than as its // own — everything else (resim, formalt, hevmane, dijmane, jornav, // jernav, bikaranin, cavkani, xwendin, bnrh). A newly-picked section is // inserted right after the picker (see renderBesenDinPicker()), which // sits above je/tekildar/binereherwiha in the DOM — so picking one // pushes those down rather than the other way around. "mane" stays // first as the default-active tab since Mane is required content. // Tewandin keeps its own free-text {{ku-tewîn-nav}} field and does NOT // absorb the Cins/zayend form parameters (m=/n=/p=), which stay on the // headword template. // Steps that live behind the "Beşên din" picker inside Eleqedar — only // these need an explicit "open" before they're shown, even once // Eleqedar's tab is active. var BESENDIN_STEP_IDS = ["resim", "formalt", "hevmane", "dijmane", "jornav", "jernav", "bikaranin", "cavkani", "xwendin", "bnrh"]; var STEP_GROUPS = [ { id: "mane", label: "Mane", steps: ["dfn", "tewandin", "alfabeyendin", "zarava", "trans"] }, { id: "etimoloji", label: "Etîmolojî", steps: ["etym", "dunde"] }, { id: "eleqedar", label: "Eleqedar", steps: ["je", "tekildar", "binereherwiha"].concat(BESENDIN_STEP_IDS) }, ]; // Reverse lookup: step id -> index into STEP_GROUPS (undefined for // ungrouped steps — now only lang/pos/posparams/cinsiyet/lektur/tr, // which stay always-visible since they're required to get to everything // else). var stepIdToGroup = {}; $.each(STEP_GROUPS, function (gi, g) { $.each(g.steps, function (_, sid) { stepIdToGroup[sid] = gi; }); }); // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "posparams", "cinsiyet", "jimar", "lektur", "tr", "resim", "dfn", "tewandin", "formalt", "bikaranin", "alfabeyendin", "hevmane", "dijmane", "jornav", "jernav", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans", "cavkani", "xwendin" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; // ── Bilêvkirin as a standalone section ─────────────────────────────── // Pronunciation belongs to the word, not to one part of speech, so it // sits beside Navdêr/Lêker in the tab bar rather than inside any of them. // Modelled as a flag rather than an entry in `sections` since // activeSection is used as an array index in many places — viewing // Bilêvkirin leaves activeSection pointing at the POS section you were on. var viewingPron = false; // is it the tab currently on screen // Which STEP_GROUPS tab is currently shown. Lives out here (like // activeSection above) so refresh() — which is not nested inside build() // — can read it and so renderGroupTabs()/updateGroupTabIndicators() below // can be called from refresh() too. Both operate on the tab bar via its // #wiktku-group-tabs id rather than a closured element reference, for the // same reason. var activeGroup = 0; // Unsaved-changes / autosave state. Lives out here (same reason as // activeGroup above) so destroy() — which runs on final submit and on // switching to the source editor, and is not nested inside build() — // can clear the timers and the beforeunload warning. build() assigns // into these; it doesn't re-declare them. var formDirty = false; var autosaveDebounceTimer = null; var autosaveInterval = null; /** Re-renders the step-group tab bar to reflect the current activeGroup. */ function renderGroupTabs() { var groupTabsDiv = $("#wiktku-group-tabs"); if (!groupTabsDiv.length) return; groupTabsDiv.empty(); $.each(STEP_GROUPS, function (i, g) { var tab = $("<span></span>") .addClass("wiktku-group-tab") .attr("data-group-idx", i) .text(g.label) .toggleClass("wiktku-tab-active", i === activeGroup); (function (idx) { tab.on("click", function () { if (idx === activeGroup) return; activeGroup = idx; renderGroupTabs(); if (idx === ELEQEDAR_GROUP_IDX) renderBesenDinPicker(); refresh(); // Switching tabs can shorten the page (e.g. leaving a long // "Beşên din" field), and the browser may clamp the scroll // position on its own timing before our measurement runs. // Deferring one frame lets that settle first, so the // offsetTop read below is the final, post-refresh one. window.requestAnimationFrame(function () { var bar = document.getElementById("wiktku-group-tabs"); if (!bar) return; var form = document.getElementById("wiktku-start-form"); var stabsH = form ? (parseFloat(form.style.getPropertyValue("--wiktku-stabs-h")) || 0) : 0; var siteHeaderH = form ? (parseFloat(form.style.getPropertyValue("--wiktku-siteheader-h")) || 0) : 0; var top = bar.getBoundingClientRect().top + window.pageYOffset - stabsH - siteHeaderH; $("html, body").animate({ scrollTop: Math.max(0, top) }, 200); }); }); }(i)); groupTabsDiv.append(tab); }); } /** * Toggles a "needs attention" dot on any group tab that still has a * required, unfilled field hidden inside it — so switching tabs doesn't * leave the person wondering why "Bişîne" stays disabled. */ function updateGroupTabIndicators(values) { var tabs = $("#wiktku-group-tabs .wiktku-group-tab"); if (!tabs.length) return; $.each(STEP_GROUPS, function (i, g) { var missing = false; $.each(g.steps, function (_, sid) { var step = steps[sid]; if (!step || !step.required) return; var val = values[sid]; if (val === "" || (step.multiple && $.isArray(val) && val.join("") === "")) { missing = true; } }); tabs.eq(i).toggleClass("wiktku-tab-missing", missing && i !== activeGroup); }); } // "Beşên din" reveals one field at a time via a picker rather than // stacking them all. Per-section state, snapshotted in // saveCurrentSection() and restored in restoreSection() below, and // auto-seeded from any field that already has content (so a returning // draft doesn't hide something already filled in). var openedOtherSections = {}; var BESENDIN_SET = {}; $.each(BESENDIN_STEP_IDS, function (_, sid) { BESENDIN_SET[sid] = true; }); // "eleqedar"'s index in STEP_GROUPS — the Beşên din picker now renders // inside this tab rather than having its own. Derived rather than // hardcoded — this was once a literal 2 and silently pointed at the // wrong tab the moment Etîmolojî and Eleqedar were reordered. var ELEQEDAR_GROUP_IDX = (function () { for (var i = 0; i < STEP_GROUPS.length; i++) { if (STEP_GROUPS[i].id === "eleqedar") return i; } return STEP_GROUPS.length - 1; }()); /** Re-renders the "Beşên din" picker to list only the not-yet-opened sections. */ function renderBesenDinPicker() { var wrap = $("#wiktku-besendin-picker"); if (!wrap.length) return; wrap.empty(); var pickerValues = getValues(); var unopened = $.grep(BESENDIN_STEP_IDS, function (sid) { if (openedOtherSections[sid]) return false; // Don't offer a section that would open onto nothing: several of // these are gated (Bi zaravayên din / Werger need lang=ku, most // need a pos). refresh() would hide it again straight away, so // picking it would read as a broken dropdown. var step = steps[sid]; if (step && typeof step.visible === "function") { try { if (!step.visible(pickerValues)) return false; } catch (e) { /* a step whose visible() needs DOM we lack yet — offer it */ } } return true; }); if (!unopened.length) return; // everything's open — nothing left to pick var sel = $("<select class='wiktku-besendin-select'></select>"); sel.attr("data-placeholder", "— beşek hilbijêre —"); sel.append($("<option value=''>— beşek hilbijêre —</option>")); $.each(unopened, function (_, sid) { var step = steps[sid]; if (!step) return; sel.append($("<option></option>").val(sid).text(capitalize(step.name))); }); sel.on("change", function () { var sid = $(this).val(); if (!sid) return; openedOtherSections[sid] = true; // Newly opened section moves right under the picker, ahead of // whatever's already open, instead of wherever it happened to // sit in the fixed step order. $("#wiktku-start-" + sid).insertAfter(wrap); renderBesenDinPicker(); refresh(); }); wrap.append(sel); initSelects(wrap); } /** Marks any BESENDIN_STEP_IDS field that already has real content as * "opened", so restoring a draft doesn't bury filled-in sections behind * the picker. Reuses each step's own output() as the emptiness check — * it already knows what "empty" means per field, and it reads the DOM * the restore just populated. Call this AFTER the DOM has the restored * values in it. */ function seedOpenedFromContent() { var values = getValues(); $.each(BESENDIN_STEP_IDS, function (_, sid) { if (openedOtherSections[sid]) return; var step = steps[sid]; if (!step || typeof step.output !== "function") return; try { if (step.output(values)) openedOtherSections[sid] = true; } catch (e) { /* a step whose output() needs more state than we have yet — skip it */ } }); } function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } // Rebuilds the dfn DOM from a previously snapshotted senses array. function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing tab bar + list so build() recreates them cleanly. stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); // The picker is collapsed behind a link by default; a restored // sense that already uses a template has to show it, or the // chosen template is invisible and looks lost. var reveal = block.data("revealTplRow"); if (typeof reveal === "function") reveal(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // dfnArea is the only thing actually saved, so split it back into // tercime/îzah for editing (mirrors syncNonKuToMane's join format). var maneParts = splitTercimeIzah(sense.mane); block.find(".wiktku-dfn-tercime").val(maneParts ? maneParts.tercime : (sense.mane || "")); block.find(".wiktku-dfn-izah").val(maneParts ? maneParts.izah : ""); // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Same for the mane-box mode (plain vs tercime+îzah), since this // also depends on tplSelect's (and lang's) value. var updateMane = block.data("updateManeMode"); if (updateMane) updateMane(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found var useModifiers = !!MODIFIER_SUBGROUPS[cls]; // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true, useModifiers); }); subList.append(useModifiers ? makeModifierLi(ta) : $("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text).each(function () { highlightLinebreak(this); }); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder entries — accepts current array shape or a legacy // single object (older saved sections) for backwards compat. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote).each(function () { highlightLinebreak(this); }); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederCatTpl) { // Legacy format from before the şablon search switched rows to // manual mode directly — convert it the same way now, so it's // editable like any other free-form source. var catSelEl = li.find(".wiktku-dfn-quote-src-sel"); catSelEl.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val("{{" + j.jederCatTpl + "}}"); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); // Restoring a draft opens the first sense's tab by default. steps.dfn.setOpenSense(stepDiv, list.find("li.wiktku-dfn-sense").first()); } // Snapshots simple (non-dfn) per-section steps from the DOM into obj. function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } if (id === "cavkani") { snap.cavkani = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); return; } if (id === "posparams") { snap.posparams = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); return; } if (id === "resim") { // One entry per row, including blank ones, so a mid-edit draft // (e.g. a filename typed but no caption yet) survives a cache // restore instead of being silently dropped. snap.resim = $("#wiktku-start-resim li.wiktku-resim-item").map(function () { return { file: $.trim($(this).find(".wiktku-resim-file").val()), caption: $.trim($(this).find(".wiktku-resim-caption").val()), alt: $.trim($(this).find(".wiktku-resim-alt").val()) }; }).get(); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); // Which "Beşên din" sub-sections this section has already opened // via the picker — per-section, like everything else here. snap.openedOtherSections = $.extend({}, openedOtherSections); sections[activeSection] = snap; } // Restores a previously saved snapshot into the form DOM. function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); $("#wiktku-start-cavkani .wiktku-cavkani-text").val(snap.cavkani || ""); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); steps.posparams.build(ppDiv); var savedTa = snap.posparams || ""; ppDiv.find(".wiktku-posparams-text").val(savedTa); // Re-parse saved textarea to restore helper widget states. if (savedTa) { var cMatch = savedTa.match(/\|c=([^|}\s]+)/); var jMatch = savedTa.match(/\|j=([^|}\s]+)/); var trMatch = savedTa.match(/\|tr=([^|}\s]+)/); // Write into the shared hidden field (not the visible // select, which has no <option>s yet) — syncHelpers() // below reads it back to restore the dropdown once the // gender/number options for this language are populated. if (cMatch) $("#wiktku-start-cinsiyet-field").val(cMatch[1]); if (jMatch) $("#wiktku-start-jimar-field").val(jMatch[1]); if (trMatch) ppDiv.find(".wiktku-posparams-field[data-pp-key='tr']").val(trMatch[1]); // For lêker, c= holds the verb-type code instead of a // gender — split it back across the two dropdowns it is // now assembled from ("x-gh" → form "x" + base "gh"). if (cMatch && /^lêker/.test(snap.pos || "")) { var lekturParts = /^(?:([xphb])-)?(n?gh)$/.exec(cMatch[1]); if (lekturParts) { ppDiv.find(".wiktku-posparams-lektur-sel").val(lekturParts[2]); ppDiv.find(".wiktku-posparams-lekturform-sel").val(lekturParts[1] || ""); } } // Restore checked optional params. "form" is stored as // "erê" rather than "1" (see rebuildTa), so it needs its // own check here. ppDiv.find(".wiktku-posparams-opt-panel input[type='checkbox']").each(function () { var key = $(this).val(); var expected = key === "form" ? "erê" : "1"; $(this).prop("checked", savedTa.indexOf("|" + key + "=" + expected) !== -1); }); } steps.posparams.syncHelpers(ppDiv); return; } if (id === "resim") { var resimDiv = $("#wiktku-start-resim"); resimDiv.find(".wiktku-resim-wrap").remove(); steps.resim.build(resimDiv); // Accept both the new array-of-rows format and the older // single {file, caption} object saved before multi-image // support existed. var resimSnap = snap.resim; var rows = $.isArray(resimSnap) ? resimSnap : (resimSnap ? [resimSnap] : []); if (rows.length) { var list = resimDiv.find("ol.wiktku-resim-list"); list.empty(); $.each(rows, function (_, r) { var item = steps.resim.buildItem(resimDiv); item.find(".wiktku-resim-file").val(r.file || ""); item.find(".wiktku-resim-caption").val(r.caption || ""); item.find(".wiktku-resim-alt").val(r.alt || ""); list.append(item); }); // Always keep a blank trailing row, same as Nimûne/Dûnde. var lastItem = list.children("li.wiktku-resim-item").last(); if ($.trim(lastItem.find(".wiktku-resim-file").val())) { list.append(steps.resim.buildItem(resimDiv)); } } return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Tell the pickers about the programmatic value change. fields.filter("select").trigger("wiktku:refresh"); }); // Restore which "Beşên din" sub-sections were already opened for // this section, then seed in anything the DOM restore above just // filled in but that wasn't marked opened yet. openedOtherSections = $.extend({}, snap.openedOtherSections || {}); seedOpenedFromContent(); renderBesenDinPicker(); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); // Bilêvkirin is NOT emitted here — it is one shared field for the // whole word, so emitting it per section duplicated it. getWikitext() // prints it once, above the POS sections. steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.tewandin.output(values); entry += steps.bikaranin.output(values); entry += steps.alfabeyendin.output(values); entry += steps.formalt.output(values); entry += steps.hevmane.output(values); entry += steps.dijmane.output(values); entry += steps.jornav.output(values); entry += steps.jernav.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); entry += steps.cavkani.output(values); entry += steps.xwendin.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { // Each hop through here can be reached asynchronously: the dfn // step waits on mw.loader.using("ext.gadget.linkify") before // calling back, so from that point on the submit handler's own // try/catch is no longer on the stack. Guard every hop instead, // or a throw after linkify loads vanishes into an unhandled // rejection and the form just sits there looking busy. try { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } catch (e) { if (typeof onSubmitError === "function") onSubmitError(e); else throw e; } } processSection(0); } // Assembles wikitext for all sections plus the shared lang header. function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var bnrh = steps.bnrh.output(sharedValues); var entry = steps.lang.output(sharedValues); // One pronunciation per word, printed once between the language // header and the POS sections — see steps.pron.output. entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // bnr-h goes before the language section — only prepended when // generating fresh wikitext (not addLangMode, which handles it separately). if (!addLangMode && bnrh) entry = bnrh + entry; // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { if (s.mane) return s.mane; // Template sense (e.g. {{guharto|ku|somepage}}) — same // construction as the tplCall built in getOutput, so the // summary shows what actually gets written to the entry // instead of going blank. if (s.tpl && s.tplTitle) { return s.tplNoLang ? "{{" + s.tpl + "|" + s.tplTitle + "}}" : "{{" + s.tpl + "|" + sharedValues.lang + "|" + s.tplTitle + "}}"; } return ""; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; // Set by build() to its submitFailed(). Lives out here because the // wikitext-assembly functions below are outside build()'s closure but // still need a way to report a failure to the person rather than dying // silently in the console. var onSubmitError = null; // Whether Mane/Bi zaravayên din/Werger has anything in it — kept // outside refresh() so the click handler can read the latest value. var wiktkuContentGateOk = true; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues, placeholderText) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>").text(placeholderText || "")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice.label); if (choice.sortKey !== undefined) { // This is a language choice {code, label, sortKey} — show code. displayText = capitalize(choice.label) + " (" + choice.code + ")"; } var option = $(mw.html.element("option", { value: choice.code }, displayText)); if (disabledValues[choice.code]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } // Keys to disable for a key menu: already-taken or explicitly disabled. function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); populateMenus(input, step.keys, getDisabledKeys(step)); // Keep the key menus mutually exclusive: whatever one row selects is // disabled in every other row. Recomputed from the DOM on each change. input.on("change", function () { var all = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield"); var taken = {}; all.each(function () { var v = $(this).val(); if (v) taken[v] = true; }); all.not(this).each(function () { var self = $(this), own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (code) $(this).prop("disabled", !!taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }); // Return the wrapper; the select lives inside it and still fires change. return wrapNativeSelect(input); } // Adds another text field to the list if the last one now has text. function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); if (step.placeholder) { nextInput.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = step.modifiers ? makeModifierLi(nextInput).prepend(nextKeyInput || "") : $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) initSelects(nextItem); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } // Shows/hides steps based on whether their prerequisites are met, and // updates placeholders where applicable. function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); steps.cavkani.refreshTplSelect(); // Re-render any step's question label that depends on current values // (e.g. dfn's Werger-section reminder, which only applies to ku). $.each(steps, function (stepId, step) { if (typeof step.question_fmt === "function") { $("#wiktku-start-" + stepId + " .wiktku-start-step-question") .text(step.question_fmt(values)); } }); // Sync every sense block's mane-box mode (plain mane vs tercime+îzah) // to the current language, in case lang changes after blocks exist. $("#wiktku-start-dfn li.wiktku-dfn-sense").each(function () { var updateMane = $(this).data("updateManeMode"); if (updateMane) updateMane(); }); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Re-sync the "<label> bi <ziman>…" placeholder on every always-visible // sub-field list (etîket, kategorî, hevmane, …), since the language may // not have been chosen yet when these lists were first built, or may // have changed since. $("#wiktku-start-dfn .wiktku-dfn-sublist").each(function () { var upd = $(this).data("updatePlaceholders"); if (typeof upd === "function") upd(); }); // Same idea for word-list steps (jê, têkildar, binêre herwiha, …) // whose placeholder is a function of the current language. $.each(steps, function (stepId, step) { if (typeof step.placeholder === "function") { $("#wiktku-start-" + stepId + " textarea.wiktku-start-step-field") .attr("placeholder", step.placeholder()); } }); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // Insert after the quote textarea's resize-wrap (if the manual // resize handle has already been attached to it), not after the // bare textarea -- otherwise this lands *inside* that wrap, // between the textarea and its own grip, breaking jêgirtin's // handle and nesting the tr/t boxes inside it. var quoteTa = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap = quoteTa.closest(".wiktku-resize-wrap"); (quoteResizeWrap.length ? quoteResizeWrap : quoteTa).after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // See the tr-field branch above for why this targets the // resize-wrap instead of the bare textarea. var quoteTa2 = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap2 = quoteTa2.closest(".wiktku-resize-wrap"); (quoteResizeWrap2.length ? quoteResizeWrap2 : quoteTa2).after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { var groupIdx = stepIdToGroup[stepId]; var hiddenByTab = (groupIdx !== undefined && groupIdx !== activeGroup) || // Beşên din picker: stays hidden even while its tab is // active until explicitly opened from the dropdown. (BESENDIN_SET[stepId] && !openedOtherSections[stepId]); // Bilêvkirin is its own section now, so the two views are // mutually exclusive: on it, only pron shows (plus Ziman, which // is shared and stays above every section); off it, pron is // hidden no matter which tab is active. pron is deliberately // ungrouped — stepIdToGroup has no entry for it — so without // this branch it would show on all four tabs at once. if (stepId === "pron") { hiddenByTab = hiddenByTab || !viewingPron; } else if (viewingPron && stepId !== "lang") { hiddenByTab = true; } if (hiddenByTab || (typeof(step.visible) === "function" && !step.visible(values))) { $("#wiktku-start-" + stepId).hide(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } // After build, sync the posparams helper widgets whenever pos or lang changes. if (step.id === "posparams" && typeof step.syncHelpers === "function") { step.syncHelpers(stepDiv); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } stepDiv.slideDown(); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); // The three content tabs belong to a POS section — Bilêvkirin has no // sub-tabs of its own, so the bar goes away while it's on screen. $("#wiktku-group-tabs").toggle(!!values.pos && !viewingPron); var besenDinActive = activeGroup === ELEQEDAR_GROUP_IDX && !viewingPron; $("#wiktku-besendin-picker").toggle(besenDinActive); // The option list is filtered by each step's visible(), which depends // on lang/pos — so it has to be rebuilt when those change, not just // when a section is opened. Safe to call from here: rendering the // picker doesn't itself call refresh(), only picking an option does. if (besenDinActive) renderBesenDinPicker(); updateGroupTabIndicators(values); continueBtn.setDisabled(!canContinue); // Soft gate: stays a real, clickable OOUI button — a hard // setDisabled(true) here would swallow the click entirely, leaving // no way to tell the person why nothing happened. The CSS-only // "looks disabled" class lets the click handler still run and show // wiktkuNotify's explanation. wiktkuContentGateOk = !canContinue || hasMinRequiredContent(values); continueBtn.$element.toggleClass("wiktku-btn-soft-disabled", !wiktkuContentGateOk); } function destroy() { if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); if (autosaveInterval) clearInterval(autosaveInterval); formDirty = false; $(window).off("beforeunload.wiktkuUnsaved"); $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard").slideDown(); // #editform was kept laid-out but off-screen (see build()) instead of // display:none, precisely so the editor never had to size itself // against a zero-width/height box. Just bring it back on-screen — // no slideDown needed since it was never actually collapsed. $("#editform").removeClass("wiktku-offscreen"); // Belt-and-braces: if WikiEditor/CodeMirror/mobile's auto-grow still // cached a stale size from some earlier point, nudge them to // recalculate now that the box is genuinely visible. $(window).trigger("resize"); if (window.CodeMirror) { var cm = $("#wpTextbox1").data("CodeMirror") || $("#wpTextbox1").data("cmInstance"); if (cm && typeof cm.refresh === "function") cm.refresh(); } $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and navz. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; // Inserts a new "== {{ziman|code}} ==" section at the correct sorted // position: navz, then ku/hac/sdh/lki/ckb/zza, then alphabetical by name. function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections — just write the new section. // Add \n\n only when there is real non-whitespace content above. var trimmed = existing.replace(/\s+$/, ""); return trimmed ? trimmed + "\n\n" + wikitext : wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // (?![\s\S]) matches only true end-of-string, since a bare "$" with // /m would stop at the section's first line break instead. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections, each separated by exactly \n\n. // Trim trailing whitespace off each section's content first so we // control the spacing precisely. var joined = sections.map(function (s) { return s.content.replace(/\s+$/, ""); }).join("\n\n"); // Only add a separator after the preamble when it has real content. var preambleTrimmed = preamble.replace(/\s+$/, ""); var prefix = preambleTrimmed ? preambleTrimmed + "\n\n" : ""; return prefix + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê zimanekî nû li rûpelê îlawe bikî. Eger ev ziman jixwe hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bike, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Muhtewaya rûpelê paqij bike (her tiştî jê bibe û rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); // Tab bar for switching between step-groups (topics) within a section. // renderGroupTabs()/updateGroupTabIndicators() (which populate and // maintain it) live outside build() — see near "var activeSection". var groupTabsDiv = $("<div id='wiktku-group-tabs'></div>"); // Both tab bars are sticky (CSS). group-tabs' sticky "top" has to sit // right below section-tabs' actual rendered height, which isn't a // fixed number since the bar can wrap onto a second line. Measured // here and published as a CSS custom property the stylesheet reads // back; recomputed on content changes and window resize. // // Vector 2022 has its own sticky header (.vector-sticky-header) that // pins to the real top:0 once you scroll past the page title, which // would otherwise sit directly behind (and hide) our section-tabs. // Fixed by measuring how much of the viewport Vector's header // currently occupies and offsetting both our bars below it, via // --wiktku-siteheader-h. Vector's header slides in/out with scroll // position, so this is re-measured on scroll too, not just resize. function siteHeaderOffset() { var el = document.querySelector(".vector-sticky-header"); if (!el) return 0; var rect = el.getBoundingClientRect(); // Present in the DOM at all times on Vector 2022, but only // actually occupying screen space once scrolled into place — // before that it sits translated above the viewport (negative/ // zero rect), which must not add a phantom gap under our bars. if (rect.bottom <= 0 || rect.top > 4) return 0; return Math.max(0, rect.bottom); } var stickyOffsetQueued = false; function syncStickyTabsOffset() { var h = sectionTabsDiv.is(":visible") ? (sectionTabsDiv.outerHeight() || 0) : 0; startForm.css("--wiktku-stabs-h", h + "px"); startForm.css("--wiktku-siteheader-h", siteHeaderOffset() + "px"); } function queueStickyTabsOffsetSync() { if (stickyOffsetQueued) return; stickyOffsetQueued = true; window.requestAnimationFrame(function () { stickyOffsetQueued = false; syncStickyTabsOffset(); }); } $(window).on("resize.wiktkuStickyTabs scroll.wiktkuStickyTabs", queueStickyTabsOffsetSync); // "Beşên din" picker — sits right under the group tab bar, only // shown while the Eleqedar tab is active (toggled in refresh(), see // ELEQEDAR_GROUP_IDX); renderBesenDinPicker() fills it. var besenDinPickerDiv = $("<div id='wiktku-besendin-picker' class='wiktku-besendin-picker'></div>"); /** Puts the form back in a usable state after a failed submit and * says what happened. Without this the button stays disabled and * the spinner spins forever on any exception — the person is left * staring at a form that looks busy but is dead, with the reason * visible only in the browser console. */ function submitFailed(err) { spinner.hide(); continueBtn.setDisabled(false); continueBtn.$element.removeClass("wiktku-btn-sending"); var detail = (err && (err.message || err.toString())) || "sedem nediyar"; mw.notify( "Şandin bi ser neket: " + detail + " — tiştê ku te nivîsî winda nebûye. Heke ev dubare bibe, " + "bi 'Edîtora çavkaniyê veke' berdewam bike.", { type: "error", tag: "wiktku-submit", autoHide: false } ); // Deliberately console.error as well: the notification is for the // person, this is for whoever they report the bug to. if (window.console && console.error) console.error("[wiktku] submit failed", err); } onSubmitError = submitFailed; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); continueBtn.$element.addClass("wiktku-btn-sending"); spinner.show(); try { getWikitext(function (wikitext) { try { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page — write fresh content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // ── bnr-h merge ────────────────────────────────────────── // If the user filled bnr-h inputs, either merge into the // existing {{bnr-h|…}} call or prepend a new one. var bnrhOut = steps.bnrh.output(getValues()); if (bnrhOut) { var newPages = bnrhOut.replace(/^\{\{bnr-h\|/, "").replace(/\}\}\n?$/, "").split("|"); var bnrhRe = /\{\{bnr-h\|([^}]*)\}\}/i; if (bnrhRe.test(existing)) { existing = existing.replace(bnrhRe, function (_, inner) { var existingPages = inner.split("|").map(function (p) { return p.trim(); }); $.each(newPages, function (_, p) { p = p.trim(); if (p && existingPages.indexOf(p) === -1) existingPages.push(p); }); return "{{bnr-h|" + existingPages.join("|") + "}}"; }); } else { existing = bnrhOut + existing; } } // If this language's section already exists (whitespace // differences aside), merge into it; otherwise insert new. var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); } catch (e) { // Thrown while writing the result into #wpTextbox1. submitFailed(e); } }); } catch (e) { // Catches anything thrown synchronously inside getWikitext. submitFailed(e); } }); // Tracks whether groupTabsDiv has been inserted yet. var groupTabsInserted = false; $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); var nameH3 = $("<h3></h3>").addClass("wiktku-start-step-name"); var nameLabel = $("<label></label>") .attr("for", "wiktku-start-" + step.id + "-field") .text(name); nameH3.append(nameLabel); stepDiv.append(nameH3); if (step.question_fmt) { // question_fmt can be a plain string, or a function of the // current values (used by steps whose question text depends // on e.g. the chosen language) — refresh() keeps it in sync // afterwards via the .wiktku-start-step-question class. var questionText = typeof step.question_fmt === "function" ? step.question_fmt(getValues()) : step.question_fmt; stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, questionText))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); // initSelects() runs over the whole form once it is in the DOM. stepDiv.append(input); } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.placeholder) { input.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append(step.modifiers ? makeModifierLi(input) : $("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Section tabs (switch between POS sections) sit above the // per-section fields, starting at "pos". if (step.id === "pos") { startForm.append(sectionTabsDiv); } // Step-group tabs sit just before the first grouped step in // ordered_steps. Derived from stepIdToGroup so this keeps // working no matter how STEP_GROUPS/ordered_steps get reordered. if (!groupTabsInserted && stepIdToGroup[step.id] !== undefined) { startForm.append(groupTabsDiv); startForm.append(besenDinPickerDiv); groupTabsInserted = true; } startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); /** Adds a new, empty POS section and switches to it. */ function addPosSection() { saveCurrentSection(); viewingPron = false; sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); return; } if (id === "resim") { $("#wiktku-start-resim .wiktku-resim-wrap").remove(); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); stepDiv.find("select.wiktku-start-step-field").trigger("wiktku:refresh"); }); // Fresh section — no "Beşên din" sub-section has been opened yet. openedOtherSections = {}; renderBesenDinPicker(); renderSectionTabs(); refresh(); } addSectionBtn.on("click", addPosSection); /** Removes one POS section. Assumes the caller already confirmed and * already checked more than one section remains. If the removed * section was the one on screen, its in-progress DOM edits are * discarded along with it (never saved back into sections[]) and a * neighboring section is restored in its place. */ function removePosSection(idx) { sections.splice(idx, 1); if (idx === activeSection) { viewingPron = false; activeSection = Math.min(idx, sections.length - 1); restoreSection(sections[activeSection]); refresh(); } else if (idx < activeSection) { activeSection -= 1; } renderSectionTabs(); } /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); syncStickyTabsOffset(); return; } sectionTabsDiv.show(); // Bilêvkirin leads the bar, ahead of the POS sections. var pronTab = $("<span></span>") .addClass("wiktku-section-tab wiktku-section-tab-pron") .text("Bilêvkirin") .toggleClass("wiktku-tab-active", viewingPron); pronTab.on("click", function () { if (viewingPron) return; saveCurrentSection(); viewingPron = true; refresh(); renderSectionTabs(); }); sectionTabsDiv.append(pronTab); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection && !viewingPron); (function (idx) { tab.on("click", function () { if (idx === activeSection && !viewingPron) return; // Leaving Bilêvkirin doesn't need a save — its field // is shared and never part of a section snapshot. if (!viewingPron) saveCurrentSection(); viewingPron = false; activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // One delete button for the whole bar — not one per tab — same // reasoning as the Mane tabs' trash button: deletes whichever // Beş is currently open, so there's only one thing a click on it // can possibly remove. Not shown on Bilêvkirin (nothing to // delete there) or when it's the only Beş left. if (sections.length > 1 && !viewingPron) { var activeTabLabel = sections[activeSection] && sections[activeSection].pos ? capitalize(sections[activeSection].pos) : ("Beş " + (activeSection + 1)); var sectionTrash = makeTrashButton("Vê beşê jê bibe (" + activeTabLabel + ")"); sectionTrash.on("click", function () { if (!window.confirm("Tu dixwazî \"" + activeTabLabel + "\" jê bibî? Ev tişt nayê vegerandin.")) return; removePosSection(activeSection); }); sectionTabsDiv.append(sectionTrash.$element); } // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); syncStickyTabsOffset(); } renderSectionTabs(); /** * Re-populates a dynamically-growing "multiple" field list (bnrh, je, * tekildar, …) from a saved array of strings. Sets each value via * .val() + a triggered "input" event rather than touching the DOM * structure directly, so the normal refreshForTextField() growth * logic adds exactly as many rows as needed — the same thing that * happens when a person types into the last (empty) row. */ function restoreMultiField(id, values) { var container = $("#wiktku-start-" + id); $.each(values || [], function (i, v) { var field = container.find(".wiktku-start-step-field").eq(i); if (!field.length || !v) return; field.val(v).trigger("input"); }); } /** * Restores a full cached draft: shared lang/pron/bnrh fields, then * every section (via the same restoreSection()/refresh()/ * renderSectionTabs() sequence already used when switching tabs). * @param cached {{lang: string, pron: string, bnrh: Array, sections: Array, activeSection: number}} */ function restoreFromCache(cached) { if (cached.lang) { $("#wiktku-start-lang-field").val(cached.lang); $("#wiktku-start-lang-field").trigger("wiktku:refresh"); } // Rebuild dependent steps (pos, pron wrap, etc.) now that lang is set. refresh(); if (cached.pron !== undefined) { $("#wiktku-start-pron .wiktku-pron-text").val(cached.pron); } if (cached.bnrh) { restoreMultiField("bnrh", cached.bnrh); } sections = (cached.sections && cached.sections.length) ? cached.sections : [{}]; activeSection = (typeof cached.activeSection === "number" && cached.activeSection >= 0 && cached.activeSection < sections.length) ? cached.activeSection : 0; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); updateLastSavedIndicator(cached.savedAt || null); formDirty = false; wiktkuNotify("Danûstandina berê ya qeydkirî ji cache hate barkirin.", { type: "info", tag: "wiktku-cache-restore" }); } // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); // A new cureyê rêzimanî means any previously chosen cinsiyet/ // cureyê lêkerê no longer applies — clear both selections (and // the shared hidden cinsiyet field, since rebuildTa()/syncHelpers() // fall back to it) before wiping the textarea, so nothing stale // gets carried over into the rebuilt template. var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-cinsiyet-sel").val(""); ppDiv.find(".wiktku-posparams-jimar-sel").val(""); ppDiv.find(".wiktku-posparams-lektur-sel").prop("selectedIndex", 0); ppDiv.find(".wiktku-posparams-lekturform-sel").prop("selectedIndex", 0); $("#wiktku-start-cinsiyet-field").val(""); $("#wiktku-start-jimar-field").val(""); ppDiv.find(".wiktku-posparams-text").val(""); // refresh() runs steps.posparams.syncHelpers(), which toggles the // param rows for the new pos and — since the textarea is now // empty — calls rebuildTa() to repopulate it. refresh(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { // Immediate feedback that the click registered continueBtn.$element.addClass("wiktku-btn-flash"); setTimeout(function () { continueBtn.$element.removeClass("wiktku-btn-flash"); }, 500); // Ziman/Cureyê rêzimanî already block submission via the real // OOUI setDisabled (see canContinue in refresh()) — this is a // second, softer check that still lets the click through so we // can explain why, instead of the button just silently doing nothing. if (!wiktkuContentGateOk) { wiktkuNotify( "Berî şandinê, tiştekî binivîse: Mane, Bi zaravayên din, an jî Werger — kêmasî yek ji van sê beşan divê tijî be.", { type: "warn", tag: "wiktku-mincontent" } ); return; } wiktkuNotify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", flags: [ "destructive" ], }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Cache save/clear buttons ───────────────────────────────────────── // Manual, page-scoped save of the entire wizard (all sections, not // just the active one) via [[MediaWiki:Gadget-StorageUtils.js]]'s // ObjectStorage. Restoring happens silently on load at the end of // build(), once the full language list is available. // // Saving also happens automatically (debounced while typing, plus a // periodic fallback) — see "Autosave" below — since relying on the // person to remember to click "Li cache qeyd bike" before an // accidental tab close/reload defeats the point of having a cache // at all. function buildCacheSnapshot() { return { lang: getValues().lang || "", pron: $("#wiktku-start-pron .wiktku-pron-text").val() || "", // bnrh is shared (page-level), same as lang/pron above — not // per-section, so it doesn't live in sections[]. bnrh: getValuesForStep("bnrh"), sections: sections, activeSection: activeSection, savedAt: Date.now() }; } // ── Last-saved indicator ───────────────────────────────────────────── var lastSavedEl = $("<span id='wiktku-last-saved'></span>"); function formatSavedTime(ts) { try { return new Date(ts).toLocaleTimeString(mw.config.get("wgUserLanguage"), { hour: "2-digit", minute: "2-digit" }); } catch (e) { return new Date(ts).toLocaleTimeString(); } } function updateLastSavedIndicator(ts) { lastSavedEl.text(ts ? ("Cache: qeydkirî di saet " + formatSavedTime(ts) + " de") : ""); } // ── Dirty-state tracking + autosave ────────────────────────────────── // formDirty mirrors "does the live form differ from what's in cache". // Anything the person types/selects sets it; a successful save (auto // or manual) clears it; destroy() (final submit, or switching to the // source editor) also clears it since the wizard's job is over at // that point either way. formDirty/autosaveDebounceTimer/autosaveInterval // are declared in the outer scope (near activeGroup) — assigned here, // not re-declared — so destroy() can reach them too. var AUTOSAVE_DEBOUNCE_MS = 8000; // save shortly after typing pauses var AUTOSAVE_INTERVAL_MS = 60000; // …and at least this often regardless function performAutosave() { if (!formDirty) return; saveCurrentSection(); try { formCache.Set(buildCacheSnapshot()); formDirty = false; updateLastSavedIndicator(Date.now()); } catch (e) { // Silent on autosave failure (storage blocked/full, etc.) — the // manual button still surfaces a proper error if the person // tries it directly, no need to interrupt typing with a toast. } } function scheduleAutosave() { formDirty = true; if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = setTimeout(performAutosave, AUTOSAVE_DEBOUNCE_MS); } startForm.on("input change", "input, textarea, select", scheduleAutosave); autosaveInterval = setInterval(performAutosave, AUTOSAVE_INTERVAL_MS); // Warn on accidental tab close/reload while there's anything unsaved. $(window).on("beforeunload.wiktkuUnsaved", function (e) { if (!formDirty) return undefined; e.preventDefault(); e.returnValue = ""; return ""; }); var saveCacheBtn = new OO.ui.ButtonWidget({ label: "Li cache qeyd bike", title: "Halê vê formê yê niha (ziman, bilêvkirin û hemû beş) li cache (localStorage) qeyd bike, da ku eger rûpel bêyî xwestin were girtin an ji nû ve were barkirin, tu karibî berdewam bikî." }); saveCacheBtn.on("click", function () { saveCurrentSection(); // ObjectStorage.Set() doesn't return a success/failure value, so // the only way to detect a real failure (storage blocked, quota // exceeded, JSON.stringify choking on something unexpected) is to // catch it here rather than inspect a (nonexistent) return value. try { var snapshot = buildCacheSnapshot(); formCache.Set(snapshot); formDirty = false; updateLastSavedIndicator(snapshot.savedAt); wiktkuNotify("Halê formê li cache hate qeydkirin.", { type: "success", tag: "wiktku-cache-save" }); } catch (e) { mw.notify("Qeydkirina li cache bi ser neket.", { type: "error", tag: "wiktku-cache-save" }); } }); var clearCacheBtn = new OO.ui.ButtonWidget({ label: "Cache paqij bike", flags: [ "destructive" ], title: "Datayên qeydkirî yên vê rûpelê ji cache jê bibe (forma ku niha xuya dike naguherîne)." }); clearCacheBtn.on("click", function () { formCache.Set({}); // The live form still has whatever the person typed — it's just no // longer backed up anywhere, so treat this like a fresh unsaved edit. formDirty = true; updateLastSavedIndicator(null); wiktkuNotify("Cache hate paqijkirin.", { type: "success", tag: "wiktku-cache-clear" }); }); // ── "⋯" overflow ───────────────────────────────────────────── // One primary action and one secondary stay on the bar; everything // else moves in here, to avoid four same-weight buttons crowding // (and wrapping to three rows on a phone). var moreBtn = $("<button type='button' class='wiktku-more-btn' title='Vebijarkên din'>⋯</button>"); var moreMenu = $("<div class='wiktku-more-menu'></div>").hide(); /** Moves an existing OOUI button into the overflow menu, keeping its * handlers — the widgets already carry the behaviour, so this is * purely about where they are shown. */ function intoMenu(btn, extraClass) { var row = $("<div class='wiktku-more-item'></div>"); if (extraClass) row.addClass(extraClass); btn.$element.on("click", function () { moreMenu.hide(); }); row.append(btn.$element); moreMenu.append(row); } intoMenu(saveCacheBtn); intoMenu(clearCacheBtn, "wiktku-more-item-danger"); moreMenu.append($("<div class='wiktku-more-sep'></div>")); moreMenu.append($("<div class='wiktku-more-item wiktku-more-note'></div>").append(lastSavedEl)); moreBtn.on("click", function (e) { e.preventDefault(); e.stopPropagation(); var open = moreMenu.is(":visible"); moreMenu.toggle(!open); if (!open) { setTimeout(function () { $(document).one("click.wiktkuMore", function () { moreMenu.hide(); }); }, 0); } }); var moreWrap = $("<span class='wiktku-more-wrap'></span>").append(moreBtn).append(moreMenu); footer.append(moreWrap); // Icon-only settings button — opens the Tercîh dialog. Plain OOUI // icon names depend on which icon-pack module happens to be loaded, // so this uses the actual Codex "settings" (color-subtle) SVG from // Commons directly, the same way the spinner above hotlinks its gif. var prefsBtn = $("<button></button>", { type: "button", "class": "wiktku-prefs-btn", title: "Tercîh — sazkariyên vê amûrê biguherîne" }); prefsBtn.on("click", function (e) { e.preventDefault(); wiktkuOpenPrefsDialog(); }); // The gear is icon-only on the bar; inside a text menu it needs a // label like everything else around it. prefsBtn.on("click", function () { moreMenu.hide(); }); moreMenu.prepend($("<div class='wiktku-more-sep'></div>")); moreMenu.prepend($("<div class='wiktku-more-item wiktku-more-item-prefs'></div>") .append(prefsBtn) .append($("<span class='wiktku-more-item-label'></span>").text("Tercîh"))); startForm.append(footer); // NOTE: deliberately NOT .hide() (display:none). WikiEditor/CodeMirror/ // the mobile editor's auto-grow logic measure #wpTextbox1's real // dimensions during their own init, which happens while the wizard is // up. A display:none ancestor reports 0 for offsetWidth/offsetHeight/ // scrollHeight, so those scripts bake in a near-zero height that never // gets recalculated later — slideDown() in destroy() only animates the // outer box, it doesn't re-trigger their sizing. Pushing #editform // off-screen instead keeps it laid out (real width/height available to // measure) without being visible, so the editbox opens at full size. $("#editform").addClass("wiktku-offscreen").before(startForm); // renderGroupTabs() looks up #wiktku-group-tabs via a live DOM // selector, so it must run after startForm is actually in the document. renderGroupTabs(); renderBesenDinPicker(); // One pass over the whole form: every select that hasn't already been // initialised, and isn't opted out with .wiktku-plain-select, gets // the searchable picker. initSelects(startForm); refresh(); // Give every draggable textarea a custom resize grip (works // consistently on Safari/iOS, unlike the native corner grip — see // the "Manual drag-to-resize handle" comment in styles.css), and // keep applying it to textareas added later on (new sense blocks, // quote-source fields, nimûne rows, …). wiktkuInitManualResize(startForm); new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { $(mutation.addedNodes).each(function () { if (this.nodeType !== 1) return; wiktkuInitManualResize(this); }); }); }).observe(startForm[0], { childList: true, subtree: true }); // Now that the full language list is loaded, silently restore any // draft the editor previously saved for this page. var cachedDraft = formCache.Get(); if (cachedDraft && cachedDraft.sections && cachedDraft.sections.length) { restoreFromCache(cachedDraft); } } // "oojs-ui.styles.icons-moderation" carries the "trash" glyph used by // makeTrashButton() below — without it the delete buttons on the Mane // and Beş tab bars would render as blank icon-less buttons. mw.loader.using(["oojs-ui-core", "oojs-ui.styles.icons-moderation"], function () { function wiktkuProceedWithData(wiktkuData) { var d = wiktkuData || {}; // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Jimar (number) code definitions — same shape as the wiki's // own Lua number-type table (code -> {cat, display[, req]}). if (d.numberLabels) $.extend(NUMBER_LABELS, d.numberLabels); // Populate lang choices (pinned list). if (d.langChoices) steps.lang.choices = choicesFromObject(d.langChoices, true); // Populate langsByCode and merge full language list from d.ziman. // d.ziman is a {code: name} object with all known languages. $.each(steps.lang.choices, function (i, choice) { if (choice.sortKey === undefined) choice.sortKey = choice.label; langsByCode[choice.code] = choice; }); if (d.ziman) { var pinnedCodes = {}; $.each(steps.lang.choices, function (i, c) { pinnedCodes[c.code] = true; }); var extraChoices = []; $.each(d.ziman, function (code, name) { if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; if (pinnedCodes[code]) return; var choice = { code: code, label: name, sortKey: name }; extraChoices.push(choice); langsByCode[code] = choice; }); extraChoices.sort(function (a, b) { return a.sortKey.localeCompare(b.sortKey, userLang); }); steps.lang.choices = steps.lang.choices.concat(extraChoices); } // Keep the full merged list around for trans/dunde/zarava — those // should still be able to reference any language even when the // Tercîh panel restricts the main "ziman" step below — then, if // the user set a restriction there, narrow steps.lang.choices // itself to just those codes. var wiktkuFullLangChoices = steps.lang.choices; if (wiktkuPrefs.langCodes && wiktkuPrefs.langCodes.length) { var wiktkuAllowedLangSet = {}; $.each(wiktkuPrefs.langCodes, function (i, code) { wiktkuAllowedLangSet[code] = true; }); var wiktkuRestrictedChoices = $.grep(wiktkuFullLangChoices, function (c) { return !!wiktkuAllowedLangSet[c.code]; }); // Fall back to the full list instead of showing an empty // dropdown if none of the saved codes matched anything // (typo'd code, data.json changed since, …). steps.lang.choices = wiktkuRestrictedChoices.length ? wiktkuRestrictedChoices : wiktkuFullLangChoices; } // Populate POS choices — also a plain {code: label} object in data.json. if (d.posChoices) steps.pos.choices = choicesFromObject(d.posChoices, false); // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the full language list // (not the possibly Tercîh-restricted steps.lang.choices). steps.trans.keys = wiktkuFullLangChoices; steps.dunde.keys = wiktkuFullLangChoices; steps.zarava.keys = getZaravaKeys(wiktkuFullLangChoices); build(); } // data.json ships inside this package module, so it is already parsed // and in memory — no action=raw round trip, and no Testing switch to // forget to flip back before deploying. wiktkuProceedWithData(require("./start/data.json")); }); }); //</nowiki> sva07zf5u3nqvcd0zffkgt561i8fq7i 6333906 6333861 2026-08-15T21:13:17Z Wikihez 7344 6333906 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. // implicit dependencies: StorageUtils (ObjectStorage) //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var addLangMode = mw.util.getParamValue("wiktkuaddlang") === "1"; // ── Tercîh (user settings) panel stored via mw.storage (localStorage), globally var WIKTKU_PREFS_KEY = "wiktku_start_prefs"; var WIKTKU_PREFS_DEFAULTS = { // [] = show the full language list in the "ziman" step; otherwise // only these codes are shown there (data.json codes, not names). langCodes: [], // true = never auto-open on a new/empty page — only via the // "+Ziman/beşeke din" portlet link. onlyOnClick: false, // "auto" | "p-cactions" | "p-tb" | "p-views" — where the // "+Ziman/beşeke din" portlet link is added. portlet: "auto", // true = suppress routine/informational mw.notify toasts (page // loading, cache auto-restored, cache saved/cleared, "tê şandin…"). // Errors and direct results of an explicit action (like saving // Tercîh itself) always show regardless of this setting. quiet: false }; function wiktkuLoadPrefs() { if (!(window.mw && mw.storage)) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var raw; try { raw = mw.storage.get(WIKTKU_PREFS_KEY); } catch (e) { raw = null; } if (!raw) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var parsed; try { parsed = JSON.parse(raw); } catch (e) { parsed = {}; } return $.extend({}, WIKTKU_PREFS_DEFAULTS, parsed); } function wiktkuSavePrefs(prefs) { if (!(window.mw && mw.storage)) return false; try { mw.storage.set(WIKTKU_PREFS_KEY, JSON.stringify(prefs)); return true; } catch (e) { return false; } } var wiktkuPrefs = wiktkuLoadPrefs(); // Routine/informational notices go through here so "quiet mode" can // suppress them; errors and explicit-action confirmations (like the // Tercîh save toast) call mw.notify directly instead, and always show. function wiktkuNotify(message, options) { if (wiktkuPrefs.quiet) return; mw.notify(message, options); } // Lazily built the first time it's opened; reused after that (see // wiktkuOpenPrefsDialog below, defined once we know OOUI is available). var wiktkuPrefsWindowManager = null; var wiktkuPrefsDialog = null; function wiktkuOpenPrefsDialog() { mw.loader.using(["oojs-ui-core", "oojs-ui-windows"], function () { function WiktkuPrefsDialog(config) { WiktkuPrefsDialog.super.call(this, config); } if (!wiktkuPrefsDialog) { OO.inheritClass(WiktkuPrefsDialog, OO.ui.ProcessDialog); WiktkuPrefsDialog.static.name = "wiktkuPrefsDialog"; WiktkuPrefsDialog.static.title = "Tercîhên min"; WiktkuPrefsDialog.static.actions = [ { action: "save", label: "Qeyd bike", flags: ["primary", "progressive"] }, { action: "cancel", label: "Betal bike", flags: "safe" } ]; WiktkuPrefsDialog.prototype.initialize = function () { WiktkuPrefsDialog.super.prototype.initialize.call(this); this.langCodesInput = new OO.ui.TextInputWidget({ placeholder: "ku, zza, ckb (vala bihêle ji bo hemû zimanan)" }); this.onlyOnClickCheckbox = new OO.ui.CheckboxInputWidget({}); this.quietCheckbox = new OO.ui.CheckboxInputWidget({}); this.portletDropdown = new OO.ui.DropdownInputWidget({ options: [ { data: "auto", label: "Otomatîk (li gorî rûyê wîkiyê)" }, { data: "p-cactions", label: "p-cactions - Li qismê Amûran" }, { data: "left-navigation", label: "left-navigation - Li qismê Gotar-Gotûbêj" }, { data: "p-tb", label: "p-tb - Li qismê Giştî" }, { data: "p-views", label: "p-views - Li qismê Bixwîne" } ] }); var fieldset = new OO.ui.FieldsetLayout({ label: "Eyar" }); fieldset.addItems([ new OO.ui.FieldLayout(this.langCodesInput, { label: "Kodên zimanan ku tê xuyakirin li qismê \"ziman\"", align: "top", help: "Kodan bi virgulê (,) ji hev veqetîne. Vala bihêle da ku hemû ziman were nîşandan.", helpInline: true }), new OO.ui.FieldLayout(this.onlyOnClickCheckbox, { label: "Tenê veke wextê \"+Ziman/beşeke din\" were tikandin", align: "inline", help: "Eger were hilbijartin, ev amûr êdî otomatîk li ser rûpelên nû/vala dest pê nake — divê meriv her carê pêl \"+Ziman/beşeke din\" bike.", helpInline: true }), new OO.ui.FieldLayout(this.portletDropdown, { label: "Cihê lînka \"+Ziman/beşeke din\"", align: "top", help: "\"Otomatîk\" li gorî rûyê wîkiyê hildibijêre.", helpInline: true }), new OO.ui.FieldLayout(this.quietCheckbox, { label: "Moda bêdeng (kêmtir agahdarî nîşan bide)", align: "inline", help: "Agahdariyên normal nîşan nede. Xeta her tim tên xuyakirin.", helpInline: true }) ]); this.$body.addClass("wiktku-prefs-dialog-body").append(fieldset.$element); }; WiktkuPrefsDialog.prototype.getSetupProcess = function (data) { return WiktkuPrefsDialog.super.prototype.getSetupProcess.call(this, data) .next(function () { this.langCodesInput.setValue(wiktkuPrefs.langCodes.join(", ")); this.onlyOnClickCheckbox.setSelected(!!wiktkuPrefs.onlyOnClick); this.portletDropdown.setValue(wiktkuPrefs.portlet || "auto"); this.quietCheckbox.setSelected(!!wiktkuPrefs.quiet); }, this); }; WiktkuPrefsDialog.prototype.getActionProcess = function (action) { var dialog = this; if (action === "save") { return new OO.ui.Process(function () { var codes = dialog.langCodesInput.getValue() .split(/[,\s]+/) .map(function (c) { return c.trim().toLowerCase(); }) .filter(function (c) { return !!c; }); wiktkuPrefs = { langCodes: codes, onlyOnClick: dialog.onlyOnClickCheckbox.isSelected(), portlet: dialog.portletDropdown.getValue() || "auto", quiet: dialog.quietCheckbox.isSelected() }; wiktkuSavePrefs(wiktkuPrefs); mw.notify( "Tercîh hatin qeydkirin. Rûpelê ji nû ve bar bike (F5).", { type: "success", tag: "wiktku-prefs-save" } ); dialog.close({ action: "save" }); }); } if (action === "cancel") { return new OO.ui.Process(function () { dialog.close({ action: "cancel" }); }); } return WiktkuPrefsDialog.super.prototype.getActionProcess.call(this, action); }; wiktkuPrefsWindowManager = new OO.ui.WindowManager(); $(document.body).append(wiktkuPrefsWindowManager.$element); wiktkuPrefsDialog = new WiktkuPrefsDialog(); wiktkuPrefsWindowManager.addWindows([wiktkuPrefsDialog]); } wiktkuPrefsWindowManager.openWindow(wiktkuPrefsDialog); }); } var targetContainer; var skin = mw.config.get('skin'); if (wiktkuPrefs.portlet && wiktkuPrefs.portlet !== "auto") { targetContainer = wiktkuPrefs.portlet; } else if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Li vê rûpelê, ziman an jî beşeke nû zêde bike"); // If "onlyOnClick" is set, the wizard should ONLY ever open via the // "+Ziman/beşeke din" link — never automatically var wiktkuNewPageDetected = $(".mw-newarticletext, .mw-newarticletextanon").length > 0; if (wiktkuPrefs.onlyOnClick ? !addLangMode : (!addLangMode && !wiktkuNewPageDetected)) { return; } // ── Shared helpers ─────────────────────────────────────────────────── // Generic text/UI utilities live in their own package file now — see the // header of util.js for why. Aliased to bare names here so the ~400 call // sites below read exactly as they did when these were local functions. var wiktkuUtil = require("./start/util.js"); var capitalize = wiktkuUtil.capitalize; var decapitalize = wiktkuUtil.decapitalize; var escapeRegExp = wiktkuUtil.escapeRegExp; var stripWikilinks = wiktkuUtil.stripWikilinks; var splitTercimeIzah = wiktkuUtil.splitTercimeIzah; var insertAtCursor = wiktkuUtil.insertAtCursor; var foldDiacritics = wiktkuUtil.foldDiacritics; var wrapNativeSelect = wiktkuUtil.wrapNativeSelect; var initSelects = wiktkuUtil.initSelects; var wiktkuInitManualResize = wiktkuUtil.initManualResize; function langHeaderSource(codePattern) { return "\n?==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } // Delete button (real OOUI "trash" icon, destructive-flagged) shared by // the Mane tab bar and the Beş tab bar. One button per bar — sitting // right before "+ Mane zêde bike" / "+ Beş zêde bike", not one per tab // — deletes whichever sense/section is currently open. A trash icon on // every individual tab put the hit-target right where people click to // switch tabs, which is exactly how a stray click ended up deleting the // wrong one; a single button acting on "the one you're looking at" has // only one thing it can possibly delete. function makeTrashButton(title) { return new OO.ui.ButtonWidget({ icon: "trash", flags: ["destructive"], framed: false, invisibleLabel: true, label: title, title: title, classes: ["wiktku-trash-btn"] }); } function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } var catSrcTemplates = null; var catSrcTemplatesPromise = null; function fetchCatSrcTemplates() { if (catSrcTemplatesPromise) return catSrcTemplatesPromise; catSrcTemplatesPromise = new mw.Api().get({ action: "query", list: "categorymembers", cmtitle: "Kategorî:Çavkanî", cmnamespace: 10, cmlimit: "max", formatversion: 2 }).then(function (data) { var members = (data.query && data.query.categorymembers) || []; catSrcTemplates = $.map(members, function (m) { // Pêşgira navî ya "Şablon:" rake. return m.title.replace(/^[^:]+:/, ""); }); catSrcTemplates.sort(function (a, b) { return a.localeCompare(b, userLang); }); return catSrcTemplates; }, function () { catSrcTemplates = []; return catSrcTemplates; }); return catSrcTemplatesPromise; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var formCache = new ObjectStorage("wiktku_start_draft_" + mw.config.get("wgPageName"), 1); var langsByCode = {}; // Looks up the display label for a language code, falling back to the // code itself if it isn't known yet (e.g. langsByCode not loaded). function getLangLabel(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; // Converts a {code: label} object (langChoices/posChoices in data.json) // into the {code, label[, sortKey]} array the rest of the script uses. // isLang: true adds a sortKey and shows "(code)" after the label — // language choices only. function choicesFromObject(obj, isLang) { var result = []; $.each(obj || {}, function (code, label) { var choice = { code: code, label: label }; if (isLang) choice.sortKey = label; result.push(choice); }); return result; } function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c.code] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Number codes (y, s, d, p, p+, tp, j, j+, j/nj, nj, nj+, hj!, hj?) from // data.json's "numberLabels". Same {code: {cat, display[, req]}} shape as // the wiki's Lua number-type table; "display" can contain HTML (<abbr>) // or wikilinks, so it's only used as-is in wikitext output, never dropped // straight into an <option> (see stripMarkupForOption below). var NUMBER_LABELS = {}; // Distinguishes the Jimar dropdown (j= param) from the Cîns dropdown // (c= param): a code that's a key in NUMBER_LABELS is a number code, // everything else is a gender code. Compound codes like "m-p"/"n-p" are // gender+plural pairs and correctly stay on the gender side. function isNumberCode(code) { return Object.prototype.hasOwnProperty.call(NUMBER_LABELS, code); } // Strips the bit of markup "display" is allowed to contain so it's safe // to use as plain <option> text (options can't render HTML or wikilinks): // <abbr title="X">Y</abbr> -> "Y (X)", [[a|b]] -> "b", [[a]] -> "a". function stripMarkupForOption(html) { if (!html) return ""; return $.trim( String(html) .replace(/<abbr[^>]*title="([^"]*)"[^>]*>([\s\S]*?)<\/abbr>/gi, "$2 ($1)") .replace(/\[\[[^\]|]*\|([^\]]*)\]\]/g, "$1") .replace(/\[\[([^\]]*)\]\]/g, "$1") .replace(/<[^>]+>/g, "") ); } // Builds the Jimar dropdown's <option> text for one code: "j — jimarbar". function numberOptionLabel(code) { var def = NUMBER_LABELS[code]; if (!def) return code; var text = stripMarkupForOption(def.display); return text ? (code + " — " + text) : code; } // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } // ── Template explanations ──────────────────────────────────────────── // Every place a template can be picked shows the same row: a status // dot, the name, a link to the template page, and an ⓘ. This is the ⓘ. // // Text comes from the template's own TemplateData where it has any, so // the explanation stays right without anyone maintaining a second copy // by hand — with the desc already in data.json as the fallback for // templates that have none. var wiktkuTplDataCache = {}; // name -> {desc, params[]} or null when absent /** Fetches TemplateData for one template. Resolves to null if the * template has none (a plain, undocumented template — very common). */ function fetchTemplateData(name) { if (Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, name)) { return $.Deferred().resolve(wiktkuTplDataCache[name]).promise(); } return new mw.Api().get({ action: "templatedata", titles: "Şablon:" + name, redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; var first = null; $.each(pages, function (_, p) { if (!first) first = p; }); var out = null; if (first) { var desc = first.description; // TemplateData descriptions are language maps when the // template is documented in more than one language. if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(first.params || {}, function (key, p) { var label = p && p.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(p && p.required) }); }); out = { desc: desc || "", params: params }; } wiktkuTplDataCache[name] = out; return out; }, function () { // No TemplateData, or the API is unhappy — cache the miss so a // repeated ⓘ click doesn't re-request it every time. wiktkuTplDataCache[name] = null; return null; }); } /** Fetches TemplateData for many templates in one request and fills the * cache; resolves either way, a template with no TemplateData caches as null. */ function prefetchTemplateData(names) { var missing = $.grep(names || [], function (n) { return n && !Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n); }); if (!missing.length) return $.Deferred().resolve().promise(); // The API caps a titles list at 50 for normal users. missing = missing.slice(0, 50); return new mw.Api().get({ action: "templatedata", titles: $.map(missing, function (n) { return "Şablon:" + n; }).join("|"), redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; $.each(pages, function (_, page) { if (!page || !page.title) return; var name = String(page.title).replace(/^[^:]+:/, ""); var desc = page.description; if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(page.params || {}, function (key, prm) { var label = prm && prm.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(prm && prm.required) }); }); wiktkuTplDataCache[name] = { desc: desc || "", params: params }; }); // Anything the API didn't answer for simply has none — cache the // miss so the per-row ⓘ doesn't re-request it one at a time. $.each(missing, function (_, n) { if (!Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n)) wiktkuTplDataCache[n] = null; }); }, function () { $.each(missing, function (_, n) { wiktkuTplDataCache[n] = null; }); }); } /** Rewrites each tagged <option> in `sel` as "name — description", using * TemplateData. Only fills rows that have no description yet, so the * hand-written ones in data.json (which carry usage examples the API * does not) are left exactly as they are. */ function applyTplDescriptions(sel) { if (!sel || !sel.length) return; var changed = false; sel.find("option[data-tpl]").each(function () { var opt = $(this); var name = opt.attr("data-tpl"); if (opt.text().indexOf(" — ") !== -1) return; // already described var td = wiktkuTplDataCache[name]; var desc = (td && td.desc) || localTplDesc(name); if (!desc) return; // One line: TemplateData descriptions can run to a paragraph. desc = $.trim(String(desc).split("\n")[0]); if (desc.length > 90) desc = desc.slice(0, 90) + "…"; opt.text(name + " — " + desc); changed = true; }); // The picker caches option text for searching, so it has to re-read. if (changed) sel.trigger("wiktku:refresh"); } /** Hand-written fallback description, from data.json. * * This is the escape hatch for templates with no TemplateData on the * wiki: add a "desc" to the entry in data.json and it shows up in the * dropdown and in the ⓘ immediately, no code change. TemplateData is * still the better place — VisualEditor and every other tool reads it * too — but this keeps the picker useful in the meantime. * * Works for any pool: pronTpls, etymTpls, tplDefs, jederDefs. */ function localTplDesc(name) { var pools = [steps.pron.pronTpls, steps.etym.etymTpls, steps.dfn.tplDefs, steps.dfn.jederDefs]; var found = ""; $.each(pools, function (_, pool) { if (pool && pool[name] && pool[name].desc) { found = pool[name].desc; return false; } }); return found; } /** Opens the inline explanation panel for `name`, anchored under the * picker it was opened from. */ function showTemplateInfo(name, anchorWrap) { $(".wiktku-tpl-info").remove(); var panel = $("<div class='wiktku-tpl-info'></div>"); panel.append($("<div class='wiktku-tpl-info-name'></div>").text("{{" + name + "}}")); var body = $("<div class='wiktku-tpl-info-desc'></div>").text("Tê barkirin…"); panel.append(body); var params = $("<div class='wiktku-tpl-info-params'></div>"); panel.append(params); panel.append($("<a class='wiktku-tpl-info-link' target='_blank' rel='noopener'></a>") .attr("href", wiktkuUtil.tplPageUrl(name)) .text("Rûpela şablonê veke →")); var close = $("<button type='button' class='wiktku-tpl-info-close' title='Bigire'>✕</button>"); close.on("click", function () { panel.remove(); }); panel.prepend(close); $(anchorWrap).after(panel); fetchTemplateData(name).then(function (td) { var desc = (td && td.desc) || localTplDesc(name); body.text(desc || "Ji bo vê şablonê ravek nehatiye nivîsandin."); if (td && td.params && td.params.length) { params.append($("<div class='wiktku-tpl-info-params-title'></div>").text("Parametre:")); var listEl = $("<ul></ul>"); $.each(td.params, function (_, p) { var line = p.name + (p.label ? " — " + p.label : "") + (p.required ? " (pêwîst)" : ""); listEl.append($("<li></li>").text(line)); }); params.append(listEl); } }); } /** Marks a picker's <option>s as template rows so the searchable widget * renders them with the dot / 🔗 / ⓘ affordances, and wires the ⓘ * handler for that picker. `nameOf` maps an <option> to a template * name — the pickers store different things in value= (a snippet for * the insert dropdowns, the bare name for the sense selector). */ function markTemplateOptions(sel, nameOf) { if (!sel || !sel.length) return; var names = []; sel.find("option").each(function () { var opt = $(this); var name = nameOf(opt); if (!name) return; opt.attr("data-tpl", name); // Deprecated/typo templates are the "special cases only" ones. opt.attr("data-tpl-status", /kevnbûyî|şaşnivîs|kêmpeyda/i.test(opt.text()) ? "yellow" : "green"); names.push(name); }); sel.data("wiktkuTplInfo", showTemplateInfo); // Fill in the descriptions. Matters most for the Mane picker, whose // entries in data.json are names with no desc at all — "rastnivîs", // "ku-Latn", "guharto" on their own. One request covers every // template in the picker, cached for the per-row ⓘ as well. prefetchTemplateData(names).always(function () { applyTplDescriptions(sel); }); } /** Pulls the template name out of a snippet like "* {{ku-IPA}}" or * "{{ji|SOURCELANG|CODE|…}}". */ function tplNameFromSnippet(snippet) { var m = /\{\{\s*([^|}\n]+)/.exec(snippet || ""); return m ? $.trim(m[1]) : ""; } // True if a sense has content beyond mane worth keeping (etîket, word // lists, nimûne, jêder) — so it's still emitted with {{mane?}} if empty. function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } // A technically-"complete" entry (Ziman + Cureyê rêzimanî filled) with // nothing in Mane, Bi zaravayên din or Werger is still meaningfully // empty, so this is checked separately at submit-click time with its // own message. function hasMinRequiredContent(values) { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasMane = dfnSenses.some(function (s) { return (s.tpl && s.tplTitle) || (!s.tpl && (s.mane !== "" || senseHasExtraContent(s))); }); if (hasMane) return true; if (values.lang === "ku") { var hasWerger = false; $("#wiktku-start-trans .wiktku-trans-group").each(function () { if (steps.trans.getGroupTranslations($(this)).length) hasWerger = true; }); if (hasWerger) return true; var hasZarava = false; $("#wiktku-start-zarava .wiktku-zarava-group").each(function () { if (steps.zarava.getGroupTranslations($(this)).length) hasZarava = true; }); if (hasZarava) return true; } return false; } // Bolds the *first* occurrence of the page name function boldPageNameOnce(text) { if (!text || !pageNameRe) return text; var re = new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "i"); return text.replace(re, "'''$1'''"); } // Converts literal line breaks typed into a nimûne/jêgirtin box into // wikitext <br> tags, function nlToBr(text) { return text ? text.replace(/\r\n|\r|\n/g, "<br>") : text; } function escapeHtmlForBackdrop(str) { return String(str) .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;"); } // Mirrors a textarea's text, with a small highlighted marker placed // right after each line that's followed by an actual typed/pasted // linebreak. Rendered into a transparent backdrop layer behind the // textarea (see ensureLinebreakBackdrop()), so only the point of the // break is marked instead of the whole box. function buildLinebreakBackdropHtml(text) { var lines = text.split(/\r\n|\r|\n/); return $.map(lines, function (line, i) { var isLast = i === lines.length - 1; return escapeHtmlForBackdrop(line) + (isLast ? "" : "<mark class='wiktku-linebreak-mark'>↵</mark>\n"); }).join(""); } // Copies the metrics that affect where text wraps/lands (font, line // height, padding, border) from the real textarea onto its backdrop, // via computed style rather than shared CSS classes — most of the // box's own rules are written as "textarea.foo", which a <div> with // the same class wouldn't match. Re-run on every update in case a // responsive breakpoint changed the textarea's own font-size. function syncLinebreakBackdropMetrics(textarea, backdrop) { var cs = window.getComputedStyle(textarea[0]); backdrop.css({ "box-sizing": cs.boxSizing, "padding-top": cs.paddingTop, "padding-right": cs.paddingRight, "padding-bottom": cs.paddingBottom, "padding-left": cs.paddingLeft, "border-width": cs.borderWidth, "border-style": "solid", "font-family": cs.fontFamily, "font-size": cs.fontSize, "font-weight": cs.fontWeight, "line-height": cs.lineHeight, "letter-spacing": cs.letterSpacing }); } // Lazily wraps a textarea in its own positioning anchor (independent // of .wiktku-resize-wrap, so this doesn't depend on load order versus // wiktkuMakeManualResizable) and inserts the transparent backdrop // layer used to mark the exact point of a linebreak. Safe to call // more than once on the same textarea — the backdrop is cached. function ensureLinebreakBackdrop(textarea) { var existing = textarea.data("wiktkuLinebreakBackdrop"); if (existing) return existing; textarea.wrap("<div class='wiktku-linebreak-wrap'></div>"); var backdrop = $("<div aria-hidden='true'></div>").addClass("wiktku-linebreak-backdrop"); textarea.before(backdrop); textarea.data("wiktkuLinebreakBackdrop", backdrop); textarea.on("scroll.wiktkuLinebreak", function () { backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); }); return backdrop; } // Flags a nimûne/jêgirtin textarea (via CSS class, for the border // tint + tooltip) while it contains a typed/pasted linebreak, so the // user notices before it's silently turned into <br> on output. // Marks only the exact point of the break via a mirrored backdrop, // rather than tinting the whole box. function highlightLinebreak(el) { var textarea = $(el); var text = textarea.val(); var hasBreak = /\r|\n/.test(text); textarea .toggleClass("wiktku-has-linebreak", hasBreak) .attr("title", hasBreak ? "Xeta nû dê wek <br> bê nivîsandin" : ""); if (!hasBreak) { var cached = textarea.data("wiktkuLinebreakBackdrop"); if (cached) cached.hide(); textarea.removeClass("wiktku-has-linebreak-source"); return; } var backdrop = ensureLinebreakBackdrop(textarea); textarea.addClass("wiktku-has-linebreak-source"); syncLinebreakBackdropMetrics(textarea, backdrop); backdrop.html(buildLinebreakBackdropHtml(text)).show(); backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); } // Each nimûne item can be { text, tr, t }: text, transliteration, translation. function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{nimûne?|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = nlToBr(boldPageNameOnce(text)); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + nlToBr(n.tr); // Translation as third positional param (no key needed). if (n.t) tpl += "|" + nlToBr(n.t); } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 60 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } // Formats jêder (citation) entries into "#* {{jêder…|…}}" lines; skips // entries with no quote text. Falls back to the generic {{jêder}} // template when no specific template was chosen. function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; var quote = nlToBr(boldPageNameOnce(jeder.quote)); var quoteTr = nlToBr(jeder.quoteTr); var quoteT = nlToBr(jeder.quoteT); if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + quote; if (quoteTr) cite += "|tr=" + quoteTr; if (quoteT) cite += "|tercime=" + quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + quote; if (quoteTr) out += "|tr=" + quoteTr; if (quoteT) out += "|tercime=" + quoteT; // A şablon picked from Kategorî:Çavkanî is transcluded as the // source param (e.g. |{{Kovara X}}); manual text is used as-is. var srcParam = jeder.jederCatTpl ? ("{{" + jeder.jederCatTpl + "}}") : (jeder.jederManual ? jeder.jederManual : "çavkanî?"); // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } // True if a sense has at least one jêder entry with quote text. function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } // Builds "{{tplName|lang|part1|part2|…}}" from a sense field (kategori, // etiket), wrapped inline (" {{…}} ") or on its own line ("\n#: {{…}}"). function buildSenseTpl(sense, field, lang, tplName) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return call } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } // ── Inline modifier system ─────────────────────────────────────────────── // Appends a ⊕ button to a word input <li>. Clicking it shows a compact // modifier picker; selecting one prompts for the value and appends // <modifier:value> to the textarea's current content. 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îf" }, { 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: qualifier (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" }, { key: "qq", label: "qq: qualifier (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î" } ]; // Sub-groups (inside a sense/definition block) that get the same ⊕ // modifier button as makeWordListStep fields. var MODIFIER_SUBGROUPS = { "wiktku-dfn-alternativ": true, "wiktku-dfn-hevmane": true, "wiktku-dfn-dijmane": true, "wiktku-dfn-koordine": true, "wiktku-dfn-jornav": true, "wiktku-dfn-jernav": true }; /** * Wraps a freshly-created textarea in a <li> with a ⊕ modifier button. * `ta` — the jQuery textarea element. * Returns the <li>. */ function makeModifierLi(ta) { var li = $("<li class='wiktku-word-li'></li>"); var btn = $("<button type='button' class='wiktku-mod-btn' title='Modifiyerê lê zêde bike'>⊕</button>"); var picker = $("<div class='wiktku-mod-picker'></div>").hide(); // Which modifier keys are already present in the textarea's current // text — e.g. "<t:...>" → "t" used. Each modifier can only be // applied once per word, so its pill gets disabled once used. function usedKeys() { var used = {}; var re = /<([a-zA-Z]+):/g; var val = ta.val() || ""; var m; while ((m = re.exec(val)) !== null) used[m[1]] = true; return used; } $.each(WORD_MODIFIERS, function (_, mod) { var pill = $("<button type='button' class='wiktku-mod-pill'></button>").text(mod.label); pill.attr("title", mod.hint); pill.data("mod-key", mod.key); pill.on("click", function (e) { e.preventDefault(); if (pill.prop("disabled")) return; // already used on this word picker.hide(); // Show a tiny inline input for the modifier value. var valWrap = $("<span class='wiktku-mod-val-wrap'></span>"); var valInp = $("<input type='text' class='wiktku-mod-val-input'>") .attr("placeholder", mod.hint + "…") .attr("size", 20); var confirm = $("<button type='button' class='wiktku-mod-confirm'>✓</button>"); var cancel = $("<button type='button' class='wiktku-mod-cancel'>✕</button>"); function applyModifier() { var v = $.trim(valInp.val()); if (v) { ta.val(ta.val() + "<" + mod.key + ":" + v + ">"); ta.trigger("input"); } valWrap.remove(); ta.focus(); } confirm.on("click", applyModifier); cancel.on("click", function () { valWrap.remove(); ta.focus(); }); valInp.on("keydown", function (e) { if (e.which === 13) { e.preventDefault(); applyModifier(); } if (e.which === 27) { valWrap.remove(); ta.focus(); } }); valWrap.append(valInp).append(confirm).append(cancel); li.append(valWrap); valInp.focus(); }); picker.append(pill); }); btn.on("click", function (e) { e.preventDefault(); // Close any other open pickers in the same list. li.closest("ol, ul").find(".wiktku-mod-picker").not(picker).hide(); // Grey out modifiers already used on this word — refreshed on // every open since the text (and thus what's "used") can change. var used = usedKeys(); picker.find(".wiktku-mod-pill").each(function () { var isUsed = !!used[$(this).data("mod-key")]; $(this).prop("disabled", isUsed).toggleClass("wiktku-mod-pill-used", isUsed); }); picker.toggle(); }); // Close picker when focus leaves the li entirely. li.on("focusout", function () { setTimeout(function () { if (!$.contains(li[0], document.activeElement)) picker.hide(); }, 150); }); li.append(ta).append(btn).append(picker); return li; } function makeWordListStep(id, name, question_fmt) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, modifiers: true, // Function instead of a plain string so it can name the current // language — computed fresh at build time and re-applied by // refresh() whenever the language changes. placeholder: function () { var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return "Kelîme" + (langLabel ? " bi " + langLabel : "") + "…"; }, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); var header = capitalize(name); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: {}, visible: function (values) { if (!values.lang) return false; // addLangMode: skip pron only if this lang already has a section. if (addLangMode) { // Clearing the page makes existing content irrelevant. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, // Fills the insert-dropdown from pronTpls, filtered by language. refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); // Reassures the user this field is optional — the dropdown // below writes the template for them, no syntax needed up front. wrap.append( $("<p class='wiktku-step-hint'></p>").text( "Ev qad ne mecbûrî ye. Heke tu nizanî kîjan şablonî hilbijêrî, vale bihêle — an ji pêşkêşkariya jêrîn şablonekî hilbijêre, ew ê bixweber li vir were nivîsandin." ) ); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike "); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); // Clear the picker's search box sel.trigger("wiktku:refresh"); ta.focus(); return; } // The noLang templates (ku-IPA, ku-kîte, zza-IPA, zza-kîte) // auto-generate content from a Lua module reading the page // title, so show a live preview and require confirmation // before inserting. var tplLabel = selectedOption.text(); $(this).val(""); sel.trigger("wiktku:refresh"); steps.pron.showTplPreview(stepDiv, ta, snippet, tplLabel); }); wrap.append(sel).append(ta); stepDiv.append(wrap); steps.pron.buildIpaPalette(wrap, ta); initSelects(wrap); return ta; }, // ── IPA character palette ────────────────────────────────── // Modelled on fr.wiktionary's: every character is a button that // drops itself in at the cursor. Two sub-tabs, because the full // IPA chart is ~180 symbols and roughly twenty of them ever // appear in Kurmancî — "IPA (kurdî)" opens by default and the // full chart is one click away for loanwords and other // languages. Grouped with a label down the left so it reads as // a chart rather than one long line of glyphs. IPA_KU: [ { label: "Kît/stres", chars: ["ˈ", "ˌ", "ː"] }, { label: "Bêdeng", chars: ["d͡ʒ", "t͡ʃ", "ʒ", "ʃ", "ɫ", "ŋ", "ɾ", "r", "ʋ", "ħ", "ʕ", "ɣ", "χ", "ʔ"] }, { label: "Dengdêr", chars: ["ɑː", "eː", "ɛ", "ɪ", "iː", "ɯ", "ʊ", "uː", "yː", "ø", "œ"] } ], IPA_FULL: [ { label: "Bêdeng 1", chars: ["m", "ɱ", "n", "ɳ", "ɲ", "ŋ", "ɴ", "p", "b", "t", "d", "t̪", "d̪", "ʈ", "ɖ", "c", "ɟ", "k", "ɡ", "q", "ɢ", "ʡ", "ʔ"] }, { label: "Bêdeng 2", chars: ["ɸ", "β", "f", "v", "θ", "ð", "s", "z", "ʃ", "ʒ", "ʂ", "ʐ", "ɕ", "ʑ", "ç", "ʝ", "x", "ɣ", "χ", "ʁ", "ħ", "ʕ", "h", "ɦ", "ʜ", "ʢ", "ɧ"] }, { label: "Bêdeng 3", chars: ["ʋ", "ɹ", "ɻ", "j", "ɥ", "ɰ", "ʍ", "w", "ʙ", "ⱱ", "ɾ", "ɽ", "r", "ʀ", "ɺ", "l", "ɫ", "ɬ", "ɮ", "ɭ", "ʎ", "ʟ"] }, { label: "Bêdeng 4", chars: ["ɓ", "ɗ", "ᶑ", "ʄ", "ɠ", "ʛ", "ʘ", "ǀ", "ǃ", "ǂ", "ǁ"] }, { label: "Dengdêr", chars: ["i", "y", "ɪ", "ʏ", "ɨ", "ʉ", "ɯ", "u", "ʊ", "e", "ø", "ɘ", "ɵ", "ɤ", "o", "ə", "ɚ", "ɛ", "œ", "ɜ", "ɝ", "ɞ", "ʌ", "ɔ", "æ", "ɶ", "ɐ", "a", "ɑ", "ɒ"] }, { label: "Suprasegmental", chars: ["ˈ", "ˌ", "ː", "ˑ", "ʼ", "ˀ", "ˤ", "ᵝ", "ᵊ", "ˠ", "ʰ", "ʱ", "ʲ", "ˡ", "ⁿ", "ᵑ", "ʷ", "ᶣ", "˞", "‿"] }, { label: "Dîakrîtîk", chars: ["̚", "̪", "̺", "̻", "̼", "̬", "̊", "̥", "̞", "̝", "̘", "̙", "̽", "̟", "̠", "̈", "̤", "̹", "̜", "̍", "̩", "̆", "̯", "̃", "̰", "͡", "͜"] }, { label: "Ton", chars: ["̋", "́", "̄", "̀", "̏", "̌", "̂", "˥", "˦", "˧", "˨", "˩", "ꜛ", "ꜜ", "↗", "↘", "‖"] } ], /** Builds the two-sub-tab character palette under the textarea. */ buildIpaPalette: function (wrap, ta) { if (wrap.find(".wiktku-ipa-palette").length) return; var panel = $("<div class='wiktku-ipa-panel'></div>").hide(); var toggle = $("<a href='#' class='wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tîpên bilêvkirinê</span>")); toggle.on("click", function (e) { e.preventDefault(); var open = panel.is(":visible"); panel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); wrap.append($("<div class='wiktku-adv-toggle-row'></div>").append(toggle)); // Sub-tab bar, with the two template buttons pinned right. var subTabs = $("<div class='wiktku-ipa-subtabs'></div>"); var kuTab = $("<span class='wiktku-ipa-subtab wiktku-tab-active'>IPA (kurdî)</span>"); var fullTab = $("<span class='wiktku-ipa-subtab'>IPA</span>"); subTabs.append(kuTab).append(fullTab); var tplBtns = $("<span class='wiktku-ipa-tplbtns'></span>"); $.each([ { label: "{{ku-IPA|+}}", snippet: "{{ku-IPA|}}", back: 2 }, { label: "{{IPA|+}}", snippet: "{{IPA|ku|}}", back: 2 } ], function (_, t) { var b = $("<button type='button' class='wiktku-ipa-tplbtn'></button>").text(t.label); b.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], t.snippet); // Park the cursor inside the braces, where the value goes. var pos = ta[0].selectionStart - t.back; ta[0].selectionStart = ta[0].selectionEnd = pos; ta.focus(); }); tplBtns.append(b); }); subTabs.append(tplBtns); panel.append(subTabs); function buildGrid(groups) { var grid = $("<div class='wiktku-ipa-grid'></div>"); $.each(groups, function (_, g) { var row = $("<div class='wiktku-ipa-row'></div>"); row.append($("<span class='wiktku-ipa-rowlabel'></span>").text(g.label)); var keys = $("<span class='wiktku-ipa-keys'></span>"); $.each(g.chars, function (_, ch) { var btn = $("<button type='button' class='wiktku-ipa-key'></button>"); // A combining mark on its own renders as a stray // accent floating over whatever precedes it, so // show it on a dotted circle — but insert only // the mark itself. var combining = /^[̀-ͯ҃-҉]$/.test(ch); btn.text(combining ? "◌" + ch : ch); if (combining) btn.addClass("wiktku-ipa-key-combining"); btn.attr("title", ch); btn.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], ch); ta.focus(); }); keys.append(btn); }); row.append(keys); grid.append(row); }); return grid; } var kuGrid = buildGrid(steps.pron.IPA_KU); var fullGrid = buildGrid(steps.pron.IPA_FULL).hide(); panel.append(kuGrid).append(fullGrid); kuTab.on("click", function () { kuTab.addClass("wiktku-tab-active"); fullTab.removeClass("wiktku-tab-active"); kuGrid.show(); fullGrid.hide(); }); fullTab.on("click", function () { fullTab.addClass("wiktku-tab-active"); kuTab.removeClass("wiktku-tab-active"); fullGrid.show(); kuGrid.hide(); }); panel.addClass("wiktku-ipa-palette"); wrap.append(panel); }, /** Inline preview + confirm panel for a "noLang" (auto-content) * pronunciation template — fetches what the snippet expands to * for this page and only inserts it if the user confirms. */ showTplPreview: function (stepDiv, ta, snippet, tplLabel) { // Only one preview panel open at a time. stepDiv.find(".wiktku-pron-preview").remove(); var panel = $("<div class='wiktku-pron-preview'></div>"); panel.append($("<div class='wiktku-pron-preview-label'></div>") .text("Pêşdîtina " + tplLabel + ":")); var body = $("<div class='wiktku-pron-preview-body'></div>").text("Tê barkirin…"); panel.append(body); var actions = $("<div class='wiktku-pron-preview-actions'></div>"); var confirmBtn = $("<button type='button' class='wiktku-pron-preview-confirm'>✓ Tevlî bike</button>") .prop("disabled", true); var cancelBtn = $("<button type='button' class='wiktku-pron-preview-cancel'>✕ Betal bike</button>"); actions.append(confirmBtn).append(cancelBtn); panel.append(actions); ta.before(panel); confirmBtn.on("click", function () { insertAtCursor(ta[0], snippet); panel.remove(); ta.focus(); }); cancelBtn.on("click", function () { panel.remove(); }); // action=parse, not action=expandtemplates. expandtemplates // returns *expanded wikitext*, so the preview read as // [[IPA]]<sup>([[Wîkîferheng:IPA kurmancî|kilîd]])</sup>: // <span class="IPA">/-{kshhe}-/</span>[[Kategorî:…]] — which // is exactly what the person is trying to avoid having to // read. parse hands back the rendered HTML the page will // actually show. // // Drop the leading "* " first: it is wikitext list syntax // wrapping the template, and keeping it would render the // preview as a bulleted list rather than the line itself. new mw.Api().post({ action: "parse", title: pageName, text: snippet.replace(/^\*\s*/, ""), prop: "text", wrapoutputclass: "", disablelimitreport: 1, disableeditsection: 1, contentmodel: "wikitext", formatversion: 2 }).done(function (data) { var html = (data && data.parse && data.parse.text) || ""; if ($.trim($("<div>").html(html).text())) { body.html(html); // Category links render as nothing but still exist; // and any real link inside a preview should not // navigate away from a half-filled form. body.find("a").attr("target", "_blank").attr("rel", "noopener"); } else { body.text("(vala — ji bo vê rûpelê tiştek nehate afirandin)"); } confirmBtn.prop("disabled", false); }).fail(function () { body.text("Pêşdîtin nehate barkirin — tu dikarî hîn jî wê tevlî bikî."); confirmBtn.prop("disabled", false); }); }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line; }).join("\n"); // "===" heading under Ziman and above the POS sections; the // field is shared across sections, so it's emitted once by // getWikitext() rather than per-POS-section (would otherwise // print the pronunciation twice for a two-POS entry). return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var capitalizedPos = capitalize(pos); // "form" opt-param (checked in posparams) marks this as a // form-of/inflected entry — the section title becomes // "Formeke <pos>ê" instead of the plain pos name. The // template call itself still uses the unchanged pos name. var isForm = $("#wiktku-posparams-opt-form").is(":checked"); var header = isForm ? "\n=== Formeke " + pos + "ê ===\n" : "\n=== " + capitalizedPos + " ===\n"; // Image line (between header and template call) var imageLine = steps.resim.output(values); // Read the live wikitext from the posparams textarea. // Fall back to a plain {{pos|lang}} if the step hasn't been built yet. var tplLine = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); if (!tplLine) { tplLine = "{{" + pos + "|" + (values.lang || "") + "}}"; } return header + imageLine + tplLine + "\n"; } }, // cinsiyet (gender) — shown for navdêr/serenav only, with choices built // from metadata[lang].g since not every language has grammatical gender. cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams // Single source of truth for the selected gender code. The visible // dropdown lives inside the posparams step (see steps.posparams), // but it must always read/write THIS hidden field — not a field of // its own — since getValuesForStep("cinsiyet") reads from here. build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-cinsiyet-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // jimar (grammatical number) — same hidden-field pattern as cinsiyet // above, but writes into its own j= template parameter instead of // sharing c=. Shown for navdêr/serenav only, with choices built from // whichever of metadata[lang].g are number codes (see isNumberCode). jimar: { id: "jimar", name: "jimar", question_fmt: 'Jimara "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-jimar-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // Lêker transitivity — hidden step, handled inside posparams lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function () { return false; }, choices: [ { code: "gh", label: "gerguhêz" }, { code: "x-gh", label: "xwerû-gerguhêz" }, { code: "p-gh", label: "pêkhatî-gerguhêz" }, { code: "h-gh", label: "hevedudanî-gerguhêz" }, { code: "b-gh", label: "biwêjî-gerguhêz" }, { code: "ngh", label: "negerguhêz" }, { code: "x-ngh", label: "xwerû-negerguhêz" }, { code: "p-ngh", label: "pêkhatî-negerguhêz" }, { code: "h-ngh", label: "hevedudanî-negerguhêz" }, { code: "b-ngh", label: "biwêjî-negerguhêz" } ], output: function () { return ""; } }, // tr — hidden step, handled inside posparams tr: { id: "tr", name: "transliterasyon", question_fmt: "Transliterasyona vê kelîmeyê", multiple: false, narrow: true, visible: function () { return false; } }, posparams: { id: "posparams", // Fused onto the "pos" card visually (see #wiktku-start-posparams // in styles.css) so the two read as ONE question — this name is // only a no-CSS/no-JS fallback, since the h3 that would show it // is hidden by CSS. name: "taybetmendî", // Shows what's actually being asked for: gender for nouns, verb // type for verbs, a generic fallback otherwise. question_fmt: function (values) { var pos = values.pos || ""; // Cinsiyet/Jimar fields below are self-labelled, so no title needed here. if (pos === "navdêr" || pos === "serenav") return ""; if (/^lêker/.test(pos)) return "Cureyê lêkerê"; return "Taybetmendî"; }, visible: function (values) { return !!(values.lang && values.pos); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-posparams-wrap").length) return null; var wrap = $("<div class='wiktku-posparams-wrap'></div>"); var helpers = $("<div class='wiktku-posparams-helpers'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-posparams-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-posparams-text") .attr("rows", 2); var _rebuilding = false; function safeRebuild() { if (_rebuilding) return; _rebuilding = true; steps.posparams.rebuildTa(stepDiv); _rebuilding = false; refresh(); } // Generic text-input row factory function makeTextRow(key, labelText, placeholder) { var row = $("<div class='wiktku-posparams-row'></div>") .attr("id", "wiktku-posparams-row-" + key).hide(); var inp = $("<input type='text'>") .addClass("wiktku-start-narrow wiktku-posparams-field") .attr("data-pp-key", key) .attr("placeholder", placeholder || ""); inp.on("input", safeRebuild); row.append($("<label></label>").text(labelText + ": ")).append(inp); return row; } // cinsiyet var cinsiyetRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-c'></div>") .append($("<label></label>").text("Cinsiyet: ")).hide(); var cinsiyetSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-cinsiyet-sel") .append($("<option value=''>— hilbijêre —</option>")); // Writes into the real, shared #wiktku-start-cinsiyet-field (owned by // steps.cinsiyet) rather than a field of its own — see the comment // on steps.cinsiyet.build for why that matters. cinsiyetSel.on("change", function () { $("#wiktku-start-cinsiyet-field").val($(this).val()).trigger("change"); safeRebuild(); }); cinsiyetRow.append(cinsiyetSel); // jimar (number) — second dropdown next to Cinsiyet, writes // into the shared hidden #wiktku-start-jimar-field, into its // own j= param instead of sharing c=. Options + tooltip are // built in syncHelpers once the language's number codes are known. var jimarRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-jimar'></div>") .append($("<label></label>").text("Jimar: ")).hide(); var jimarSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-jimar-sel") .append($("<option value=''>— hilbijêre —</option>")); jimarSel.on("change", function () { $("#wiktku-start-jimar-field").val($(this).val()).trigger("change"); safeRebuild(); }); jimarRow.append(jimarSel); // lektur: two plain questions (transitivity + structural form) // instead of one 10-option dropdown. Emitted code: base alone // ("gh"), or prefix + "-" + base ("x-gh"). var lekturRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lektur'></div>") .append($("<label></label>").text("Lêker derbasdar e? ")).hide(); var lekturSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lektur-sel") .append($("<option value=''>— hilbijêre —</option>")) .append($("<option value='gh'>gerguhêz (bireser digire)</option>")) .append($("<option value='ngh'>negerguhêz (bireser nagire)</option>")); lekturSel.on("change", safeRebuild); lekturRow.append(lekturSel); // Second half of the same question — the structural form. // Blank = xwerû/sade, which is the common case. var lekturFormRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lekturform'></div>") .append($("<label></label>").text("Şiklê lêkerê: ")).hide(); var lekturFormSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lekturform-sel") .append($("<option value=''>sade (asayî)</option>")) .append($("<option value='x'>xwerû</option>")) .append($("<option value='p'>pêkhatî</option>")) .append($("<option value='h'>hevedudanî</option>")) .append($("<option value='b'>biwêjî</option>")); lekturFormSel.on("change", safeRebuild); lekturFormRow.append(lekturFormSel); helpers.append(cinsiyetRow).append(jimarRow).append(lekturRow).append(lekturFormRow); // ── Everything below here is "Tercîhên pêşketî" ────────────── // These rows live inside a collapsed panel, so the default // view of this card is two dropdowns instead of twenty-odd fields. // Transliteration is a primary field, not an advanced one, for // any language not written in Latin script: for those, an // entry without it is incomplete. syncHelpers already gates // the row on needsTransliteration(lang), so for Kurmancî and // other Latin-script languages it simply never appears. helpers.append(makeTextRow("tr", "Transliterasyon (tr)", "Transliterasyon…")); var advPanel = $("<div class='wiktku-posparams-adv-panel'></div>").hide(); advPanel .append(makeTextRow("cuda", "nîşankirina alternatîv", "cuda…")) .append(makeTextRow("ts", "Transkrîpsiyon (ts)", "Transkrîpsiyon…")) .append(makeTextRow("m", "Forma mê (m)", "Forma mê…")) .append(makeTextRow("mtr", "Translit. mê (mtr)", "Transliterasyona mê…")) .append(makeTextRow("n", "Forma nêr (n)", "Forma nêr…")) .append(makeTextRow("ntr", "Translit. nêr (ntr)", "Transliterasyona nêr…")) .append(makeTextRow("p", "Forma pirjimar (p)", "Forma pirjimar…")) .append(makeTextRow("ptr", "Translit. pirjimar", "Transliterasyona pirjimar…")) .append(makeTextRow("y", "Forma yekjimar (y)", "Forma yekjimar…")) .append(makeTextRow("ytr", "Translit. yekjimar", "Transliterasyona yekjimar…")) .append(makeTextRow("sûp", "Forma sûperlatîv (sûp)", "Forma sûperlatîv…")) .append(makeTextRow("sûptr", "Translit. sûperlatîv", "Transliterasyona sûperlatîv…")) .append(makeTextRow("komp", "Forma komparatîv (komp)", "Forma komparatîv…")) .append(makeTextRow("komptr", "Translit. komparatîv", "Transliterasyona komparatîv…")) .append(makeTextRow("gir", "Forma girdêk (gir)", "gir=…")) .append(makeTextRow("girtr", "Translit. gir", "girtr=…")) .append(makeTextRow("hûr", "Forma hûrek (hûr)", "hûr=…")) .append(makeTextRow("hûrtr", "Translit. hûr", "hûrtr=…")) .append(makeTextRow("hanja", "Forma hanja", "hanja=…")) .append(makeTextRow("hanjaTr","Translit. hanja", "hanjaTr=…")) // Lêker rehên demê (only shown when pos is lêker — see syncHelpers) .append(makeTextRow("niha", "Rehê dema niha (niha)", "Rehê dema niha…")) .append(makeTextRow("nihatr", "Translit. rehê dema niha", "Transliterasyona rehê dema niha…")) .append(makeTextRow("borî", "Rehê dema borî (borî)", "Rehê dema borî…")) .append(makeTextRow("borîtr", "Translit. rehê dema borî", "Transliterasyona rehê dema borî…")) .append(makeTextRow("subj", "Rehê dema bilanî (subj)", "Rehê dema bilanî…")) .append(makeTextRow("subjtr", "Translit. rehê dema bilanî", "Transliterasyona rehê dema bilanî…")); // Optional boolean params — nested inside the advanced panel // (they were already the most niche thing on the card). var optPanel = $("<div class='wiktku-posparams-opt-panel'></div>"); $.each([ { key: "form", label: "form — ev made forma tewandî ye" }, { key: "formaalt", label: "formaalt — vê madeyê bike forma alternatîv" }, { key: "nekatcure", label: "nekatcure — sinifa rêzimanî kategorîze neke" }, { key: "nekatcins", label: "nekatcins — kategoriya cinsiyetê neyîne" }, { key: "nekatçendterm", label: "nekatçendterm — kategoriya çend-term neyîne" }, { key: "serlînkneke", label: "serlînkneke — sernavê madeyê lînk neke" }, { key: "nekatpalîndrom", label: "nekatpalîndrom — kategoriya palîndromê neyîne" }, { key: "neformtr", label: "neformtr — transliterasyona forman neyîne" } ], function (_, p) { var cb = $("<input type='checkbox'>") .attr("id", "wiktku-posparams-opt-" + p.key).val(p.key).on("change", safeRebuild); var lbl = $("<label></label>").attr("for", "wiktku-posparams-opt-" + p.key).text(" " + p.label); optPanel.append($("<div class='wiktku-posparams-opt-row'></div>").append(cb).append(lbl)); }); advPanel.append(optPanel); var optToggle = $("<a href='#' class='wiktku-posparams-opt-toggle wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tercîhên pêşketî</span>")); optToggle.on("click", function (e) { e.preventDefault(); var open = advPanel.is(":visible"); advPanel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); helpers.append($("<div class='wiktku-adv-toggle-row'></div>") .append(optToggle)); helpers.append(advPanel); wrap.append(helpers).append(ta); // Typing directly in textarea keeps cinsiyet/jimar hidden // fields in sync, but does NOT call refresh() — preserves // manual edits. ta.on("input", function () { var text = $(this).val(); var cMatch = text.match(/\|c=([^|}\s]+)/); $("#wiktku-start-cinsiyet-field").val(cMatch ? cMatch[1] : ""); var jMatch = text.match(/\|j=([^|}\s]+)/); $("#wiktku-start-jimar-field").val(jMatch ? jMatch[1] : ""); }); stepDiv.append(wrap); return null; }, /** Reads all helper widget values and rewrites the textarea. * Called only by safeRebuild (user interaction) — never by syncHelpers, * so manual textarea edits are never overwritten by a refresh cycle. */ rebuildTa: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; if (!pos || !lang) return; var cinsiyet = stepDiv.find(".wiktku-posparams-cinsiyet-sel").val() || ""; var jimar = stepDiv.find(".wiktku-posparams-jimar-sel").val() || ""; // Two dropdowns, one code: "gh" / "ngh" on their own, or // prefixed with the structural form ("x-gh", "b-ngh", …). var lekturBase = stepDiv.find(".wiktku-posparams-lektur-sel").val() || ""; var lekturForm = stepDiv.find(".wiktku-posparams-lekturform-sel").val() || ""; var lektur = lekturBase ? (lekturForm ? lekturForm + "-" + lekturBase : lekturBase) : ""; function v(key) { return $.trim(stepDiv.find(".wiktku-posparams-field[data-pp-key='" + key + "']").val()); } var out = "{{" + pos + "|" + lang; if (pos === "navdêr" || pos === "serenav") { out += cinsiyet ? "|c=" + cinsiyet : (lang === "ku" ? "|c=?" : ""); // Number is its own j= param, separate from c= (which // holds gender, including compounds like m-p/n-p). if (jimar) out += "|j=" + jimar; } else if (/^lêker/.test(pos) && lektur) { out += "|c=" + lektur; } if (v("cuda")) out += "|" + v("cuda"); if (v("tr")) out += "|tr=" + v("tr"); if (v("ts")) out += "|ts=" + v("ts"); $.each(["m","n","p","y"], function (_, k) { if (v(k)) out += "|" + k + "=" + v(k); if (v(k+"tr")) out += "|" + k + "tr=" + v(k+"tr"); }); if (v("sûp")) out += "|sûp=" + v("sûp"); if (v("sûptr")) out += "|sûptr=" + v("sûptr"); if (v("komp")) out += "|komp=" + v("komp"); if (v("komptr")) out += "|komptr=" + v("komptr"); if (v("gir")) out += "|gir=" + v("gir"); if (v("girtr")) out += "|girtr=" + v("girtr"); if (v("hûr")) out += "|hûr=" + v("hûr"); if (v("hûrtr")) out += "|hûrtr=" + v("hûrtr"); if (v("hanja")) out += "|hanja=" + v("hanja"); if (v("hanjaTr")) out += "|hanjaTr=" + v("hanjaTr"); if (v("niha")) out += "|niha=" + v("niha"); if (v("nihatr")) out += "|nihatr=" + v("nihatr"); if (v("borî")) out += "|borî=" + v("borî"); if (v("borîtr")) out += "|borîtr=" + v("borîtr"); if (v("subj")) out += "|subj=" + v("subj"); if (v("subjtr")) out += "|subjtr=" + v("subjtr"); stepDiv.find(".wiktku-posparams-opt-panel input:checked").each(function () { var key = $(this).val(); // "form" marks this entry as a form-of/inflected entry — it // takes "erê" rather than the plain "1" the other boolean // opt params use. out += "|" + key + "=" + (key === "form" ? "erê" : "1"); }); out += "}}"; stepDiv.find(".wiktku-posparams-text").val(out); $("#wiktku-start-cinsiyet-field").val(cinsiyet); $("#wiktku-start-jimar-field").val(jimar); }, /** Called from refresh() — controls row visibility only. * Does NOT rewrite textarea so user edits are preserved. * Rebuilds only when textarea is empty (first pos selection). */ syncHelpers: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; var needsTr = needsTransliteration(lang); var isNom = pos === "navdêr" || pos === "serenav" || pos === "rengdêr"; var isAdj = pos === "rengdêr"; var isTîp = pos === "tîp"; var isJa = lang === "ja"; var isLeker = /^lêker/.test(pos); // Kurmancî verbs are conjugated from the present/past roots // alone — there's no separate subjunctive root the way some // other languages have — so this pair of fields is noise for // lang=ku specifically, unlike niha/borî which every lêker // language needs. var isLekerSubj = isLeker && lang !== "ku"; // metadata[lang].g lists gender AND number codes together — // split them here (see isNumberCode) so Cîns only ever offers // gender codes (and gender+plural compounds like m-p/n-p, // which aren't NUMBER_LABELS keys) and Jimar only offers number codes. var meta = metadata[lang]; var allCodes = (meta && meta.g) || []; var genderCodes = $.grep(allCodes, function (c) { return !isNumberCode(c); }); var jimarCodes = $.grep(allCodes, function (c) { return isNumberCode(c); }); var showC = (pos === "navdêr" || pos === "serenav") && genderCodes.length > 0; var cRow = stepDiv.find("#wiktku-posparams-row-c"); cRow.toggle(showC); if (showC) { var sel = cRow.find(".wiktku-posparams-cinsiyet-sel"); // Prefer the select's own current value (normal in-session // use); fall back to the shared hidden field, which is how // a cache/section restore communicates a saved gender // before this select has any <option>s to hold it. var prev = sel.val() || $("#wiktku-start-cinsiyet-field").val() || ""; sel.find("option[value!='']").remove(); $.each(genderCodes, function (_, code) { sel.append($("<option></option>").val(code).text(genderLabel(code))); }); if (prev) sel.val(prev); } var showJimar = (pos === "navdêr" || pos === "serenav") && jimarCodes.length > 0; var jimarRowEl = stepDiv.find("#wiktku-posparams-row-jimar"); jimarRowEl.toggle(showJimar); if (showJimar) { var jimarSelEl = jimarRowEl.find(".wiktku-posparams-jimar-sel"); var prevJimar = jimarSelEl.val() || $("#wiktku-start-jimar-field").val() || ""; jimarSelEl.find("option[value!='']").remove(); $.each(jimarCodes, function (_, code) { var def = NUMBER_LABELS[code] || {}; var opt = $("<option></option>").val(code).text(numberOptionLabel(code)); // The explanation (cat, e.g. "dualia tantum") shows as a // hover tooltip — <option> can't hold richer markup. if (def.cat) opt.attr("title", def.cat); jimarSelEl.append(opt); }); if (prevJimar) jimarSelEl.val(prevJimar); } stepDiv.find("#wiktku-posparams-row-lektur").toggle(isLeker); // Only ask for the structural form once gerguhêz/negerguhêz is answered. stepDiv.find("#wiktku-posparams-row-lekturform") .toggle(isLeker && !!stepDiv.find(".wiktku-posparams-lektur-sel").val()); stepDiv.find("#wiktku-posparams-row-tr").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-ts").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-m").toggle(isNom); stepDiv.find("#wiktku-posparams-row-mtr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-n").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ntr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-p").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ptr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-y").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ytr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-sûp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-sûptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-komp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-komptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-gir").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-girtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hûr").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-hûrtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hanja").toggle(isJa); stepDiv.find("#wiktku-posparams-row-hanjaTr").toggle(isJa); stepDiv.find("#wiktku-posparams-row-niha").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-nihatr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-borî").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-borîtr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-subj").toggle(isLekerSubj); stepDiv.find("#wiktku-posparams-row-subjtr").toggle(isLekerSubj && needsTr); if (!$.trim(stepDiv.find(".wiktku-posparams-text").val())) { steps.posparams.rebuildTa(stepDiv); } }, output: function () { return ""; } // pos.output reads the textarea directly }, dfn: { id: "dfn", name: "Mane", // Field types that live behind "Malûmatên pêşketî". Kept as one // list so the collapse CSS, the count badge and the allGroups // adv: flags below can't drift apart. ADV_SUBGROUPS: [ "wiktku-dfn-etiket", "wiktku-dfn-kategori", "wiktku-dfn-alternativ", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ], question_fmt: function (values) { var base = "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin!"; if (values.lang === "ku") { return base + " Ji bo tercimeyan beşa 'Werger' bi kar bîne!"; } return base; }, multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, // Builds one sense block (<li>): mane textarea, nimûne list, and // sub-lists for alternatîv/hevmane/dijmane/etc. buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // The full refresh() (which rebuilds Werger/Bi zaravayên din — // glossList()/build() re-reads every sense from the DOM) is // deferred to blur rather than run on every keystroke; see // onDfnInput for why that's safe. dfnArea.on("blur", function () { refresh(); }); // — Tercime + Îzah boxes (non-ku alternative to the plain mane box) — // Non-ku entries get a direct translation plus a {{îzah|…}}-wrapped // gloss instead of a Kurdish-style gloss. Rather than teach every // consumer (getSenses/getOutput/linkify) a second data shape, these // boxes just write their combined text into dfnArea and re-fire its // "input" event, so dfnArea stays the single source of truth. var tercimeArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-tercime-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-tercime") .attr("rows", 2) .attr("placeholder", "Tercimeyên rasterast ên kurmancî… Ji bo school-a îngilîzî li vir 'mekteb, medrese' binivîse"); var izahArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-izah-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-izah") .attr("rows", 3) .attr("placeholder", "Îzaha kurmancî… Ji bo school-a îngilîzî li vir 'cihê tehsîlgirtinê' binivîse"); var nonKuWrap = $("<div class='wiktku-dfn-nonku-wrap'></div>") .append(tercimeArea).append(izahArea) .hide(); function syncNonKuToMane() { var t = $.trim(tercimeArea.val()); var iz = $.trim(izahArea.val()); // if tercime is blank, use îzah as definition var combined = t ? (iz ? t + " {{îzah|" + iz + "}}" : t) : iz; dfnArea.val(combined); // Re-fires onDfnInput, as if this were typed directly into // the mane textarea. dfnArea.trigger("input"); } tercimeArea.on("input", syncNonKuToMane); izahArea.on("input", syncNonKuToMane); // Same deferred-refresh treatment as dfnArea itself — these two // feed into it (see syncNonKuToMane above). tercimeArea.on("blur", function () { refresh(); }); izahArea.on("blur", function () { refresh(); }); // Switches between the plain mane box and the tercime+îzah pair — // only for non-ku entries with no tplSelect selected. function updateManeMode() { var lang = getValues().lang || ""; var isTpl = !!tplSelect.val(); if (lang && lang !== "ku" && !isTpl) { dfnArea.hide(); nonKuWrap.show(); } else { nonKuWrap.hide(); if (!isTpl) dfnArea.show(); } } // Store on the block so refresh() can re-sync every block when // lang changes, and restoreDfn() can re-sync after restoring. block.data("updateManeMode", updateManeMode); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || {}; // Cache of all non-placeholder option elements, so updateTplOptions // can detach/re-attach them without losing the full list. var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.attr("data-placeholder", "Li şablonekê bigere"); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (name, tpl) { // Shows "name — tpl.desc" when a tplDefs entry has a desc // in data.json, same pattern as steps.pron's template picker. var opt = $("<option></option>") .val(name) .text(tpl.desc ? name + " — " + tpl.desc : name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); // Same status-dot / 🔗 / ⓘ row treatment as every other // template picker. This one carries the bare name in value=, // so the name mapper is the identity rather than a snippet // parse; descriptions come from each template's TemplateData. markTemplateOptions(tplSelect, function (opt) { return opt.val(); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible // ones — native <select> won't reliably hide options any other way. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); // Options that were detached when the descriptions arrived // missed that pass, so describe whatever is attached now. // The cache is warm by this point, so this is synchronous. applyTplDescriptions(tplSelect); tplSelect.trigger("wiktku:refresh"); if (currentVal && !currentStillValid) { tplSelect.val(""); tplTitleInput.hide().val(""); updateManeMode(); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpela hedefê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); tplTitleInput.on("blur", function () { refresh(); }); // Şablon senses have no plain gloss, so hide alternatîv/hevmane/ // dijmane/etc. Etîket, Nimûne and Jêgirtin stay visible either way. function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); nonKuWrap.hide(); tplTitleInput.show().focus(); } else { tplTitleInput.hide().val(""); updateManeMode(); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); // The template picker is an alternative to writing a // definition, not a step before it — so the box comes first // and this sits under it as a quiet link. It only expands // for the minority of senses that are a pointer at another // word (guharto, şaşnivîs, kevnbûyî) rather than a meaning. var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput) .hide(); var tplLink = $("<a href='#' class='wiktku-dfn-tpl-link'></a>") .text("Ev ne pênase ye — şablonek bi kar bîne"); tplLink.on("click", function (e) { e.preventDefault(); tplRow.show(); $(this).hide(); tplRow.find("input.wiktku-ac-input").first().focus(); }); /** Opens the picker without a click — used on restore, when a * sense already has a template and hiding it would make the * chosen value invisible. */ function revealTplRow() { tplRow.show(); tplLink.hide(); } block.data("revealTplRow", revealTplRow); block.append(dfnArea); block.append(nonKuWrap); block.append(tplLink); block.append(tplRow); // Apply lang filter on initial build. updateTplOptions(); updateManeMode(); // — Sub-field groups. — // The four most-used groups (Nimûne, Jêgirtin, Hevmane, Dijmane) // stay open; the rest sit behind the "Malûmatên pêşketî" toggle // (adv: true → .wiktku-dfn-subgroup-adv, keyed off by the collapse CSS). // Jêgirtin isn't in this array — it's a compound widget built // after the loop — but it's inserted right after Nimûne so the // visible order matches the list above. var allGroups = [ { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "wekî etîket lê xuya nabe tenê kategorîze dike", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê", adv: true }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in", adv: true }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e", adv: true }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e", adv: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); if (g.adv) groupDiv.addClass("wiktku-dfn-subgroup-adv"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } // The placeholder names the current language, but that's // often not chosen yet when this block is first built — // so keep a function around that refresh() (and onSubInput, // for newly-grown fields) can call again once lang is set // or changes. function subPlaceholder() { if (g.noLangSuffix) return g.label + "…"; var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return g.label + (langLabel ? " bi " + langLabel : "") + "…"; } function updateSubPlaceholders() { list.find("> li > textarea.wiktku-dfn-subfield").attr("placeholder", subPlaceholder()); } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": ") .append($("<span></span>").addClass("wiktku-dfn-sublabel-hint").text(g.izah)); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var useModifiers = !!MODIFIER_SUBGROUPS[g.cls]; list.data("updatePlaceholders", updateSubPlaceholders); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", subPlaceholder()); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow, useModifiers); }); list.append(useModifiers ? makeModifierLi(firstInput) : $("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder group — growing list, same structure as Nimûne. — (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text("Jêgirtin")) .append(": "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<textarea></textarea>") .addClass("wiktku-dfn-subfield wiktku-dfn-quote-citoid-input") .attr("rows", 1) .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi otomatîk tijî bike", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); // Fetches citation data from Citoid and fills this citation's // şablon + fields — only rebuilds fields on template change, // and never overwrites values the user already typed. function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoid.fetchJederFields(query).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only rebuild if switching şablon, so a repeat fetch // doesn't clear fields already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel wiktku-plain-select"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); srcSel.append($("<option></option>").val("__category__").text("Ji Kategorî:Çavkanî şablonekê hilbijêre")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); // Citoid is only useful before a source is chosen — // hide it once a selection is made, restore on reset. if (chosen) { citoidWrap.hide(); } else { citoidWrap.show(); return; } if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } if (chosen === "__category__") { // Search widget over the members of [[Kategorî:Çavkanî]]. // Picking a şablon here immediately switches the row to // "Bi destê xwe binivîsim" mode with {{Şablon}} pre-filled, var catWrap = $("<span></span>").addClass("wiktku-native-select-wrap wiktku-dfn-quote-src-cat"); var catInput = $("<input type='search' autocomplete='off'>") .addClass("wiktku-start-narrow wiktku-dfn-quote-src-cat-input") .attr("placeholder", "Li navê şablonê bigere…"); var catResults = $("<ul></ul>").addClass("wiktku-ac-results wiktku-dfn-quote-src-cat-results").hide(); var catStatus = $("<span></span>").addClass("wiktku-dfn-quote-src-cat-status").text("Şablon tên barkirin…"); var showCatResults = function (query) { var q = $.trim(query).toLowerCase(); catResults.empty(); var list = catSrcTemplates || []; var matched = q ? $.grep(list, function (name) { return name.toLowerCase().indexOf(q) !== -1; }) : list; if (!matched.length) { catResults.hide(); return; } $.each(matched.slice(0, 50), function (_, name) { var li = $("<li></li>").text(name).attr("data-value", name); var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; e.preventDefault(); selectCatTpl(name); }); li.on("mousedown", function (e) { e.preventDefault(); selectCatTpl(name); }); catResults.append(li); }); catResults.show(); }; // Wraps the chosen şablon as {{Name}}, drops it into the // manual textarea, and switches the row into manual mode // so the user can keep editing it (add params, etc.). var selectCatTpl = function (name) { catResults.hide(); srcSel.val("__manual__"); srcSel.trigger("change"); srcFields.find(".wiktku-dfn-quote-src-manual") .val("{{" + name + "}}") .trigger("focus"); }; catInput.on("input", function () { showCatResults($(this).val()); }); catInput.on("focus", function () { showCatResults($(this).val()); }); catInput.on("blur", function () { setTimeout(function () { catResults.hide(); }, 200); }); catWrap.append(catInput).append(catResults).append(catStatus); srcFields.append(catWrap); fetchCatSrcTemplates().then(function () { catStatus.text(""); }, function () { catStatus.text("Şablon nehatin barkirin."); }); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (key, label) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", key) .attr("placeholder", label + "…"); // "Sernav" / "Sernavê orjînal" (title fields, e.g. for // kitêb/kovar/malper) get a taller, draggable box; every // other field in the template stays as-is. Field labels // come from the on-wiki jederDefs data, so match on the // (diacritic-folded) label text rather than a fixed key. var foldedLabel = foldDiacritics(label); if (/^sernav$/.test(foldedLabel) || /orjin/.test(foldedLabel)) { inp.addClass("wiktku-dfn-quote-src-input--title"); } row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); jederGroupDiv.append(jederLbl).append(jederList); // Straight after Nimûne rather than last: Jêgirtin is the // same kind of thing (an attested use of the word) and the // two belong together — see the allGroups comment above. var nimuneGroup = block.find(".wiktku-dfn-nimune-group"); if (nimuneGroup.length) jederGroupDiv.insertAfter(nimuneGroup); else block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); // ── "Malûmatên pêşketî" — per sense, after Dijmane ─────── // One toggle per sense rather than one for the whole step: // the fields behind it (Etîket, Kategorî, Jornav…) belong to // a single meaning, so a global switch flipped them for every // sense at once and gave a count that answered "across all // senses" — not a question anybody was asking. (function () { block.addClass("wiktku-sense-adv-hidden"); var advRow = $("<div class='wiktku-adv-toggle-row wiktku-sense-adv-row'></div>"); var advToggle = $("<a href='#' class='wiktku-adv-toggle'></a>").attr("aria-expanded", "false"); var advLabel = $("<span class='wiktku-adv-toggle-text'></span>"); advToggle.append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")).append(advLabel); function syncAdv() { var hidden = block.hasClass("wiktku-sense-adv-hidden"); advLabel.text(hidden ? "Malûmatên pêşketî nîşan bide" : "Malûmatên pêşketî veşêre"); advToggle.attr("aria-expanded", hidden ? "false" : "true") .toggleClass("wiktku-adv-open", !hidden); } advToggle.on("click", function (e) { e.preventDefault(); block.toggleClass("wiktku-sense-adv-hidden"); syncAdv(); }); block.data("syncSenseAdv", syncAdv); advRow.append(advToggle); // After the last always-visible group (Dijmane) and before // the advanced ones, which sit below it in DOM order. var lastPrimary = block.find(".wiktku-dfn-dijmane-group"); if (lastPrimary.length) advRow.insertAfter(lastPrimary); else block.append(advRow); syncAdv(); }()); return block; }, /** Shows only `block` among the sense list; hides every other one. */ setOpenSense: function (stepDiv, block) { stepDiv.find("li.wiktku-dfn-sense").each(function () { $(this).toggleClass("wiktku-sense-collapsed", !$(this).is(block)); }); steps.dfn.renderSenseTabs(stepDiv); }, /** Rebuilds the "Mane 1 / Mane 2 / [trash] / + Mane zêde bike" tab row from the current sense list. */ renderSenseTabs: function (stepDiv) { var tabsDiv = stepDiv.find(".wiktku-dfn-sense-tabs"); if (!tabsDiv.length) return; tabsDiv.empty(); var blocks = stepDiv.find("li.wiktku-dfn-sense"); var openLi = null; blocks.each(function (i) { var li = $(this); var isOpen = !li.hasClass("wiktku-sense-collapsed"); if (isOpen) openLi = li; var tab = $("<span class='wiktku-dfn-sense-tab'></span>") .text("Mane " + (i + 1)) .toggleClass("wiktku-tab-active", isOpen); tab.on("click", function () { steps.dfn.setOpenSense(stepDiv, li); }); tabsDiv.append(tab); }); // One delete button for the whole bar — not one per tab — so // there's only ever a single, deliberate hit-target for a // destructive action, positioned away from the tabs people // click to switch senses. Always keep at least one Mane. if (blocks.length > 1 && openLi) { var openIdx = blocks.index(openLi); var trash = makeTrashButton("Vê maneyê jê bibe (Mane " + (openIdx + 1) + ")"); trash.on("click", function () { if (!window.confirm("Tu dixwazî Mane " + (openIdx + 1) + " jê bibî? Ev tişt nayê vegerandin.")) return; steps.dfn.removeSense(stepDiv, openLi); }); tabsDiv.append(trash.$element); } var addBtn = $("<button type='button' class='wiktku-add-sense'></button>") .append($("<span class='wiktku-add-sense-plus'>+</span>")) .append(document.createTextNode("Mane zêde bike")); addBtn.on("click", function (e) { e.preventDefault(); steps.dfn.addSense(stepDiv); }); tabsDiv.append(addBtn); }, // Deliberately does nothing on every keystroke. The only thing a // live Mane/template-title edit needs to propagate is the Werger/ // Bi zaravayên din gloss list (glossList()/build() re-read every // sense in the DOM, and get slow with more than one sense around) // — mane itself isn't a required step, so nothing else in // refresh() depends on it changing mid-keystroke. The callers // (dfnArea/tercimeArea/izahArea/tplTitleInput) run refresh() on // blur instead; getWikitext()/output() always re-read the DOM // fresh regardless, so the final wikitext is correct either way. onDfnInput: function (stepDiv, block, textarea) {}, /** Appends a sense, opens it, and hides the others. */ addSense: function (stepDiv) { var list = stepDiv.find("ol.wiktku-dfn-list"); var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); initSelects(newBlock); steps.dfn.setOpenSense(stepDiv, newBlock); newBlock.find("textarea.wiktku-dfn-mane").first().focus(); refresh(); return newBlock; }, /** Removes one sense block. Assumes the caller already confirmed * and already checked more than one sense remains. If the * removed sense was the open one, opens whichever sense ends up * taking its place (or the last one, if it was the last). */ removeSense: function (stepDiv, li) { var list = stepDiv.find("ol.wiktku-dfn-list"); var blocks = list.find("li.wiktku-dfn-sense"); var removedIdx = blocks.index(li); var wasOpen = !li.hasClass("wiktku-sense-collapsed"); li.remove(); if (wasOpen) { var remaining = list.find("li.wiktku-dfn-sense"); var next = remaining.eq(removedIdx); if (!next.length) next = remaining.last(); if (next.length) steps.dfn.setOpenSense(stepDiv, next); } steps.dfn.renderSenseTabs(stepDiv); refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow, modifiers) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow, modifiers); }); list.append(modifiers ? makeModifierLi(next) : $("<li></li>").append(next)); // New field starts with no placeholder — give it (and any // others in the list) the current one. var updatePlaceholders = list.data("updatePlaceholders"); if (typeof updatePlaceholders === "function") updatePlaceholders(); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: {}, posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; // One reassurance, shown once for the whole Mane step: the // "an jî şablonek hilbijêre" dropdown inside each sense is // optional — plain text is the normal path. if (!stepDiv.find(".wiktku-dfn-tpl-hint").length) { stepDiv.append( $("<p class='wiktku-step-hint wiktku-dfn-tpl-hint'></p>").text( "Ji bo her maneyekê, dropdown-a \"an jî şablonek hilbijêre\" ne mecbûrî ye — bi gelemperî tu tenê maneyê bi tîpên asayî dinivîsî. Ew şablon tenê ji bo rewşên taybet in (mînak: guherto, kevnbûyî, şaşnivîs); heke tu nizanî kîjan divê, vale bihêle." ) ); } var tabsDiv = $("<div class='wiktku-dfn-sense-tabs'></div>"); stepDiv.append(tabsDiv); var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); steps.dfn.renderSenseTabs(stepDiv); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName === "__category__") { // Reachable only if the user opened the category search but // never picked a şablon — picking one switches the row to // __manual__ (see selectCatTpl above), so there's nothing // meaningful to save here. } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: readList("wiktku-dfn-etiket"), kategori: readList("wiktku-dfn-kategori"), nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense var izahLines = []; // parallel — raw îzah gloss for that same sense // True only once some sense's *actual* dfn text (post tercime/îzah // split) is non-empty. var hasLinkableMane = false; $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("# " + (tplKatTpl ? tplKatTpl + " " : "") + (tplLabelTpl ? tplLabelTpl + " " : "") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(""); // template senses have no îzah return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty // Pull the îzah gloss (if any) out of the combined tercime+îzah // string — it's spliced back in separately below, after its // own linkify pass (see izahLines / the second linkifyText call). var izahRaw = null; var tercimeIzah = splitTercimeIzah(dfn); if (tercimeIzah) { dfn = tercimeIzah.tercime; izahRaw = stripWikilinks(tercimeIzah.izah); } if (dfn) { dfn = stripWikilinks(dfn); // Sentence-case + trailing period are for ku definitions, // which are written as full glosses. if (lang === "ku") { if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } // Real prose — this is what makes the sense worth running // through the main linkify pass. hasLinkableMane = true; } else if (izahRaw === null) { // No mane at all — this is just the "{{mane?|lang}}" // placeholder, a bare template call with no plain words // in it. Do NOT count it as linkable: sending nothing but // bracketed templates through the main linkify pass hangs // the linkify gadget (see the hasLinkableMane/hasIzah // check below). dfn = lang === "ku" ? "{{mane?|" + lang + "}}" : ""; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var out = "# " + (katTpl ? katTpl + " " : "") + (labelTpl ? labelTpl + " " : "") + dfn; var idx = defLines.length; var hasThisIzah = izahRaw !== null && $.trim(izahRaw) !== ""; // Bare {{...}} token — like {{wiktku-cite-N}}, this survives // linkify's first pass untouched (it treats template calls as // opaque), then gets swapped for {{îzah|…}} once the actual // gloss text has been linkified in its own separate pass. if (hasThisIzah) { out += (dfn ? " " : "") + "{{wiktku-izah-" + idx + "}}"; } function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(hasThisIzah ? izahRaw : ""); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } // Runs text through the linkify gadget if it's loaded, otherwise // just passes it through unchanged. Shared by both linkify passes // below (main mane text, and — separately — îzah glosses). function linkifyText(t, cb) { if (typeof $.kuLinkify === "function") { $.kuLinkify(t, cb); } else { cb(t); } } var hasIzah = izahLines.some(function (t) { return t && $.trim(t) !== ""; }); var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with nimûne?. text = "# {{mane?|" + lang + "}}\n#* {{nimûne?|" + lang + "}}\n"; callback(text); return; } // Runs the îzah-only linkify pass against `base` (either the raw // text, when there's no linkable mane to run the main pass on // first, or the already-linkified main text). Shared by both // branches below so the token-splice logic only lives once. function runIzahPass(base) { var izahJoined = $.map(izahLines, function (raw, idx) { if (!raw) return undefined; return "{{wiktku-izah-open-" + idx + "}}" + raw + "{{wiktku-izah-close-" + idx + "}}"; }).join("\n"); linkifyText(izahJoined, function (izahLinked) { var izahByIdx = {}; var re = /\{\{wiktku-izah-open-(\d+)\}\}([\s\S]*?)\{\{wiktku-izah-close-\1\}\}/g; var m; while ((m = re.exec(izahLinked)) !== null) { izahByIdx[parseInt(m[1], 10)] = m[2]; } var withIzah = base.replace(/\{\{wiktku-izah-(\d+)\}\}/g, function (_, n) { var linked = izahByIdx[parseInt(n, 10)]; return linked !== undefined ? "{{îzah|" + linked + "}}" : ""; }); callback(restoreCites(withIzah)); }); } if (!hasLinkableMane) { if (!hasIzah) { // All filled senses are template senses (or otherwise have // no plain text at all) — nothing here needs linkify. callback(restoreCites(text)); return; } // There's no plain mane text anywhere (e.g. tercime left blank // with only îzah filled in), so every defLine is just a bare // template call with nothing to word-link. Sending a line // like "# {{wiktku-izah-0}}" through the main linkify pass // gives it no plain words to work with, makes the linkify // gadget hang — so skip that pass entirely and run only // the îzah pass, splicing straight into the unlinkified text. var loadIzahOnly = function () { runIzahPass(text); }; mw.loader.using("ext.gadget.linkify", loadIzahOnly, loadIzahOnly); return; } var didTryToLoad = function () { // First pass: the main definition text (mane), same as before. linkifyText(text, function (mainLinked) { if (!hasIzah) { callback(restoreCites(mainLinked)); return; } // Second pass: îzah glosses, linkified via their own // separate call. Each gloss is wrapped in its own // {{wiktku-izah-open/close-N}} pair; like the existing // {{wiktku-cite-N}} tokens, these sit inside double // braces so linkify leaves the tokens themselves alone — // only the raw gloss text between each pair gets linked. runIzahPass(mainLinked); }); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, tewandin: { id: "tewandin", name: "tewandin", question_fmt: 'Tewandina "' + pageName + '" binivîse', visible: function (values) { return values.lang && values.pos; }, build: function (stepDiv) { if (stepDiv.find(".wiktku-tewandin-wrap").length) return null; var wrap = $("<div class='wiktku-tewandin-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-tewandin-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-tewandin-text") .attr("rows", 4) .attr("placeholder", "{{ku-tewîn-nav|nêr}}"); wrap.append(ta); stepDiv.append(wrap); function autoPopulate() { if (!ta.length) return; var vals = getValues(); var c = vals.cinsiyet || ""; var p = vals.pos || ""; if (!pageName.includes(" ") && c && GENDER_BASE_LABELS[c] && (p === "navdêr" || p === "serenav") && vals.lang === "ku" && c !== "mndudil") { var label = (c === "mnmane") ? "mê û nêr" : GENDER_BASE_LABELS[c]; var out = "{{ku-tewîn-nav|" + label; if (p === "serenav") out += "|y"; out += "}}"; if (!$.trim(ta.val())) ta.val(out); } } setTimeout(function () { autoPopulate(); $("#wiktku-start-form").on("change.tewandin", "#wiktku-start-lang-field, #wiktku-start-cinsiyet-field, #wiktku-start-pos-field", autoPopulate); }, 0); return ta; }, output: function () { var manualText = $.trim($("#wiktku-start-tewandin .wiktku-tewandin-text").val()); if (manualText) { return "\n==== Tewandin ====\n" + manualText + "\n"; } return ""; } }, // resim — one or more images resim: { id: "resim", name: "resim", question_fmt: "Resmekê lê zêde bike", visible: function (values) { return !!(values.lang && values.pos); }, /** Builds one image row: filename + caption + alt text. */ buildItem: function (stepDiv) { var item = $("<li class='wiktku-resim-item'></li>"); var fileRow = $("<div class='wiktku-posparams-row'></div>"); var fileInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-file") .attr("placeholder", "navê_dosyayê.jpg"); fileRow.append($("<label></label>").text("Navê dosyayê: ")).append(fileInp); var capRow = $("<div class='wiktku-posparams-row'></div>"); var capInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-caption") .attr("placeholder", "Danasîna resimê…"); capRow.append($("<label></label>").text("Danasîn: ")).append(capInp); // Alt text: what a screen reader announces for this image var altRow = $("<div class='wiktku-posparams-row'></div>"); var altInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-alt") .attr("placeholder", "Ji bo kesên nabînin, çi tê dîtin? (ne mecbûrî)"); altRow.append($("<label></label>").text("Nivîsa alternatîf: ")).append(altInp); // Auto-fill the caption with the plain page name when a filename // is typed fileInp.on("input", function () { var file = $.trim($(this).val()); var curCap = $.trim(capInp.val()); var isDefault = !curCap || curCap === pageName; if (file && isDefault) { capInp.val(pageName); } else if (!file && isDefault) { capInp.val(""); } steps.resim.onFileInput(stepDiv, item, this); }); item.append(fileRow).append(capRow).append(altRow); return item; }, /** Grows the image list when the last row's filename gets content. */ onFileInput: function (stepDiv, item, input) { var val = $.trim($(input).val()); var list = stepDiv.find("ol.wiktku-resim-list"); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { list.append(steps.resim.buildItem(stepDiv)); } }, build: function (stepDiv) { if (stepDiv.find(".wiktku-resim-wrap").length) return null; var wrap = $("<div class='wiktku-resim-wrap'></div>"); var list = $("<ol class='wiktku-resim-list'></ol>"); list.append(steps.resim.buildItem(stepDiv)); wrap.append(list); stepDiv.append(wrap); return null; }, /** Reads every filled row from the DOM into an array of {file, caption, alt} * objects — blank rows (missing filename or caption) are skipped. * Non-Kurdish captions get wrapped in {{zim|lang|…}} here, unless * the user already typed their own {{zim|…}} template. Alt text is * optional and left as plain text either way. */ getImages: function (values) { var lang = (values && values.lang) || getValues().lang || ""; var images = []; $("#wiktku-start-resim li.wiktku-resim-item").each(function () { var file = $.trim($(this).find(".wiktku-resim-file").val()); var caption = $.trim($(this).find(".wiktku-resim-caption").val()); var alt = $.trim($(this).find(".wiktku-resim-alt").val()); if (!file || !caption) return; // Strip leading "Wêne:" or "File:" if the user typed it — we add it ourselves. file = file.replace(/^(wêne|file|image)\s*:\s*/i, ""); if (lang && lang !== "ku" && !/^\{\{zim\s*\|/i.test(caption)) { caption = "{{zim|" + lang + "|" + caption + "}}"; } images.push({ file: file, caption: caption, alt: alt }); }); return images; }, output: function (values) { var images = steps.resim.getImages(values); if (!images.length) return ""; return images.map(function (img) { var altPart = img.alt ? "|alt=" + img.alt : ""; return "[[Wêne:" + img.file + "|thumb" + altPart + "|" + img.caption + "]]"; }).join("\n") + "\n"; } }, // bnr-h — {{bnr-h|Page1|Page2|…}} prepended before the lang section (shared, not per-section) bnrh: { id: "bnrh", name: "binêre herwiha (bnr-h)", question_fmt: "Şablona bnr-h li qismê herî jor a rûpelê", //visible: function (values) { return !!values.lang; }, multiple: true, narrow: true, placeholder: "Ji bo 'test' bnr 'Test', 'teşt'", output: function (values) { var pages = $.grep(values.bnrh || [], function (p) { return !!$.trim(p); }); if (!pages.length) return ""; return "{{bnr-h|" + pages.map(function (p) { return $.trim(p); }).join("|") + "}}\n"; } }, bikaranin: { id: "bikaranin", name: "Notên bikaranînê", question_fmt: "Notên bikaranînê yên li ser vê kelîmeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, output: function (values) { var text = $.trim(values.bikaranin || ""); if (!text) return ""; return "\n==== Notên bikaranînê ====\n" + text + "\n"; }, }, xwendin: { id: "xwendin", name: "Bêhtir bixwîne", question_fmt: "Lînkên derveyî eleqedarî vê madeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: function (values) { if (!values || !values.lang) { return `* {{wpedî}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; } const ziman = values.lang === "ku" ? "" : `|ziman=${values.lang}`; return `* {{wpedî${ziman}}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; }, output: function (values) { var text = $.trim(values.xwendin || ""); if (!text) return ""; return "\n==== Bêhtir bixwîne ====\n" + text + "\n"; }, }, alfabeyendin: { id: "alfabeyendin", name: "Bi alfabeyên din", question_fmt: function (values) { var base = "Nivîsîna vê kelîmeyê bi alfabeyên din" var langLabel = values.lang ? getLangLabel(values.lang) : ""; if (langLabel) { return base + " ên " + langLabel; } return base; }, visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: "Ji bo kurmancî: * {{ku-ar|şiklê alfaba erebî}}", output: function (values) { var text = $.trim(values.alfabeyendin || ""); if (!text) return ""; return "\n==== Bi alfabeyên din ====\n" + text + "\n"; }, }, formalt: makeWordListStep("formalt", "formên alternatîv", "Formên alternatîv ên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), hevmane: makeWordListStep("hevmane", "hevmane", "Hevmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), dijmane: makeWordListStep("dijmane", "dijmane", "Dijmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jornav: makeWordListStep("jornav", "jornav", "Jornavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jernav: makeWordListStep("jernav", "jêrnav", "Jêrnavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse"), binereherwiha: makeWordListStep("binereherwiha", "herwiha binêre", "Kelîmeyên din ên eleqedar binivîse"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: {}, visible: function (values) { return values.lang && values.pos; }, // Fills the insert-dropdown from the current etymTpls object. refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(ta); stepDiv.append(wrap); initSelects(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder. // Skip it only when every filled sense is a şablon sense // a completely empty entry with no şablon chosen still gets the placeholder var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasFilledTplSense = dfnSenses.some(function (s) { return !!s.tpl && !!s.tplTitle; }); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (hasFilledTplSense && !hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: function (values) { return {"navz": true, [values.lang]: true} }, // Language dropdown + growing word-input list; a new row appends // when the dropdown gets a value. Mirrors steps.trans, but flat. buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/build below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Attach the searchable picker now the select is in the DOM. initSelects(list); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", question_fmt: "'"+ pageName + "' di zaravayên din de çawa tê gotin?", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: {}, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zaravayekî bigere"); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; // A completely empty entry still gets a placeholder section // to fill in later; an individual placeholder gloss is only // skipped once some other sense already has real content. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", question_fmt: "Tercimeyên vê maneyê bi zimanên din binivîse", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide only when every sense is a filled template sense (no plain // gloss to attach translations to). A mix, or nothing filled in // yet, still shows Werger. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, // Language dropdown + growing word-input list, scoped to one gloss's // group (each gloss has its own group and row list). buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/buildGroup below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, // Builds (or fetches) the .wiktku-trans-group for one gloss. buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, // Syncs one .wiktku-trans-group per current gloss, keyed by // data-gloss-pos so groups stay matched across rebuilds. build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, // Reads all translation rows, grouped by gloss position. getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, // Builds the numbered "{ index, gloss }" list, one per dfn sense // with a real mane (skips template senses). index is 1-based and // matches the sense's position in the "#" definition list. // When nothing's filled in, returns one placeholder entry so // Werger still has a group to attach to; when every sense is a // filled template sense, stays empty (matches trans.visible()). glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane, but other fields are filled — still gets a // gloss group since dfn.getOutput() emits {{mane?}} for it. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // A completely empty entry (nothing filled in dfn at all, no // şablon chosen either) still gets a placeholder Werger section // to fill in later. Only // skip an individual placeholder gloss below when some other // sense actually has real content, making that particular // placeholder redundant. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it. If some other sense already has real // content, this placeholder is redundant — skip it. If the // whole entry is empty, keep it so Werger still gets a // section to fill in. if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, cavkani: { id: "cavkani", name: "çavkanî", question_fmt: "Çavkaniyên din (ne jêgirtin) lê zêde bike", visible: function (values) { return !!values.pos; }, // Fills the insert-dropdown from the members of [[Kategorî:Çavkanî]]. refreshTplSelect: function () { var sel = $("#wiktku-start-cavkani .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(catSrcTemplates || [], function (_, name) { sel.append($("<option></option>").val(name).text(name)); }); markTemplateOptions(sel, function (opt) { return opt.val(); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-cavkani-wrap").length) return null; var wrap = $("<div class='wiktku-cavkani-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-cavkani-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-cavkani-text") .attr("rows", 4) .attr("placeholder", "Şablonekî ji lîsteyê hilbijêre an rasterast binivîse…"); // Template insert dropdown, populated from [[Kategorî:Çavkanî]] — // options refreshed once the category members are fetched. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var status = $("<span class='wiktku-cavkani-status'></span>"); sel.on("change", function () { var name = $(this).val(); if (!name) return; insertAtCursor(ta[0], "\n* {{" + name + "}}"); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(status).append(ta); stepDiv.append(wrap); // build() runs again for every new beş (see the "+ Beş zêde bike" // handler), after the initial page-wide pass — so this select needs // its own init or it stays a plain, unsearchable native <select>. initSelects(wrap); if (catSrcTemplates) { steps.cavkani.refreshTplSelect(); } else { status.text("Şablon tên barkirin…"); fetchCatSrcTemplates().then(function () { steps.cavkani.refreshTplSelect(); status.text(""); }, function () { status.text("Şablon nehatin barkirin."); }); } return ta; }, output: function () { var text = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); if (!text) return ""; return "\n==== Çavkanî ====\n" + text + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); // This array only controls DOM build order — nothing else keys off it // (see the comment above stepIdToGroup). Mane tab order: Mane (senses, // with malûmatên pêşketî nested inside each, see steps.dfn.build) → // Wêne → Bi zaravayên din → Werger, so dfn/resim/zarava/trans sit // adjacent to each other in that order. var ordered_steps = [ steps.lang, steps.pos, steps.posparams, steps.cinsiyet, steps.jimar, steps.lektur, steps.tr, // Mane tab, in reading order: the senses, then the two things that // belong to the entry as a whole rather than to one sense. steps.dfn, steps.tewandin, steps.alfabeyendin, steps.zarava, steps.trans, // Etîmolojî tab. steps.etym, steps.dunde, // Eleqedar tab — three lists of the same shape. steps.je, steps.tekildar, steps.binereherwiha, // Bilêvkirin isn't part of any STEP_GROUPS tab, but still needs a // slot here because this array is what builds the DOM. steps.pron, // Beşên din fields — behind the picker inside the Eleqedar tab. steps.resim, steps.bnrh, steps.bikaranin, steps.formalt, steps.hevmane, steps.dijmane, steps.jornav, steps.jernav, steps.cavkani, steps.xwendin]; // ── Step-group tabs ────────────────────────────────────────────────────── // Three tabs: "Mane" holds the senses (whose own blocks carry Nimûne, // Jêgirtin, Hevmane and Dijmane — see steps.dfn.allGroups), Tewandin, // alfabeyendin, zarava and trans; "Etîmolojî" splits out that topical // cluster; "Eleqedar" holds je/tekildar/binereherwiha plus — behind the // "Beşên din" picker, which lives inside this tab rather than as its // own — everything else (resim, formalt, hevmane, dijmane, jornav, // jernav, bikaranin, cavkani, xwendin, bnrh). A newly-picked section is // inserted right after the picker (see renderBesenDinPicker()), which // sits above je/tekildar/binereherwiha in the DOM — so picking one // pushes those down rather than the other way around. "mane" stays // first as the default-active tab since Mane is required content. // Tewandin keeps its own free-text {{ku-tewîn-nav}} field and does NOT // absorb the Cins/zayend form parameters (m=/n=/p=), which stay on the // headword template. // Steps that live behind the "Beşên din" picker inside Eleqedar — only // these need an explicit "open" before they're shown, even once // Eleqedar's tab is active. var BESENDIN_STEP_IDS = ["resim", "formalt", "hevmane", "dijmane", "jornav", "jernav", "bikaranin", "cavkani", "xwendin", "bnrh"]; var STEP_GROUPS = [ { id: "mane", label: "Mane", steps: ["dfn", "tewandin", "alfabeyendin", "zarava", "trans"] }, { id: "etimoloji", label: "Etîmolojî", steps: ["etym", "dunde"] }, { id: "eleqedar", label: "Eleqedar", steps: ["je", "tekildar", "binereherwiha"].concat(BESENDIN_STEP_IDS) }, ]; // Reverse lookup: step id -> index into STEP_GROUPS (undefined for // ungrouped steps — now only lang/pos/posparams/cinsiyet/lektur/tr, // which stay always-visible since they're required to get to everything // else). var stepIdToGroup = {}; $.each(STEP_GROUPS, function (gi, g) { $.each(g.steps, function (_, sid) { stepIdToGroup[sid] = gi; }); }); // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "posparams", "cinsiyet", "jimar", "lektur", "tr", "resim", "dfn", "tewandin", "formalt", "bikaranin", "alfabeyendin", "hevmane", "dijmane", "jornav", "jernav", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans", "cavkani", "xwendin" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; // ── Bilêvkirin as a standalone section ─────────────────────────────── // Pronunciation belongs to the word, not to one part of speech, so it // sits beside Navdêr/Lêker in the tab bar rather than inside any of them. // Modelled as a flag rather than an entry in `sections` since // activeSection is used as an array index in many places — viewing // Bilêvkirin leaves activeSection pointing at the POS section you were on. var viewingPron = false; // is it the tab currently on screen // Which STEP_GROUPS tab is currently shown. Lives out here (like // activeSection above) so refresh() — which is not nested inside build() // — can read it and so renderGroupTabs()/updateGroupTabIndicators() below // can be called from refresh() too. Both operate on the tab bar via its // #wiktku-group-tabs id rather than a closured element reference, for the // same reason. var activeGroup = 0; // Unsaved-changes / autosave state. Lives out here (same reason as // activeGroup above) so destroy() — which runs on final submit and on // switching to the source editor, and is not nested inside build() — // can clear the timers and the beforeunload warning. build() assigns // into these; it doesn't re-declare them. var formDirty = false; var autosaveDebounceTimer = null; var autosaveInterval = null; /** Re-renders the step-group tab bar to reflect the current activeGroup. */ function renderGroupTabs() { var groupTabsDiv = $("#wiktku-group-tabs"); if (!groupTabsDiv.length) return; groupTabsDiv.empty(); $.each(STEP_GROUPS, function (i, g) { var tab = $("<span></span>") .addClass("wiktku-group-tab") .attr("data-group-idx", i) .text(g.label) .toggleClass("wiktku-tab-active", i === activeGroup); (function (idx) { tab.on("click", function () { if (idx === activeGroup) return; activeGroup = idx; renderGroupTabs(); if (idx === ELEQEDAR_GROUP_IDX) renderBesenDinPicker(); refresh(); // Switching tabs can shorten the page (e.g. leaving a long // "Beşên din" field), and the browser may clamp the scroll // position on its own timing before our measurement runs. // Deferring one frame lets that settle first, so the // offsetTop read below is the final, post-refresh one. window.requestAnimationFrame(function () { var bar = document.getElementById("wiktku-group-tabs"); if (!bar) return; var form = document.getElementById("wiktku-start-form"); var stabsH = form ? (parseFloat(form.style.getPropertyValue("--wiktku-stabs-h")) || 0) : 0; var siteHeaderH = form ? (parseFloat(form.style.getPropertyValue("--wiktku-siteheader-h")) || 0) : 0; var top = bar.getBoundingClientRect().top + window.pageYOffset - stabsH - siteHeaderH; $("html, body").animate({ scrollTop: Math.max(0, top) }, 200); }); }); }(i)); groupTabsDiv.append(tab); }); } /** * Toggles a "needs attention" dot on any group tab that still has a * required, unfilled field hidden inside it — so switching tabs doesn't * leave the person wondering why "Bişîne" stays disabled. */ function updateGroupTabIndicators(values) { var tabs = $("#wiktku-group-tabs .wiktku-group-tab"); if (!tabs.length) return; $.each(STEP_GROUPS, function (i, g) { var missing = false; $.each(g.steps, function (_, sid) { var step = steps[sid]; if (!step || !step.required) return; var val = values[sid]; if (val === "" || (step.multiple && $.isArray(val) && val.join("") === "")) { missing = true; } }); tabs.eq(i).toggleClass("wiktku-tab-missing", missing && i !== activeGroup); }); } // "Beşên din" reveals one field at a time via a picker rather than // stacking them all. Per-section state, snapshotted in // saveCurrentSection() and restored in restoreSection() below, and // auto-seeded from any field that already has content (so a returning // draft doesn't hide something already filled in). var openedOtherSections = {}; var BESENDIN_SET = {}; $.each(BESENDIN_STEP_IDS, function (_, sid) { BESENDIN_SET[sid] = true; }); // "eleqedar"'s index in STEP_GROUPS — the Beşên din picker now renders // inside this tab rather than having its own. Derived rather than // hardcoded — this was once a literal 2 and silently pointed at the // wrong tab the moment Etîmolojî and Eleqedar were reordered. var ELEQEDAR_GROUP_IDX = (function () { for (var i = 0; i < STEP_GROUPS.length; i++) { if (STEP_GROUPS[i].id === "eleqedar") return i; } return STEP_GROUPS.length - 1; }()); /** Re-renders the "Beşên din" picker to list only the not-yet-opened sections. */ function renderBesenDinPicker() { var wrap = $("#wiktku-besendin-picker"); if (!wrap.length) return; wrap.empty(); var pickerValues = getValues(); var unopened = $.grep(BESENDIN_STEP_IDS, function (sid) { if (openedOtherSections[sid]) return false; // Don't offer a section that would open onto nothing: several of // these are gated (Bi zaravayên din / Werger need lang=ku, most // need a pos). refresh() would hide it again straight away, so // picking it would read as a broken dropdown. var step = steps[sid]; if (step && typeof step.visible === "function") { try { if (!step.visible(pickerValues)) return false; } catch (e) { /* a step whose visible() needs DOM we lack yet — offer it */ } } return true; }); if (!unopened.length) return; // everything's open — nothing left to pick var sel = $("<select class='wiktku-besendin-select'></select>"); sel.attr("data-placeholder", "— beşek hilbijêre —"); sel.append($("<option value=''>— beşek hilbijêre —</option>")); $.each(unopened, function (_, sid) { var step = steps[sid]; if (!step) return; sel.append($("<option></option>").val(sid).text(capitalize(step.name))); }); sel.on("change", function () { var sid = $(this).val(); if (!sid) return; openedOtherSections[sid] = true; // Newly opened section moves right under the picker, ahead of // whatever's already open, instead of wherever it happened to // sit in the fixed step order. $("#wiktku-start-" + sid).insertAfter(wrap); renderBesenDinPicker(); refresh(); }); wrap.append(sel); initSelects(wrap); } /** Marks any BESENDIN_STEP_IDS field that already has real content as * "opened", so restoring a draft doesn't bury filled-in sections behind * the picker. Reuses each step's own output() as the emptiness check — * it already knows what "empty" means per field, and it reads the DOM * the restore just populated. Call this AFTER the DOM has the restored * values in it. */ function seedOpenedFromContent() { var values = getValues(); $.each(BESENDIN_STEP_IDS, function (_, sid) { if (openedOtherSections[sid]) return; var step = steps[sid]; if (!step || typeof step.output !== "function") return; try { if (step.output(values)) openedOtherSections[sid] = true; } catch (e) { /* a step whose output() needs more state than we have yet — skip it */ } }); } function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } // Rebuilds the dfn DOM from a previously snapshotted senses array. function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing tab bar + list so build() recreates them cleanly. stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); // The picker is collapsed behind a link by default; a restored // sense that already uses a template has to show it, or the // chosen template is invisible and looks lost. var reveal = block.data("revealTplRow"); if (typeof reveal === "function") reveal(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // dfnArea is the only thing actually saved, so split it back into // tercime/îzah for editing (mirrors syncNonKuToMane's join format). var maneParts = splitTercimeIzah(sense.mane); block.find(".wiktku-dfn-tercime").val(maneParts ? maneParts.tercime : (sense.mane || "")); block.find(".wiktku-dfn-izah").val(maneParts ? maneParts.izah : ""); // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Same for the mane-box mode (plain vs tercime+îzah), since this // also depends on tplSelect's (and lang's) value. var updateMane = block.data("updateManeMode"); if (updateMane) updateMane(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found var useModifiers = !!MODIFIER_SUBGROUPS[cls]; // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true, useModifiers); }); subList.append(useModifiers ? makeModifierLi(ta) : $("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text).each(function () { highlightLinebreak(this); }); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder entries — accepts current array shape or a legacy // single object (older saved sections) for backwards compat. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote).each(function () { highlightLinebreak(this); }); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederCatTpl) { // Legacy format from before the şablon search switched rows to // manual mode directly — convert it the same way now, so it's // editable like any other free-form source. var catSelEl = li.find(".wiktku-dfn-quote-src-sel"); catSelEl.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val("{{" + j.jederCatTpl + "}}"); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); // Restoring a draft opens the first sense's tab by default. steps.dfn.setOpenSense(stepDiv, list.find("li.wiktku-dfn-sense").first()); } // Snapshots simple (non-dfn) per-section steps from the DOM into obj. function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } if (id === "cavkani") { snap.cavkani = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); return; } if (id === "posparams") { snap.posparams = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); return; } if (id === "resim") { // One entry per row, including blank ones, so a mid-edit draft // (e.g. a filename typed but no caption yet) survives a cache // restore instead of being silently dropped. snap.resim = $("#wiktku-start-resim li.wiktku-resim-item").map(function () { return { file: $.trim($(this).find(".wiktku-resim-file").val()), caption: $.trim($(this).find(".wiktku-resim-caption").val()), alt: $.trim($(this).find(".wiktku-resim-alt").val()) }; }).get(); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); // Which "Beşên din" sub-sections this section has already opened // via the picker — per-section, like everything else here. snap.openedOtherSections = $.extend({}, openedOtherSections); sections[activeSection] = snap; } // Restores a previously saved snapshot into the form DOM. function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); $("#wiktku-start-cavkani .wiktku-cavkani-text").val(snap.cavkani || ""); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); steps.posparams.build(ppDiv); var savedTa = snap.posparams || ""; ppDiv.find(".wiktku-posparams-text").val(savedTa); // Re-parse saved textarea to restore helper widget states. if (savedTa) { var cMatch = savedTa.match(/\|c=([^|}\s]+)/); var jMatch = savedTa.match(/\|j=([^|}\s]+)/); var trMatch = savedTa.match(/\|tr=([^|}\s]+)/); // Write into the shared hidden field (not the visible // select, which has no <option>s yet) — syncHelpers() // below reads it back to restore the dropdown once the // gender/number options for this language are populated. if (cMatch) $("#wiktku-start-cinsiyet-field").val(cMatch[1]); if (jMatch) $("#wiktku-start-jimar-field").val(jMatch[1]); if (trMatch) ppDiv.find(".wiktku-posparams-field[data-pp-key='tr']").val(trMatch[1]); // For lêker, c= holds the verb-type code instead of a // gender — split it back across the two dropdowns it is // now assembled from ("x-gh" → form "x" + base "gh"). if (cMatch && /^lêker/.test(snap.pos || "")) { var lekturParts = /^(?:([xphb])-)?(n?gh)$/.exec(cMatch[1]); if (lekturParts) { ppDiv.find(".wiktku-posparams-lektur-sel").val(lekturParts[2]); ppDiv.find(".wiktku-posparams-lekturform-sel").val(lekturParts[1] || ""); } } // Restore checked optional params. "form" is stored as // "erê" rather than "1" (see rebuildTa), so it needs its // own check here. ppDiv.find(".wiktku-posparams-opt-panel input[type='checkbox']").each(function () { var key = $(this).val(); var expected = key === "form" ? "erê" : "1"; $(this).prop("checked", savedTa.indexOf("|" + key + "=" + expected) !== -1); }); } steps.posparams.syncHelpers(ppDiv); return; } if (id === "resim") { var resimDiv = $("#wiktku-start-resim"); resimDiv.find(".wiktku-resim-wrap").remove(); steps.resim.build(resimDiv); // Accept both the new array-of-rows format and the older // single {file, caption} object saved before multi-image // support existed. var resimSnap = snap.resim; var rows = $.isArray(resimSnap) ? resimSnap : (resimSnap ? [resimSnap] : []); if (rows.length) { var list = resimDiv.find("ol.wiktku-resim-list"); list.empty(); $.each(rows, function (_, r) { var item = steps.resim.buildItem(resimDiv); item.find(".wiktku-resim-file").val(r.file || ""); item.find(".wiktku-resim-caption").val(r.caption || ""); item.find(".wiktku-resim-alt").val(r.alt || ""); list.append(item); }); // Always keep a blank trailing row, same as Nimûne/Dûnde. var lastItem = list.children("li.wiktku-resim-item").last(); if ($.trim(lastItem.find(".wiktku-resim-file").val())) { list.append(steps.resim.buildItem(resimDiv)); } } return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Tell the pickers about the programmatic value change. fields.filter("select").trigger("wiktku:refresh"); }); // Restore which "Beşên din" sub-sections were already opened for // this section, then seed in anything the DOM restore above just // filled in but that wasn't marked opened yet. openedOtherSections = $.extend({}, snap.openedOtherSections || {}); seedOpenedFromContent(); renderBesenDinPicker(); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); // Bilêvkirin is NOT emitted here — it is one shared field for the // whole word, so emitting it per section duplicated it. getWikitext() // prints it once, above the POS sections. steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.tewandin.output(values); entry += steps.bikaranin.output(values); entry += steps.alfabeyendin.output(values); entry += steps.formalt.output(values); entry += steps.hevmane.output(values); entry += steps.dijmane.output(values); entry += steps.jornav.output(values); entry += steps.jernav.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); entry += steps.cavkani.output(values); entry += steps.xwendin.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { // Each hop through here can be reached asynchronously: the dfn // step waits on mw.loader.using("ext.gadget.linkify") before // calling back, so from that point on the submit handler's own // try/catch is no longer on the stack. Guard every hop instead, // or a throw after linkify loads vanishes into an unhandled // rejection and the form just sits there looking busy. try { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } catch (e) { if (typeof onSubmitError === "function") onSubmitError(e); else throw e; } } processSection(0); } // Assembles wikitext for all sections plus the shared lang header. function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var bnrh = steps.bnrh.output(sharedValues); var entry = steps.lang.output(sharedValues); // One pronunciation per word, printed once between the language // header and the POS sections — see steps.pron.output. entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // bnr-h goes before the language section — only prepended when // generating fresh wikitext (not addLangMode, which handles it separately). if (!addLangMode && bnrh) entry = bnrh + entry; // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { if (s.mane) return s.mane; // Template sense (e.g. {{guharto|ku|somepage}}) — same // construction as the tplCall built in getOutput, so the // summary shows what actually gets written to the entry // instead of going blank. if (s.tpl && s.tplTitle) { return s.tplNoLang ? "{{" + s.tpl + "|" + s.tplTitle + "}}" : "{{" + s.tpl + "|" + sharedValues.lang + "|" + s.tplTitle + "}}"; } return ""; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; // Set by build() to its submitFailed(). Lives out here because the // wikitext-assembly functions below are outside build()'s closure but // still need a way to report a failure to the person rather than dying // silently in the console. var onSubmitError = null; // Whether Mane/Bi zaravayên din/Werger has anything in it — kept // outside refresh() so the click handler can read the latest value. var wiktkuContentGateOk = true; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues, placeholderText) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>").text(placeholderText || "")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice.label); if (choice.sortKey !== undefined) { // This is a language choice {code, label, sortKey} — show code. displayText = capitalize(choice.label) + " (" + choice.code + ")"; } var option = $(mw.html.element("option", { value: choice.code }, displayText)); if (disabledValues[choice.code]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } // Keys to disable for a key menu: already-taken or explicitly disabled. function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); populateMenus(input, step.keys, getDisabledKeys(step)); // Keep the key menus mutually exclusive: whatever one row selects is // disabled in every other row. Recomputed from the DOM on each change. input.on("change", function () { var all = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield"); var taken = {}; all.each(function () { var v = $(this).val(); if (v) taken[v] = true; }); all.not(this).each(function () { var self = $(this), own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (code) $(this).prop("disabled", !!taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }); // Return the wrapper; the select lives inside it and still fires change. return wrapNativeSelect(input); } // Adds another text field to the list if the last one now has text. function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); if (step.placeholder) { nextInput.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = step.modifiers ? makeModifierLi(nextInput).prepend(nextKeyInput || "") : $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) initSelects(nextItem); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } // Shows/hides steps based on whether their prerequisites are met, and // updates placeholders where applicable. function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); steps.cavkani.refreshTplSelect(); // Re-render any step's question label that depends on current values // (e.g. dfn's Werger-section reminder, which only applies to ku). $.each(steps, function (stepId, step) { if (typeof step.question_fmt === "function") { $("#wiktku-start-" + stepId + " .wiktku-start-step-question") .text(step.question_fmt(values)); } }); // Sync every sense block's mane-box mode (plain mane vs tercime+îzah) // to the current language, in case lang changes after blocks exist. $("#wiktku-start-dfn li.wiktku-dfn-sense").each(function () { var updateMane = $(this).data("updateManeMode"); if (updateMane) updateMane(); }); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Re-sync the "<label> bi <ziman>…" placeholder on every always-visible // sub-field list (etîket, kategorî, hevmane, …), since the language may // not have been chosen yet when these lists were first built, or may // have changed since. $("#wiktku-start-dfn .wiktku-dfn-sublist").each(function () { var upd = $(this).data("updatePlaceholders"); if (typeof upd === "function") upd(); }); // Same idea for word-list steps (jê, têkildar, binêre herwiha, …) // whose placeholder is a function of the current language. $.each(steps, function (stepId, step) { if (typeof step.placeholder === "function") { $("#wiktku-start-" + stepId + " textarea.wiktku-start-step-field") .attr("placeholder", step.placeholder()); } }); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // Insert after the quote textarea's resize-wrap (if the manual // resize handle has already been attached to it), not after the // bare textarea -- otherwise this lands *inside* that wrap, // between the textarea and its own grip, breaking jêgirtin's // handle and nesting the tr/t boxes inside it. var quoteTa = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap = quoteTa.closest(".wiktku-resize-wrap"); (quoteResizeWrap.length ? quoteResizeWrap : quoteTa).after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // See the tr-field branch above for why this targets the // resize-wrap instead of the bare textarea. var quoteTa2 = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap2 = quoteTa2.closest(".wiktku-resize-wrap"); (quoteResizeWrap2.length ? quoteResizeWrap2 : quoteTa2).after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { var groupIdx = stepIdToGroup[stepId]; var hiddenByTab = (groupIdx !== undefined && groupIdx !== activeGroup) || // Beşên din picker: stays hidden even while its tab is // active until explicitly opened from the dropdown. (BESENDIN_SET[stepId] && !openedOtherSections[stepId]); // Bilêvkirin is its own section now, so the two views are // mutually exclusive: on it, only pron shows (plus Ziman, which // is shared and stays above every section); off it, pron is // hidden no matter which tab is active. pron is deliberately // ungrouped — stepIdToGroup has no entry for it — so without // this branch it would show on all four tabs at once. if (stepId === "pron") { hiddenByTab = hiddenByTab || !viewingPron; } else if (viewingPron && stepId !== "lang") { hiddenByTab = true; } if (hiddenByTab || (typeof(step.visible) === "function" && !step.visible(values))) { $("#wiktku-start-" + stepId).hide(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } // After build, sync the posparams helper widgets whenever pos or lang changes. if (step.id === "posparams" && typeof step.syncHelpers === "function") { step.syncHelpers(stepDiv); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } stepDiv.slideDown(); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); // The three content tabs belong to a POS section — Bilêvkirin has no // sub-tabs of its own, so the bar goes away while it's on screen. $("#wiktku-group-tabs").toggle(!!values.pos && !viewingPron); var besenDinActive = activeGroup === ELEQEDAR_GROUP_IDX && !viewingPron; $("#wiktku-besendin-picker").toggle(besenDinActive); // The option list is filtered by each step's visible(), which depends // on lang/pos — so it has to be rebuilt when those change, not just // when a section is opened. Safe to call from here: rendering the // picker doesn't itself call refresh(), only picking an option does. if (besenDinActive) renderBesenDinPicker(); updateGroupTabIndicators(values); continueBtn.setDisabled(!canContinue); // Soft gate: stays a real, clickable OOUI button — a hard // setDisabled(true) here would swallow the click entirely, leaving // no way to tell the person why nothing happened. The CSS-only // "looks disabled" class lets the click handler still run and show // wiktkuNotify's explanation. wiktkuContentGateOk = !canContinue || hasMinRequiredContent(values); continueBtn.$element.toggleClass("wiktku-btn-soft-disabled", !wiktkuContentGateOk); } function destroy() { if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); if (autosaveInterval) clearInterval(autosaveInterval); formDirty = false; $(window).off("beforeunload.wiktkuUnsaved"); $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard").slideDown(); // #editform was kept laid-out but off-screen (see build()) instead of // display:none, precisely so the editor never had to size itself // against a zero-width/height box. Just bring it back on-screen — // no slideDown needed since it was never actually collapsed. $("#editform").removeClass("wiktku-offscreen"); // Belt-and-braces: if WikiEditor/CodeMirror/mobile's auto-grow still // cached a stale size from some earlier point, nudge them to // recalculate now that the box is genuinely visible. $(window).trigger("resize"); if (window.CodeMirror) { var cm = $("#wpTextbox1").data("CodeMirror") || $("#wpTextbox1").data("cmInstance"); if (cm && typeof cm.refresh === "function") cm.refresh(); } $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and navz. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; // Inserts a new "== {{ziman|code}} ==" section at the correct sorted // position: navz, then ku/hac/sdh/lki/ckb/zza, then alphabetical by name. function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections — just write the new section. // Add \n\n only when there is real non-whitespace content above. var trimmed = existing.replace(/\s+$/, ""); return trimmed ? trimmed + "\n\n" + wikitext : wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // (?![\s\S]) matches only true end-of-string, since a bare "$" with // /m would stop at the section's first line break instead. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections, each separated by exactly \n\n. // Trim trailing whitespace off each section's content first so we // control the spacing precisely. var joined = sections.map(function (s) { return s.content.replace(/\s+$/, ""); }).join("\n\n"); // Only add a separator after the preamble when it has real content. var preambleTrimmed = preamble.replace(/\s+$/, ""); var prefix = preambleTrimmed ? preambleTrimmed + "\n\n" : ""; return prefix + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê zimanekî nû li rûpelê îlawe bikî. Eger ev ziman jixwe hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bike, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Muhtewaya rûpelê paqij bike (her tiştî jê bibe û rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); // Tab bar for switching between step-groups (topics) within a section. // renderGroupTabs()/updateGroupTabIndicators() (which populate and // maintain it) live outside build() — see near "var activeSection". var groupTabsDiv = $("<div id='wiktku-group-tabs'></div>"); // Both tab bars are sticky (CSS). group-tabs' sticky "top" has to sit // right below section-tabs' actual rendered height, which isn't a // fixed number since the bar can wrap onto a second line. Measured // here and published as a CSS custom property the stylesheet reads // back; recomputed on content changes and window resize. // // Vector 2022 has its own sticky header (.vector-sticky-header) that // pins to the real top:0 once you scroll past the page title, which // would otherwise sit directly behind (and hide) our section-tabs. // Fixed by measuring how much of the viewport Vector's header // currently occupies and offsetting both our bars below it, via // --wiktku-siteheader-h. Vector's header slides in/out with scroll // position, so this is re-measured on scroll too, not just resize. function siteHeaderOffset() { var el = document.querySelector(".vector-sticky-header"); if (!el) return 0; var rect = el.getBoundingClientRect(); // Present in the DOM at all times on Vector 2022, but only // actually occupying screen space once scrolled into place — // before that it sits translated above the viewport (negative/ // zero rect), which must not add a phantom gap under our bars. if (rect.bottom <= 0 || rect.top > 4) return 0; return Math.max(0, rect.bottom); } var stickyOffsetQueued = false; function syncStickyTabsOffset() { var h = sectionTabsDiv.is(":visible") ? (sectionTabsDiv.outerHeight() || 0) : 0; startForm.css("--wiktku-stabs-h", h + "px"); startForm.css("--wiktku-siteheader-h", siteHeaderOffset() + "px"); } function queueStickyTabsOffsetSync() { if (stickyOffsetQueued) return; stickyOffsetQueued = true; window.requestAnimationFrame(function () { stickyOffsetQueued = false; syncStickyTabsOffset(); }); } $(window).on("resize.wiktkuStickyTabs scroll.wiktkuStickyTabs", queueStickyTabsOffsetSync); // "Beşên din" picker — sits right under the group tab bar, only // shown while the Eleqedar tab is active (toggled in refresh(), see // ELEQEDAR_GROUP_IDX); renderBesenDinPicker() fills it. var besenDinPickerDiv = $("<div id='wiktku-besendin-picker' class='wiktku-besendin-picker'></div>"); /** Puts the form back in a usable state after a failed submit and * says what happened. Without this the button stays disabled and * the spinner spins forever on any exception — the person is left * staring at a form that looks busy but is dead, with the reason * visible only in the browser console. */ function submitFailed(err) { spinner.hide(); continueBtn.setDisabled(false); continueBtn.$element.removeClass("wiktku-btn-sending"); var detail = (err && (err.message || err.toString())) || "sedem nediyar"; mw.notify( "Şandin bi ser neket: " + detail + " — tiştê ku te nivîsî winda nebûye. Heke ev dubare bibe, " + "bi 'Edîtora çavkaniyê veke' berdewam bike.", { type: "error", tag: "wiktku-submit", autoHide: false } ); // Deliberately console.error as well: the notification is for the // person, this is for whoever they report the bug to. if (window.console && console.error) console.error("[wiktku] submit failed", err); } onSubmitError = submitFailed; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); continueBtn.$element.addClass("wiktku-btn-sending"); spinner.show(); try { getWikitext(function (wikitext) { try { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page — write fresh content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // ── bnr-h merge ────────────────────────────────────────── // If the user filled bnr-h inputs, either merge into the // existing {{bnr-h|…}} call or prepend a new one. var bnrhOut = steps.bnrh.output(getValues()); if (bnrhOut) { var newPages = bnrhOut.replace(/^\{\{bnr-h\|/, "").replace(/\}\}\n?$/, "").split("|"); var bnrhRe = /\{\{bnr-h\|([^}]*)\}\}/i; if (bnrhRe.test(existing)) { existing = existing.replace(bnrhRe, function (_, inner) { var existingPages = inner.split("|").map(function (p) { return p.trim(); }); $.each(newPages, function (_, p) { p = p.trim(); if (p && existingPages.indexOf(p) === -1) existingPages.push(p); }); return "{{bnr-h|" + existingPages.join("|") + "}}"; }); } else { existing = bnrhOut + existing; } } // If this language's section already exists (whitespace // differences aside), merge into it; otherwise insert new. var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); } catch (e) { // Thrown while writing the result into #wpTextbox1. submitFailed(e); } }); } catch (e) { // Catches anything thrown synchronously inside getWikitext. submitFailed(e); } }); // Tracks whether groupTabsDiv has been inserted yet. var groupTabsInserted = false; $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); var nameH3 = $("<h3></h3>").addClass("wiktku-start-step-name"); var nameLabel = $("<label></label>") .attr("for", "wiktku-start-" + step.id + "-field") .text(name); nameH3.append(nameLabel); stepDiv.append(nameH3); if (step.question_fmt) { // question_fmt can be a plain string, or a function of the // current values (used by steps whose question text depends // on e.g. the chosen language) — refresh() keeps it in sync // afterwards via the .wiktku-start-step-question class. var questionText = typeof step.question_fmt === "function" ? step.question_fmt(getValues()) : step.question_fmt; stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, questionText))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); // initSelects() runs over the whole form once it is in the DOM. stepDiv.append(input); } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.placeholder) { input.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append(step.modifiers ? makeModifierLi(input) : $("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Section tabs (switch between POS sections) sit above the // per-section fields, starting at "pos". if (step.id === "pos") { startForm.append(sectionTabsDiv); } // Step-group tabs sit just before the first grouped step in // ordered_steps. Derived from stepIdToGroup so this keeps // working no matter how STEP_GROUPS/ordered_steps get reordered. if (!groupTabsInserted && stepIdToGroup[step.id] !== undefined) { startForm.append(groupTabsDiv); startForm.append(besenDinPickerDiv); groupTabsInserted = true; } startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); /** Adds a new, empty POS section and switches to it. */ function addPosSection() { saveCurrentSection(); viewingPron = false; sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); return; } if (id === "resim") { $("#wiktku-start-resim .wiktku-resim-wrap").remove(); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); stepDiv.find("select.wiktku-start-step-field").trigger("wiktku:refresh"); }); // Fresh section — no "Beşên din" sub-section has been opened yet. openedOtherSections = {}; renderBesenDinPicker(); renderSectionTabs(); refresh(); } addSectionBtn.on("click", addPosSection); /** Removes one POS section. Assumes the caller already confirmed and * already checked more than one section remains. If the removed * section was the one on screen, its in-progress DOM edits are * discarded along with it (never saved back into sections[]) and a * neighboring section is restored in its place. */ function removePosSection(idx) { sections.splice(idx, 1); if (idx === activeSection) { viewingPron = false; activeSection = Math.min(idx, sections.length - 1); restoreSection(sections[activeSection]); refresh(); } else if (idx < activeSection) { activeSection -= 1; } renderSectionTabs(); } /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); syncStickyTabsOffset(); return; } sectionTabsDiv.show(); // Bilêvkirin leads the bar, ahead of the POS sections. var pronTab = $("<span></span>") .addClass("wiktku-section-tab wiktku-section-tab-pron") .text("Bilêvkirin") .toggleClass("wiktku-tab-active", viewingPron); pronTab.on("click", function () { if (viewingPron) return; saveCurrentSection(); viewingPron = true; refresh(); renderSectionTabs(); }); sectionTabsDiv.append(pronTab); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection && !viewingPron); (function (idx) { tab.on("click", function () { if (idx === activeSection && !viewingPron) return; // Leaving Bilêvkirin doesn't need a save — its field // is shared and never part of a section snapshot. if (!viewingPron) saveCurrentSection(); viewingPron = false; activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // One delete button for the whole bar — not one per tab — same // reasoning as the Mane tabs' trash button: deletes whichever // Beş is currently open, so there's only one thing a click on it // can possibly remove. Not shown on Bilêvkirin (nothing to // delete there) or when it's the only Beş left. if (sections.length > 1 && !viewingPron) { var activeTabLabel = sections[activeSection] && sections[activeSection].pos ? capitalize(sections[activeSection].pos) : ("Beş " + (activeSection + 1)); var sectionTrash = makeTrashButton("Vê beşê jê bibe (" + activeTabLabel + ")"); sectionTrash.on("click", function () { if (!window.confirm("Tu dixwazî \"" + activeTabLabel + "\" jê bibî? Ev tişt nayê vegerandin.")) return; removePosSection(activeSection); }); sectionTabsDiv.append(sectionTrash.$element); } // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); syncStickyTabsOffset(); } renderSectionTabs(); /** * Re-populates a dynamically-growing "multiple" field list (bnrh, je, * tekildar, …) from a saved array of strings. Sets each value via * .val() + a triggered "input" event rather than touching the DOM * structure directly, so the normal refreshForTextField() growth * logic adds exactly as many rows as needed — the same thing that * happens when a person types into the last (empty) row. */ function restoreMultiField(id, values) { var container = $("#wiktku-start-" + id); $.each(values || [], function (i, v) { var field = container.find(".wiktku-start-step-field").eq(i); if (!field.length || !v) return; field.val(v).trigger("input"); }); } /** * Restores a full cached draft: shared lang/pron/bnrh fields, then * every section (via the same restoreSection()/refresh()/ * renderSectionTabs() sequence already used when switching tabs). * @param cached {{lang: string, pron: string, bnrh: Array, sections: Array, activeSection: number}} */ function restoreFromCache(cached) { if (cached.lang) { $("#wiktku-start-lang-field").val(cached.lang); $("#wiktku-start-lang-field").trigger("wiktku:refresh"); } // Rebuild dependent steps (pos, pron wrap, etc.) now that lang is set. refresh(); if (cached.pron !== undefined) { $("#wiktku-start-pron .wiktku-pron-text").val(cached.pron); } if (cached.bnrh) { restoreMultiField("bnrh", cached.bnrh); } sections = (cached.sections && cached.sections.length) ? cached.sections : [{}]; activeSection = (typeof cached.activeSection === "number" && cached.activeSection >= 0 && cached.activeSection < sections.length) ? cached.activeSection : 0; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); updateLastSavedIndicator(cached.savedAt || null); formDirty = false; wiktkuNotify("Danûstandina berê ya qeydkirî ji cache hate barkirin.", { type: "info", tag: "wiktku-cache-restore" }); } // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { // renderSectionTabs() labels each tab from sections[i].pos, which // is only synced from the DOM by saveCurrentSection() (on tab // switch/section add). Without this, the active tab's own label // stays on the previous pos (or "Beş N") until the user switches // away and back. Update it directly so the rename is immediate. if (sections[activeSection]) sections[activeSection].pos = $(this).val(); renderSectionTabs(); // A new cureyê rêzimanî means any previously chosen cinsiyet/ // cureyê lêkerê no longer applies — clear both selections (and // the shared hidden cinsiyet field, since rebuildTa()/syncHelpers() // fall back to it) before wiping the textarea, so nothing stale // gets carried over into the rebuilt template. var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-cinsiyet-sel").val(""); ppDiv.find(".wiktku-posparams-jimar-sel").val(""); ppDiv.find(".wiktku-posparams-lektur-sel").prop("selectedIndex", 0); ppDiv.find(".wiktku-posparams-lekturform-sel").prop("selectedIndex", 0); $("#wiktku-start-cinsiyet-field").val(""); $("#wiktku-start-jimar-field").val(""); ppDiv.find(".wiktku-posparams-text").val(""); // refresh() runs steps.posparams.syncHelpers(), which toggles the // param rows for the new pos and — since the textarea is now // empty — calls rebuildTa() to repopulate it. refresh(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { // Immediate feedback that the click registered continueBtn.$element.addClass("wiktku-btn-flash"); setTimeout(function () { continueBtn.$element.removeClass("wiktku-btn-flash"); }, 500); // Ziman/Cureyê rêzimanî already block submission via the real // OOUI setDisabled (see canContinue in refresh()) — this is a // second, softer check that still lets the click through so we // can explain why, instead of the button just silently doing nothing. if (!wiktkuContentGateOk) { wiktkuNotify( "Berî şandinê, tiştekî binivîse: Mane, Bi zaravayên din, an jî Werger — kêmasî yek ji van sê beşan divê tijî be.", { type: "warn", tag: "wiktku-mincontent" } ); return; } wiktkuNotify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", flags: [ "destructive" ], }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Cache save/clear buttons ───────────────────────────────────────── // Manual, page-scoped save of the entire wizard (all sections, not // just the active one) via [[MediaWiki:Gadget-StorageUtils.js]]'s // ObjectStorage. Restoring happens silently on load at the end of // build(), once the full language list is available. // // Saving also happens automatically (debounced while typing, plus a // periodic fallback) — see "Autosave" below — since relying on the // person to remember to click "Li cache qeyd bike" before an // accidental tab close/reload defeats the point of having a cache // at all. function buildCacheSnapshot() { return { lang: getValues().lang || "", pron: $("#wiktku-start-pron .wiktku-pron-text").val() || "", // bnrh is shared (page-level), same as lang/pron above — not // per-section, so it doesn't live in sections[]. bnrh: getValuesForStep("bnrh"), sections: sections, activeSection: activeSection, savedAt: Date.now() }; } // ── Last-saved indicator ───────────────────────────────────────────── var lastSavedEl = $("<span id='wiktku-last-saved'></span>"); function formatSavedTime(ts) { try { return new Date(ts).toLocaleTimeString(mw.config.get("wgUserLanguage"), { hour: "2-digit", minute: "2-digit" }); } catch (e) { return new Date(ts).toLocaleTimeString(); } } function updateLastSavedIndicator(ts) { lastSavedEl.text(ts ? ("Cache: qeydkirî di saet " + formatSavedTime(ts) + " de") : ""); } // ── Dirty-state tracking + autosave ────────────────────────────────── // formDirty mirrors "does the live form differ from what's in cache". // Anything the person types/selects sets it; a successful save (auto // or manual) clears it; destroy() (final submit, or switching to the // source editor) also clears it since the wizard's job is over at // that point either way. formDirty/autosaveDebounceTimer/autosaveInterval // are declared in the outer scope (near activeGroup) — assigned here, // not re-declared — so destroy() can reach them too. var AUTOSAVE_DEBOUNCE_MS = 8000; // save shortly after typing pauses var AUTOSAVE_INTERVAL_MS = 60000; // …and at least this often regardless function performAutosave() { if (!formDirty) return; saveCurrentSection(); try { formCache.Set(buildCacheSnapshot()); formDirty = false; updateLastSavedIndicator(Date.now()); } catch (e) { // Silent on autosave failure (storage blocked/full, etc.) — the // manual button still surfaces a proper error if the person // tries it directly, no need to interrupt typing with a toast. } } function scheduleAutosave() { formDirty = true; if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = setTimeout(performAutosave, AUTOSAVE_DEBOUNCE_MS); } startForm.on("input change", "input, textarea, select", scheduleAutosave); autosaveInterval = setInterval(performAutosave, AUTOSAVE_INTERVAL_MS); // Warn on accidental tab close/reload while there's anything unsaved. $(window).on("beforeunload.wiktkuUnsaved", function (e) { if (!formDirty) return undefined; e.preventDefault(); e.returnValue = ""; return ""; }); var saveCacheBtn = new OO.ui.ButtonWidget({ label: "Li cache qeyd bike", title: "Halê vê formê yê niha (ziman, bilêvkirin û hemû beş) li cache (localStorage) qeyd bike, da ku eger rûpel bêyî xwestin were girtin an ji nû ve were barkirin, tu karibî berdewam bikî." }); saveCacheBtn.on("click", function () { saveCurrentSection(); // ObjectStorage.Set() doesn't return a success/failure value, so // the only way to detect a real failure (storage blocked, quota // exceeded, JSON.stringify choking on something unexpected) is to // catch it here rather than inspect a (nonexistent) return value. try { var snapshot = buildCacheSnapshot(); formCache.Set(snapshot); formDirty = false; updateLastSavedIndicator(snapshot.savedAt); wiktkuNotify("Halê formê li cache hate qeydkirin.", { type: "success", tag: "wiktku-cache-save" }); } catch (e) { mw.notify("Qeydkirina li cache bi ser neket.", { type: "error", tag: "wiktku-cache-save" }); } }); var clearCacheBtn = new OO.ui.ButtonWidget({ label: "Cache paqij bike", flags: [ "destructive" ], title: "Datayên qeydkirî yên vê rûpelê ji cache jê bibe (forma ku niha xuya dike naguherîne)." }); clearCacheBtn.on("click", function () { formCache.Set({}); // The live form still has whatever the person typed — it's just no // longer backed up anywhere, so treat this like a fresh unsaved edit. formDirty = true; updateLastSavedIndicator(null); wiktkuNotify("Cache hate paqijkirin.", { type: "success", tag: "wiktku-cache-clear" }); }); // ── "⋯" overflow ───────────────────────────────────────────── // One primary action and one secondary stay on the bar; everything // else moves in here, to avoid four same-weight buttons crowding // (and wrapping to three rows on a phone). var moreBtn = $("<button type='button' class='wiktku-more-btn' title='Vebijarkên din'>⋯</button>"); var moreMenu = $("<div class='wiktku-more-menu'></div>").hide(); /** Moves an existing OOUI button into the overflow menu, keeping its * handlers — the widgets already carry the behaviour, so this is * purely about where they are shown. */ function intoMenu(btn, extraClass) { var row = $("<div class='wiktku-more-item'></div>"); if (extraClass) row.addClass(extraClass); btn.$element.on("click", function () { moreMenu.hide(); }); row.append(btn.$element); moreMenu.append(row); } intoMenu(saveCacheBtn); intoMenu(clearCacheBtn, "wiktku-more-item-danger"); moreMenu.append($("<div class='wiktku-more-sep'></div>")); moreMenu.append($("<div class='wiktku-more-item wiktku-more-note'></div>").append(lastSavedEl)); moreBtn.on("click", function (e) { e.preventDefault(); e.stopPropagation(); var open = moreMenu.is(":visible"); moreMenu.toggle(!open); if (!open) { setTimeout(function () { $(document).one("click.wiktkuMore", function () { moreMenu.hide(); }); }, 0); } }); var moreWrap = $("<span class='wiktku-more-wrap'></span>").append(moreBtn).append(moreMenu); footer.append(moreWrap); // Icon-only settings button — opens the Tercîh dialog. Plain OOUI // icon names depend on which icon-pack module happens to be loaded, // so this uses the actual Codex "settings" (color-subtle) SVG from // Commons directly, the same way the spinner above hotlinks its gif. var prefsBtn = $("<button></button>", { type: "button", "class": "wiktku-prefs-btn", title: "Tercîh — sazkariyên vê amûrê biguherîne" }); prefsBtn.on("click", function (e) { e.preventDefault(); wiktkuOpenPrefsDialog(); }); // The gear is icon-only on the bar; inside a text menu it needs a // label like everything else around it. prefsBtn.on("click", function () { moreMenu.hide(); }); moreMenu.prepend($("<div class='wiktku-more-sep'></div>")); moreMenu.prepend($("<div class='wiktku-more-item wiktku-more-item-prefs'></div>") .append(prefsBtn) .append($("<span class='wiktku-more-item-label'></span>").text("Tercîh"))); startForm.append(footer); // NOTE: deliberately NOT .hide() (display:none). WikiEditor/CodeMirror/ // the mobile editor's auto-grow logic measure #wpTextbox1's real // dimensions during their own init, which happens while the wizard is // up. A display:none ancestor reports 0 for offsetWidth/offsetHeight/ // scrollHeight, so those scripts bake in a near-zero height that never // gets recalculated later — slideDown() in destroy() only animates the // outer box, it doesn't re-trigger their sizing. Pushing #editform // off-screen instead keeps it laid out (real width/height available to // measure) without being visible, so the editbox opens at full size. $("#editform").addClass("wiktku-offscreen").before(startForm); // renderGroupTabs() looks up #wiktku-group-tabs via a live DOM // selector, so it must run after startForm is actually in the document. renderGroupTabs(); renderBesenDinPicker(); // One pass over the whole form: every select that hasn't already been // initialised, and isn't opted out with .wiktku-plain-select, gets // the searchable picker. initSelects(startForm); refresh(); // Give every draggable textarea a custom resize grip (works // consistently on Safari/iOS, unlike the native corner grip — see // the "Manual drag-to-resize handle" comment in styles.css), and // keep applying it to textareas added later on (new sense blocks, // quote-source fields, nimûne rows, …). wiktkuInitManualResize(startForm); new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { $(mutation.addedNodes).each(function () { if (this.nodeType !== 1) return; wiktkuInitManualResize(this); }); }); }).observe(startForm[0], { childList: true, subtree: true }); // Now that the full language list is loaded, silently restore any // draft the editor previously saved for this page. var cachedDraft = formCache.Get(); if (cachedDraft && cachedDraft.sections && cachedDraft.sections.length) { restoreFromCache(cachedDraft); } } // "oojs-ui.styles.icons-moderation" carries the "trash" glyph used by // makeTrashButton() below — without it the delete buttons on the Mane // and Beş tab bars would render as blank icon-less buttons. mw.loader.using(["oojs-ui-core", "oojs-ui.styles.icons-moderation"], function () { function wiktkuProceedWithData(wiktkuData) { var d = wiktkuData || {}; // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Jimar (number) code definitions — same shape as the wiki's // own Lua number-type table (code -> {cat, display[, req]}). if (d.numberLabels) $.extend(NUMBER_LABELS, d.numberLabels); // Populate lang choices (pinned list). if (d.langChoices) steps.lang.choices = choicesFromObject(d.langChoices, true); // Populate langsByCode and merge full language list from d.ziman. // d.ziman is a {code: name} object with all known languages. $.each(steps.lang.choices, function (i, choice) { if (choice.sortKey === undefined) choice.sortKey = choice.label; langsByCode[choice.code] = choice; }); if (d.ziman) { var pinnedCodes = {}; $.each(steps.lang.choices, function (i, c) { pinnedCodes[c.code] = true; }); var extraChoices = []; $.each(d.ziman, function (code, name) { if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; if (pinnedCodes[code]) return; var choice = { code: code, label: name, sortKey: name }; extraChoices.push(choice); langsByCode[code] = choice; }); extraChoices.sort(function (a, b) { return a.sortKey.localeCompare(b.sortKey, userLang); }); steps.lang.choices = steps.lang.choices.concat(extraChoices); } // Keep the full merged list around for trans/dunde/zarava — those // should still be able to reference any language even when the // Tercîh panel restricts the main "ziman" step below — then, if // the user set a restriction there, narrow steps.lang.choices // itself to just those codes. var wiktkuFullLangChoices = steps.lang.choices; if (wiktkuPrefs.langCodes && wiktkuPrefs.langCodes.length) { var wiktkuAllowedLangSet = {}; $.each(wiktkuPrefs.langCodes, function (i, code) { wiktkuAllowedLangSet[code] = true; }); var wiktkuRestrictedChoices = $.grep(wiktkuFullLangChoices, function (c) { return !!wiktkuAllowedLangSet[c.code]; }); // Fall back to the full list instead of showing an empty // dropdown if none of the saved codes matched anything // (typo'd code, data.json changed since, …). steps.lang.choices = wiktkuRestrictedChoices.length ? wiktkuRestrictedChoices : wiktkuFullLangChoices; } // Populate POS choices — also a plain {code: label} object in data.json. if (d.posChoices) steps.pos.choices = choicesFromObject(d.posChoices, false); // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the full language list // (not the possibly Tercîh-restricted steps.lang.choices). steps.trans.keys = wiktkuFullLangChoices; steps.dunde.keys = wiktkuFullLangChoices; steps.zarava.keys = getZaravaKeys(wiktkuFullLangChoices); build(); } // data.json ships inside this package module, so it is already parsed // and in memory — no action=raw round trip, and no Testing switch to // forget to flip back before deploying. wiktkuProceedWithData(require("./start/data.json")); }); }); //</nowiki> 3gw2lgb7glnw6dcbthqe2e9tidhhkgm 6333907 6333906 2026-08-15T21:20:00Z Wikihez 7344 6333907 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. // implicit dependencies: StorageUtils (ObjectStorage) //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var addLangMode = mw.util.getParamValue("wiktkuaddlang") === "1"; // ── Tercîh (user settings) panel stored via mw.storage (localStorage), globally var WIKTKU_PREFS_KEY = "wiktku_start_prefs"; var WIKTKU_PREFS_DEFAULTS = { // [] = show the full language list in the "ziman" step; otherwise // only these codes are shown there (data.json codes, not names). langCodes: [], // true = never auto-open on a new/empty page — only via the // "+Ziman/beşeke din" portlet link. onlyOnClick: false, // "auto" | "p-cactions" | "p-tb" | "p-views" — where the // "+Ziman/beşeke din" portlet link is added. portlet: "auto", // true = suppress routine/informational mw.notify toasts (page // loading, cache auto-restored, cache saved/cleared, "tê şandin…"). // Errors and direct results of an explicit action (like saving // Tercîh itself) always show regardless of this setting. quiet: false }; function wiktkuLoadPrefs() { if (!(window.mw && mw.storage)) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var raw; try { raw = mw.storage.get(WIKTKU_PREFS_KEY); } catch (e) { raw = null; } if (!raw) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var parsed; try { parsed = JSON.parse(raw); } catch (e) { parsed = {}; } return $.extend({}, WIKTKU_PREFS_DEFAULTS, parsed); } function wiktkuSavePrefs(prefs) { if (!(window.mw && mw.storage)) return false; try { mw.storage.set(WIKTKU_PREFS_KEY, JSON.stringify(prefs)); return true; } catch (e) { return false; } } var wiktkuPrefs = wiktkuLoadPrefs(); // Routine/informational notices go through here so "quiet mode" can // suppress them; errors and explicit-action confirmations (like the // Tercîh save toast) call mw.notify directly instead, and always show. function wiktkuNotify(message, options) { if (wiktkuPrefs.quiet) return; mw.notify(message, options); } // Removes every localStorage entry this script writes, across every // page: the per-page draft caches (formCache below, one key per page // under "wiktku_start_draft_") and the per-textarea manual-resize // heights ("wiktku_resize_height_…", set in util.js). Tercîh itself // (WIKTKU_PREFS_KEY) is deliberately left alone — it's a setting the // person is actively editing when they reach for this button inside the // Tercîh dialog, not a draft/cache to discard. // // formDirty/autosaveDebounceTimer are declared further down (assigned by // build()) but resolved by closure at call time, same as elsewhere in // this file — this is only ever invoked after the wizard has built, // since that's the only place the Tercîh button lives. function wiktkuClearAllScriptCache() { // Cancel the current page's pending autosave — otherwise it fires a // few seconds later (or the periodic one does, within a minute) // using the still-unblanked live form and silently re-writes the // cache this just removed. Same reasoning as the single-page // "Cache paqij bike" button. if (autosaveDebounceTimer) { clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = null; } formDirty = false; $("#wiktku-last-saved").text(""); if (!window.localStorage) return; var toRemove = []; try { for (var i = 0; i < localStorage.length; i++) { var key = localStorage.key(i); if (key && (key.indexOf("wiktku_start_draft_") === 0 || key.indexOf("wiktku_resize_height_") === 0)) { toRemove.push(key); } } } catch (e) { return; } $.each(toRemove, function (_, key) { try { if (window.mw && mw.storage) mw.storage.remove(key); else localStorage.removeItem(key); } catch (e) { /* skip this key, keep clearing the rest */ } }); } // Lazily built the first time it's opened; reused after that (see // wiktkuOpenPrefsDialog below, defined once we know OOUI is available). var wiktkuPrefsWindowManager = null; var wiktkuPrefsDialog = null; function wiktkuOpenPrefsDialog() { mw.loader.using(["oojs-ui-core", "oojs-ui-windows"], function () { function WiktkuPrefsDialog(config) { WiktkuPrefsDialog.super.call(this, config); } if (!wiktkuPrefsDialog) { OO.inheritClass(WiktkuPrefsDialog, OO.ui.ProcessDialog); WiktkuPrefsDialog.static.name = "wiktkuPrefsDialog"; WiktkuPrefsDialog.static.title = "Tercîhên min"; WiktkuPrefsDialog.static.actions = [ { action: "save", label: "Qeyd bike", flags: ["primary", "progressive"] }, { action: "cancel", label: "Betal bike", flags: "safe" }, { action: "clearcache", label: "Hemû cache paqij bike", flags: "destructive" } ]; WiktkuPrefsDialog.prototype.initialize = function () { WiktkuPrefsDialog.super.prototype.initialize.call(this); this.langCodesInput = new OO.ui.TextInputWidget({ placeholder: "ku, zza, ckb (vala bihêle ji bo hemû zimanan)" }); this.onlyOnClickCheckbox = new OO.ui.CheckboxInputWidget({}); this.quietCheckbox = new OO.ui.CheckboxInputWidget({}); this.portletDropdown = new OO.ui.DropdownInputWidget({ options: [ { data: "auto", label: "Otomatîk (li gorî rûyê wîkiyê)" }, { data: "p-cactions", label: "p-cactions - Li qismê Amûran" }, { data: "left-navigation", label: "left-navigation - Li qismê Gotar-Gotûbêj" }, { data: "p-tb", label: "p-tb - Li qismê Giştî" }, { data: "p-views", label: "p-views - Li qismê Bixwîne" } ] }); var fieldset = new OO.ui.FieldsetLayout({ label: "Eyar" }); fieldset.addItems([ new OO.ui.FieldLayout(this.langCodesInput, { label: "Kodên zimanan ku tê xuyakirin li qismê \"ziman\"", align: "top", help: "Kodan bi virgulê (,) ji hev veqetîne. Vala bihêle da ku hemû ziman were nîşandan.", helpInline: true }), new OO.ui.FieldLayout(this.onlyOnClickCheckbox, { label: "Tenê veke wextê \"+Ziman/beşeke din\" were tikandin", align: "inline", help: "Eger were hilbijartin, ev amûr êdî otomatîk li ser rûpelên nû/vala dest pê nake — divê meriv her carê pêl \"+Ziman/beşeke din\" bike.", helpInline: true }), new OO.ui.FieldLayout(this.portletDropdown, { label: "Cihê lînka \"+Ziman/beşeke din\"", align: "top", help: "\"Otomatîk\" li gorî rûyê wîkiyê hildibijêre.", helpInline: true }), new OO.ui.FieldLayout(this.quietCheckbox, { label: "Moda bêdeng (kêmtir agahdarî nîşan bide)", align: "inline", help: "Agahdariyên normal nîşan nede. Xeta her tim tên xuyakirin.", helpInline: true }) ]); this.$body.addClass("wiktku-prefs-dialog-body").append(fieldset.$element); }; WiktkuPrefsDialog.prototype.getSetupProcess = function (data) { return WiktkuPrefsDialog.super.prototype.getSetupProcess.call(this, data) .next(function () { this.langCodesInput.setValue(wiktkuPrefs.langCodes.join(", ")); this.onlyOnClickCheckbox.setSelected(!!wiktkuPrefs.onlyOnClick); this.portletDropdown.setValue(wiktkuPrefs.portlet || "auto"); this.quietCheckbox.setSelected(!!wiktkuPrefs.quiet); }, this); }; WiktkuPrefsDialog.prototype.getActionProcess = function (action) { var dialog = this; if (action === "save") { return new OO.ui.Process(function () { var codes = dialog.langCodesInput.getValue() .split(/[,\s]+/) .map(function (c) { return c.trim().toLowerCase(); }) .filter(function (c) { return !!c; }); wiktkuPrefs = { langCodes: codes, onlyOnClick: dialog.onlyOnClickCheckbox.isSelected(), portlet: dialog.portletDropdown.getValue() || "auto", quiet: dialog.quietCheckbox.isSelected() }; wiktkuSavePrefs(wiktkuPrefs); mw.notify( "Tercîh hatin qeydkirin. Rûpelê ji nû ve bar bike (F5).", { type: "success", tag: "wiktku-prefs-save" } ); dialog.close({ action: "save" }); }); } if (action === "cancel") { return new OO.ui.Process(function () { dialog.close({ action: "cancel" }); }); } if (action === "clearcache") { return new OO.ui.Process(function () { if (!window.confirm( "Tu dixwazî hemû cache ya vê amûrê ji her rûpelê paqij bikî " + "(danûstandinên qeydkirî yên hemû rûpelan, bilindahiyên qadan)? " + "Tercîhên li jor nayên jêbirin. Ev tişt nayê vegerandin." )) return; wiktkuClearAllScriptCache(); mw.notify("Hemû cache hate paqijkirin.", { type: "success", tag: "wiktku-cache-clear-all" }); dialog.close({ action: "clearcache" }); }); } return WiktkuPrefsDialog.super.prototype.getActionProcess.call(this, action); }; wiktkuPrefsWindowManager = new OO.ui.WindowManager(); $(document.body).append(wiktkuPrefsWindowManager.$element); wiktkuPrefsDialog = new WiktkuPrefsDialog(); wiktkuPrefsWindowManager.addWindows([wiktkuPrefsDialog]); } wiktkuPrefsWindowManager.openWindow(wiktkuPrefsDialog); }); } var targetContainer; var skin = mw.config.get('skin'); if (wiktkuPrefs.portlet && wiktkuPrefs.portlet !== "auto") { targetContainer = wiktkuPrefs.portlet; } else if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Li vê rûpelê, ziman an jî beşeke nû zêde bike"); // If "onlyOnClick" is set, the wizard should ONLY ever open via the // "+Ziman/beşeke din" link — never automatically var wiktkuNewPageDetected = $(".mw-newarticletext, .mw-newarticletextanon").length > 0; if (wiktkuPrefs.onlyOnClick ? !addLangMode : (!addLangMode && !wiktkuNewPageDetected)) { return; } // ── Shared helpers ─────────────────────────────────────────────────── // Generic text/UI utilities live in their own package file now — see the // header of util.js for why. Aliased to bare names here so the ~400 call // sites below read exactly as they did when these were local functions. var wiktkuUtil = require("./start/util.js"); var capitalize = wiktkuUtil.capitalize; var decapitalize = wiktkuUtil.decapitalize; var escapeRegExp = wiktkuUtil.escapeRegExp; var stripWikilinks = wiktkuUtil.stripWikilinks; var splitTercimeIzah = wiktkuUtil.splitTercimeIzah; var insertAtCursor = wiktkuUtil.insertAtCursor; var foldDiacritics = wiktkuUtil.foldDiacritics; var wrapNativeSelect = wiktkuUtil.wrapNativeSelect; var initSelects = wiktkuUtil.initSelects; var wiktkuInitManualResize = wiktkuUtil.initManualResize; function langHeaderSource(codePattern) { return "\n?==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } // Delete button (real OOUI "trash" icon, destructive-flagged) shared by // the Mane tab bar and the Beş tab bar. One button per bar — sitting // right before "+ Mane zêde bike" / "+ Beş zêde bike", not one per tab // — deletes whichever sense/section is currently open. A trash icon on // every individual tab put the hit-target right where people click to // switch tabs, which is exactly how a stray click ended up deleting the // wrong one; a single button acting on "the one you're looking at" has // only one thing it can possibly delete. function makeTrashButton(title) { return new OO.ui.ButtonWidget({ icon: "trash", flags: ["destructive"], framed: false, invisibleLabel: true, label: title, title: title, classes: ["wiktku-trash-btn"] }); } function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } var catSrcTemplates = null; var catSrcTemplatesPromise = null; function fetchCatSrcTemplates() { if (catSrcTemplatesPromise) return catSrcTemplatesPromise; catSrcTemplatesPromise = new mw.Api().get({ action: "query", list: "categorymembers", cmtitle: "Kategorî:Çavkanî", cmnamespace: 10, cmlimit: "max", formatversion: 2 }).then(function (data) { var members = (data.query && data.query.categorymembers) || []; catSrcTemplates = $.map(members, function (m) { // Pêşgira navî ya "Şablon:" rake. return m.title.replace(/^[^:]+:/, ""); }); catSrcTemplates.sort(function (a, b) { return a.localeCompare(b, userLang); }); return catSrcTemplates; }, function () { catSrcTemplates = []; return catSrcTemplates; }); return catSrcTemplatesPromise; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var formCache = new ObjectStorage("wiktku_start_draft_" + mw.config.get("wgPageName"), 1); var langsByCode = {}; // Looks up the display label for a language code, falling back to the // code itself if it isn't known yet (e.g. langsByCode not loaded). function getLangLabel(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; // Converts a {code: label} object (langChoices/posChoices in data.json) // into the {code, label[, sortKey]} array the rest of the script uses. // isLang: true adds a sortKey and shows "(code)" after the label — // language choices only. function choicesFromObject(obj, isLang) { var result = []; $.each(obj || {}, function (code, label) { var choice = { code: code, label: label }; if (isLang) choice.sortKey = label; result.push(choice); }); return result; } function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c.code] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Number codes (y, s, d, p, p+, tp, j, j+, j/nj, nj, nj+, hj!, hj?) from // data.json's "numberLabels". Same {code: {cat, display[, req]}} shape as // the wiki's Lua number-type table; "display" can contain HTML (<abbr>) // or wikilinks, so it's only used as-is in wikitext output, never dropped // straight into an <option> (see stripMarkupForOption below). var NUMBER_LABELS = {}; // Distinguishes the Jimar dropdown (j= param) from the Cîns dropdown // (c= param): a code that's a key in NUMBER_LABELS is a number code, // everything else is a gender code. Compound codes like "m-p"/"n-p" are // gender+plural pairs and correctly stay on the gender side. function isNumberCode(code) { return Object.prototype.hasOwnProperty.call(NUMBER_LABELS, code); } // Strips the bit of markup "display" is allowed to contain so it's safe // to use as plain <option> text (options can't render HTML or wikilinks): // <abbr title="X">Y</abbr> -> "Y (X)", [[a|b]] -> "b", [[a]] -> "a". function stripMarkupForOption(html) { if (!html) return ""; return $.trim( String(html) .replace(/<abbr[^>]*title="([^"]*)"[^>]*>([\s\S]*?)<\/abbr>/gi, "$2 ($1)") .replace(/\[\[[^\]|]*\|([^\]]*)\]\]/g, "$1") .replace(/\[\[([^\]]*)\]\]/g, "$1") .replace(/<[^>]+>/g, "") ); } // Builds the Jimar dropdown's <option> text for one code: "j — jimarbar". function numberOptionLabel(code) { var def = NUMBER_LABELS[code]; if (!def) return code; var text = stripMarkupForOption(def.display); return text ? (code + " — " + text) : code; } // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } // ── Template explanations ──────────────────────────────────────────── // Every place a template can be picked shows the same row: a status // dot, the name, a link to the template page, and an ⓘ. This is the ⓘ. // // Text comes from the template's own TemplateData where it has any, so // the explanation stays right without anyone maintaining a second copy // by hand — with the desc already in data.json as the fallback for // templates that have none. var wiktkuTplDataCache = {}; // name -> {desc, params[]} or null when absent /** Fetches TemplateData for one template. Resolves to null if the * template has none (a plain, undocumented template — very common). */ function fetchTemplateData(name) { if (Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, name)) { return $.Deferred().resolve(wiktkuTplDataCache[name]).promise(); } return new mw.Api().get({ action: "templatedata", titles: "Şablon:" + name, redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; var first = null; $.each(pages, function (_, p) { if (!first) first = p; }); var out = null; if (first) { var desc = first.description; // TemplateData descriptions are language maps when the // template is documented in more than one language. if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(first.params || {}, function (key, p) { var label = p && p.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(p && p.required) }); }); out = { desc: desc || "", params: params }; } wiktkuTplDataCache[name] = out; return out; }, function () { // No TemplateData, or the API is unhappy — cache the miss so a // repeated ⓘ click doesn't re-request it every time. wiktkuTplDataCache[name] = null; return null; }); } /** Fetches TemplateData for many templates in one request and fills the * cache; resolves either way, a template with no TemplateData caches as null. */ function prefetchTemplateData(names) { var missing = $.grep(names || [], function (n) { return n && !Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n); }); if (!missing.length) return $.Deferred().resolve().promise(); // The API caps a titles list at 50 for normal users. missing = missing.slice(0, 50); return new mw.Api().get({ action: "templatedata", titles: $.map(missing, function (n) { return "Şablon:" + n; }).join("|"), redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; $.each(pages, function (_, page) { if (!page || !page.title) return; var name = String(page.title).replace(/^[^:]+:/, ""); var desc = page.description; if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(page.params || {}, function (key, prm) { var label = prm && prm.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(prm && prm.required) }); }); wiktkuTplDataCache[name] = { desc: desc || "", params: params }; }); // Anything the API didn't answer for simply has none — cache the // miss so the per-row ⓘ doesn't re-request it one at a time. $.each(missing, function (_, n) { if (!Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n)) wiktkuTplDataCache[n] = null; }); }, function () { $.each(missing, function (_, n) { wiktkuTplDataCache[n] = null; }); }); } /** Rewrites each tagged <option> in `sel` as "name — description", using * TemplateData. Only fills rows that have no description yet, so the * hand-written ones in data.json (which carry usage examples the API * does not) are left exactly as they are. */ function applyTplDescriptions(sel) { if (!sel || !sel.length) return; var changed = false; sel.find("option[data-tpl]").each(function () { var opt = $(this); var name = opt.attr("data-tpl"); if (opt.text().indexOf(" — ") !== -1) return; // already described var td = wiktkuTplDataCache[name]; var desc = (td && td.desc) || localTplDesc(name); if (!desc) return; // One line: TemplateData descriptions can run to a paragraph. desc = $.trim(String(desc).split("\n")[0]); if (desc.length > 90) desc = desc.slice(0, 90) + "…"; opt.text(name + " — " + desc); changed = true; }); // The picker caches option text for searching, so it has to re-read. if (changed) sel.trigger("wiktku:refresh"); } /** Hand-written fallback description, from data.json. * * This is the escape hatch for templates with no TemplateData on the * wiki: add a "desc" to the entry in data.json and it shows up in the * dropdown and in the ⓘ immediately, no code change. TemplateData is * still the better place — VisualEditor and every other tool reads it * too — but this keeps the picker useful in the meantime. * * Works for any pool: pronTpls, etymTpls, tplDefs, jederDefs. */ function localTplDesc(name) { var pools = [steps.pron.pronTpls, steps.etym.etymTpls, steps.dfn.tplDefs, steps.dfn.jederDefs]; var found = ""; $.each(pools, function (_, pool) { if (pool && pool[name] && pool[name].desc) { found = pool[name].desc; return false; } }); return found; } /** Opens the inline explanation panel for `name`, anchored under the * picker it was opened from. */ function showTemplateInfo(name, anchorWrap) { $(".wiktku-tpl-info").remove(); var panel = $("<div class='wiktku-tpl-info'></div>"); panel.append($("<div class='wiktku-tpl-info-name'></div>").text("{{" + name + "}}")); var body = $("<div class='wiktku-tpl-info-desc'></div>").text("Tê barkirin…"); panel.append(body); var params = $("<div class='wiktku-tpl-info-params'></div>"); panel.append(params); panel.append($("<a class='wiktku-tpl-info-link' target='_blank' rel='noopener'></a>") .attr("href", wiktkuUtil.tplPageUrl(name)) .text("Rûpela şablonê veke →")); var close = $("<button type='button' class='wiktku-tpl-info-close' title='Bigire'>✕</button>"); close.on("click", function () { panel.remove(); }); panel.prepend(close); $(anchorWrap).after(panel); fetchTemplateData(name).then(function (td) { var desc = (td && td.desc) || localTplDesc(name); body.text(desc || "Ji bo vê şablonê ravek nehatiye nivîsandin."); if (td && td.params && td.params.length) { params.append($("<div class='wiktku-tpl-info-params-title'></div>").text("Parametre:")); var listEl = $("<ul></ul>"); $.each(td.params, function (_, p) { var line = p.name + (p.label ? " — " + p.label : "") + (p.required ? " (pêwîst)" : ""); listEl.append($("<li></li>").text(line)); }); params.append(listEl); } }); } /** Marks a picker's <option>s as template rows so the searchable widget * renders them with the dot / 🔗 / ⓘ affordances, and wires the ⓘ * handler for that picker. `nameOf` maps an <option> to a template * name — the pickers store different things in value= (a snippet for * the insert dropdowns, the bare name for the sense selector). */ function markTemplateOptions(sel, nameOf) { if (!sel || !sel.length) return; var names = []; sel.find("option").each(function () { var opt = $(this); var name = nameOf(opt); if (!name) return; opt.attr("data-tpl", name); // Deprecated/typo templates are the "special cases only" ones. opt.attr("data-tpl-status", /kevnbûyî|şaşnivîs|kêmpeyda/i.test(opt.text()) ? "yellow" : "green"); names.push(name); }); sel.data("wiktkuTplInfo", showTemplateInfo); // Fill in the descriptions. Matters most for the Mane picker, whose // entries in data.json are names with no desc at all — "rastnivîs", // "ku-Latn", "guharto" on their own. One request covers every // template in the picker, cached for the per-row ⓘ as well. prefetchTemplateData(names).always(function () { applyTplDescriptions(sel); }); } /** Pulls the template name out of a snippet like "* {{ku-IPA}}" or * "{{ji|SOURCELANG|CODE|…}}". */ function tplNameFromSnippet(snippet) { var m = /\{\{\s*([^|}\n]+)/.exec(snippet || ""); return m ? $.trim(m[1]) : ""; } // True if a sense has content beyond mane worth keeping (etîket, word // lists, nimûne, jêder) — so it's still emitted with {{mane?}} if empty. function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } // A technically-"complete" entry (Ziman + Cureyê rêzimanî filled) with // nothing in Mane, Bi zaravayên din or Werger is still meaningfully // empty, so this is checked separately at submit-click time with its // own message. function hasMinRequiredContent(values) { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasMane = dfnSenses.some(function (s) { return (s.tpl && s.tplTitle) || (!s.tpl && (s.mane !== "" || senseHasExtraContent(s))); }); if (hasMane) return true; if (values.lang === "ku") { var hasWerger = false; $("#wiktku-start-trans .wiktku-trans-group").each(function () { if (steps.trans.getGroupTranslations($(this)).length) hasWerger = true; }); if (hasWerger) return true; var hasZarava = false; $("#wiktku-start-zarava .wiktku-zarava-group").each(function () { if (steps.zarava.getGroupTranslations($(this)).length) hasZarava = true; }); if (hasZarava) return true; } return false; } // Bolds the *first* occurrence of the page name function boldPageNameOnce(text) { if (!text || !pageNameRe) return text; var re = new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "i"); return text.replace(re, "'''$1'''"); } // Converts literal line breaks typed into a nimûne/jêgirtin box into // wikitext <br> tags, function nlToBr(text) { return text ? text.replace(/\r\n|\r|\n/g, "<br>") : text; } function escapeHtmlForBackdrop(str) { return String(str) .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;"); } // Mirrors a textarea's text, with a small highlighted marker placed // right after each line that's followed by an actual typed/pasted // linebreak. Rendered into a transparent backdrop layer behind the // textarea (see ensureLinebreakBackdrop()), so only the point of the // break is marked instead of the whole box. function buildLinebreakBackdropHtml(text) { var lines = text.split(/\r\n|\r|\n/); return $.map(lines, function (line, i) { var isLast = i === lines.length - 1; return escapeHtmlForBackdrop(line) + (isLast ? "" : "<mark class='wiktku-linebreak-mark'>↵</mark>\n"); }).join(""); } // Copies the metrics that affect where text wraps/lands (font, line // height, padding, border) from the real textarea onto its backdrop, // via computed style rather than shared CSS classes — most of the // box's own rules are written as "textarea.foo", which a <div> with // the same class wouldn't match. Re-run on every update in case a // responsive breakpoint changed the textarea's own font-size. function syncLinebreakBackdropMetrics(textarea, backdrop) { var cs = window.getComputedStyle(textarea[0]); backdrop.css({ "box-sizing": cs.boxSizing, "padding-top": cs.paddingTop, "padding-right": cs.paddingRight, "padding-bottom": cs.paddingBottom, "padding-left": cs.paddingLeft, "border-width": cs.borderWidth, "border-style": "solid", "font-family": cs.fontFamily, "font-size": cs.fontSize, "font-weight": cs.fontWeight, "line-height": cs.lineHeight, "letter-spacing": cs.letterSpacing }); } // Lazily wraps a textarea in its own positioning anchor (independent // of .wiktku-resize-wrap, so this doesn't depend on load order versus // wiktkuMakeManualResizable) and inserts the transparent backdrop // layer used to mark the exact point of a linebreak. Safe to call // more than once on the same textarea — the backdrop is cached. function ensureLinebreakBackdrop(textarea) { var existing = textarea.data("wiktkuLinebreakBackdrop"); if (existing) return existing; textarea.wrap("<div class='wiktku-linebreak-wrap'></div>"); var backdrop = $("<div aria-hidden='true'></div>").addClass("wiktku-linebreak-backdrop"); textarea.before(backdrop); textarea.data("wiktkuLinebreakBackdrop", backdrop); textarea.on("scroll.wiktkuLinebreak", function () { backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); }); return backdrop; } // Flags a nimûne/jêgirtin textarea (via CSS class, for the border // tint + tooltip) while it contains a typed/pasted linebreak, so the // user notices before it's silently turned into <br> on output. // Marks only the exact point of the break via a mirrored backdrop, // rather than tinting the whole box. function highlightLinebreak(el) { var textarea = $(el); var text = textarea.val(); var hasBreak = /\r|\n/.test(text); textarea .toggleClass("wiktku-has-linebreak", hasBreak) .attr("title", hasBreak ? "Xeta nû dê wek <br> bê nivîsandin" : ""); if (!hasBreak) { var cached = textarea.data("wiktkuLinebreakBackdrop"); if (cached) cached.hide(); textarea.removeClass("wiktku-has-linebreak-source"); return; } var backdrop = ensureLinebreakBackdrop(textarea); textarea.addClass("wiktku-has-linebreak-source"); syncLinebreakBackdropMetrics(textarea, backdrop); backdrop.html(buildLinebreakBackdropHtml(text)).show(); backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); } // Each nimûne item can be { text, tr, t }: text, transliteration, translation. function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{nimûne?|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = nlToBr(boldPageNameOnce(text)); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + nlToBr(n.tr); // Translation as third positional param (no key needed). if (n.t) tpl += "|" + nlToBr(n.t); } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 60 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } // Formats jêder (citation) entries into "#* {{jêder…|…}}" lines; skips // entries with no quote text. Falls back to the generic {{jêder}} // template when no specific template was chosen. function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; var quote = nlToBr(boldPageNameOnce(jeder.quote)); var quoteTr = nlToBr(jeder.quoteTr); var quoteT = nlToBr(jeder.quoteT); if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + quote; if (quoteTr) cite += "|tr=" + quoteTr; if (quoteT) cite += "|tercime=" + quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + quote; if (quoteTr) out += "|tr=" + quoteTr; if (quoteT) out += "|tercime=" + quoteT; // A şablon picked from Kategorî:Çavkanî is transcluded as the // source param (e.g. |{{Kovara X}}); manual text is used as-is. var srcParam = jeder.jederCatTpl ? ("{{" + jeder.jederCatTpl + "}}") : (jeder.jederManual ? jeder.jederManual : "çavkanî?"); // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } // True if a sense has at least one jêder entry with quote text. function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } // Builds "{{tplName|lang|part1|part2|…}}" from a sense field (kategori, // etiket), wrapped inline (" {{…}} ") or on its own line ("\n#: {{…}}"). function buildSenseTpl(sense, field, lang, tplName) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return call } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } // ── Inline modifier system ─────────────────────────────────────────────── // Appends a ⊕ button to a word input <li>. Clicking it shows a compact // modifier picker; selecting one prompts for the value and appends // <modifier:value> to the textarea's current content. 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îf" }, { 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: qualifier (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" }, { key: "qq", label: "qq: qualifier (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î" } ]; // Sub-groups (inside a sense/definition block) that get the same ⊕ // modifier button as makeWordListStep fields. var MODIFIER_SUBGROUPS = { "wiktku-dfn-alternativ": true, "wiktku-dfn-hevmane": true, "wiktku-dfn-dijmane": true, "wiktku-dfn-koordine": true, "wiktku-dfn-jornav": true, "wiktku-dfn-jernav": true }; /** * Wraps a freshly-created textarea in a <li> with a ⊕ modifier button. * `ta` — the jQuery textarea element. * Returns the <li>. */ function makeModifierLi(ta) { var li = $("<li class='wiktku-word-li'></li>"); var btn = $("<button type='button' class='wiktku-mod-btn' title='Modifiyerê lê zêde bike'>⊕</button>"); var picker = $("<div class='wiktku-mod-picker'></div>").hide(); // Which modifier keys are already present in the textarea's current // text — e.g. "<t:...>" → "t" used. Each modifier can only be // applied once per word, so its pill gets disabled once used. function usedKeys() { var used = {}; var re = /<([a-zA-Z]+):/g; var val = ta.val() || ""; var m; while ((m = re.exec(val)) !== null) used[m[1]] = true; return used; } $.each(WORD_MODIFIERS, function (_, mod) { var pill = $("<button type='button' class='wiktku-mod-pill'></button>").text(mod.label); pill.attr("title", mod.hint); pill.data("mod-key", mod.key); pill.on("click", function (e) { e.preventDefault(); if (pill.prop("disabled")) return; // already used on this word picker.hide(); // Show a tiny inline input for the modifier value. var valWrap = $("<span class='wiktku-mod-val-wrap'></span>"); var valInp = $("<input type='text' class='wiktku-mod-val-input'>") .attr("placeholder", mod.hint + "…") .attr("size", 20); var confirm = $("<button type='button' class='wiktku-mod-confirm'>✓</button>"); var cancel = $("<button type='button' class='wiktku-mod-cancel'>✕</button>"); function applyModifier() { var v = $.trim(valInp.val()); if (v) { ta.val(ta.val() + "<" + mod.key + ":" + v + ">"); ta.trigger("input"); } valWrap.remove(); ta.focus(); } confirm.on("click", applyModifier); cancel.on("click", function () { valWrap.remove(); ta.focus(); }); valInp.on("keydown", function (e) { if (e.which === 13) { e.preventDefault(); applyModifier(); } if (e.which === 27) { valWrap.remove(); ta.focus(); } }); valWrap.append(valInp).append(confirm).append(cancel); li.append(valWrap); valInp.focus(); }); picker.append(pill); }); btn.on("click", function (e) { e.preventDefault(); // Close any other open pickers in the same list. li.closest("ol, ul").find(".wiktku-mod-picker").not(picker).hide(); // Grey out modifiers already used on this word — refreshed on // every open since the text (and thus what's "used") can change. var used = usedKeys(); picker.find(".wiktku-mod-pill").each(function () { var isUsed = !!used[$(this).data("mod-key")]; $(this).prop("disabled", isUsed).toggleClass("wiktku-mod-pill-used", isUsed); }); picker.toggle(); }); // Close picker when focus leaves the li entirely. li.on("focusout", function () { setTimeout(function () { if (!$.contains(li[0], document.activeElement)) picker.hide(); }, 150); }); li.append(ta).append(btn).append(picker); return li; } function makeWordListStep(id, name, question_fmt) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, modifiers: true, // Function instead of a plain string so it can name the current // language — computed fresh at build time and re-applied by // refresh() whenever the language changes. placeholder: function () { var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return "Kelîme" + (langLabel ? " bi " + langLabel : "") + "…"; }, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); var header = capitalize(name); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: {}, visible: function (values) { if (!values.lang) return false; // addLangMode: skip pron only if this lang already has a section. if (addLangMode) { // Clearing the page makes existing content irrelevant. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, // Fills the insert-dropdown from pronTpls, filtered by language. refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); // Reassures the user this field is optional — the dropdown // below writes the template for them, no syntax needed up front. wrap.append( $("<p class='wiktku-step-hint'></p>").text( "Ev qad ne mecbûrî ye. Heke tu nizanî kîjan şablonî hilbijêrî, vale bihêle — an ji pêşkêşkariya jêrîn şablonekî hilbijêre, ew ê bixweber li vir were nivîsandin." ) ); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike "); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); // Clear the picker's search box sel.trigger("wiktku:refresh"); ta.focus(); return; } // The noLang templates (ku-IPA, ku-kîte, zza-IPA, zza-kîte) // auto-generate content from a Lua module reading the page // title, so show a live preview and require confirmation // before inserting. var tplLabel = selectedOption.text(); $(this).val(""); sel.trigger("wiktku:refresh"); steps.pron.showTplPreview(stepDiv, ta, snippet, tplLabel); }); wrap.append(sel).append(ta); stepDiv.append(wrap); steps.pron.buildIpaPalette(wrap, ta); initSelects(wrap); return ta; }, // ── IPA character palette ────────────────────────────────── // Modelled on fr.wiktionary's: every character is a button that // drops itself in at the cursor. Two sub-tabs, because the full // IPA chart is ~180 symbols and roughly twenty of them ever // appear in Kurmancî — "IPA (kurdî)" opens by default and the // full chart is one click away for loanwords and other // languages. Grouped with a label down the left so it reads as // a chart rather than one long line of glyphs. IPA_KU: [ { label: "Kît/stres", chars: ["ˈ", "ˌ", "ː"] }, { label: "Bêdeng", chars: ["d͡ʒ", "t͡ʃ", "ʒ", "ʃ", "ɫ", "ŋ", "ɾ", "r", "ʋ", "ħ", "ʕ", "ɣ", "χ", "ʔ"] }, { label: "Dengdêr", chars: ["ɑː", "eː", "ɛ", "ɪ", "iː", "ɯ", "ʊ", "uː", "yː", "ø", "œ"] } ], IPA_FULL: [ { label: "Bêdeng 1", chars: ["m", "ɱ", "n", "ɳ", "ɲ", "ŋ", "ɴ", "p", "b", "t", "d", "t̪", "d̪", "ʈ", "ɖ", "c", "ɟ", "k", "ɡ", "q", "ɢ", "ʡ", "ʔ"] }, { label: "Bêdeng 2", chars: ["ɸ", "β", "f", "v", "θ", "ð", "s", "z", "ʃ", "ʒ", "ʂ", "ʐ", "ɕ", "ʑ", "ç", "ʝ", "x", "ɣ", "χ", "ʁ", "ħ", "ʕ", "h", "ɦ", "ʜ", "ʢ", "ɧ"] }, { label: "Bêdeng 3", chars: ["ʋ", "ɹ", "ɻ", "j", "ɥ", "ɰ", "ʍ", "w", "ʙ", "ⱱ", "ɾ", "ɽ", "r", "ʀ", "ɺ", "l", "ɫ", "ɬ", "ɮ", "ɭ", "ʎ", "ʟ"] }, { label: "Bêdeng 4", chars: ["ɓ", "ɗ", "ᶑ", "ʄ", "ɠ", "ʛ", "ʘ", "ǀ", "ǃ", "ǂ", "ǁ"] }, { label: "Dengdêr", chars: ["i", "y", "ɪ", "ʏ", "ɨ", "ʉ", "ɯ", "u", "ʊ", "e", "ø", "ɘ", "ɵ", "ɤ", "o", "ə", "ɚ", "ɛ", "œ", "ɜ", "ɝ", "ɞ", "ʌ", "ɔ", "æ", "ɶ", "ɐ", "a", "ɑ", "ɒ"] }, { label: "Suprasegmental", chars: ["ˈ", "ˌ", "ː", "ˑ", "ʼ", "ˀ", "ˤ", "ᵝ", "ᵊ", "ˠ", "ʰ", "ʱ", "ʲ", "ˡ", "ⁿ", "ᵑ", "ʷ", "ᶣ", "˞", "‿"] }, { label: "Dîakrîtîk", chars: ["̚", "̪", "̺", "̻", "̼", "̬", "̊", "̥", "̞", "̝", "̘", "̙", "̽", "̟", "̠", "̈", "̤", "̹", "̜", "̍", "̩", "̆", "̯", "̃", "̰", "͡", "͜"] }, { label: "Ton", chars: ["̋", "́", "̄", "̀", "̏", "̌", "̂", "˥", "˦", "˧", "˨", "˩", "ꜛ", "ꜜ", "↗", "↘", "‖"] } ], /** Builds the two-sub-tab character palette under the textarea. */ buildIpaPalette: function (wrap, ta) { if (wrap.find(".wiktku-ipa-palette").length) return; var panel = $("<div class='wiktku-ipa-panel'></div>").hide(); var toggle = $("<a href='#' class='wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tîpên bilêvkirinê</span>")); toggle.on("click", function (e) { e.preventDefault(); var open = panel.is(":visible"); panel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); wrap.append($("<div class='wiktku-adv-toggle-row'></div>").append(toggle)); // Sub-tab bar, with the two template buttons pinned right. var subTabs = $("<div class='wiktku-ipa-subtabs'></div>"); var kuTab = $("<span class='wiktku-ipa-subtab wiktku-tab-active'>IPA (kurdî)</span>"); var fullTab = $("<span class='wiktku-ipa-subtab'>IPA</span>"); subTabs.append(kuTab).append(fullTab); var tplBtns = $("<span class='wiktku-ipa-tplbtns'></span>"); $.each([ { label: "{{ku-IPA|+}}", snippet: "{{ku-IPA|}}", back: 2 }, { label: "{{IPA|+}}", snippet: "{{IPA|ku|}}", back: 2 } ], function (_, t) { var b = $("<button type='button' class='wiktku-ipa-tplbtn'></button>").text(t.label); b.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], t.snippet); // Park the cursor inside the braces, where the value goes. var pos = ta[0].selectionStart - t.back; ta[0].selectionStart = ta[0].selectionEnd = pos; ta.focus(); }); tplBtns.append(b); }); subTabs.append(tplBtns); panel.append(subTabs); function buildGrid(groups) { var grid = $("<div class='wiktku-ipa-grid'></div>"); $.each(groups, function (_, g) { var row = $("<div class='wiktku-ipa-row'></div>"); row.append($("<span class='wiktku-ipa-rowlabel'></span>").text(g.label)); var keys = $("<span class='wiktku-ipa-keys'></span>"); $.each(g.chars, function (_, ch) { var btn = $("<button type='button' class='wiktku-ipa-key'></button>"); // A combining mark on its own renders as a stray // accent floating over whatever precedes it, so // show it on a dotted circle — but insert only // the mark itself. var combining = /^[̀-ͯ҃-҉]$/.test(ch); btn.text(combining ? "◌" + ch : ch); if (combining) btn.addClass("wiktku-ipa-key-combining"); btn.attr("title", ch); btn.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], ch); ta.focus(); }); keys.append(btn); }); row.append(keys); grid.append(row); }); return grid; } var kuGrid = buildGrid(steps.pron.IPA_KU); var fullGrid = buildGrid(steps.pron.IPA_FULL).hide(); panel.append(kuGrid).append(fullGrid); kuTab.on("click", function () { kuTab.addClass("wiktku-tab-active"); fullTab.removeClass("wiktku-tab-active"); kuGrid.show(); fullGrid.hide(); }); fullTab.on("click", function () { fullTab.addClass("wiktku-tab-active"); kuTab.removeClass("wiktku-tab-active"); fullGrid.show(); kuGrid.hide(); }); panel.addClass("wiktku-ipa-palette"); wrap.append(panel); }, /** Inline preview + confirm panel for a "noLang" (auto-content) * pronunciation template — fetches what the snippet expands to * for this page and only inserts it if the user confirms. */ showTplPreview: function (stepDiv, ta, snippet, tplLabel) { // Only one preview panel open at a time. stepDiv.find(".wiktku-pron-preview").remove(); var panel = $("<div class='wiktku-pron-preview'></div>"); panel.append($("<div class='wiktku-pron-preview-label'></div>") .text("Pêşdîtina " + tplLabel + ":")); var body = $("<div class='wiktku-pron-preview-body'></div>").text("Tê barkirin…"); panel.append(body); var actions = $("<div class='wiktku-pron-preview-actions'></div>"); var confirmBtn = $("<button type='button' class='wiktku-pron-preview-confirm'>✓ Tevlî bike</button>") .prop("disabled", true); var cancelBtn = $("<button type='button' class='wiktku-pron-preview-cancel'>✕ Betal bike</button>"); actions.append(confirmBtn).append(cancelBtn); panel.append(actions); ta.before(panel); confirmBtn.on("click", function () { insertAtCursor(ta[0], snippet); panel.remove(); ta.focus(); }); cancelBtn.on("click", function () { panel.remove(); }); // action=parse, not action=expandtemplates. expandtemplates // returns *expanded wikitext*, so the preview read as // [[IPA]]<sup>([[Wîkîferheng:IPA kurmancî|kilîd]])</sup>: // <span class="IPA">/-{kshhe}-/</span>[[Kategorî:…]] — which // is exactly what the person is trying to avoid having to // read. parse hands back the rendered HTML the page will // actually show. // // Drop the leading "* " first: it is wikitext list syntax // wrapping the template, and keeping it would render the // preview as a bulleted list rather than the line itself. new mw.Api().post({ action: "parse", title: pageName, text: snippet.replace(/^\*\s*/, ""), prop: "text", wrapoutputclass: "", disablelimitreport: 1, disableeditsection: 1, contentmodel: "wikitext", formatversion: 2 }).done(function (data) { var html = (data && data.parse && data.parse.text) || ""; if ($.trim($("<div>").html(html).text())) { body.html(html); // Category links render as nothing but still exist; // and any real link inside a preview should not // navigate away from a half-filled form. body.find("a").attr("target", "_blank").attr("rel", "noopener"); } else { body.text("(vala — ji bo vê rûpelê tiştek nehate afirandin)"); } confirmBtn.prop("disabled", false); }).fail(function () { body.text("Pêşdîtin nehate barkirin — tu dikarî hîn jî wê tevlî bikî."); confirmBtn.prop("disabled", false); }); }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line; }).join("\n"); // "===" heading under Ziman and above the POS sections; the // field is shared across sections, so it's emitted once by // getWikitext() rather than per-POS-section (would otherwise // print the pronunciation twice for a two-POS entry). return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var capitalizedPos = capitalize(pos); // "form" opt-param (checked in posparams) marks this as a // form-of/inflected entry — the section title becomes // "Formeke <pos>ê" instead of the plain pos name. The // template call itself still uses the unchanged pos name. var isForm = $("#wiktku-posparams-opt-form").is(":checked"); var header = isForm ? "\n=== Formeke " + pos + "ê ===\n" : "\n=== " + capitalizedPos + " ===\n"; // Image line (between header and template call) var imageLine = steps.resim.output(values); // Read the live wikitext from the posparams textarea. // Fall back to a plain {{pos|lang}} if the step hasn't been built yet. var tplLine = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); if (!tplLine) { tplLine = "{{" + pos + "|" + (values.lang || "") + "}}"; } return header + imageLine + tplLine + "\n"; } }, // cinsiyet (gender) — shown for navdêr/serenav only, with choices built // from metadata[lang].g since not every language has grammatical gender. cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams // Single source of truth for the selected gender code. The visible // dropdown lives inside the posparams step (see steps.posparams), // but it must always read/write THIS hidden field — not a field of // its own — since getValuesForStep("cinsiyet") reads from here. build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-cinsiyet-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // jimar (grammatical number) — same hidden-field pattern as cinsiyet // above, but writes into its own j= template parameter instead of // sharing c=. Shown for navdêr/serenav only, with choices built from // whichever of metadata[lang].g are number codes (see isNumberCode). jimar: { id: "jimar", name: "jimar", question_fmt: 'Jimara "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-jimar-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // Lêker transitivity — hidden step, handled inside posparams lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function () { return false; }, choices: [ { code: "gh", label: "gerguhêz" }, { code: "x-gh", label: "xwerû-gerguhêz" }, { code: "p-gh", label: "pêkhatî-gerguhêz" }, { code: "h-gh", label: "hevedudanî-gerguhêz" }, { code: "b-gh", label: "biwêjî-gerguhêz" }, { code: "ngh", label: "negerguhêz" }, { code: "x-ngh", label: "xwerû-negerguhêz" }, { code: "p-ngh", label: "pêkhatî-negerguhêz" }, { code: "h-ngh", label: "hevedudanî-negerguhêz" }, { code: "b-ngh", label: "biwêjî-negerguhêz" } ], output: function () { return ""; } }, // tr — hidden step, handled inside posparams tr: { id: "tr", name: "transliterasyon", question_fmt: "Transliterasyona vê kelîmeyê", multiple: false, narrow: true, visible: function () { return false; } }, posparams: { id: "posparams", // Fused onto the "pos" card visually (see #wiktku-start-posparams // in styles.css) so the two read as ONE question — this name is // only a no-CSS/no-JS fallback, since the h3 that would show it // is hidden by CSS. name: "taybetmendî", // Shows what's actually being asked for: gender for nouns, verb // type for verbs, a generic fallback otherwise. question_fmt: function (values) { var pos = values.pos || ""; // Cinsiyet/Jimar fields below are self-labelled, so no title needed here. if (pos === "navdêr" || pos === "serenav") return ""; if (/^lêker/.test(pos)) return "Cureyê lêkerê"; return "Taybetmendî"; }, visible: function (values) { return !!(values.lang && values.pos); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-posparams-wrap").length) return null; var wrap = $("<div class='wiktku-posparams-wrap'></div>"); var helpers = $("<div class='wiktku-posparams-helpers'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-posparams-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-posparams-text") .attr("rows", 2); var _rebuilding = false; function safeRebuild() { if (_rebuilding) return; _rebuilding = true; steps.posparams.rebuildTa(stepDiv); _rebuilding = false; refresh(); } // Generic text-input row factory function makeTextRow(key, labelText, placeholder) { var row = $("<div class='wiktku-posparams-row'></div>") .attr("id", "wiktku-posparams-row-" + key).hide(); var inp = $("<input type='text'>") .addClass("wiktku-start-narrow wiktku-posparams-field") .attr("data-pp-key", key) .attr("placeholder", placeholder || ""); inp.on("input", safeRebuild); row.append($("<label></label>").text(labelText + ": ")).append(inp); return row; } // cinsiyet var cinsiyetRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-c'></div>") .append($("<label></label>").text("Cinsiyet: ")).hide(); var cinsiyetSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-cinsiyet-sel") .append($("<option value=''>— hilbijêre —</option>")); // Writes into the real, shared #wiktku-start-cinsiyet-field (owned by // steps.cinsiyet) rather than a field of its own — see the comment // on steps.cinsiyet.build for why that matters. cinsiyetSel.on("change", function () { $("#wiktku-start-cinsiyet-field").val($(this).val()).trigger("change"); safeRebuild(); }); cinsiyetRow.append(cinsiyetSel); // jimar (number) — second dropdown next to Cinsiyet, writes // into the shared hidden #wiktku-start-jimar-field, into its // own j= param instead of sharing c=. Options + tooltip are // built in syncHelpers once the language's number codes are known. var jimarRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-jimar'></div>") .append($("<label></label>").text("Jimar: ")).hide(); var jimarSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-jimar-sel") .append($("<option value=''>— hilbijêre —</option>")); jimarSel.on("change", function () { $("#wiktku-start-jimar-field").val($(this).val()).trigger("change"); safeRebuild(); }); jimarRow.append(jimarSel); // lektur: two plain questions (transitivity + structural form) // instead of one 10-option dropdown. Emitted code: base alone // ("gh"), or prefix + "-" + base ("x-gh"). var lekturRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lektur'></div>") .append($("<label></label>").text("Lêker derbasdar e? ")).hide(); var lekturSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lektur-sel") .append($("<option value=''>— hilbijêre —</option>")) .append($("<option value='gh'>gerguhêz (bireser digire)</option>")) .append($("<option value='ngh'>negerguhêz (bireser nagire)</option>")); lekturSel.on("change", safeRebuild); lekturRow.append(lekturSel); // Second half of the same question — the structural form. // Blank = xwerû/sade, which is the common case. var lekturFormRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lekturform'></div>") .append($("<label></label>").text("Şiklê lêkerê: ")).hide(); var lekturFormSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lekturform-sel") .append($("<option value=''>sade (asayî)</option>")) .append($("<option value='x'>xwerû</option>")) .append($("<option value='p'>pêkhatî</option>")) .append($("<option value='h'>hevedudanî</option>")) .append($("<option value='b'>biwêjî</option>")); lekturFormSel.on("change", safeRebuild); lekturFormRow.append(lekturFormSel); helpers.append(cinsiyetRow).append(jimarRow).append(lekturRow).append(lekturFormRow); // ── Everything below here is "Tercîhên pêşketî" ────────────── // These rows live inside a collapsed panel, so the default // view of this card is two dropdowns instead of twenty-odd fields. // Transliteration is a primary field, not an advanced one, for // any language not written in Latin script: for those, an // entry without it is incomplete. syncHelpers already gates // the row on needsTransliteration(lang), so for Kurmancî and // other Latin-script languages it simply never appears. helpers.append(makeTextRow("tr", "Transliterasyon (tr)", "Transliterasyon…")); var advPanel = $("<div class='wiktku-posparams-adv-panel'></div>").hide(); advPanel .append(makeTextRow("cuda", "nîşankirina alternatîv", "cuda…")) .append(makeTextRow("ts", "Transkrîpsiyon (ts)", "Transkrîpsiyon…")) .append(makeTextRow("m", "Forma mê (m)", "Forma mê…")) .append(makeTextRow("mtr", "Translit. mê (mtr)", "Transliterasyona mê…")) .append(makeTextRow("n", "Forma nêr (n)", "Forma nêr…")) .append(makeTextRow("ntr", "Translit. nêr (ntr)", "Transliterasyona nêr…")) .append(makeTextRow("p", "Forma pirjimar (p)", "Forma pirjimar…")) .append(makeTextRow("ptr", "Translit. pirjimar", "Transliterasyona pirjimar…")) .append(makeTextRow("y", "Forma yekjimar (y)", "Forma yekjimar…")) .append(makeTextRow("ytr", "Translit. yekjimar", "Transliterasyona yekjimar…")) .append(makeTextRow("sûp", "Forma sûperlatîv (sûp)", "Forma sûperlatîv…")) .append(makeTextRow("sûptr", "Translit. sûperlatîv", "Transliterasyona sûperlatîv…")) .append(makeTextRow("komp", "Forma komparatîv (komp)", "Forma komparatîv…")) .append(makeTextRow("komptr", "Translit. komparatîv", "Transliterasyona komparatîv…")) .append(makeTextRow("gir", "Forma girdêk (gir)", "gir=…")) .append(makeTextRow("girtr", "Translit. gir", "girtr=…")) .append(makeTextRow("hûr", "Forma hûrek (hûr)", "hûr=…")) .append(makeTextRow("hûrtr", "Translit. hûr", "hûrtr=…")) .append(makeTextRow("hanja", "Forma hanja", "hanja=…")) .append(makeTextRow("hanjaTr","Translit. hanja", "hanjaTr=…")) // Lêker rehên demê (only shown when pos is lêker — see syncHelpers) .append(makeTextRow("niha", "Rehê dema niha (niha)", "Rehê dema niha…")) .append(makeTextRow("nihatr", "Translit. rehê dema niha", "Transliterasyona rehê dema niha…")) .append(makeTextRow("borî", "Rehê dema borî (borî)", "Rehê dema borî…")) .append(makeTextRow("borîtr", "Translit. rehê dema borî", "Transliterasyona rehê dema borî…")) .append(makeTextRow("subj", "Rehê dema bilanî (subj)", "Rehê dema bilanî…")) .append(makeTextRow("subjtr", "Translit. rehê dema bilanî", "Transliterasyona rehê dema bilanî…")); // Optional boolean params — nested inside the advanced panel // (they were already the most niche thing on the card). var optPanel = $("<div class='wiktku-posparams-opt-panel'></div>"); $.each([ { key: "form", label: "form — ev made forma tewandî ye" }, { key: "formaalt", label: "formaalt — vê madeyê bike forma alternatîv" }, { key: "nekatcure", label: "nekatcure — sinifa rêzimanî kategorîze neke" }, { key: "nekatcins", label: "nekatcins — kategoriya cinsiyetê neyîne" }, { key: "nekatçendterm", label: "nekatçendterm — kategoriya çend-term neyîne" }, { key: "serlînkneke", label: "serlînkneke — sernavê madeyê lînk neke" }, { key: "nekatpalîndrom", label: "nekatpalîndrom — kategoriya palîndromê neyîne" }, { key: "neformtr", label: "neformtr — transliterasyona forman neyîne" } ], function (_, p) { var cb = $("<input type='checkbox'>") .attr("id", "wiktku-posparams-opt-" + p.key).val(p.key).on("change", safeRebuild); var lbl = $("<label></label>").attr("for", "wiktku-posparams-opt-" + p.key).text(" " + p.label); optPanel.append($("<div class='wiktku-posparams-opt-row'></div>").append(cb).append(lbl)); }); advPanel.append(optPanel); var optToggle = $("<a href='#' class='wiktku-posparams-opt-toggle wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tercîhên pêşketî</span>")); optToggle.on("click", function (e) { e.preventDefault(); var open = advPanel.is(":visible"); advPanel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); helpers.append($("<div class='wiktku-adv-toggle-row'></div>") .append(optToggle)); helpers.append(advPanel); wrap.append(helpers).append(ta); // Typing directly in textarea keeps cinsiyet/jimar hidden // fields in sync, but does NOT call refresh() — preserves // manual edits. ta.on("input", function () { var text = $(this).val(); var cMatch = text.match(/\|c=([^|}\s]+)/); $("#wiktku-start-cinsiyet-field").val(cMatch ? cMatch[1] : ""); var jMatch = text.match(/\|j=([^|}\s]+)/); $("#wiktku-start-jimar-field").val(jMatch ? jMatch[1] : ""); }); stepDiv.append(wrap); return null; }, /** Reads all helper widget values and rewrites the textarea. * Called only by safeRebuild (user interaction) — never by syncHelpers, * so manual textarea edits are never overwritten by a refresh cycle. */ rebuildTa: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; if (!pos || !lang) return; var cinsiyet = stepDiv.find(".wiktku-posparams-cinsiyet-sel").val() || ""; var jimar = stepDiv.find(".wiktku-posparams-jimar-sel").val() || ""; // Two dropdowns, one code: "gh" / "ngh" on their own, or // prefixed with the structural form ("x-gh", "b-ngh", …). var lekturBase = stepDiv.find(".wiktku-posparams-lektur-sel").val() || ""; var lekturForm = stepDiv.find(".wiktku-posparams-lekturform-sel").val() || ""; var lektur = lekturBase ? (lekturForm ? lekturForm + "-" + lekturBase : lekturBase) : ""; function v(key) { return $.trim(stepDiv.find(".wiktku-posparams-field[data-pp-key='" + key + "']").val()); } var out = "{{" + pos + "|" + lang; if (pos === "navdêr" || pos === "serenav") { out += cinsiyet ? "|c=" + cinsiyet : (lang === "ku" ? "|c=?" : ""); // Number is its own j= param, separate from c= (which // holds gender, including compounds like m-p/n-p). if (jimar) out += "|j=" + jimar; } else if (/^lêker/.test(pos) && lektur) { out += "|c=" + lektur; } if (v("cuda")) out += "|" + v("cuda"); if (v("tr")) out += "|tr=" + v("tr"); if (v("ts")) out += "|ts=" + v("ts"); $.each(["m","n","p","y"], function (_, k) { if (v(k)) out += "|" + k + "=" + v(k); if (v(k+"tr")) out += "|" + k + "tr=" + v(k+"tr"); }); if (v("sûp")) out += "|sûp=" + v("sûp"); if (v("sûptr")) out += "|sûptr=" + v("sûptr"); if (v("komp")) out += "|komp=" + v("komp"); if (v("komptr")) out += "|komptr=" + v("komptr"); if (v("gir")) out += "|gir=" + v("gir"); if (v("girtr")) out += "|girtr=" + v("girtr"); if (v("hûr")) out += "|hûr=" + v("hûr"); if (v("hûrtr")) out += "|hûrtr=" + v("hûrtr"); if (v("hanja")) out += "|hanja=" + v("hanja"); if (v("hanjaTr")) out += "|hanjaTr=" + v("hanjaTr"); if (v("niha")) out += "|niha=" + v("niha"); if (v("nihatr")) out += "|nihatr=" + v("nihatr"); if (v("borî")) out += "|borî=" + v("borî"); if (v("borîtr")) out += "|borîtr=" + v("borîtr"); if (v("subj")) out += "|subj=" + v("subj"); if (v("subjtr")) out += "|subjtr=" + v("subjtr"); stepDiv.find(".wiktku-posparams-opt-panel input:checked").each(function () { var key = $(this).val(); // "form" marks this entry as a form-of/inflected entry — it // takes "erê" rather than the plain "1" the other boolean // opt params use. out += "|" + key + "=" + (key === "form" ? "erê" : "1"); }); out += "}}"; stepDiv.find(".wiktku-posparams-text").val(out); $("#wiktku-start-cinsiyet-field").val(cinsiyet); $("#wiktku-start-jimar-field").val(jimar); }, /** Called from refresh() — controls row visibility only. * Does NOT rewrite textarea so user edits are preserved. * Rebuilds only when textarea is empty (first pos selection). */ syncHelpers: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; var needsTr = needsTransliteration(lang); var isNom = pos === "navdêr" || pos === "serenav" || pos === "rengdêr"; var isAdj = pos === "rengdêr"; var isTîp = pos === "tîp"; var isJa = lang === "ja"; var isLeker = /^lêker/.test(pos); // Kurmancî verbs are conjugated from the present/past roots // alone — there's no separate subjunctive root the way some // other languages have — so this pair of fields is noise for // lang=ku specifically, unlike niha/borî which every lêker // language needs. var isLekerSubj = isLeker && lang !== "ku"; // metadata[lang].g lists gender AND number codes together — // split them here (see isNumberCode) so Cîns only ever offers // gender codes (and gender+plural compounds like m-p/n-p, // which aren't NUMBER_LABELS keys) and Jimar only offers number codes. var meta = metadata[lang]; var allCodes = (meta && meta.g) || []; var genderCodes = $.grep(allCodes, function (c) { return !isNumberCode(c); }); var jimarCodes = $.grep(allCodes, function (c) { return isNumberCode(c); }); var showC = (pos === "navdêr" || pos === "serenav") && genderCodes.length > 0; var cRow = stepDiv.find("#wiktku-posparams-row-c"); cRow.toggle(showC); if (showC) { var sel = cRow.find(".wiktku-posparams-cinsiyet-sel"); // Prefer the select's own current value (normal in-session // use); fall back to the shared hidden field, which is how // a cache/section restore communicates a saved gender // before this select has any <option>s to hold it. var prev = sel.val() || $("#wiktku-start-cinsiyet-field").val() || ""; sel.find("option[value!='']").remove(); $.each(genderCodes, function (_, code) { sel.append($("<option></option>").val(code).text(genderLabel(code))); }); if (prev) sel.val(prev); } var showJimar = (pos === "navdêr" || pos === "serenav") && jimarCodes.length > 0; var jimarRowEl = stepDiv.find("#wiktku-posparams-row-jimar"); jimarRowEl.toggle(showJimar); if (showJimar) { var jimarSelEl = jimarRowEl.find(".wiktku-posparams-jimar-sel"); var prevJimar = jimarSelEl.val() || $("#wiktku-start-jimar-field").val() || ""; jimarSelEl.find("option[value!='']").remove(); $.each(jimarCodes, function (_, code) { var def = NUMBER_LABELS[code] || {}; var opt = $("<option></option>").val(code).text(numberOptionLabel(code)); // The explanation (cat, e.g. "dualia tantum") shows as a // hover tooltip — <option> can't hold richer markup. if (def.cat) opt.attr("title", def.cat); jimarSelEl.append(opt); }); if (prevJimar) jimarSelEl.val(prevJimar); } stepDiv.find("#wiktku-posparams-row-lektur").toggle(isLeker); // Only ask for the structural form once gerguhêz/negerguhêz is answered. stepDiv.find("#wiktku-posparams-row-lekturform") .toggle(isLeker && !!stepDiv.find(".wiktku-posparams-lektur-sel").val()); stepDiv.find("#wiktku-posparams-row-tr").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-ts").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-m").toggle(isNom); stepDiv.find("#wiktku-posparams-row-mtr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-n").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ntr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-p").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ptr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-y").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ytr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-sûp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-sûptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-komp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-komptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-gir").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-girtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hûr").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-hûrtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hanja").toggle(isJa); stepDiv.find("#wiktku-posparams-row-hanjaTr").toggle(isJa); stepDiv.find("#wiktku-posparams-row-niha").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-nihatr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-borî").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-borîtr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-subj").toggle(isLekerSubj); stepDiv.find("#wiktku-posparams-row-subjtr").toggle(isLekerSubj && needsTr); if (!$.trim(stepDiv.find(".wiktku-posparams-text").val())) { steps.posparams.rebuildTa(stepDiv); } }, output: function () { return ""; } // pos.output reads the textarea directly }, dfn: { id: "dfn", name: "Mane", // Field types that live behind "Malûmatên pêşketî". Kept as one // list so the collapse CSS, the count badge and the allGroups // adv: flags below can't drift apart. ADV_SUBGROUPS: [ "wiktku-dfn-etiket", "wiktku-dfn-kategori", "wiktku-dfn-alternativ", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ], question_fmt: function (values) { var base = "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin!"; if (values.lang === "ku") { return base + " Ji bo tercimeyan beşa 'Werger' bi kar bîne!"; } return base; }, multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, // Builds one sense block (<li>): mane textarea, nimûne list, and // sub-lists for alternatîv/hevmane/dijmane/etc. buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // The full refresh() (which rebuilds Werger/Bi zaravayên din — // glossList()/build() re-reads every sense from the DOM) is // deferred to blur rather than run on every keystroke; see // onDfnInput for why that's safe. dfnArea.on("blur", function () { refresh(); }); // — Tercime + Îzah boxes (non-ku alternative to the plain mane box) — // Non-ku entries get a direct translation plus a {{îzah|…}}-wrapped // gloss instead of a Kurdish-style gloss. Rather than teach every // consumer (getSenses/getOutput/linkify) a second data shape, these // boxes just write their combined text into dfnArea and re-fire its // "input" event, so dfnArea stays the single source of truth. var tercimeArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-tercime-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-tercime") .attr("rows", 2) .attr("placeholder", "Tercimeyên rasterast ên kurmancî… Ji bo school-a îngilîzî li vir 'mekteb, medrese' binivîse"); var izahArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-izah-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-izah") .attr("rows", 3) .attr("placeholder", "Îzaha kurmancî… Ji bo school-a îngilîzî li vir 'cihê tehsîlgirtinê' binivîse"); var nonKuWrap = $("<div class='wiktku-dfn-nonku-wrap'></div>") .append(tercimeArea).append(izahArea) .hide(); function syncNonKuToMane() { var t = $.trim(tercimeArea.val()); var iz = $.trim(izahArea.val()); // if tercime is blank, use îzah as definition var combined = t ? (iz ? t + " {{îzah|" + iz + "}}" : t) : iz; dfnArea.val(combined); // Re-fires onDfnInput, as if this were typed directly into // the mane textarea. dfnArea.trigger("input"); } tercimeArea.on("input", syncNonKuToMane); izahArea.on("input", syncNonKuToMane); // Same deferred-refresh treatment as dfnArea itself — these two // feed into it (see syncNonKuToMane above). tercimeArea.on("blur", function () { refresh(); }); izahArea.on("blur", function () { refresh(); }); // Switches between the plain mane box and the tercime+îzah pair — // only for non-ku entries with no tplSelect selected. function updateManeMode() { var lang = getValues().lang || ""; var isTpl = !!tplSelect.val(); if (lang && lang !== "ku" && !isTpl) { dfnArea.hide(); nonKuWrap.show(); } else { nonKuWrap.hide(); if (!isTpl) dfnArea.show(); } } // Store on the block so refresh() can re-sync every block when // lang changes, and restoreDfn() can re-sync after restoring. block.data("updateManeMode", updateManeMode); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || {}; // Cache of all non-placeholder option elements, so updateTplOptions // can detach/re-attach them without losing the full list. var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.attr("data-placeholder", "Li şablonekê bigere"); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (name, tpl) { // Shows "name — tpl.desc" when a tplDefs entry has a desc // in data.json, same pattern as steps.pron's template picker. var opt = $("<option></option>") .val(name) .text(tpl.desc ? name + " — " + tpl.desc : name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); // Same status-dot / 🔗 / ⓘ row treatment as every other // template picker. This one carries the bare name in value=, // so the name mapper is the identity rather than a snippet // parse; descriptions come from each template's TemplateData. markTemplateOptions(tplSelect, function (opt) { return opt.val(); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible // ones — native <select> won't reliably hide options any other way. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); // Options that were detached when the descriptions arrived // missed that pass, so describe whatever is attached now. // The cache is warm by this point, so this is synchronous. applyTplDescriptions(tplSelect); tplSelect.trigger("wiktku:refresh"); if (currentVal && !currentStillValid) { tplSelect.val(""); tplTitleInput.hide().val(""); updateManeMode(); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpela hedefê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); tplTitleInput.on("blur", function () { refresh(); }); // Şablon senses have no plain gloss, so hide alternatîv/hevmane/ // dijmane/etc. Etîket, Nimûne and Jêgirtin stay visible either way. function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); nonKuWrap.hide(); tplTitleInput.show().focus(); } else { tplTitleInput.hide().val(""); updateManeMode(); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); // The template picker is an alternative to writing a // definition, not a step before it — so the box comes first // and this sits under it as a quiet link. It only expands // for the minority of senses that are a pointer at another // word (guharto, şaşnivîs, kevnbûyî) rather than a meaning. var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput) .hide(); var tplLink = $("<a href='#' class='wiktku-dfn-tpl-link'></a>") .text("Ev ne pênase ye — şablonek bi kar bîne"); tplLink.on("click", function (e) { e.preventDefault(); tplRow.show(); $(this).hide(); tplRow.find("input.wiktku-ac-input").first().focus(); }); /** Opens the picker without a click — used on restore, when a * sense already has a template and hiding it would make the * chosen value invisible. */ function revealTplRow() { tplRow.show(); tplLink.hide(); } block.data("revealTplRow", revealTplRow); block.append(dfnArea); block.append(nonKuWrap); block.append(tplLink); block.append(tplRow); // Apply lang filter on initial build. updateTplOptions(); updateManeMode(); // — Sub-field groups. — // The four most-used groups (Nimûne, Jêgirtin, Hevmane, Dijmane) // stay open; the rest sit behind the "Malûmatên pêşketî" toggle // (adv: true → .wiktku-dfn-subgroup-adv, keyed off by the collapse CSS). // Jêgirtin isn't in this array — it's a compound widget built // after the loop — but it's inserted right after Nimûne so the // visible order matches the list above. var allGroups = [ { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "wekî etîket lê xuya nabe tenê kategorîze dike", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê", adv: true }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in", adv: true }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e", adv: true }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e", adv: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); if (g.adv) groupDiv.addClass("wiktku-dfn-subgroup-adv"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } // The placeholder names the current language, but that's // often not chosen yet when this block is first built — // so keep a function around that refresh() (and onSubInput, // for newly-grown fields) can call again once lang is set // or changes. function subPlaceholder() { if (g.noLangSuffix) return g.label + "…"; var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return g.label + (langLabel ? " bi " + langLabel : "") + "…"; } function updateSubPlaceholders() { list.find("> li > textarea.wiktku-dfn-subfield").attr("placeholder", subPlaceholder()); } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": ") .append($("<span></span>").addClass("wiktku-dfn-sublabel-hint").text(g.izah)); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var useModifiers = !!MODIFIER_SUBGROUPS[g.cls]; list.data("updatePlaceholders", updateSubPlaceholders); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", subPlaceholder()); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow, useModifiers); }); list.append(useModifiers ? makeModifierLi(firstInput) : $("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder group — growing list, same structure as Nimûne. — (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text("Jêgirtin")) .append(": "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<textarea></textarea>") .addClass("wiktku-dfn-subfield wiktku-dfn-quote-citoid-input") .attr("rows", 1) .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi otomatîk tijî bike", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); // Fetches citation data from Citoid and fills this citation's // şablon + fields — only rebuilds fields on template change, // and never overwrites values the user already typed. function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoid.fetchJederFields(query).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only rebuild if switching şablon, so a repeat fetch // doesn't clear fields already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel wiktku-plain-select"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); srcSel.append($("<option></option>").val("__category__").text("Ji Kategorî:Çavkanî şablonekê hilbijêre")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); // Citoid is only useful before a source is chosen — // hide it once a selection is made, restore on reset. if (chosen) { citoidWrap.hide(); } else { citoidWrap.show(); return; } if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } if (chosen === "__category__") { // Search widget over the members of [[Kategorî:Çavkanî]]. // Picking a şablon here immediately switches the row to // "Bi destê xwe binivîsim" mode with {{Şablon}} pre-filled, var catWrap = $("<span></span>").addClass("wiktku-native-select-wrap wiktku-dfn-quote-src-cat"); var catInput = $("<input type='search' autocomplete='off'>") .addClass("wiktku-start-narrow wiktku-dfn-quote-src-cat-input") .attr("placeholder", "Li navê şablonê bigere…"); var catResults = $("<ul></ul>").addClass("wiktku-ac-results wiktku-dfn-quote-src-cat-results").hide(); var catStatus = $("<span></span>").addClass("wiktku-dfn-quote-src-cat-status").text("Şablon tên barkirin…"); var showCatResults = function (query) { var q = $.trim(query).toLowerCase(); catResults.empty(); var list = catSrcTemplates || []; var matched = q ? $.grep(list, function (name) { return name.toLowerCase().indexOf(q) !== -1; }) : list; if (!matched.length) { catResults.hide(); return; } $.each(matched.slice(0, 50), function (_, name) { var li = $("<li></li>").text(name).attr("data-value", name); var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; e.preventDefault(); selectCatTpl(name); }); li.on("mousedown", function (e) { e.preventDefault(); selectCatTpl(name); }); catResults.append(li); }); catResults.show(); }; // Wraps the chosen şablon as {{Name}}, drops it into the // manual textarea, and switches the row into manual mode // so the user can keep editing it (add params, etc.). var selectCatTpl = function (name) { catResults.hide(); srcSel.val("__manual__"); srcSel.trigger("change"); srcFields.find(".wiktku-dfn-quote-src-manual") .val("{{" + name + "}}") .trigger("focus"); }; catInput.on("input", function () { showCatResults($(this).val()); }); catInput.on("focus", function () { showCatResults($(this).val()); }); catInput.on("blur", function () { setTimeout(function () { catResults.hide(); }, 200); }); catWrap.append(catInput).append(catResults).append(catStatus); srcFields.append(catWrap); fetchCatSrcTemplates().then(function () { catStatus.text(""); }, function () { catStatus.text("Şablon nehatin barkirin."); }); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (key, label) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", key) .attr("placeholder", label + "…"); // "Sernav" / "Sernavê orjînal" (title fields, e.g. for // kitêb/kovar/malper) get a taller, draggable box; every // other field in the template stays as-is. Field labels // come from the on-wiki jederDefs data, so match on the // (diacritic-folded) label text rather than a fixed key. var foldedLabel = foldDiacritics(label); if (/^sernav$/.test(foldedLabel) || /orjin/.test(foldedLabel)) { inp.addClass("wiktku-dfn-quote-src-input--title"); } row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); jederGroupDiv.append(jederLbl).append(jederList); // Straight after Nimûne rather than last: Jêgirtin is the // same kind of thing (an attested use of the word) and the // two belong together — see the allGroups comment above. var nimuneGroup = block.find(".wiktku-dfn-nimune-group"); if (nimuneGroup.length) jederGroupDiv.insertAfter(nimuneGroup); else block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); // ── "Malûmatên pêşketî" — per sense, after Dijmane ─────── // One toggle per sense rather than one for the whole step: // the fields behind it (Etîket, Kategorî, Jornav…) belong to // a single meaning, so a global switch flipped them for every // sense at once and gave a count that answered "across all // senses" — not a question anybody was asking. (function () { block.addClass("wiktku-sense-adv-hidden"); var advRow = $("<div class='wiktku-adv-toggle-row wiktku-sense-adv-row'></div>"); var advToggle = $("<a href='#' class='wiktku-adv-toggle'></a>").attr("aria-expanded", "false"); var advLabel = $("<span class='wiktku-adv-toggle-text'></span>"); advToggle.append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")).append(advLabel); function syncAdv() { var hidden = block.hasClass("wiktku-sense-adv-hidden"); advLabel.text(hidden ? "Malûmatên pêşketî nîşan bide" : "Malûmatên pêşketî veşêre"); advToggle.attr("aria-expanded", hidden ? "false" : "true") .toggleClass("wiktku-adv-open", !hidden); } advToggle.on("click", function (e) { e.preventDefault(); block.toggleClass("wiktku-sense-adv-hidden"); syncAdv(); }); block.data("syncSenseAdv", syncAdv); advRow.append(advToggle); // After the last always-visible group (Dijmane) and before // the advanced ones, which sit below it in DOM order. var lastPrimary = block.find(".wiktku-dfn-dijmane-group"); if (lastPrimary.length) advRow.insertAfter(lastPrimary); else block.append(advRow); syncAdv(); }()); return block; }, /** Shows only `block` among the sense list; hides every other one. */ setOpenSense: function (stepDiv, block) { stepDiv.find("li.wiktku-dfn-sense").each(function () { $(this).toggleClass("wiktku-sense-collapsed", !$(this).is(block)); }); steps.dfn.renderSenseTabs(stepDiv); }, /** Rebuilds the "Mane 1 / Mane 2 / [trash] / + Mane zêde bike" tab row from the current sense list. */ renderSenseTabs: function (stepDiv) { var tabsDiv = stepDiv.find(".wiktku-dfn-sense-tabs"); if (!tabsDiv.length) return; tabsDiv.empty(); var blocks = stepDiv.find("li.wiktku-dfn-sense"); var openLi = null; blocks.each(function (i) { var li = $(this); var isOpen = !li.hasClass("wiktku-sense-collapsed"); if (isOpen) openLi = li; var tab = $("<span class='wiktku-dfn-sense-tab'></span>") .text("Mane " + (i + 1)) .toggleClass("wiktku-tab-active", isOpen); tab.on("click", function () { steps.dfn.setOpenSense(stepDiv, li); }); tabsDiv.append(tab); }); // One delete button for the whole bar — not one per tab — so // there's only ever a single, deliberate hit-target for a // destructive action, positioned away from the tabs people // click to switch senses. Always keep at least one Mane. if (blocks.length > 1 && openLi) { var openIdx = blocks.index(openLi); var trash = makeTrashButton("Vê maneyê jê bibe (Mane " + (openIdx + 1) + ")"); trash.on("click", function () { if (!window.confirm("Tu dixwazî Mane " + (openIdx + 1) + " jê bibî? Ev tişt nayê vegerandin.")) return; steps.dfn.removeSense(stepDiv, openLi); }); tabsDiv.append(trash.$element); } var addBtn = $("<button type='button' class='wiktku-add-sense'></button>") .append($("<span class='wiktku-add-sense-plus'>+</span>")) .append(document.createTextNode("Mane zêde bike")); addBtn.on("click", function (e) { e.preventDefault(); steps.dfn.addSense(stepDiv); }); tabsDiv.append(addBtn); }, // Deliberately does nothing on every keystroke. The only thing a // live Mane/template-title edit needs to propagate is the Werger/ // Bi zaravayên din gloss list (glossList()/build() re-read every // sense in the DOM, and get slow with more than one sense around) // — mane itself isn't a required step, so nothing else in // refresh() depends on it changing mid-keystroke. The callers // (dfnArea/tercimeArea/izahArea/tplTitleInput) run refresh() on // blur instead; getWikitext()/output() always re-read the DOM // fresh regardless, so the final wikitext is correct either way. onDfnInput: function (stepDiv, block, textarea) {}, /** Appends a sense, opens it, and hides the others. */ addSense: function (stepDiv) { var list = stepDiv.find("ol.wiktku-dfn-list"); var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); initSelects(newBlock); steps.dfn.setOpenSense(stepDiv, newBlock); newBlock.find("textarea.wiktku-dfn-mane").first().focus(); refresh(); return newBlock; }, /** Removes one sense block. Assumes the caller already confirmed * and already checked more than one sense remains. If the * removed sense was the open one, opens whichever sense ends up * taking its place (or the last one, if it was the last). */ removeSense: function (stepDiv, li) { var list = stepDiv.find("ol.wiktku-dfn-list"); var blocks = list.find("li.wiktku-dfn-sense"); var removedIdx = blocks.index(li); var wasOpen = !li.hasClass("wiktku-sense-collapsed"); li.remove(); if (wasOpen) { var remaining = list.find("li.wiktku-dfn-sense"); var next = remaining.eq(removedIdx); if (!next.length) next = remaining.last(); if (next.length) steps.dfn.setOpenSense(stepDiv, next); } steps.dfn.renderSenseTabs(stepDiv); refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow, modifiers) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow, modifiers); }); list.append(modifiers ? makeModifierLi(next) : $("<li></li>").append(next)); // New field starts with no placeholder — give it (and any // others in the list) the current one. var updatePlaceholders = list.data("updatePlaceholders"); if (typeof updatePlaceholders === "function") updatePlaceholders(); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: {}, posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; // One reassurance, shown once for the whole Mane step: the // "an jî şablonek hilbijêre" dropdown inside each sense is // optional — plain text is the normal path. if (!stepDiv.find(".wiktku-dfn-tpl-hint").length) { stepDiv.append( $("<p class='wiktku-step-hint wiktku-dfn-tpl-hint'></p>").text( "Ji bo her maneyekê, dropdown-a \"an jî şablonek hilbijêre\" ne mecbûrî ye — bi gelemperî tu tenê maneyê bi tîpên asayî dinivîsî. Ew şablon tenê ji bo rewşên taybet in (mînak: guherto, kevnbûyî, şaşnivîs); heke tu nizanî kîjan divê, vale bihêle." ) ); } var tabsDiv = $("<div class='wiktku-dfn-sense-tabs'></div>"); stepDiv.append(tabsDiv); var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); steps.dfn.renderSenseTabs(stepDiv); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName === "__category__") { // Reachable only if the user opened the category search but // never picked a şablon — picking one switches the row to // __manual__ (see selectCatTpl above), so there's nothing // meaningful to save here. } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: readList("wiktku-dfn-etiket"), kategori: readList("wiktku-dfn-kategori"), nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense var izahLines = []; // parallel — raw îzah gloss for that same sense // True only once some sense's *actual* dfn text (post tercime/îzah // split) is non-empty. var hasLinkableMane = false; $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("# " + (tplKatTpl ? tplKatTpl + " " : "") + (tplLabelTpl ? tplLabelTpl + " " : "") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(""); // template senses have no îzah return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty // Pull the îzah gloss (if any) out of the combined tercime+îzah // string — it's spliced back in separately below, after its // own linkify pass (see izahLines / the second linkifyText call). var izahRaw = null; var tercimeIzah = splitTercimeIzah(dfn); if (tercimeIzah) { dfn = tercimeIzah.tercime; izahRaw = stripWikilinks(tercimeIzah.izah); } if (dfn) { dfn = stripWikilinks(dfn); // Sentence-case + trailing period are for ku definitions, // which are written as full glosses. if (lang === "ku") { if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } // Real prose — this is what makes the sense worth running // through the main linkify pass. hasLinkableMane = true; } else if (izahRaw === null) { // No mane at all — this is just the "{{mane?|lang}}" // placeholder, a bare template call with no plain words // in it. Do NOT count it as linkable: sending nothing but // bracketed templates through the main linkify pass hangs // the linkify gadget (see the hasLinkableMane/hasIzah // check below). dfn = lang === "ku" ? "{{mane?|" + lang + "}}" : ""; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var out = "# " + (katTpl ? katTpl + " " : "") + (labelTpl ? labelTpl + " " : "") + dfn; var idx = defLines.length; var hasThisIzah = izahRaw !== null && $.trim(izahRaw) !== ""; // Bare {{...}} token — like {{wiktku-cite-N}}, this survives // linkify's first pass untouched (it treats template calls as // opaque), then gets swapped for {{îzah|…}} once the actual // gloss text has been linkified in its own separate pass. if (hasThisIzah) { out += (dfn ? " " : "") + "{{wiktku-izah-" + idx + "}}"; } function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(hasThisIzah ? izahRaw : ""); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } // Runs text through the linkify gadget if it's loaded, otherwise // just passes it through unchanged. Shared by both linkify passes // below (main mane text, and — separately — îzah glosses). function linkifyText(t, cb) { if (typeof $.kuLinkify === "function") { $.kuLinkify(t, cb); } else { cb(t); } } var hasIzah = izahLines.some(function (t) { return t && $.trim(t) !== ""; }); var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with nimûne?. text = "# {{mane?|" + lang + "}}\n#* {{nimûne?|" + lang + "}}\n"; callback(text); return; } // Runs the îzah-only linkify pass against `base` (either the raw // text, when there's no linkable mane to run the main pass on // first, or the already-linkified main text). Shared by both // branches below so the token-splice logic only lives once. function runIzahPass(base) { var izahJoined = $.map(izahLines, function (raw, idx) { if (!raw) return undefined; return "{{wiktku-izah-open-" + idx + "}}" + raw + "{{wiktku-izah-close-" + idx + "}}"; }).join("\n"); linkifyText(izahJoined, function (izahLinked) { var izahByIdx = {}; var re = /\{\{wiktku-izah-open-(\d+)\}\}([\s\S]*?)\{\{wiktku-izah-close-\1\}\}/g; var m; while ((m = re.exec(izahLinked)) !== null) { izahByIdx[parseInt(m[1], 10)] = m[2]; } var withIzah = base.replace(/\{\{wiktku-izah-(\d+)\}\}/g, function (_, n) { var linked = izahByIdx[parseInt(n, 10)]; return linked !== undefined ? "{{îzah|" + linked + "}}" : ""; }); callback(restoreCites(withIzah)); }); } if (!hasLinkableMane) { if (!hasIzah) { // All filled senses are template senses (or otherwise have // no plain text at all) — nothing here needs linkify. callback(restoreCites(text)); return; } // There's no plain mane text anywhere (e.g. tercime left blank // with only îzah filled in), so every defLine is just a bare // template call with nothing to word-link. Sending a line // like "# {{wiktku-izah-0}}" through the main linkify pass // gives it no plain words to work with, makes the linkify // gadget hang — so skip that pass entirely and run only // the îzah pass, splicing straight into the unlinkified text. var loadIzahOnly = function () { runIzahPass(text); }; mw.loader.using("ext.gadget.linkify", loadIzahOnly, loadIzahOnly); return; } var didTryToLoad = function () { // First pass: the main definition text (mane), same as before. linkifyText(text, function (mainLinked) { if (!hasIzah) { callback(restoreCites(mainLinked)); return; } // Second pass: îzah glosses, linkified via their own // separate call. Each gloss is wrapped in its own // {{wiktku-izah-open/close-N}} pair; like the existing // {{wiktku-cite-N}} tokens, these sit inside double // braces so linkify leaves the tokens themselves alone — // only the raw gloss text between each pair gets linked. runIzahPass(mainLinked); }); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, tewandin: { id: "tewandin", name: "tewandin", question_fmt: 'Tewandina "' + pageName + '" binivîse', visible: function (values) { return values.lang && values.pos; }, build: function (stepDiv) { if (stepDiv.find(".wiktku-tewandin-wrap").length) return null; var wrap = $("<div class='wiktku-tewandin-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-tewandin-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-tewandin-text") .attr("rows", 4) .attr("placeholder", "{{ku-tewîn-nav|nêr}}"); wrap.append(ta); stepDiv.append(wrap); function autoPopulate() { if (!ta.length) return; var vals = getValues(); var c = vals.cinsiyet || ""; var p = vals.pos || ""; if (!pageName.includes(" ") && c && GENDER_BASE_LABELS[c] && (p === "navdêr" || p === "serenav") && vals.lang === "ku" && c !== "mndudil") { var label = (c === "mnmane") ? "mê û nêr" : GENDER_BASE_LABELS[c]; var out = "{{ku-tewîn-nav|" + label; if (p === "serenav") out += "|y"; out += "}}"; if (!$.trim(ta.val())) ta.val(out); } } setTimeout(function () { autoPopulate(); $("#wiktku-start-form").on("change.tewandin", "#wiktku-start-lang-field, #wiktku-start-cinsiyet-field, #wiktku-start-pos-field", autoPopulate); }, 0); return ta; }, output: function () { var manualText = $.trim($("#wiktku-start-tewandin .wiktku-tewandin-text").val()); if (manualText) { return "\n==== Tewandin ====\n" + manualText + "\n"; } return ""; } }, // resim — one or more images resim: { id: "resim", name: "resim", question_fmt: "Resmekê lê zêde bike", visible: function (values) { return !!(values.lang && values.pos); }, /** Builds one image row: filename + caption + alt text. */ buildItem: function (stepDiv) { var item = $("<li class='wiktku-resim-item'></li>"); var fileRow = $("<div class='wiktku-posparams-row'></div>"); var fileInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-file") .attr("placeholder", "navê_dosyayê.jpg"); fileRow.append($("<label></label>").text("Navê dosyayê: ")).append(fileInp); var capRow = $("<div class='wiktku-posparams-row'></div>"); var capInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-caption") .attr("placeholder", "Danasîna resimê…"); capRow.append($("<label></label>").text("Danasîn: ")).append(capInp); // Alt text: what a screen reader announces for this image var altRow = $("<div class='wiktku-posparams-row'></div>"); var altInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-alt") .attr("placeholder", "Ji bo kesên nabînin, çi tê dîtin? (ne mecbûrî)"); altRow.append($("<label></label>").text("Nivîsa alternatîf: ")).append(altInp); // Auto-fill the caption with the plain page name when a filename // is typed fileInp.on("input", function () { var file = $.trim($(this).val()); var curCap = $.trim(capInp.val()); var isDefault = !curCap || curCap === pageName; if (file && isDefault) { capInp.val(pageName); } else if (!file && isDefault) { capInp.val(""); } steps.resim.onFileInput(stepDiv, item, this); }); item.append(fileRow).append(capRow).append(altRow); return item; }, /** Grows the image list when the last row's filename gets content. */ onFileInput: function (stepDiv, item, input) { var val = $.trim($(input).val()); var list = stepDiv.find("ol.wiktku-resim-list"); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { list.append(steps.resim.buildItem(stepDiv)); } }, build: function (stepDiv) { if (stepDiv.find(".wiktku-resim-wrap").length) return null; var wrap = $("<div class='wiktku-resim-wrap'></div>"); var list = $("<ol class='wiktku-resim-list'></ol>"); list.append(steps.resim.buildItem(stepDiv)); wrap.append(list); stepDiv.append(wrap); return null; }, /** Reads every filled row from the DOM into an array of {file, caption, alt} * objects — blank rows (missing filename or caption) are skipped. * Non-Kurdish captions get wrapped in {{zim|lang|…}} here, unless * the user already typed their own {{zim|…}} template. Alt text is * optional and left as plain text either way. */ getImages: function (values) { var lang = (values && values.lang) || getValues().lang || ""; var images = []; $("#wiktku-start-resim li.wiktku-resim-item").each(function () { var file = $.trim($(this).find(".wiktku-resim-file").val()); var caption = $.trim($(this).find(".wiktku-resim-caption").val()); var alt = $.trim($(this).find(".wiktku-resim-alt").val()); if (!file || !caption) return; // Strip leading "Wêne:" or "File:" if the user typed it — we add it ourselves. file = file.replace(/^(wêne|file|image)\s*:\s*/i, ""); if (lang && lang !== "ku" && !/^\{\{zim\s*\|/i.test(caption)) { caption = "{{zim|" + lang + "|" + caption + "}}"; } images.push({ file: file, caption: caption, alt: alt }); }); return images; }, output: function (values) { var images = steps.resim.getImages(values); if (!images.length) return ""; return images.map(function (img) { var altPart = img.alt ? "|alt=" + img.alt : ""; return "[[Wêne:" + img.file + "|thumb" + altPart + "|" + img.caption + "]]"; }).join("\n") + "\n"; } }, // bnr-h — {{bnr-h|Page1|Page2|…}} prepended before the lang section (shared, not per-section) bnrh: { id: "bnrh", name: "binêre herwiha (bnr-h)", question_fmt: "Şablona bnr-h li qismê herî jor a rûpelê", //visible: function (values) { return !!values.lang; }, multiple: true, narrow: true, placeholder: "Ji bo 'test' bnr 'Test', 'teşt'", output: function (values) { var pages = $.grep(values.bnrh || [], function (p) { return !!$.trim(p); }); if (!pages.length) return ""; return "{{bnr-h|" + pages.map(function (p) { return $.trim(p); }).join("|") + "}}\n"; } }, bikaranin: { id: "bikaranin", name: "Notên bikaranînê", question_fmt: "Notên bikaranînê yên li ser vê kelîmeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, output: function (values) { var text = $.trim(values.bikaranin || ""); if (!text) return ""; return "\n==== Notên bikaranînê ====\n" + text + "\n"; }, }, xwendin: { id: "xwendin", name: "Bêhtir bixwîne", question_fmt: "Lînkên derveyî eleqedarî vê madeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: function (values) { if (!values || !values.lang) { return `* {{wpedî}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; } const ziman = values.lang === "ku" ? "" : `|ziman=${values.lang}`; return `* {{wpedî${ziman}}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; }, output: function (values) { var text = $.trim(values.xwendin || ""); if (!text) return ""; return "\n==== Bêhtir bixwîne ====\n" + text + "\n"; }, }, alfabeyendin: { id: "alfabeyendin", name: "Bi alfabeyên din", question_fmt: function (values) { var base = "Nivîsîna vê kelîmeyê bi alfabeyên din" var langLabel = values.lang ? getLangLabel(values.lang) : ""; if (langLabel) { return base + " ên " + langLabel; } return base; }, visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: "Ji bo kurmancî: * {{ku-ar|şiklê alfaba erebî}}", output: function (values) { var text = $.trim(values.alfabeyendin || ""); if (!text) return ""; return "\n==== Bi alfabeyên din ====\n" + text + "\n"; }, }, formalt: makeWordListStep("formalt", "formên alternatîv", "Formên alternatîv ên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), hevmane: makeWordListStep("hevmane", "hevmane", "Hevmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), dijmane: makeWordListStep("dijmane", "dijmane", "Dijmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jornav: makeWordListStep("jornav", "jornav", "Jornavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jernav: makeWordListStep("jernav", "jêrnav", "Jêrnavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse"), binereherwiha: makeWordListStep("binereherwiha", "herwiha binêre", "Kelîmeyên din ên eleqedar binivîse"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: {}, visible: function (values) { return values.lang && values.pos; }, // Fills the insert-dropdown from the current etymTpls object. refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(ta); stepDiv.append(wrap); initSelects(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder. // Skip it only when every filled sense is a şablon sense // a completely empty entry with no şablon chosen still gets the placeholder var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasFilledTplSense = dfnSenses.some(function (s) { return !!s.tpl && !!s.tplTitle; }); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (hasFilledTplSense && !hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: function (values) { return {"navz": true, [values.lang]: true} }, // Language dropdown + growing word-input list; a new row appends // when the dropdown gets a value. Mirrors steps.trans, but flat. buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/build below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Attach the searchable picker now the select is in the DOM. initSelects(list); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", question_fmt: "'"+ pageName + "' di zaravayên din de çawa tê gotin?", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: {}, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zaravayekî bigere"); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; // A completely empty entry still gets a placeholder section // to fill in later; an individual placeholder gloss is only // skipped once some other sense already has real content. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", question_fmt: "Tercimeyên vê maneyê bi zimanên din binivîse", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide only when every sense is a filled template sense (no plain // gloss to attach translations to). A mix, or nothing filled in // yet, still shows Werger. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, // Language dropdown + growing word-input list, scoped to one gloss's // group (each gloss has its own group and row list). buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/buildGroup below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, // Builds (or fetches) the .wiktku-trans-group for one gloss. buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, // Syncs one .wiktku-trans-group per current gloss, keyed by // data-gloss-pos so groups stay matched across rebuilds. build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, // Reads all translation rows, grouped by gloss position. getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, // Builds the numbered "{ index, gloss }" list, one per dfn sense // with a real mane (skips template senses). index is 1-based and // matches the sense's position in the "#" definition list. // When nothing's filled in, returns one placeholder entry so // Werger still has a group to attach to; when every sense is a // filled template sense, stays empty (matches trans.visible()). glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane, but other fields are filled — still gets a // gloss group since dfn.getOutput() emits {{mane?}} for it. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // A completely empty entry (nothing filled in dfn at all, no // şablon chosen either) still gets a placeholder Werger section // to fill in later. Only // skip an individual placeholder gloss below when some other // sense actually has real content, making that particular // placeholder redundant. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it. If some other sense already has real // content, this placeholder is redundant — skip it. If the // whole entry is empty, keep it so Werger still gets a // section to fill in. if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, cavkani: { id: "cavkani", name: "çavkanî", question_fmt: "Çavkaniyên din (ne jêgirtin) lê zêde bike", visible: function (values) { return !!values.pos; }, // Fills the insert-dropdown from the members of [[Kategorî:Çavkanî]]. refreshTplSelect: function () { var sel = $("#wiktku-start-cavkani .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(catSrcTemplates || [], function (_, name) { sel.append($("<option></option>").val(name).text(name)); }); markTemplateOptions(sel, function (opt) { return opt.val(); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-cavkani-wrap").length) return null; var wrap = $("<div class='wiktku-cavkani-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-cavkani-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-cavkani-text") .attr("rows", 4) .attr("placeholder", "Şablonekî ji lîsteyê hilbijêre an rasterast binivîse…"); // Template insert dropdown, populated from [[Kategorî:Çavkanî]] — // options refreshed once the category members are fetched. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var status = $("<span class='wiktku-cavkani-status'></span>"); sel.on("change", function () { var name = $(this).val(); if (!name) return; insertAtCursor(ta[0], "\n* {{" + name + "}}"); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(status).append(ta); stepDiv.append(wrap); // build() runs again for every new beş (see the "+ Beş zêde bike" // handler), after the initial page-wide pass — so this select needs // its own init or it stays a plain, unsearchable native <select>. initSelects(wrap); if (catSrcTemplates) { steps.cavkani.refreshTplSelect(); } else { status.text("Şablon tên barkirin…"); fetchCatSrcTemplates().then(function () { steps.cavkani.refreshTplSelect(); status.text(""); }, function () { status.text("Şablon nehatin barkirin."); }); } return ta; }, output: function () { var text = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); if (!text) return ""; return "\n==== Çavkanî ====\n" + text + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); // This array only controls DOM build order — nothing else keys off it // (see the comment above stepIdToGroup). Mane tab order: Mane (senses, // with malûmatên pêşketî nested inside each, see steps.dfn.build) → // Wêne → Bi zaravayên din → Werger, so dfn/resim/zarava/trans sit // adjacent to each other in that order. var ordered_steps = [ steps.lang, steps.pos, steps.posparams, steps.cinsiyet, steps.jimar, steps.lektur, steps.tr, // Mane tab, in reading order: the senses, then the two things that // belong to the entry as a whole rather than to one sense. steps.dfn, steps.tewandin, steps.alfabeyendin, steps.zarava, steps.trans, // Etîmolojî tab. steps.etym, steps.dunde, // Eleqedar tab — three lists of the same shape. steps.je, steps.tekildar, steps.binereherwiha, // Bilêvkirin isn't part of any STEP_GROUPS tab, but still needs a // slot here because this array is what builds the DOM. steps.pron, // Beşên din fields — behind the picker inside the Eleqedar tab. steps.resim, steps.bnrh, steps.bikaranin, steps.formalt, steps.hevmane, steps.dijmane, steps.jornav, steps.jernav, steps.cavkani, steps.xwendin]; // ── Step-group tabs ────────────────────────────────────────────────────── // Three tabs: "Mane" holds the senses (whose own blocks carry Nimûne, // Jêgirtin, Hevmane and Dijmane — see steps.dfn.allGroups), Tewandin, // alfabeyendin, zarava and trans; "Etîmolojî" splits out that topical // cluster; "Eleqedar" holds je/tekildar/binereherwiha plus — behind the // "Beşên din" picker, which lives inside this tab rather than as its // own — everything else (resim, formalt, hevmane, dijmane, jornav, // jernav, bikaranin, cavkani, xwendin, bnrh). A newly-picked section is // inserted right after the picker (see renderBesenDinPicker()), which // sits above je/tekildar/binereherwiha in the DOM — so picking one // pushes those down rather than the other way around. "mane" stays // first as the default-active tab since Mane is required content. // Tewandin keeps its own free-text {{ku-tewîn-nav}} field and does NOT // absorb the Cins/zayend form parameters (m=/n=/p=), which stay on the // headword template. // Steps that live behind the "Beşên din" picker inside Eleqedar — only // these need an explicit "open" before they're shown, even once // Eleqedar's tab is active. var BESENDIN_STEP_IDS = ["resim", "formalt", "hevmane", "dijmane", "jornav", "jernav", "bikaranin", "cavkani", "xwendin", "bnrh"]; var STEP_GROUPS = [ { id: "mane", label: "Mane", steps: ["dfn", "tewandin", "alfabeyendin", "zarava", "trans"] }, { id: "etimoloji", label: "Etîmolojî", steps: ["etym", "dunde"] }, { id: "eleqedar", label: "Eleqedar", steps: ["je", "tekildar", "binereherwiha"].concat(BESENDIN_STEP_IDS) }, ]; // Reverse lookup: step id -> index into STEP_GROUPS (undefined for // ungrouped steps — now only lang/pos/posparams/cinsiyet/lektur/tr, // which stay always-visible since they're required to get to everything // else). var stepIdToGroup = {}; $.each(STEP_GROUPS, function (gi, g) { $.each(g.steps, function (_, sid) { stepIdToGroup[sid] = gi; }); }); // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "posparams", "cinsiyet", "jimar", "lektur", "tr", "resim", "dfn", "tewandin", "formalt", "bikaranin", "alfabeyendin", "hevmane", "dijmane", "jornav", "jernav", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans", "cavkani", "xwendin" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; // ── Bilêvkirin as a standalone section ─────────────────────────────── // Pronunciation belongs to the word, not to one part of speech, so it // sits beside Navdêr/Lêker in the tab bar rather than inside any of them. // Modelled as a flag rather than an entry in `sections` since // activeSection is used as an array index in many places — viewing // Bilêvkirin leaves activeSection pointing at the POS section you were on. var viewingPron = false; // is it the tab currently on screen // Which STEP_GROUPS tab is currently shown. Lives out here (like // activeSection above) so refresh() — which is not nested inside build() // — can read it and so renderGroupTabs()/updateGroupTabIndicators() below // can be called from refresh() too. Both operate on the tab bar via its // #wiktku-group-tabs id rather than a closured element reference, for the // same reason. var activeGroup = 0; // Unsaved-changes / autosave state. Lives out here (same reason as // activeGroup above) so destroy() — which runs on final submit and on // switching to the source editor, and is not nested inside build() — // can clear the timers and the beforeunload warning. build() assigns // into these; it doesn't re-declare them. var formDirty = false; var autosaveDebounceTimer = null; var autosaveInterval = null; /** Re-renders the step-group tab bar to reflect the current activeGroup. */ function renderGroupTabs() { var groupTabsDiv = $("#wiktku-group-tabs"); if (!groupTabsDiv.length) return; groupTabsDiv.empty(); $.each(STEP_GROUPS, function (i, g) { var tab = $("<span></span>") .addClass("wiktku-group-tab") .attr("data-group-idx", i) .text(g.label) .toggleClass("wiktku-tab-active", i === activeGroup); (function (idx) { tab.on("click", function () { if (idx === activeGroup) return; activeGroup = idx; renderGroupTabs(); if (idx === ELEQEDAR_GROUP_IDX) renderBesenDinPicker(); refresh(); // Switching tabs can shorten the page (e.g. leaving a long // "Beşên din" field), and the browser may clamp the scroll // position on its own timing before our measurement runs. // Deferring one frame lets that settle first, so the // offsetTop read below is the final, post-refresh one. window.requestAnimationFrame(function () { var bar = document.getElementById("wiktku-group-tabs"); if (!bar) return; var form = document.getElementById("wiktku-start-form"); var stabsH = form ? (parseFloat(form.style.getPropertyValue("--wiktku-stabs-h")) || 0) : 0; var siteHeaderH = form ? (parseFloat(form.style.getPropertyValue("--wiktku-siteheader-h")) || 0) : 0; var top = bar.getBoundingClientRect().top + window.pageYOffset - stabsH - siteHeaderH; $("html, body").animate({ scrollTop: Math.max(0, top) }, 200); }); }); }(i)); groupTabsDiv.append(tab); }); } /** * Toggles a "needs attention" dot on any group tab that still has a * required, unfilled field hidden inside it — so switching tabs doesn't * leave the person wondering why "Bişîne" stays disabled. */ function updateGroupTabIndicators(values) { var tabs = $("#wiktku-group-tabs .wiktku-group-tab"); if (!tabs.length) return; $.each(STEP_GROUPS, function (i, g) { var missing = false; $.each(g.steps, function (_, sid) { var step = steps[sid]; if (!step || !step.required) return; var val = values[sid]; if (val === "" || (step.multiple && $.isArray(val) && val.join("") === "")) { missing = true; } }); tabs.eq(i).toggleClass("wiktku-tab-missing", missing && i !== activeGroup); }); } // "Beşên din" reveals one field at a time via a picker rather than // stacking them all. Per-section state, snapshotted in // saveCurrentSection() and restored in restoreSection() below, and // auto-seeded from any field that already has content (so a returning // draft doesn't hide something already filled in). var openedOtherSections = {}; var BESENDIN_SET = {}; $.each(BESENDIN_STEP_IDS, function (_, sid) { BESENDIN_SET[sid] = true; }); // "eleqedar"'s index in STEP_GROUPS — the Beşên din picker now renders // inside this tab rather than having its own. Derived rather than // hardcoded — this was once a literal 2 and silently pointed at the // wrong tab the moment Etîmolojî and Eleqedar were reordered. var ELEQEDAR_GROUP_IDX = (function () { for (var i = 0; i < STEP_GROUPS.length; i++) { if (STEP_GROUPS[i].id === "eleqedar") return i; } return STEP_GROUPS.length - 1; }()); /** Re-renders the "Beşên din" picker to list only the not-yet-opened sections. */ function renderBesenDinPicker() { var wrap = $("#wiktku-besendin-picker"); if (!wrap.length) return; wrap.empty(); var pickerValues = getValues(); var unopened = $.grep(BESENDIN_STEP_IDS, function (sid) { if (openedOtherSections[sid]) return false; // Don't offer a section that would open onto nothing: several of // these are gated (Bi zaravayên din / Werger need lang=ku, most // need a pos). refresh() would hide it again straight away, so // picking it would read as a broken dropdown. var step = steps[sid]; if (step && typeof step.visible === "function") { try { if (!step.visible(pickerValues)) return false; } catch (e) { /* a step whose visible() needs DOM we lack yet — offer it */ } } return true; }); if (!unopened.length) return; // everything's open — nothing left to pick var sel = $("<select class='wiktku-besendin-select'></select>"); sel.attr("data-placeholder", "— beşek hilbijêre —"); sel.append($("<option value=''>— beşek hilbijêre —</option>")); $.each(unopened, function (_, sid) { var step = steps[sid]; if (!step) return; sel.append($("<option></option>").val(sid).text(capitalize(step.name))); }); sel.on("change", function () { var sid = $(this).val(); if (!sid) return; openedOtherSections[sid] = true; // Newly opened section moves right under the picker, ahead of // whatever's already open, instead of wherever it happened to // sit in the fixed step order. $("#wiktku-start-" + sid).insertAfter(wrap); renderBesenDinPicker(); refresh(); }); wrap.append(sel); initSelects(wrap); } /** Marks any BESENDIN_STEP_IDS field that already has real content as * "opened", so restoring a draft doesn't bury filled-in sections behind * the picker. Reuses each step's own output() as the emptiness check — * it already knows what "empty" means per field, and it reads the DOM * the restore just populated. Call this AFTER the DOM has the restored * values in it. */ function seedOpenedFromContent() { var values = getValues(); $.each(BESENDIN_STEP_IDS, function (_, sid) { if (openedOtherSections[sid]) return; var step = steps[sid]; if (!step || typeof step.output !== "function") return; try { if (step.output(values)) openedOtherSections[sid] = true; } catch (e) { /* a step whose output() needs more state than we have yet — skip it */ } }); } function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } // Rebuilds the dfn DOM from a previously snapshotted senses array. function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing tab bar + list so build() recreates them cleanly. stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); // The picker is collapsed behind a link by default; a restored // sense that already uses a template has to show it, or the // chosen template is invisible and looks lost. var reveal = block.data("revealTplRow"); if (typeof reveal === "function") reveal(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // dfnArea is the only thing actually saved, so split it back into // tercime/îzah for editing (mirrors syncNonKuToMane's join format). var maneParts = splitTercimeIzah(sense.mane); block.find(".wiktku-dfn-tercime").val(maneParts ? maneParts.tercime : (sense.mane || "")); block.find(".wiktku-dfn-izah").val(maneParts ? maneParts.izah : ""); // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Same for the mane-box mode (plain vs tercime+îzah), since this // also depends on tplSelect's (and lang's) value. var updateMane = block.data("updateManeMode"); if (updateMane) updateMane(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found var useModifiers = !!MODIFIER_SUBGROUPS[cls]; // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true, useModifiers); }); subList.append(useModifiers ? makeModifierLi(ta) : $("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text).each(function () { highlightLinebreak(this); }); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder entries — accepts current array shape or a legacy // single object (older saved sections) for backwards compat. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote).each(function () { highlightLinebreak(this); }); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederCatTpl) { // Legacy format from before the şablon search switched rows to // manual mode directly — convert it the same way now, so it's // editable like any other free-form source. var catSelEl = li.find(".wiktku-dfn-quote-src-sel"); catSelEl.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val("{{" + j.jederCatTpl + "}}"); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); // Restoring a draft opens the first sense's tab by default. steps.dfn.setOpenSense(stepDiv, list.find("li.wiktku-dfn-sense").first()); } // Snapshots simple (non-dfn) per-section steps from the DOM into obj. function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } if (id === "cavkani") { snap.cavkani = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); return; } if (id === "posparams") { snap.posparams = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); return; } if (id === "resim") { // One entry per row, including blank ones, so a mid-edit draft // (e.g. a filename typed but no caption yet) survives a cache // restore instead of being silently dropped. snap.resim = $("#wiktku-start-resim li.wiktku-resim-item").map(function () { return { file: $.trim($(this).find(".wiktku-resim-file").val()), caption: $.trim($(this).find(".wiktku-resim-caption").val()), alt: $.trim($(this).find(".wiktku-resim-alt").val()) }; }).get(); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); // Which "Beşên din" sub-sections this section has already opened // via the picker — per-section, like everything else here. snap.openedOtherSections = $.extend({}, openedOtherSections); sections[activeSection] = snap; } // Restores a previously saved snapshot into the form DOM. function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); $("#wiktku-start-cavkani .wiktku-cavkani-text").val(snap.cavkani || ""); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); steps.posparams.build(ppDiv); var savedTa = snap.posparams || ""; ppDiv.find(".wiktku-posparams-text").val(savedTa); // Re-parse saved textarea to restore helper widget states. if (savedTa) { var cMatch = savedTa.match(/\|c=([^|}\s]+)/); var jMatch = savedTa.match(/\|j=([^|}\s]+)/); var trMatch = savedTa.match(/\|tr=([^|}\s]+)/); // Write into the shared hidden field (not the visible // select, which has no <option>s yet) — syncHelpers() // below reads it back to restore the dropdown once the // gender/number options for this language are populated. if (cMatch) $("#wiktku-start-cinsiyet-field").val(cMatch[1]); if (jMatch) $("#wiktku-start-jimar-field").val(jMatch[1]); if (trMatch) ppDiv.find(".wiktku-posparams-field[data-pp-key='tr']").val(trMatch[1]); // For lêker, c= holds the verb-type code instead of a // gender — split it back across the two dropdowns it is // now assembled from ("x-gh" → form "x" + base "gh"). if (cMatch && /^lêker/.test(snap.pos || "")) { var lekturParts = /^(?:([xphb])-)?(n?gh)$/.exec(cMatch[1]); if (lekturParts) { ppDiv.find(".wiktku-posparams-lektur-sel").val(lekturParts[2]); ppDiv.find(".wiktku-posparams-lekturform-sel").val(lekturParts[1] || ""); } } // Restore checked optional params. "form" is stored as // "erê" rather than "1" (see rebuildTa), so it needs its // own check here. ppDiv.find(".wiktku-posparams-opt-panel input[type='checkbox']").each(function () { var key = $(this).val(); var expected = key === "form" ? "erê" : "1"; $(this).prop("checked", savedTa.indexOf("|" + key + "=" + expected) !== -1); }); } steps.posparams.syncHelpers(ppDiv); return; } if (id === "resim") { var resimDiv = $("#wiktku-start-resim"); resimDiv.find(".wiktku-resim-wrap").remove(); steps.resim.build(resimDiv); // Accept both the new array-of-rows format and the older // single {file, caption} object saved before multi-image // support existed. var resimSnap = snap.resim; var rows = $.isArray(resimSnap) ? resimSnap : (resimSnap ? [resimSnap] : []); if (rows.length) { var list = resimDiv.find("ol.wiktku-resim-list"); list.empty(); $.each(rows, function (_, r) { var item = steps.resim.buildItem(resimDiv); item.find(".wiktku-resim-file").val(r.file || ""); item.find(".wiktku-resim-caption").val(r.caption || ""); item.find(".wiktku-resim-alt").val(r.alt || ""); list.append(item); }); // Always keep a blank trailing row, same as Nimûne/Dûnde. var lastItem = list.children("li.wiktku-resim-item").last(); if ($.trim(lastItem.find(".wiktku-resim-file").val())) { list.append(steps.resim.buildItem(resimDiv)); } } return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Tell the pickers about the programmatic value change. fields.filter("select").trigger("wiktku:refresh"); }); // Restore which "Beşên din" sub-sections were already opened for // this section, then seed in anything the DOM restore above just // filled in but that wasn't marked opened yet. openedOtherSections = $.extend({}, snap.openedOtherSections || {}); seedOpenedFromContent(); renderBesenDinPicker(); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); // Bilêvkirin is NOT emitted here — it is one shared field for the // whole word, so emitting it per section duplicated it. getWikitext() // prints it once, above the POS sections. steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.tewandin.output(values); entry += steps.bikaranin.output(values); entry += steps.alfabeyendin.output(values); entry += steps.formalt.output(values); entry += steps.hevmane.output(values); entry += steps.dijmane.output(values); entry += steps.jornav.output(values); entry += steps.jernav.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); entry += steps.cavkani.output(values); entry += steps.xwendin.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { // Each hop through here can be reached asynchronously: the dfn // step waits on mw.loader.using("ext.gadget.linkify") before // calling back, so from that point on the submit handler's own // try/catch is no longer on the stack. Guard every hop instead, // or a throw after linkify loads vanishes into an unhandled // rejection and the form just sits there looking busy. try { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } catch (e) { if (typeof onSubmitError === "function") onSubmitError(e); else throw e; } } processSection(0); } // Assembles wikitext for all sections plus the shared lang header. function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var bnrh = steps.bnrh.output(sharedValues); var entry = steps.lang.output(sharedValues); // One pronunciation per word, printed once between the language // header and the POS sections — see steps.pron.output. entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // bnr-h goes before the language section — only prepended when // generating fresh wikitext (not addLangMode, which handles it separately). if (!addLangMode && bnrh) entry = bnrh + entry; // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { if (s.mane) return s.mane; // Template sense (e.g. {{guharto|ku|somepage}}) — same // construction as the tplCall built in getOutput, so the // summary shows what actually gets written to the entry // instead of going blank. if (s.tpl && s.tplTitle) { return s.tplNoLang ? "{{" + s.tpl + "|" + s.tplTitle + "}}" : "{{" + s.tpl + "|" + sharedValues.lang + "|" + s.tplTitle + "}}"; } return ""; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; // Set by build() to its submitFailed(). Lives out here because the // wikitext-assembly functions below are outside build()'s closure but // still need a way to report a failure to the person rather than dying // silently in the console. var onSubmitError = null; // Whether Mane/Bi zaravayên din/Werger has anything in it — kept // outside refresh() so the click handler can read the latest value. var wiktkuContentGateOk = true; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues, placeholderText) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>").text(placeholderText || "")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice.label); if (choice.sortKey !== undefined) { // This is a language choice {code, label, sortKey} — show code. displayText = capitalize(choice.label) + " (" + choice.code + ")"; } var option = $(mw.html.element("option", { value: choice.code }, displayText)); if (disabledValues[choice.code]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } // Keys to disable for a key menu: already-taken or explicitly disabled. function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); populateMenus(input, step.keys, getDisabledKeys(step)); // Keep the key menus mutually exclusive: whatever one row selects is // disabled in every other row. Recomputed from the DOM on each change. input.on("change", function () { var all = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield"); var taken = {}; all.each(function () { var v = $(this).val(); if (v) taken[v] = true; }); all.not(this).each(function () { var self = $(this), own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (code) $(this).prop("disabled", !!taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }); // Return the wrapper; the select lives inside it and still fires change. return wrapNativeSelect(input); } // Adds another text field to the list if the last one now has text. function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); if (step.placeholder) { nextInput.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = step.modifiers ? makeModifierLi(nextInput).prepend(nextKeyInput || "") : $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) initSelects(nextItem); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } // Shows/hides steps based on whether their prerequisites are met, and // updates placeholders where applicable. function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); steps.cavkani.refreshTplSelect(); // Re-render any step's question label that depends on current values // (e.g. dfn's Werger-section reminder, which only applies to ku). $.each(steps, function (stepId, step) { if (typeof step.question_fmt === "function") { $("#wiktku-start-" + stepId + " .wiktku-start-step-question") .text(step.question_fmt(values)); } }); // Sync every sense block's mane-box mode (plain mane vs tercime+îzah) // to the current language, in case lang changes after blocks exist. $("#wiktku-start-dfn li.wiktku-dfn-sense").each(function () { var updateMane = $(this).data("updateManeMode"); if (updateMane) updateMane(); }); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Re-sync the "<label> bi <ziman>…" placeholder on every always-visible // sub-field list (etîket, kategorî, hevmane, …), since the language may // not have been chosen yet when these lists were first built, or may // have changed since. $("#wiktku-start-dfn .wiktku-dfn-sublist").each(function () { var upd = $(this).data("updatePlaceholders"); if (typeof upd === "function") upd(); }); // Same idea for word-list steps (jê, têkildar, binêre herwiha, …) // whose placeholder is a function of the current language. $.each(steps, function (stepId, step) { if (typeof step.placeholder === "function") { $("#wiktku-start-" + stepId + " textarea.wiktku-start-step-field") .attr("placeholder", step.placeholder()); } }); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // Insert after the quote textarea's resize-wrap (if the manual // resize handle has already been attached to it), not after the // bare textarea -- otherwise this lands *inside* that wrap, // between the textarea and its own grip, breaking jêgirtin's // handle and nesting the tr/t boxes inside it. var quoteTa = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap = quoteTa.closest(".wiktku-resize-wrap"); (quoteResizeWrap.length ? quoteResizeWrap : quoteTa).after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // See the tr-field branch above for why this targets the // resize-wrap instead of the bare textarea. var quoteTa2 = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap2 = quoteTa2.closest(".wiktku-resize-wrap"); (quoteResizeWrap2.length ? quoteResizeWrap2 : quoteTa2).after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { var groupIdx = stepIdToGroup[stepId]; var hiddenByTab = (groupIdx !== undefined && groupIdx !== activeGroup) || // Beşên din picker: stays hidden even while its tab is // active until explicitly opened from the dropdown. (BESENDIN_SET[stepId] && !openedOtherSections[stepId]); // Bilêvkirin is its own section now, so the two views are // mutually exclusive: on it, only pron shows (plus Ziman, which // is shared and stays above every section); off it, pron is // hidden no matter which tab is active. pron is deliberately // ungrouped — stepIdToGroup has no entry for it — so without // this branch it would show on all four tabs at once. if (stepId === "pron") { hiddenByTab = hiddenByTab || !viewingPron; } else if (viewingPron && stepId !== "lang") { hiddenByTab = true; } if (hiddenByTab || (typeof(step.visible) === "function" && !step.visible(values))) { $("#wiktku-start-" + stepId).hide(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } // After build, sync the posparams helper widgets whenever pos or lang changes. if (step.id === "posparams" && typeof step.syncHelpers === "function") { step.syncHelpers(stepDiv); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } stepDiv.slideDown(); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); // The three content tabs belong to a POS section — Bilêvkirin has no // sub-tabs of its own, so the bar goes away while it's on screen. $("#wiktku-group-tabs").toggle(!!values.pos && !viewingPron); var besenDinActive = activeGroup === ELEQEDAR_GROUP_IDX && !viewingPron; $("#wiktku-besendin-picker").toggle(besenDinActive); // The option list is filtered by each step's visible(), which depends // on lang/pos — so it has to be rebuilt when those change, not just // when a section is opened. Safe to call from here: rendering the // picker doesn't itself call refresh(), only picking an option does. if (besenDinActive) renderBesenDinPicker(); updateGroupTabIndicators(values); continueBtn.setDisabled(!canContinue); // Soft gate: stays a real, clickable OOUI button — a hard // setDisabled(true) here would swallow the click entirely, leaving // no way to tell the person why nothing happened. The CSS-only // "looks disabled" class lets the click handler still run and show // wiktkuNotify's explanation. wiktkuContentGateOk = !canContinue || hasMinRequiredContent(values); continueBtn.$element.toggleClass("wiktku-btn-soft-disabled", !wiktkuContentGateOk); } function destroy() { if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); if (autosaveInterval) clearInterval(autosaveInterval); formDirty = false; $(window).off("beforeunload.wiktkuUnsaved"); $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard").slideDown(); // #editform was kept laid-out but off-screen (see build()) instead of // display:none, precisely so the editor never had to size itself // against a zero-width/height box. Just bring it back on-screen — // no slideDown needed since it was never actually collapsed. $("#editform").removeClass("wiktku-offscreen"); // Belt-and-braces: if WikiEditor/CodeMirror/mobile's auto-grow still // cached a stale size from some earlier point, nudge them to // recalculate now that the box is genuinely visible. $(window).trigger("resize"); if (window.CodeMirror) { var cm = $("#wpTextbox1").data("CodeMirror") || $("#wpTextbox1").data("cmInstance"); if (cm && typeof cm.refresh === "function") cm.refresh(); } $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and navz. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; // Inserts a new "== {{ziman|code}} ==" section at the correct sorted // position: navz, then ku/hac/sdh/lki/ckb/zza, then alphabetical by name. function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections — just write the new section. // Add \n\n only when there is real non-whitespace content above. var trimmed = existing.replace(/\s+$/, ""); return trimmed ? trimmed + "\n\n" + wikitext : wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // (?![\s\S]) matches only true end-of-string, since a bare "$" with // /m would stop at the section's first line break instead. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections, each separated by exactly \n\n. // Trim trailing whitespace off each section's content first so we // control the spacing precisely. var joined = sections.map(function (s) { return s.content.replace(/\s+$/, ""); }).join("\n\n"); // Only add a separator after the preamble when it has real content. var preambleTrimmed = preamble.replace(/\s+$/, ""); var prefix = preambleTrimmed ? preambleTrimmed + "\n\n" : ""; return prefix + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê zimanekî nû li rûpelê îlawe bikî. Eger ev ziman jixwe hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bike, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Muhtewaya rûpelê paqij bike (her tiştî jê bibe û rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); // Tab bar for switching between step-groups (topics) within a section. // renderGroupTabs()/updateGroupTabIndicators() (which populate and // maintain it) live outside build() — see near "var activeSection". var groupTabsDiv = $("<div id='wiktku-group-tabs'></div>"); // Both tab bars are sticky (CSS). group-tabs' sticky "top" has to sit // right below section-tabs' actual rendered height, which isn't a // fixed number since the bar can wrap onto a second line. Measured // here and published as a CSS custom property the stylesheet reads // back; recomputed on content changes and window resize. // // Vector 2022 has its own sticky header (.vector-sticky-header) that // pins to the real top:0 once you scroll past the page title, which // would otherwise sit directly behind (and hide) our section-tabs. // Fixed by measuring how much of the viewport Vector's header // currently occupies and offsetting both our bars below it, via // --wiktku-siteheader-h. Vector's header slides in/out with scroll // position, so this is re-measured on scroll too, not just resize. function siteHeaderOffset() { var el = document.querySelector(".vector-sticky-header"); if (!el) return 0; var rect = el.getBoundingClientRect(); // Present in the DOM at all times on Vector 2022, but only // actually occupying screen space once scrolled into place — // before that it sits translated above the viewport (negative/ // zero rect), which must not add a phantom gap under our bars. if (rect.bottom <= 0 || rect.top > 4) return 0; return Math.max(0, rect.bottom); } var stickyOffsetQueued = false; function syncStickyTabsOffset() { var h = sectionTabsDiv.is(":visible") ? (sectionTabsDiv.outerHeight() || 0) : 0; startForm.css("--wiktku-stabs-h", h + "px"); startForm.css("--wiktku-siteheader-h", siteHeaderOffset() + "px"); } function queueStickyTabsOffsetSync() { if (stickyOffsetQueued) return; stickyOffsetQueued = true; window.requestAnimationFrame(function () { stickyOffsetQueued = false; syncStickyTabsOffset(); }); } $(window).on("resize.wiktkuStickyTabs scroll.wiktkuStickyTabs", queueStickyTabsOffsetSync); // "Beşên din" picker — sits right under the group tab bar, only // shown while the Eleqedar tab is active (toggled in refresh(), see // ELEQEDAR_GROUP_IDX); renderBesenDinPicker() fills it. var besenDinPickerDiv = $("<div id='wiktku-besendin-picker' class='wiktku-besendin-picker'></div>"); /** Puts the form back in a usable state after a failed submit and * says what happened. Without this the button stays disabled and * the spinner spins forever on any exception — the person is left * staring at a form that looks busy but is dead, with the reason * visible only in the browser console. */ function submitFailed(err) { spinner.hide(); continueBtn.setDisabled(false); continueBtn.$element.removeClass("wiktku-btn-sending"); var detail = (err && (err.message || err.toString())) || "sedem nediyar"; mw.notify( "Şandin bi ser neket: " + detail + " — tiştê ku te nivîsî winda nebûye. Heke ev dubare bibe, " + "bi 'Edîtora çavkaniyê veke' berdewam bike.", { type: "error", tag: "wiktku-submit", autoHide: false } ); // Deliberately console.error as well: the notification is for the // person, this is for whoever they report the bug to. if (window.console && console.error) console.error("[wiktku] submit failed", err); } onSubmitError = submitFailed; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); continueBtn.$element.addClass("wiktku-btn-sending"); spinner.show(); try { getWikitext(function (wikitext) { try { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page — write fresh content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // ── bnr-h merge ────────────────────────────────────────── // If the user filled bnr-h inputs, either merge into the // existing {{bnr-h|…}} call or prepend a new one. var bnrhOut = steps.bnrh.output(getValues()); if (bnrhOut) { var newPages = bnrhOut.replace(/^\{\{bnr-h\|/, "").replace(/\}\}\n?$/, "").split("|"); var bnrhRe = /\{\{bnr-h\|([^}]*)\}\}/i; if (bnrhRe.test(existing)) { existing = existing.replace(bnrhRe, function (_, inner) { var existingPages = inner.split("|").map(function (p) { return p.trim(); }); $.each(newPages, function (_, p) { p = p.trim(); if (p && existingPages.indexOf(p) === -1) existingPages.push(p); }); return "{{bnr-h|" + existingPages.join("|") + "}}"; }); } else { existing = bnrhOut + existing; } } // If this language's section already exists (whitespace // differences aside), merge into it; otherwise insert new. var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); } catch (e) { // Thrown while writing the result into #wpTextbox1. submitFailed(e); } }); } catch (e) { // Catches anything thrown synchronously inside getWikitext. submitFailed(e); } }); // Tracks whether groupTabsDiv has been inserted yet. var groupTabsInserted = false; $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); var nameH3 = $("<h3></h3>").addClass("wiktku-start-step-name"); var nameLabel = $("<label></label>") .attr("for", "wiktku-start-" + step.id + "-field") .text(name); nameH3.append(nameLabel); stepDiv.append(nameH3); if (step.question_fmt) { // question_fmt can be a plain string, or a function of the // current values (used by steps whose question text depends // on e.g. the chosen language) — refresh() keeps it in sync // afterwards via the .wiktku-start-step-question class. var questionText = typeof step.question_fmt === "function" ? step.question_fmt(getValues()) : step.question_fmt; stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, questionText))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); // initSelects() runs over the whole form once it is in the DOM. stepDiv.append(input); } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.placeholder) { input.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append(step.modifiers ? makeModifierLi(input) : $("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Section tabs (switch between POS sections) sit above the // per-section fields, starting at "pos". if (step.id === "pos") { startForm.append(sectionTabsDiv); } // Step-group tabs sit just before the first grouped step in // ordered_steps. Derived from stepIdToGroup so this keeps // working no matter how STEP_GROUPS/ordered_steps get reordered. if (!groupTabsInserted && stepIdToGroup[step.id] !== undefined) { startForm.append(groupTabsDiv); startForm.append(besenDinPickerDiv); groupTabsInserted = true; } startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); /** Adds a new, empty POS section and switches to it. */ function addPosSection() { saveCurrentSection(); viewingPron = false; sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); return; } if (id === "resim") { $("#wiktku-start-resim .wiktku-resim-wrap").remove(); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); stepDiv.find("select.wiktku-start-step-field").trigger("wiktku:refresh"); }); // Fresh section — no "Beşên din" sub-section has been opened yet. openedOtherSections = {}; renderBesenDinPicker(); renderSectionTabs(); refresh(); } addSectionBtn.on("click", addPosSection); /** Removes one POS section. Assumes the caller already confirmed and * already checked more than one section remains. If the removed * section was the one on screen, its in-progress DOM edits are * discarded along with it (never saved back into sections[]) and a * neighboring section is restored in its place. */ function removePosSection(idx) { sections.splice(idx, 1); if (idx === activeSection) { viewingPron = false; activeSection = Math.min(idx, sections.length - 1); restoreSection(sections[activeSection]); refresh(); } else if (idx < activeSection) { activeSection -= 1; } renderSectionTabs(); } /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); syncStickyTabsOffset(); return; } sectionTabsDiv.show(); // Bilêvkirin leads the bar, ahead of the POS sections. var pronTab = $("<span></span>") .addClass("wiktku-section-tab wiktku-section-tab-pron") .text("Bilêvkirin") .toggleClass("wiktku-tab-active", viewingPron); pronTab.on("click", function () { if (viewingPron) return; saveCurrentSection(); viewingPron = true; refresh(); renderSectionTabs(); }); sectionTabsDiv.append(pronTab); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection && !viewingPron); (function (idx) { tab.on("click", function () { if (idx === activeSection && !viewingPron) return; // Leaving Bilêvkirin doesn't need a save — its field // is shared and never part of a section snapshot. if (!viewingPron) saveCurrentSection(); viewingPron = false; activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // One delete button for the whole bar — not one per tab — same // reasoning as the Mane tabs' trash button: deletes whichever // Beş is currently open, so there's only one thing a click on it // can possibly remove. Not shown on Bilêvkirin (nothing to // delete there) or when it's the only Beş left. if (sections.length > 1 && !viewingPron) { var activeTabLabel = sections[activeSection] && sections[activeSection].pos ? capitalize(sections[activeSection].pos) : ("Beş " + (activeSection + 1)); var sectionTrash = makeTrashButton("Vê beşê jê bibe (" + activeTabLabel + ")"); sectionTrash.on("click", function () { if (!window.confirm("Tu dixwazî \"" + activeTabLabel + "\" jê bibî? Ev tişt nayê vegerandin.")) return; removePosSection(activeSection); }); sectionTabsDiv.append(sectionTrash.$element); } // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); syncStickyTabsOffset(); } renderSectionTabs(); /** * Re-populates a dynamically-growing "multiple" field list (bnrh, je, * tekildar, …) from a saved array of strings. Sets each value via * .val() + a triggered "input" event rather than touching the DOM * structure directly, so the normal refreshForTextField() growth * logic adds exactly as many rows as needed — the same thing that * happens when a person types into the last (empty) row. */ function restoreMultiField(id, values) { var container = $("#wiktku-start-" + id); $.each(values || [], function (i, v) { var field = container.find(".wiktku-start-step-field").eq(i); if (!field.length || !v) return; field.val(v).trigger("input"); }); } /** * Restores a full cached draft: shared lang/pron/bnrh fields, then * every section (via the same restoreSection()/refresh()/ * renderSectionTabs() sequence already used when switching tabs). * @param cached {{lang: string, pron: string, bnrh: Array, sections: Array, activeSection: number}} */ function restoreFromCache(cached) { if (cached.lang) { $("#wiktku-start-lang-field").val(cached.lang); $("#wiktku-start-lang-field").trigger("wiktku:refresh"); } // Rebuild dependent steps (pos, pron wrap, etc.) now that lang is set. refresh(); if (cached.pron !== undefined) { $("#wiktku-start-pron .wiktku-pron-text").val(cached.pron); } if (cached.bnrh) { restoreMultiField("bnrh", cached.bnrh); } sections = (cached.sections && cached.sections.length) ? cached.sections : [{}]; activeSection = (typeof cached.activeSection === "number" && cached.activeSection >= 0 && cached.activeSection < sections.length) ? cached.activeSection : 0; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); updateLastSavedIndicator(cached.savedAt || null); formDirty = false; wiktkuNotify("Danûstandina berê ya qeydkirî ji cache hate barkirin.", { type: "info", tag: "wiktku-cache-restore" }); } // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { // renderSectionTabs() labels each tab from sections[i].pos, which // is only synced from the DOM by saveCurrentSection() (on tab // switch/section add). Without this, the active tab's own label // stays on the previous pos (or "Beş N") until the user switches // away and back. Update it directly so the rename is immediate. if (sections[activeSection]) sections[activeSection].pos = $(this).val(); renderSectionTabs(); // A new cureyê rêzimanî means any previously chosen cinsiyet/ // cureyê lêkerê no longer applies — clear both selections (and // the shared hidden cinsiyet field, since rebuildTa()/syncHelpers() // fall back to it) before wiping the textarea, so nothing stale // gets carried over into the rebuilt template. var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-cinsiyet-sel").val(""); ppDiv.find(".wiktku-posparams-jimar-sel").val(""); ppDiv.find(".wiktku-posparams-lektur-sel").prop("selectedIndex", 0); ppDiv.find(".wiktku-posparams-lekturform-sel").prop("selectedIndex", 0); $("#wiktku-start-cinsiyet-field").val(""); $("#wiktku-start-jimar-field").val(""); ppDiv.find(".wiktku-posparams-text").val(""); // refresh() runs steps.posparams.syncHelpers(), which toggles the // param rows for the new pos and — since the textarea is now // empty — calls rebuildTa() to repopulate it. refresh(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { // Immediate feedback that the click registered continueBtn.$element.addClass("wiktku-btn-flash"); setTimeout(function () { continueBtn.$element.removeClass("wiktku-btn-flash"); }, 500); // Ziman/Cureyê rêzimanî already block submission via the real // OOUI setDisabled (see canContinue in refresh()) — this is a // second, softer check that still lets the click through so we // can explain why, instead of the button just silently doing nothing. if (!wiktkuContentGateOk) { wiktkuNotify( "Berî şandinê, tiştekî binivîse: Mane, Bi zaravayên din, an jî Werger — kêmasî yek ji van sê beşan divê tijî be.", { type: "warn", tag: "wiktku-mincontent" } ); return; } wiktkuNotify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", flags: [ "destructive" ], }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Cache save/clear buttons ───────────────────────────────────────── // Manual, page-scoped save of the entire wizard (all sections, not // just the active one) via [[MediaWiki:Gadget-StorageUtils.js]]'s // ObjectStorage. Restoring happens silently on load at the end of // build(), once the full language list is available. // // Saving also happens automatically (debounced while typing, plus a // periodic fallback) — see "Autosave" below — since relying on the // person to remember to click "Li cache qeyd bike" before an // accidental tab close/reload defeats the point of having a cache // at all. function buildCacheSnapshot() { return { lang: getValues().lang || "", pron: $("#wiktku-start-pron .wiktku-pron-text").val() || "", // bnrh is shared (page-level), same as lang/pron above — not // per-section, so it doesn't live in sections[]. bnrh: getValuesForStep("bnrh"), sections: sections, activeSection: activeSection, savedAt: Date.now() }; } // ── Last-saved indicator ───────────────────────────────────────────── var lastSavedEl = $("<span id='wiktku-last-saved'></span>"); function formatSavedTime(ts) { try { return new Date(ts).toLocaleTimeString(mw.config.get("wgUserLanguage"), { hour: "2-digit", minute: "2-digit" }); } catch (e) { return new Date(ts).toLocaleTimeString(); } } function updateLastSavedIndicator(ts) { lastSavedEl.text(ts ? ("Cache: qeydkirî di saet " + formatSavedTime(ts) + " de") : ""); } // ── Dirty-state tracking + autosave ────────────────────────────────── // formDirty mirrors "does the live form differ from what's in cache". // Anything the person types/selects sets it; a successful save (auto // or manual) clears it; destroy() (final submit, or switching to the // source editor) also clears it since the wizard's job is over at // that point either way. formDirty/autosaveDebounceTimer/autosaveInterval // are declared in the outer scope (near activeGroup) — assigned here, // not re-declared — so destroy() can reach them too. var AUTOSAVE_DEBOUNCE_MS = 8000; // save shortly after typing pauses var AUTOSAVE_INTERVAL_MS = 60000; // …and at least this often regardless function performAutosave() { if (!formDirty) return; saveCurrentSection(); try { formCache.Set(buildCacheSnapshot()); formDirty = false; updateLastSavedIndicator(Date.now()); } catch (e) { // Silent on autosave failure (storage blocked/full, etc.) — the // manual button still surfaces a proper error if the person // tries it directly, no need to interrupt typing with a toast. } } function scheduleAutosave() { formDirty = true; if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = setTimeout(performAutosave, AUTOSAVE_DEBOUNCE_MS); } startForm.on("input change", "input, textarea, select", scheduleAutosave); autosaveInterval = setInterval(performAutosave, AUTOSAVE_INTERVAL_MS); // Warn on accidental tab close/reload while there's anything unsaved. $(window).on("beforeunload.wiktkuUnsaved", function (e) { if (!formDirty) return undefined; e.preventDefault(); e.returnValue = ""; return ""; }); var saveCacheBtn = new OO.ui.ButtonWidget({ label: "Li cache qeyd bike", title: "Halê vê formê yê niha (ziman, bilêvkirin û hemû beş) li cache (localStorage) qeyd bike, da ku eger rûpel bêyî xwestin were girtin an ji nû ve were barkirin, tu karibî berdewam bikî." }); saveCacheBtn.on("click", function () { saveCurrentSection(); // ObjectStorage.Set() doesn't return a success/failure value, so // the only way to detect a real failure (storage blocked, quota // exceeded, JSON.stringify choking on something unexpected) is to // catch it here rather than inspect a (nonexistent) return value. try { var snapshot = buildCacheSnapshot(); formCache.Set(snapshot); formDirty = false; updateLastSavedIndicator(snapshot.savedAt); wiktkuNotify("Halê formê li cache hate qeydkirin.", { type: "success", tag: "wiktku-cache-save" }); } catch (e) { mw.notify("Qeydkirina li cache bi ser neket.", { type: "error", tag: "wiktku-cache-save" }); } }); var clearCacheBtn = new OO.ui.ButtonWidget({ label: "Cache paqij bike", flags: [ "destructive" ], title: "Datayên qeydkirî yên vê rûpelê ji cache jê bibe (forma ku niha xuya dike naguherîne)." }); clearCacheBtn.on("click", function () { formCache.Set({}); // Cancel any autosave already scheduled from typing before this // click — left alone, it fires a few seconds later (or the // unconditional periodic autosave does, within a minute) using // the still-unblanked live form, silently re-writing the very // cache just cleared. That's why "clear cache, refresh later" // could still show the old data. Not marking the form dirty here // means autosave stays off until the person actually edits // something again, at which point it resumes normally. if (autosaveDebounceTimer) { clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = null; } formDirty = false; updateLastSavedIndicator(null); wiktkuNotify("Cache hate paqijkirin.", { type: "success", tag: "wiktku-cache-clear" }); }); // ── "⋯" overflow ───────────────────────────────────────────── // One primary action and one secondary stay on the bar; everything // else moves in here, to avoid four same-weight buttons crowding // (and wrapping to three rows on a phone). var moreBtn = $("<button type='button' class='wiktku-more-btn' title='Vebijarkên din'>⋯</button>"); var moreMenu = $("<div class='wiktku-more-menu'></div>").hide(); /** Moves an existing OOUI button into the overflow menu, keeping its * handlers — the widgets already carry the behaviour, so this is * purely about where they are shown. */ function intoMenu(btn, extraClass) { var row = $("<div class='wiktku-more-item'></div>"); if (extraClass) row.addClass(extraClass); btn.$element.on("click", function () { moreMenu.hide(); }); row.append(btn.$element); moreMenu.append(row); } intoMenu(saveCacheBtn); intoMenu(clearCacheBtn, "wiktku-more-item-danger"); moreMenu.append($("<div class='wiktku-more-sep'></div>")); moreMenu.append($("<div class='wiktku-more-item wiktku-more-note'></div>").append(lastSavedEl)); moreBtn.on("click", function (e) { e.preventDefault(); e.stopPropagation(); var open = moreMenu.is(":visible"); moreMenu.toggle(!open); if (!open) { setTimeout(function () { $(document).one("click.wiktkuMore", function () { moreMenu.hide(); }); }, 0); } }); var moreWrap = $("<span class='wiktku-more-wrap'></span>").append(moreBtn).append(moreMenu); footer.append(moreWrap); // Icon-only settings button — opens the Tercîh dialog. Plain OOUI // icon names depend on which icon-pack module happens to be loaded, // so this uses the actual Codex "settings" (color-subtle) SVG from // Commons directly, the same way the spinner above hotlinks its gif. var prefsBtn = $("<button></button>", { type: "button", "class": "wiktku-prefs-btn", title: "Tercîh — sazkariyên vê amûrê biguherîne" }); prefsBtn.on("click", function (e) { e.preventDefault(); wiktkuOpenPrefsDialog(); }); // The gear is icon-only on the bar; inside a text menu it needs a // label like everything else around it. prefsBtn.on("click", function () { moreMenu.hide(); }); moreMenu.prepend($("<div class='wiktku-more-sep'></div>")); moreMenu.prepend($("<div class='wiktku-more-item wiktku-more-item-prefs'></div>") .append(prefsBtn) .append($("<span class='wiktku-more-item-label'></span>").text("Tercîh"))); startForm.append(footer); // NOTE: deliberately NOT .hide() (display:none). WikiEditor/CodeMirror/ // the mobile editor's auto-grow logic measure #wpTextbox1's real // dimensions during their own init, which happens while the wizard is // up. A display:none ancestor reports 0 for offsetWidth/offsetHeight/ // scrollHeight, so those scripts bake in a near-zero height that never // gets recalculated later — slideDown() in destroy() only animates the // outer box, it doesn't re-trigger their sizing. Pushing #editform // off-screen instead keeps it laid out (real width/height available to // measure) without being visible, so the editbox opens at full size. $("#editform").addClass("wiktku-offscreen").before(startForm); // renderGroupTabs() looks up #wiktku-group-tabs via a live DOM // selector, so it must run after startForm is actually in the document. renderGroupTabs(); renderBesenDinPicker(); // One pass over the whole form: every select that hasn't already been // initialised, and isn't opted out with .wiktku-plain-select, gets // the searchable picker. initSelects(startForm); refresh(); // Give every draggable textarea a custom resize grip (works // consistently on Safari/iOS, unlike the native corner grip — see // the "Manual drag-to-resize handle" comment in styles.css), and // keep applying it to textareas added later on (new sense blocks, // quote-source fields, nimûne rows, …). wiktkuInitManualResize(startForm); new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { $(mutation.addedNodes).each(function () { if (this.nodeType !== 1) return; wiktkuInitManualResize(this); }); }); }).observe(startForm[0], { childList: true, subtree: true }); // Now that the full language list is loaded, silently restore any // draft the editor previously saved for this page. var cachedDraft = formCache.Get(); if (cachedDraft && cachedDraft.sections && cachedDraft.sections.length) { restoreFromCache(cachedDraft); } } // "oojs-ui.styles.icons-moderation" carries the "trash" glyph used by // makeTrashButton() below — without it the delete buttons on the Mane // and Beş tab bars would render as blank icon-less buttons. mw.loader.using(["oojs-ui-core", "oojs-ui.styles.icons-moderation"], function () { function wiktkuProceedWithData(wiktkuData) { var d = wiktkuData || {}; // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Jimar (number) code definitions — same shape as the wiki's // own Lua number-type table (code -> {cat, display[, req]}). if (d.numberLabels) $.extend(NUMBER_LABELS, d.numberLabels); // Populate lang choices (pinned list). if (d.langChoices) steps.lang.choices = choicesFromObject(d.langChoices, true); // Populate langsByCode and merge full language list from d.ziman. // d.ziman is a {code: name} object with all known languages. $.each(steps.lang.choices, function (i, choice) { if (choice.sortKey === undefined) choice.sortKey = choice.label; langsByCode[choice.code] = choice; }); if (d.ziman) { var pinnedCodes = {}; $.each(steps.lang.choices, function (i, c) { pinnedCodes[c.code] = true; }); var extraChoices = []; $.each(d.ziman, function (code, name) { if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; if (pinnedCodes[code]) return; var choice = { code: code, label: name, sortKey: name }; extraChoices.push(choice); langsByCode[code] = choice; }); extraChoices.sort(function (a, b) { return a.sortKey.localeCompare(b.sortKey, userLang); }); steps.lang.choices = steps.lang.choices.concat(extraChoices); } // Keep the full merged list around for trans/dunde/zarava — those // should still be able to reference any language even when the // Tercîh panel restricts the main "ziman" step below — then, if // the user set a restriction there, narrow steps.lang.choices // itself to just those codes. var wiktkuFullLangChoices = steps.lang.choices; if (wiktkuPrefs.langCodes && wiktkuPrefs.langCodes.length) { var wiktkuAllowedLangSet = {}; $.each(wiktkuPrefs.langCodes, function (i, code) { wiktkuAllowedLangSet[code] = true; }); var wiktkuRestrictedChoices = $.grep(wiktkuFullLangChoices, function (c) { return !!wiktkuAllowedLangSet[c.code]; }); // Fall back to the full list instead of showing an empty // dropdown if none of the saved codes matched anything // (typo'd code, data.json changed since, …). steps.lang.choices = wiktkuRestrictedChoices.length ? wiktkuRestrictedChoices : wiktkuFullLangChoices; } // Populate POS choices — also a plain {code: label} object in data.json. if (d.posChoices) steps.pos.choices = choicesFromObject(d.posChoices, false); // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the full language list // (not the possibly Tercîh-restricted steps.lang.choices). steps.trans.keys = wiktkuFullLangChoices; steps.dunde.keys = wiktkuFullLangChoices; steps.zarava.keys = getZaravaKeys(wiktkuFullLangChoices); build(); } // data.json ships inside this package module, so it is already parsed // and in memory — no action=raw round trip, and no Testing switch to // forget to flip back before deploying. wiktkuProceedWithData(require("./start/data.json")); }); }); //</nowiki> f2ycplobne19hr1r6nnxx45klqn0qll 6333908 6333907 2026-08-15T21:37:23Z Wikihez 7344 6333908 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. // implicit dependencies: StorageUtils (ObjectStorage) //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var addLangMode = mw.util.getParamValue("wiktkuaddlang") === "1"; // ── Tercîh (user settings) panel stored via mw.storage (localStorage), globally var WIKTKU_PREFS_KEY = "wiktku_start_prefs"; var WIKTKU_PREFS_DEFAULTS = { // [] = show the full language list in the "ziman" step; otherwise // only these codes are shown there (data.json codes, not names). langCodes: [], // true = never auto-open on a new/empty page — only via the // "+Ziman/beşeke din" portlet link. onlyOnClick: false, // "auto" | "p-cactions" | "p-tb" | "p-views" — where the // "+Ziman/beşeke din" portlet link is added. portlet: "auto", // true = suppress routine/informational mw.notify toasts (page // loading, cache auto-restored, cache saved/cleared, "tê şandin…"). // Errors and direct results of an explicit action (like saving // Tercîh itself) always show regardless of this setting. quiet: false }; function wiktkuLoadPrefs() { if (!(window.mw && mw.storage)) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var raw; try { raw = mw.storage.get(WIKTKU_PREFS_KEY); } catch (e) { raw = null; } if (!raw) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var parsed; try { parsed = JSON.parse(raw); } catch (e) { parsed = {}; } return $.extend({}, WIKTKU_PREFS_DEFAULTS, parsed); } function wiktkuSavePrefs(prefs) { if (!(window.mw && mw.storage)) return false; try { mw.storage.set(WIKTKU_PREFS_KEY, JSON.stringify(prefs)); return true; } catch (e) { return false; } } var wiktkuPrefs = wiktkuLoadPrefs(); // Routine/informational notices go through here so "quiet mode" can // suppress them; errors and explicit-action confirmations (like the // Tercîh save toast) call mw.notify directly instead, and always show. function wiktkuNotify(message, options) { if (wiktkuPrefs.quiet) return; mw.notify(message, options); } // Removes every localStorage entry this script writes, across every // page: the per-page draft caches (formCache below, one per page under // "wiktku_start_draft_") and the per-textarea manual-resize heights // ("wiktku_resize_height_…", set in util.js). Tercîh itself // (WIKTKU_PREFS_KEY) is deliberately left alone — it's a setting the // person is actively editing when they reach for this button inside the // Tercîh dialog, not a draft/cache to discard. // // formDirty/autosaveDebounceTimer/formCache are declared further down // (assigned by build()) but resolved by closure at call time, same as // elsewhere in this file — this is only ever invoked after the wizard // has built, since that's the only place the Tercîh button lives. function wiktkuClearAllScriptCache() { // Cancel the current page's pending autosave — otherwise it fires a // few seconds later (or the periodic one does, within a minute) // using the still-unblanked live form and silently re-writes the // cache this just removed. Same reasoning as the single-page // "Cache paqij bike" button. if (autosaveDebounceTimer) { clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = null; } formDirty = false; $("#wiktku-last-saved").text(""); // Keeps the current page's formCache instance (and its in-memory // _cachedData) consistent with what's about to happen to its actual // localStorage entries below. try { formCache.Set({}); } catch (e) {} if (!window.localStorage) return; var toRemove = []; try { for (var i = 0; i < localStorage.length; i++) { var key = localStorage.key(i); if (!key) continue; // The draft cache goes through [[MediaWiki:Gadget-StorageUtils.js]]'s // ObjectStorage, which does NOT store it under the plain // "wiktku_start_draft_<page>" name formCache is constructed // with — it wraps it as "enwikt/ObjectStorage/ // wiktku_start_draft_<page>?v=<n>&Type=Data|Type". Matching // as a substring (not a prefix) catches both the Data and // Type entries, for every page and every cache version. The // resize-height entries aren't wrapped — set directly via // mw.storage in util.js — so those match as a plain prefix. if (key.indexOf("wiktku_start_draft_") !== -1 || key.indexOf("wiktku_resize_height_") === 0) { toRemove.push(key); } } } catch (e) { return; } $.each(toRemove, function (_, key) { try { localStorage.removeItem(key); } catch (e) { /* skip this key, keep clearing the rest */ } }); } // Lazily built the first time it's opened; reused after that (see // wiktkuOpenPrefsDialog below, defined once we know OOUI is available). var wiktkuPrefsWindowManager = null; var wiktkuPrefsDialog = null; function wiktkuOpenPrefsDialog() { mw.loader.using(["oojs-ui-core", "oojs-ui-windows"], function () { function WiktkuPrefsDialog(config) { WiktkuPrefsDialog.super.call(this, config); } if (!wiktkuPrefsDialog) { OO.inheritClass(WiktkuPrefsDialog, OO.ui.ProcessDialog); WiktkuPrefsDialog.static.name = "wiktkuPrefsDialog"; WiktkuPrefsDialog.static.title = "Tercîhên min"; WiktkuPrefsDialog.static.actions = [ { action: "save", label: "Qeyd bike", flags: ["primary", "progressive"] }, { action: "cancel", label: "Betal bike", flags: "safe" }, { action: "clearcache", label: "Hemû cache paqij bike", flags: "destructive" } ]; WiktkuPrefsDialog.prototype.initialize = function () { WiktkuPrefsDialog.super.prototype.initialize.call(this); this.langCodesInput = new OO.ui.TextInputWidget({ placeholder: "ku, zza, ckb (vala bihêle ji bo hemû zimanan)" }); this.onlyOnClickCheckbox = new OO.ui.CheckboxInputWidget({}); this.quietCheckbox = new OO.ui.CheckboxInputWidget({}); this.portletDropdown = new OO.ui.DropdownInputWidget({ options: [ { data: "auto", label: "Otomatîk (li gorî rûyê wîkiyê)" }, { data: "p-cactions", label: "p-cactions - Li qismê Amûran" }, { data: "left-navigation", label: "left-navigation - Li qismê Gotar-Gotûbêj" }, { data: "p-tb", label: "p-tb - Li qismê Giştî" }, { data: "p-views", label: "p-views - Li qismê Bixwîne" } ] }); var fieldset = new OO.ui.FieldsetLayout({ label: "Eyar" }); fieldset.addItems([ new OO.ui.FieldLayout(this.langCodesInput, { label: "Kodên zimanan ku tê xuyakirin li qismê \"ziman\"", align: "top", help: "Kodan bi virgulê (,) ji hev veqetîne. Vala bihêle da ku hemû ziman were nîşandan.", helpInline: true }), new OO.ui.FieldLayout(this.onlyOnClickCheckbox, { label: "Tenê veke wextê \"+Ziman/beşeke din\" were tikandin", align: "inline", help: "Eger were hilbijartin, ev amûr êdî otomatîk li ser rûpelên nû/vala dest pê nake — divê meriv her carê pêl \"+Ziman/beşeke din\" bike.", helpInline: true }), new OO.ui.FieldLayout(this.portletDropdown, { label: "Cihê lînka \"+Ziman/beşeke din\"", align: "top", help: "\"Otomatîk\" li gorî rûyê wîkiyê hildibijêre.", helpInline: true }), new OO.ui.FieldLayout(this.quietCheckbox, { label: "Moda bêdeng (kêmtir agahdarî nîşan bide)", align: "inline", help: "Agahdariyên normal nîşan nede. Xeta her tim tên xuyakirin.", helpInline: true }) ]); this.$body.addClass("wiktku-prefs-dialog-body").append(fieldset.$element); }; WiktkuPrefsDialog.prototype.getSetupProcess = function (data) { return WiktkuPrefsDialog.super.prototype.getSetupProcess.call(this, data) .next(function () { this.langCodesInput.setValue(wiktkuPrefs.langCodes.join(", ")); this.onlyOnClickCheckbox.setSelected(!!wiktkuPrefs.onlyOnClick); this.portletDropdown.setValue(wiktkuPrefs.portlet || "auto"); this.quietCheckbox.setSelected(!!wiktkuPrefs.quiet); }, this); }; WiktkuPrefsDialog.prototype.getActionProcess = function (action) { var dialog = this; if (action === "save") { return new OO.ui.Process(function () { var codes = dialog.langCodesInput.getValue() .split(/[,\s]+/) .map(function (c) { return c.trim().toLowerCase(); }) .filter(function (c) { return !!c; }); wiktkuPrefs = { langCodes: codes, onlyOnClick: dialog.onlyOnClickCheckbox.isSelected(), portlet: dialog.portletDropdown.getValue() || "auto", quiet: dialog.quietCheckbox.isSelected() }; wiktkuSavePrefs(wiktkuPrefs); mw.notify( "Tercîh hatin qeydkirin. Rûpelê ji nû ve bar bike (F5).", { type: "success", tag: "wiktku-prefs-save" } ); dialog.close({ action: "save" }); }); } if (action === "cancel") { return new OO.ui.Process(function () { dialog.close({ action: "cancel" }); }); } if (action === "clearcache") { return new OO.ui.Process(function () { if (!window.confirm( "Tu dixwazî hemû cache ya vê amûrê ji her rûpelê paqij bikî " + "(danûstandinên qeydkirî yên hemû rûpelan, bilindahiyên qadan)? " + "Tercîhên li jor nayên jêbirin. Ev tişt nayê vegerandin." )) return; wiktkuClearAllScriptCache(); mw.notify("Hemû cache hate paqijkirin.", { type: "success", tag: "wiktku-cache-clear-all" }); dialog.close({ action: "clearcache" }); }); } return WiktkuPrefsDialog.super.prototype.getActionProcess.call(this, action); }; wiktkuPrefsWindowManager = new OO.ui.WindowManager(); $(document.body).append(wiktkuPrefsWindowManager.$element); wiktkuPrefsDialog = new WiktkuPrefsDialog(); wiktkuPrefsWindowManager.addWindows([wiktkuPrefsDialog]); } wiktkuPrefsWindowManager.openWindow(wiktkuPrefsDialog); }); } var targetContainer; var skin = mw.config.get('skin'); if (wiktkuPrefs.portlet && wiktkuPrefs.portlet !== "auto") { targetContainer = wiktkuPrefs.portlet; } else if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Li vê rûpelê, ziman an jî beşeke nû zêde bike"); // If "onlyOnClick" is set, the wizard should ONLY ever open via the // "+Ziman/beşeke din" link — never automatically var wiktkuNewPageDetected = $(".mw-newarticletext, .mw-newarticletextanon").length > 0; if (wiktkuPrefs.onlyOnClick ? !addLangMode : (!addLangMode && !wiktkuNewPageDetected)) { return; } // ── Shared helpers ─────────────────────────────────────────────────── // Generic text/UI utilities live in their own package file now — see the // header of util.js for why. Aliased to bare names here so the ~400 call // sites below read exactly as they did when these were local functions. var wiktkuUtil = require("./start/util.js"); var capitalize = wiktkuUtil.capitalize; var decapitalize = wiktkuUtil.decapitalize; var escapeRegExp = wiktkuUtil.escapeRegExp; var stripWikilinks = wiktkuUtil.stripWikilinks; var splitTercimeIzah = wiktkuUtil.splitTercimeIzah; var insertAtCursor = wiktkuUtil.insertAtCursor; var foldDiacritics = wiktkuUtil.foldDiacritics; var wrapNativeSelect = wiktkuUtil.wrapNativeSelect; var initSelects = wiktkuUtil.initSelects; var wiktkuInitManualResize = wiktkuUtil.initManualResize; function langHeaderSource(codePattern) { return "\n?==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } // Delete button (real OOUI "trash" icon, destructive-flagged) shared by // the Mane tab bar and the Beş tab bar. One button per bar — sitting // right before "+ Mane zêde bike" / "+ Beş zêde bike", not one per tab // — deletes whichever sense/section is currently open. A trash icon on // every individual tab put the hit-target right where people click to // switch tabs, which is exactly how a stray click ended up deleting the // wrong one; a single button acting on "the one you're looking at" has // only one thing it can possibly delete. function makeTrashButton(title) { return new OO.ui.ButtonWidget({ icon: "trash", flags: ["destructive"], framed: false, invisibleLabel: true, label: title, title: title, classes: ["wiktku-trash-btn"] }); } function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } var catSrcTemplates = null; var catSrcTemplatesPromise = null; function fetchCatSrcTemplates() { if (catSrcTemplatesPromise) return catSrcTemplatesPromise; catSrcTemplatesPromise = new mw.Api().get({ action: "query", list: "categorymembers", cmtitle: "Kategorî:Çavkanî", cmnamespace: 10, cmlimit: "max", formatversion: 2 }).then(function (data) { var members = (data.query && data.query.categorymembers) || []; catSrcTemplates = $.map(members, function (m) { // Pêşgira navî ya "Şablon:" rake. return m.title.replace(/^[^:]+:/, ""); }); catSrcTemplates.sort(function (a, b) { return a.localeCompare(b, userLang); }); return catSrcTemplates; }, function () { catSrcTemplates = []; return catSrcTemplates; }); return catSrcTemplatesPromise; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var formCache = new ObjectStorage("wiktku_start_draft_" + mw.config.get("wgPageName"), 1); var langsByCode = {}; // Looks up the display label for a language code, falling back to the // code itself if it isn't known yet (e.g. langsByCode not loaded). function getLangLabel(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; // Converts a {code: label} object (langChoices/posChoices in data.json) // into the {code, label[, sortKey]} array the rest of the script uses. // isLang: true adds a sortKey and shows "(code)" after the label — // language choices only. function choicesFromObject(obj, isLang) { var result = []; $.each(obj || {}, function (code, label) { var choice = { code: code, label: label }; if (isLang) choice.sortKey = label; result.push(choice); }); return result; } function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c.code] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Number codes (y, s, d, p, p+, tp, j, j+, j/nj, nj, nj+, hj!, hj?) from // data.json's "numberLabels". Same {code: {cat, display[, req]}} shape as // the wiki's Lua number-type table; "display" can contain HTML (<abbr>) // or wikilinks, so it's only used as-is in wikitext output, never dropped // straight into an <option> (see stripMarkupForOption below). var NUMBER_LABELS = {}; // Distinguishes the Jimar dropdown (j= param) from the Cîns dropdown // (c= param): a code that's a key in NUMBER_LABELS is a number code, // everything else is a gender code. Compound codes like "m-p"/"n-p" are // gender+plural pairs and correctly stay on the gender side. function isNumberCode(code) { return Object.prototype.hasOwnProperty.call(NUMBER_LABELS, code); } // Strips the bit of markup "display" is allowed to contain so it's safe // to use as plain <option> text (options can't render HTML or wikilinks): // <abbr title="X">Y</abbr> -> "Y (X)", [[a|b]] -> "b", [[a]] -> "a". function stripMarkupForOption(html) { if (!html) return ""; return $.trim( String(html) .replace(/<abbr[^>]*title="([^"]*)"[^>]*>([\s\S]*?)<\/abbr>/gi, "$2 ($1)") .replace(/\[\[[^\]|]*\|([^\]]*)\]\]/g, "$1") .replace(/\[\[([^\]]*)\]\]/g, "$1") .replace(/<[^>]+>/g, "") ); } // Builds the Jimar dropdown's <option> text for one code: "j — jimarbar". function numberOptionLabel(code) { var def = NUMBER_LABELS[code]; if (!def) return code; var text = stripMarkupForOption(def.display); return text ? (code + " — " + text) : code; } // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } // ── Template explanations ──────────────────────────────────────────── // Every place a template can be picked shows the same row: a status // dot, the name, a link to the template page, and an ⓘ. This is the ⓘ. // // Text comes from the template's own TemplateData where it has any, so // the explanation stays right without anyone maintaining a second copy // by hand — with the desc already in data.json as the fallback for // templates that have none. var wiktkuTplDataCache = {}; // name -> {desc, params[]} or null when absent /** Fetches TemplateData for one template. Resolves to null if the * template has none (a plain, undocumented template — very common). */ function fetchTemplateData(name) { if (Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, name)) { return $.Deferred().resolve(wiktkuTplDataCache[name]).promise(); } return new mw.Api().get({ action: "templatedata", titles: "Şablon:" + name, redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; var first = null; $.each(pages, function (_, p) { if (!first) first = p; }); var out = null; if (first) { var desc = first.description; // TemplateData descriptions are language maps when the // template is documented in more than one language. if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(first.params || {}, function (key, p) { var label = p && p.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(p && p.required) }); }); out = { desc: desc || "", params: params }; } wiktkuTplDataCache[name] = out; return out; }, function () { // No TemplateData, or the API is unhappy — cache the miss so a // repeated ⓘ click doesn't re-request it every time. wiktkuTplDataCache[name] = null; return null; }); } /** Fetches TemplateData for many templates in one request and fills the * cache; resolves either way, a template with no TemplateData caches as null. */ function prefetchTemplateData(names) { var missing = $.grep(names || [], function (n) { return n && !Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n); }); if (!missing.length) return $.Deferred().resolve().promise(); // The API caps a titles list at 50 for normal users. missing = missing.slice(0, 50); return new mw.Api().get({ action: "templatedata", titles: $.map(missing, function (n) { return "Şablon:" + n; }).join("|"), redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; $.each(pages, function (_, page) { if (!page || !page.title) return; var name = String(page.title).replace(/^[^:]+:/, ""); var desc = page.description; if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(page.params || {}, function (key, prm) { var label = prm && prm.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(prm && prm.required) }); }); wiktkuTplDataCache[name] = { desc: desc || "", params: params }; }); // Anything the API didn't answer for simply has none — cache the // miss so the per-row ⓘ doesn't re-request it one at a time. $.each(missing, function (_, n) { if (!Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n)) wiktkuTplDataCache[n] = null; }); }, function () { $.each(missing, function (_, n) { wiktkuTplDataCache[n] = null; }); }); } /** Rewrites each tagged <option> in `sel` as "name — description", using * TemplateData. Only fills rows that have no description yet, so the * hand-written ones in data.json (which carry usage examples the API * does not) are left exactly as they are. */ function applyTplDescriptions(sel) { if (!sel || !sel.length) return; var changed = false; sel.find("option[data-tpl]").each(function () { var opt = $(this); var name = opt.attr("data-tpl"); if (opt.text().indexOf(" — ") !== -1) return; // already described var td = wiktkuTplDataCache[name]; var desc = (td && td.desc) || localTplDesc(name); if (!desc) return; // One line: TemplateData descriptions can run to a paragraph. desc = $.trim(String(desc).split("\n")[0]); if (desc.length > 90) desc = desc.slice(0, 90) + "…"; opt.text(name + " — " + desc); changed = true; }); // The picker caches option text for searching, so it has to re-read. if (changed) sel.trigger("wiktku:refresh"); } /** Hand-written fallback description, from data.json. * * This is the escape hatch for templates with no TemplateData on the * wiki: add a "desc" to the entry in data.json and it shows up in the * dropdown and in the ⓘ immediately, no code change. TemplateData is * still the better place — VisualEditor and every other tool reads it * too — but this keeps the picker useful in the meantime. * * Works for any pool: pronTpls, etymTpls, tplDefs, jederDefs. */ function localTplDesc(name) { var pools = [steps.pron.pronTpls, steps.etym.etymTpls, steps.dfn.tplDefs, steps.dfn.jederDefs]; var found = ""; $.each(pools, function (_, pool) { if (pool && pool[name] && pool[name].desc) { found = pool[name].desc; return false; } }); return found; } /** Opens the inline explanation panel for `name`, anchored under the * picker it was opened from. */ function showTemplateInfo(name, anchorWrap) { $(".wiktku-tpl-info").remove(); var panel = $("<div class='wiktku-tpl-info'></div>"); panel.append($("<div class='wiktku-tpl-info-name'></div>").text("{{" + name + "}}")); var body = $("<div class='wiktku-tpl-info-desc'></div>").text("Tê barkirin…"); panel.append(body); var params = $("<div class='wiktku-tpl-info-params'></div>"); panel.append(params); panel.append($("<a class='wiktku-tpl-info-link' target='_blank' rel='noopener'></a>") .attr("href", wiktkuUtil.tplPageUrl(name)) .text("Rûpela şablonê veke →")); var close = $("<button type='button' class='wiktku-tpl-info-close' title='Bigire'>✕</button>"); close.on("click", function () { panel.remove(); }); panel.prepend(close); $(anchorWrap).after(panel); fetchTemplateData(name).then(function (td) { var desc = (td && td.desc) || localTplDesc(name); body.text(desc || "Ji bo vê şablonê ravek nehatiye nivîsandin."); if (td && td.params && td.params.length) { params.append($("<div class='wiktku-tpl-info-params-title'></div>").text("Parametre:")); var listEl = $("<ul></ul>"); $.each(td.params, function (_, p) { var line = p.name + (p.label ? " — " + p.label : "") + (p.required ? " (pêwîst)" : ""); listEl.append($("<li></li>").text(line)); }); params.append(listEl); } }); } /** Marks a picker's <option>s as template rows so the searchable widget * renders them with the dot / 🔗 / ⓘ affordances, and wires the ⓘ * handler for that picker. `nameOf` maps an <option> to a template * name — the pickers store different things in value= (a snippet for * the insert dropdowns, the bare name for the sense selector). */ function markTemplateOptions(sel, nameOf) { if (!sel || !sel.length) return; var names = []; sel.find("option").each(function () { var opt = $(this); var name = nameOf(opt); if (!name) return; opt.attr("data-tpl", name); // Deprecated/typo templates are the "special cases only" ones. opt.attr("data-tpl-status", /kevnbûyî|şaşnivîs|kêmpeyda/i.test(opt.text()) ? "yellow" : "green"); names.push(name); }); sel.data("wiktkuTplInfo", showTemplateInfo); // Fill in the descriptions. Matters most for the Mane picker, whose // entries in data.json are names with no desc at all — "rastnivîs", // "ku-Latn", "guharto" on their own. One request covers every // template in the picker, cached for the per-row ⓘ as well. prefetchTemplateData(names).always(function () { applyTplDescriptions(sel); }); } /** Pulls the template name out of a snippet like "* {{ku-IPA}}" or * "{{ji|SOURCELANG|CODE|…}}". */ function tplNameFromSnippet(snippet) { var m = /\{\{\s*([^|}\n]+)/.exec(snippet || ""); return m ? $.trim(m[1]) : ""; } // True if a sense has content beyond mane worth keeping (etîket, word // lists, nimûne, jêder) — so it's still emitted with {{mane?}} if empty. function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } // A technically-"complete" entry (Ziman + Cureyê rêzimanî filled) with // nothing in Mane, Bi zaravayên din or Werger is still meaningfully // empty, so this is checked separately at submit-click time with its // own message. function hasMinRequiredContent(values) { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasMane = dfnSenses.some(function (s) { return (s.tpl && s.tplTitle) || (!s.tpl && (s.mane !== "" || senseHasExtraContent(s))); }); if (hasMane) return true; if (values.lang === "ku") { var hasWerger = false; $("#wiktku-start-trans .wiktku-trans-group").each(function () { if (steps.trans.getGroupTranslations($(this)).length) hasWerger = true; }); if (hasWerger) return true; var hasZarava = false; $("#wiktku-start-zarava .wiktku-zarava-group").each(function () { if (steps.zarava.getGroupTranslations($(this)).length) hasZarava = true; }); if (hasZarava) return true; } return false; } // Bolds the *first* occurrence of the page name function boldPageNameOnce(text) { if (!text || !pageNameRe) return text; var re = new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "i"); return text.replace(re, "'''$1'''"); } // Converts literal line breaks typed into a nimûne/jêgirtin box into // wikitext <br> tags, function nlToBr(text) { return text ? text.replace(/\r\n|\r|\n/g, "<br>") : text; } function escapeHtmlForBackdrop(str) { return String(str) .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;"); } // Mirrors a textarea's text, with a small highlighted marker placed // right after each line that's followed by an actual typed/pasted // linebreak. Rendered into a transparent backdrop layer behind the // textarea (see ensureLinebreakBackdrop()), so only the point of the // break is marked instead of the whole box. function buildLinebreakBackdropHtml(text) { var lines = text.split(/\r\n|\r|\n/); return $.map(lines, function (line, i) { var isLast = i === lines.length - 1; return escapeHtmlForBackdrop(line) + (isLast ? "" : "<mark class='wiktku-linebreak-mark'>↵</mark>\n"); }).join(""); } // Copies the metrics that affect where text wraps/lands (font, line // height, padding, border) from the real textarea onto its backdrop, // via computed style rather than shared CSS classes — most of the // box's own rules are written as "textarea.foo", which a <div> with // the same class wouldn't match. Re-run on every update in case a // responsive breakpoint changed the textarea's own font-size. function syncLinebreakBackdropMetrics(textarea, backdrop) { var cs = window.getComputedStyle(textarea[0]); backdrop.css({ "box-sizing": cs.boxSizing, "padding-top": cs.paddingTop, "padding-right": cs.paddingRight, "padding-bottom": cs.paddingBottom, "padding-left": cs.paddingLeft, "border-width": cs.borderWidth, "border-style": "solid", "font-family": cs.fontFamily, "font-size": cs.fontSize, "font-weight": cs.fontWeight, "line-height": cs.lineHeight, "letter-spacing": cs.letterSpacing }); } // Lazily wraps a textarea in its own positioning anchor (independent // of .wiktku-resize-wrap, so this doesn't depend on load order versus // wiktkuMakeManualResizable) and inserts the transparent backdrop // layer used to mark the exact point of a linebreak. Safe to call // more than once on the same textarea — the backdrop is cached. function ensureLinebreakBackdrop(textarea) { var existing = textarea.data("wiktkuLinebreakBackdrop"); if (existing) return existing; textarea.wrap("<div class='wiktku-linebreak-wrap'></div>"); var backdrop = $("<div aria-hidden='true'></div>").addClass("wiktku-linebreak-backdrop"); textarea.before(backdrop); textarea.data("wiktkuLinebreakBackdrop", backdrop); textarea.on("scroll.wiktkuLinebreak", function () { backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); }); return backdrop; } // Flags a nimûne/jêgirtin textarea (via CSS class, for the border // tint + tooltip) while it contains a typed/pasted linebreak, so the // user notices before it's silently turned into <br> on output. // Marks only the exact point of the break via a mirrored backdrop, // rather than tinting the whole box. function highlightLinebreak(el) { var textarea = $(el); var text = textarea.val(); var hasBreak = /\r|\n/.test(text); textarea .toggleClass("wiktku-has-linebreak", hasBreak) .attr("title", hasBreak ? "Xeta nû dê wek <br> bê nivîsandin" : ""); if (!hasBreak) { var cached = textarea.data("wiktkuLinebreakBackdrop"); if (cached) cached.hide(); textarea.removeClass("wiktku-has-linebreak-source"); return; } var backdrop = ensureLinebreakBackdrop(textarea); textarea.addClass("wiktku-has-linebreak-source"); syncLinebreakBackdropMetrics(textarea, backdrop); backdrop.html(buildLinebreakBackdropHtml(text)).show(); backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); } // Each nimûne item can be { text, tr, t }: text, transliteration, translation. function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{nimûne?|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = nlToBr(boldPageNameOnce(text)); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + nlToBr(n.tr); // Translation as third positional param (no key needed). if (n.t) tpl += "|" + nlToBr(n.t); } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 60 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } // Formats jêder (citation) entries into "#* {{jêder…|…}}" lines; skips // entries with no quote text. Falls back to the generic {{jêder}} // template when no specific template was chosen. function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; var quote = nlToBr(boldPageNameOnce(jeder.quote)); var quoteTr = nlToBr(jeder.quoteTr); var quoteT = nlToBr(jeder.quoteT); if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + quote; if (quoteTr) cite += "|tr=" + quoteTr; if (quoteT) cite += "|tercime=" + quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + quote; if (quoteTr) out += "|tr=" + quoteTr; if (quoteT) out += "|tercime=" + quoteT; // A şablon picked from Kategorî:Çavkanî is transcluded as the // source param (e.g. |{{Kovara X}}); manual text is used as-is. var srcParam = jeder.jederCatTpl ? ("{{" + jeder.jederCatTpl + "}}") : (jeder.jederManual ? jeder.jederManual : "çavkanî?"); // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } // True if a sense has at least one jêder entry with quote text. function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } // Builds "{{tplName|lang|part1|part2|…}}" from a sense field (kategori, // etiket), wrapped inline (" {{…}} ") or on its own line ("\n#: {{…}}"). function buildSenseTpl(sense, field, lang, tplName) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return call } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } // ── Inline modifier system ─────────────────────────────────────────────── // Appends a ⊕ button to a word input <li>. Clicking it shows a compact // modifier picker; selecting one prompts for the value and appends // <modifier:value> to the textarea's current content. 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îf" }, { 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: qualifier (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" }, { key: "qq", label: "qq: qualifier (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î" } ]; // Sub-groups (inside a sense/definition block) that get the same ⊕ // modifier button as makeWordListStep fields. var MODIFIER_SUBGROUPS = { "wiktku-dfn-alternativ": true, "wiktku-dfn-hevmane": true, "wiktku-dfn-dijmane": true, "wiktku-dfn-koordine": true, "wiktku-dfn-jornav": true, "wiktku-dfn-jernav": true }; /** * Wraps a freshly-created textarea in a <li> with a ⊕ modifier button. * `ta` — the jQuery textarea element. * Returns the <li>. */ function makeModifierLi(ta) { var li = $("<li class='wiktku-word-li'></li>"); var btn = $("<button type='button' class='wiktku-mod-btn' title='Modifiyerê lê zêde bike'>⊕</button>"); var picker = $("<div class='wiktku-mod-picker'></div>").hide(); // Which modifier keys are already present in the textarea's current // text — e.g. "<t:...>" → "t" used. Each modifier can only be // applied once per word, so its pill gets disabled once used. function usedKeys() { var used = {}; var re = /<([a-zA-Z]+):/g; var val = ta.val() || ""; var m; while ((m = re.exec(val)) !== null) used[m[1]] = true; return used; } $.each(WORD_MODIFIERS, function (_, mod) { var pill = $("<button type='button' class='wiktku-mod-pill'></button>").text(mod.label); pill.attr("title", mod.hint); pill.data("mod-key", mod.key); pill.on("click", function (e) { e.preventDefault(); if (pill.prop("disabled")) return; // already used on this word picker.hide(); // Show a tiny inline input for the modifier value. var valWrap = $("<span class='wiktku-mod-val-wrap'></span>"); var valInp = $("<input type='text' class='wiktku-mod-val-input'>") .attr("placeholder", mod.hint + "…") .attr("size", 20); var confirm = $("<button type='button' class='wiktku-mod-confirm'>✓</button>"); var cancel = $("<button type='button' class='wiktku-mod-cancel'>✕</button>"); function applyModifier() { var v = $.trim(valInp.val()); if (v) { ta.val(ta.val() + "<" + mod.key + ":" + v + ">"); ta.trigger("input"); } valWrap.remove(); ta.focus(); } confirm.on("click", applyModifier); cancel.on("click", function () { valWrap.remove(); ta.focus(); }); valInp.on("keydown", function (e) { if (e.which === 13) { e.preventDefault(); applyModifier(); } if (e.which === 27) { valWrap.remove(); ta.focus(); } }); valWrap.append(valInp).append(confirm).append(cancel); li.append(valWrap); valInp.focus(); }); picker.append(pill); }); btn.on("click", function (e) { e.preventDefault(); // Close any other open pickers in the same list. li.closest("ol, ul").find(".wiktku-mod-picker").not(picker).hide(); // Grey out modifiers already used on this word — refreshed on // every open since the text (and thus what's "used") can change. var used = usedKeys(); picker.find(".wiktku-mod-pill").each(function () { var isUsed = !!used[$(this).data("mod-key")]; $(this).prop("disabled", isUsed).toggleClass("wiktku-mod-pill-used", isUsed); }); picker.toggle(); }); // Close picker when focus leaves the li entirely. li.on("focusout", function () { setTimeout(function () { if (!$.contains(li[0], document.activeElement)) picker.hide(); }, 150); }); li.append(ta).append(btn).append(picker); return li; } function makeWordListStep(id, name, question_fmt) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, modifiers: true, // Function instead of a plain string so it can name the current // language — computed fresh at build time and re-applied by // refresh() whenever the language changes. placeholder: function () { var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return "Kelîme" + (langLabel ? " bi " + langLabel : "") + "…"; }, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); var header = capitalize(name); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: {}, visible: function (values) { if (!values.lang) return false; // addLangMode: skip pron only if this lang already has a section. if (addLangMode) { // Clearing the page makes existing content irrelevant. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, // Fills the insert-dropdown from pronTpls, filtered by language. refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); // Reassures the user this field is optional — the dropdown // below writes the template for them, no syntax needed up front. wrap.append( $("<p class='wiktku-step-hint'></p>").text( "Ev qad ne mecbûrî ye. Heke tu nizanî kîjan şablonî hilbijêrî, vale bihêle — an ji pêşkêşkariya jêrîn şablonekî hilbijêre, ew ê bixweber li vir were nivîsandin." ) ); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike "); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); // Clear the picker's search box sel.trigger("wiktku:refresh"); ta.focus(); return; } // The noLang templates (ku-IPA, ku-kîte, zza-IPA, zza-kîte) // auto-generate content from a Lua module reading the page // title, so show a live preview and require confirmation // before inserting. var tplLabel = selectedOption.text(); $(this).val(""); sel.trigger("wiktku:refresh"); steps.pron.showTplPreview(stepDiv, ta, snippet, tplLabel); }); wrap.append(sel).append(ta); stepDiv.append(wrap); steps.pron.buildIpaPalette(wrap, ta); initSelects(wrap); return ta; }, // ── IPA character palette ────────────────────────────────── // Modelled on fr.wiktionary's: every character is a button that // drops itself in at the cursor. Two sub-tabs, because the full // IPA chart is ~180 symbols and roughly twenty of them ever // appear in Kurmancî — "IPA (kurdî)" opens by default and the // full chart is one click away for loanwords and other // languages. Grouped with a label down the left so it reads as // a chart rather than one long line of glyphs. IPA_KU: [ { label: "Kît/stres", chars: ["ˈ", "ˌ", "ː"] }, { label: "Bêdeng", chars: ["d͡ʒ", "t͡ʃ", "ʒ", "ʃ", "ɫ", "ŋ", "ɾ", "r", "ʋ", "ħ", "ʕ", "ɣ", "χ", "ʔ"] }, { label: "Dengdêr", chars: ["ɑː", "eː", "ɛ", "ɪ", "iː", "ɯ", "ʊ", "uː", "yː", "ø", "œ"] } ], IPA_FULL: [ { label: "Bêdeng 1", chars: ["m", "ɱ", "n", "ɳ", "ɲ", "ŋ", "ɴ", "p", "b", "t", "d", "t̪", "d̪", "ʈ", "ɖ", "c", "ɟ", "k", "ɡ", "q", "ɢ", "ʡ", "ʔ"] }, { label: "Bêdeng 2", chars: ["ɸ", "β", "f", "v", "θ", "ð", "s", "z", "ʃ", "ʒ", "ʂ", "ʐ", "ɕ", "ʑ", "ç", "ʝ", "x", "ɣ", "χ", "ʁ", "ħ", "ʕ", "h", "ɦ", "ʜ", "ʢ", "ɧ"] }, { label: "Bêdeng 3", chars: ["ʋ", "ɹ", "ɻ", "j", "ɥ", "ɰ", "ʍ", "w", "ʙ", "ⱱ", "ɾ", "ɽ", "r", "ʀ", "ɺ", "l", "ɫ", "ɬ", "ɮ", "ɭ", "ʎ", "ʟ"] }, { label: "Bêdeng 4", chars: ["ɓ", "ɗ", "ᶑ", "ʄ", "ɠ", "ʛ", "ʘ", "ǀ", "ǃ", "ǂ", "ǁ"] }, { label: "Dengdêr", chars: ["i", "y", "ɪ", "ʏ", "ɨ", "ʉ", "ɯ", "u", "ʊ", "e", "ø", "ɘ", "ɵ", "ɤ", "o", "ə", "ɚ", "ɛ", "œ", "ɜ", "ɝ", "ɞ", "ʌ", "ɔ", "æ", "ɶ", "ɐ", "a", "ɑ", "ɒ"] }, { label: "Suprasegmental", chars: ["ˈ", "ˌ", "ː", "ˑ", "ʼ", "ˀ", "ˤ", "ᵝ", "ᵊ", "ˠ", "ʰ", "ʱ", "ʲ", "ˡ", "ⁿ", "ᵑ", "ʷ", "ᶣ", "˞", "‿"] }, { label: "Dîakrîtîk", chars: ["̚", "̪", "̺", "̻", "̼", "̬", "̊", "̥", "̞", "̝", "̘", "̙", "̽", "̟", "̠", "̈", "̤", "̹", "̜", "̍", "̩", "̆", "̯", "̃", "̰", "͡", "͜"] }, { label: "Ton", chars: ["̋", "́", "̄", "̀", "̏", "̌", "̂", "˥", "˦", "˧", "˨", "˩", "ꜛ", "ꜜ", "↗", "↘", "‖"] } ], /** Builds the two-sub-tab character palette under the textarea. */ buildIpaPalette: function (wrap, ta) { if (wrap.find(".wiktku-ipa-palette").length) return; var panel = $("<div class='wiktku-ipa-panel'></div>").hide(); var toggle = $("<a href='#' class='wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tîpên bilêvkirinê</span>")); toggle.on("click", function (e) { e.preventDefault(); var open = panel.is(":visible"); panel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); wrap.append($("<div class='wiktku-adv-toggle-row'></div>").append(toggle)); // Sub-tab bar, with the two template buttons pinned right. var subTabs = $("<div class='wiktku-ipa-subtabs'></div>"); var kuTab = $("<span class='wiktku-ipa-subtab wiktku-tab-active'>IPA (kurdî)</span>"); var fullTab = $("<span class='wiktku-ipa-subtab'>IPA</span>"); subTabs.append(kuTab).append(fullTab); var tplBtns = $("<span class='wiktku-ipa-tplbtns'></span>"); $.each([ { label: "{{ku-IPA|+}}", snippet: "{{ku-IPA|}}", back: 2 }, { label: "{{IPA|+}}", snippet: "{{IPA|ku|}}", back: 2 } ], function (_, t) { var b = $("<button type='button' class='wiktku-ipa-tplbtn'></button>").text(t.label); b.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], t.snippet); // Park the cursor inside the braces, where the value goes. var pos = ta[0].selectionStart - t.back; ta[0].selectionStart = ta[0].selectionEnd = pos; ta.focus(); }); tplBtns.append(b); }); subTabs.append(tplBtns); panel.append(subTabs); function buildGrid(groups) { var grid = $("<div class='wiktku-ipa-grid'></div>"); $.each(groups, function (_, g) { var row = $("<div class='wiktku-ipa-row'></div>"); row.append($("<span class='wiktku-ipa-rowlabel'></span>").text(g.label)); var keys = $("<span class='wiktku-ipa-keys'></span>"); $.each(g.chars, function (_, ch) { var btn = $("<button type='button' class='wiktku-ipa-key'></button>"); // A combining mark on its own renders as a stray // accent floating over whatever precedes it, so // show it on a dotted circle — but insert only // the mark itself. var combining = /^[̀-ͯ҃-҉]$/.test(ch); btn.text(combining ? "◌" + ch : ch); if (combining) btn.addClass("wiktku-ipa-key-combining"); btn.attr("title", ch); btn.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], ch); ta.focus(); }); keys.append(btn); }); row.append(keys); grid.append(row); }); return grid; } var kuGrid = buildGrid(steps.pron.IPA_KU); var fullGrid = buildGrid(steps.pron.IPA_FULL).hide(); panel.append(kuGrid).append(fullGrid); kuTab.on("click", function () { kuTab.addClass("wiktku-tab-active"); fullTab.removeClass("wiktku-tab-active"); kuGrid.show(); fullGrid.hide(); }); fullTab.on("click", function () { fullTab.addClass("wiktku-tab-active"); kuTab.removeClass("wiktku-tab-active"); fullGrid.show(); kuGrid.hide(); }); panel.addClass("wiktku-ipa-palette"); wrap.append(panel); }, /** Inline preview + confirm panel for a "noLang" (auto-content) * pronunciation template — fetches what the snippet expands to * for this page and only inserts it if the user confirms. */ showTplPreview: function (stepDiv, ta, snippet, tplLabel) { // Only one preview panel open at a time. stepDiv.find(".wiktku-pron-preview").remove(); var panel = $("<div class='wiktku-pron-preview'></div>"); panel.append($("<div class='wiktku-pron-preview-label'></div>") .text("Pêşdîtina " + tplLabel + ":")); var body = $("<div class='wiktku-pron-preview-body'></div>").text("Tê barkirin…"); panel.append(body); var actions = $("<div class='wiktku-pron-preview-actions'></div>"); var confirmBtn = $("<button type='button' class='wiktku-pron-preview-confirm'>✓ Tevlî bike</button>") .prop("disabled", true); var cancelBtn = $("<button type='button' class='wiktku-pron-preview-cancel'>✕ Betal bike</button>"); actions.append(confirmBtn).append(cancelBtn); panel.append(actions); ta.before(panel); confirmBtn.on("click", function () { insertAtCursor(ta[0], snippet); panel.remove(); ta.focus(); }); cancelBtn.on("click", function () { panel.remove(); }); // action=parse, not action=expandtemplates. expandtemplates // returns *expanded wikitext*, so the preview read as // [[IPA]]<sup>([[Wîkîferheng:IPA kurmancî|kilîd]])</sup>: // <span class="IPA">/-{kshhe}-/</span>[[Kategorî:…]] — which // is exactly what the person is trying to avoid having to // read. parse hands back the rendered HTML the page will // actually show. // // Drop the leading "* " first: it is wikitext list syntax // wrapping the template, and keeping it would render the // preview as a bulleted list rather than the line itself. new mw.Api().post({ action: "parse", title: pageName, text: snippet.replace(/^\*\s*/, ""), prop: "text", wrapoutputclass: "", disablelimitreport: 1, disableeditsection: 1, contentmodel: "wikitext", formatversion: 2 }).done(function (data) { var html = (data && data.parse && data.parse.text) || ""; if ($.trim($("<div>").html(html).text())) { body.html(html); // Category links render as nothing but still exist; // and any real link inside a preview should not // navigate away from a half-filled form. body.find("a").attr("target", "_blank").attr("rel", "noopener"); } else { body.text("(vala — ji bo vê rûpelê tiştek nehate afirandin)"); } confirmBtn.prop("disabled", false); }).fail(function () { body.text("Pêşdîtin nehate barkirin — tu dikarî hîn jî wê tevlî bikî."); confirmBtn.prop("disabled", false); }); }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line; }).join("\n"); // "===" heading under Ziman and above the POS sections; the // field is shared across sections, so it's emitted once by // getWikitext() rather than per-POS-section (would otherwise // print the pronunciation twice for a two-POS entry). return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var capitalizedPos = capitalize(pos); // "form" opt-param (checked in posparams) marks this as a // form-of/inflected entry — the section title becomes // "Formeke <pos>ê" instead of the plain pos name. The // template call itself still uses the unchanged pos name. var isForm = $("#wiktku-posparams-opt-form").is(":checked"); var header = isForm ? "\n=== Formeke " + pos + "ê ===\n" : "\n=== " + capitalizedPos + " ===\n"; // Image line (between header and template call) var imageLine = steps.resim.output(values); // Read the live wikitext from the posparams textarea. // Fall back to a plain {{pos|lang}} if the step hasn't been built yet. var tplLine = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); if (!tplLine) { tplLine = "{{" + pos + "|" + (values.lang || "") + "}}"; } return header + imageLine + tplLine + "\n"; } }, // cinsiyet (gender) — shown for navdêr/serenav only, with choices built // from metadata[lang].g since not every language has grammatical gender. cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams // Single source of truth for the selected gender code. The visible // dropdown lives inside the posparams step (see steps.posparams), // but it must always read/write THIS hidden field — not a field of // its own — since getValuesForStep("cinsiyet") reads from here. build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-cinsiyet-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // jimar (grammatical number) — same hidden-field pattern as cinsiyet // above, but writes into its own j= template parameter instead of // sharing c=. Shown for navdêr/serenav only, with choices built from // whichever of metadata[lang].g are number codes (see isNumberCode). jimar: { id: "jimar", name: "jimar", question_fmt: 'Jimara "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-jimar-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // Lêker transitivity — hidden step, handled inside posparams lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function () { return false; }, choices: [ { code: "gh", label: "gerguhêz" }, { code: "x-gh", label: "xwerû-gerguhêz" }, { code: "p-gh", label: "pêkhatî-gerguhêz" }, { code: "h-gh", label: "hevedudanî-gerguhêz" }, { code: "b-gh", label: "biwêjî-gerguhêz" }, { code: "ngh", label: "negerguhêz" }, { code: "x-ngh", label: "xwerû-negerguhêz" }, { code: "p-ngh", label: "pêkhatî-negerguhêz" }, { code: "h-ngh", label: "hevedudanî-negerguhêz" }, { code: "b-ngh", label: "biwêjî-negerguhêz" } ], output: function () { return ""; } }, // tr — hidden step, handled inside posparams tr: { id: "tr", name: "transliterasyon", question_fmt: "Transliterasyona vê kelîmeyê", multiple: false, narrow: true, visible: function () { return false; } }, posparams: { id: "posparams", // Fused onto the "pos" card visually (see #wiktku-start-posparams // in styles.css) so the two read as ONE question — this name is // only a no-CSS/no-JS fallback, since the h3 that would show it // is hidden by CSS. name: "taybetmendî", // Shows what's actually being asked for: gender for nouns, verb // type for verbs, a generic fallback otherwise. question_fmt: function (values) { var pos = values.pos || ""; // Cinsiyet/Jimar fields below are self-labelled, so no title needed here. if (pos === "navdêr" || pos === "serenav") return ""; if (/^lêker/.test(pos)) return "Cureyê lêkerê"; return "Taybetmendî"; }, visible: function (values) { return !!(values.lang && values.pos); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-posparams-wrap").length) return null; var wrap = $("<div class='wiktku-posparams-wrap'></div>"); var helpers = $("<div class='wiktku-posparams-helpers'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-posparams-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-posparams-text") .attr("rows", 2); var _rebuilding = false; function safeRebuild() { if (_rebuilding) return; _rebuilding = true; steps.posparams.rebuildTa(stepDiv); _rebuilding = false; refresh(); } // Generic text-input row factory function makeTextRow(key, labelText, placeholder) { var row = $("<div class='wiktku-posparams-row'></div>") .attr("id", "wiktku-posparams-row-" + key).hide(); var inp = $("<input type='text'>") .addClass("wiktku-start-narrow wiktku-posparams-field") .attr("data-pp-key", key) .attr("placeholder", placeholder || ""); inp.on("input", safeRebuild); row.append($("<label></label>").text(labelText + ": ")).append(inp); return row; } // cinsiyet var cinsiyetRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-c'></div>") .append($("<label></label>").text("Cinsiyet: ")).hide(); var cinsiyetSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-cinsiyet-sel") .append($("<option value=''>— hilbijêre —</option>")); // Writes into the real, shared #wiktku-start-cinsiyet-field (owned by // steps.cinsiyet) rather than a field of its own — see the comment // on steps.cinsiyet.build for why that matters. cinsiyetSel.on("change", function () { $("#wiktku-start-cinsiyet-field").val($(this).val()).trigger("change"); safeRebuild(); }); cinsiyetRow.append(cinsiyetSel); // jimar (number) — second dropdown next to Cinsiyet, writes // into the shared hidden #wiktku-start-jimar-field, into its // own j= param instead of sharing c=. Options + tooltip are // built in syncHelpers once the language's number codes are known. var jimarRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-jimar'></div>") .append($("<label></label>").text("Jimar: ")).hide(); var jimarSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-jimar-sel") .append($("<option value=''>— hilbijêre —</option>")); jimarSel.on("change", function () { $("#wiktku-start-jimar-field").val($(this).val()).trigger("change"); safeRebuild(); }); jimarRow.append(jimarSel); // lektur: two plain questions (transitivity + structural form) // instead of one 10-option dropdown. Emitted code: base alone // ("gh"), or prefix + "-" + base ("x-gh"). var lekturRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lektur'></div>") .append($("<label></label>").text("Lêker derbasdar e? ")).hide(); var lekturSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lektur-sel") .append($("<option value=''>— hilbijêre —</option>")) .append($("<option value='gh'>gerguhêz (bireser digire)</option>")) .append($("<option value='ngh'>negerguhêz (bireser nagire)</option>")); lekturSel.on("change", safeRebuild); lekturRow.append(lekturSel); // Second half of the same question — the structural form. // Blank = xwerû/sade, which is the common case. var lekturFormRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lekturform'></div>") .append($("<label></label>").text("Şiklê lêkerê: ")).hide(); var lekturFormSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lekturform-sel") .append($("<option value=''>sade (asayî)</option>")) .append($("<option value='x'>xwerû</option>")) .append($("<option value='p'>pêkhatî</option>")) .append($("<option value='h'>hevedudanî</option>")) .append($("<option value='b'>biwêjî</option>")); lekturFormSel.on("change", safeRebuild); lekturFormRow.append(lekturFormSel); helpers.append(cinsiyetRow).append(jimarRow).append(lekturRow).append(lekturFormRow); // ── Everything below here is "Tercîhên pêşketî" ────────────── // These rows live inside a collapsed panel, so the default // view of this card is two dropdowns instead of twenty-odd fields. // Transliteration is a primary field, not an advanced one, for // any language not written in Latin script: for those, an // entry without it is incomplete. syncHelpers already gates // the row on needsTransliteration(lang), so for Kurmancî and // other Latin-script languages it simply never appears. helpers.append(makeTextRow("tr", "Transliterasyon (tr)", "Transliterasyon…")); var advPanel = $("<div class='wiktku-posparams-adv-panel'></div>").hide(); advPanel .append(makeTextRow("cuda", "nîşankirina alternatîv", "cuda…")) .append(makeTextRow("ts", "Transkrîpsiyon (ts)", "Transkrîpsiyon…")) .append(makeTextRow("m", "Forma mê (m)", "Forma mê…")) .append(makeTextRow("mtr", "Translit. mê (mtr)", "Transliterasyona mê…")) .append(makeTextRow("n", "Forma nêr (n)", "Forma nêr…")) .append(makeTextRow("ntr", "Translit. nêr (ntr)", "Transliterasyona nêr…")) .append(makeTextRow("p", "Forma pirjimar (p)", "Forma pirjimar…")) .append(makeTextRow("ptr", "Translit. pirjimar", "Transliterasyona pirjimar…")) .append(makeTextRow("y", "Forma yekjimar (y)", "Forma yekjimar…")) .append(makeTextRow("ytr", "Translit. yekjimar", "Transliterasyona yekjimar…")) .append(makeTextRow("sûp", "Forma sûperlatîv (sûp)", "Forma sûperlatîv…")) .append(makeTextRow("sûptr", "Translit. sûperlatîv", "Transliterasyona sûperlatîv…")) .append(makeTextRow("komp", "Forma komparatîv (komp)", "Forma komparatîv…")) .append(makeTextRow("komptr", "Translit. komparatîv", "Transliterasyona komparatîv…")) .append(makeTextRow("gir", "Forma girdêk (gir)", "gir=…")) .append(makeTextRow("girtr", "Translit. gir", "girtr=…")) .append(makeTextRow("hûr", "Forma hûrek (hûr)", "hûr=…")) .append(makeTextRow("hûrtr", "Translit. hûr", "hûrtr=…")) .append(makeTextRow("hanja", "Forma hanja", "hanja=…")) .append(makeTextRow("hanjaTr","Translit. hanja", "hanjaTr=…")) // Lêker rehên demê (only shown when pos is lêker — see syncHelpers) .append(makeTextRow("niha", "Rehê dema niha (niha)", "Rehê dema niha…")) .append(makeTextRow("nihatr", "Translit. rehê dema niha", "Transliterasyona rehê dema niha…")) .append(makeTextRow("borî", "Rehê dema borî (borî)", "Rehê dema borî…")) .append(makeTextRow("borîtr", "Translit. rehê dema borî", "Transliterasyona rehê dema borî…")) .append(makeTextRow("subj", "Rehê dema bilanî (subj)", "Rehê dema bilanî…")) .append(makeTextRow("subjtr", "Translit. rehê dema bilanî", "Transliterasyona rehê dema bilanî…")); // Optional boolean params — nested inside the advanced panel // (they were already the most niche thing on the card). var optPanel = $("<div class='wiktku-posparams-opt-panel'></div>"); $.each([ { key: "form", label: "form — ev made forma tewandî ye" }, { key: "formaalt", label: "formaalt — vê madeyê bike forma alternatîv" }, { key: "nekatcure", label: "nekatcure — sinifa rêzimanî kategorîze neke" }, { key: "nekatcins", label: "nekatcins — kategoriya cinsiyetê neyîne" }, { key: "nekatçendterm", label: "nekatçendterm — kategoriya çend-term neyîne" }, { key: "serlînkneke", label: "serlînkneke — sernavê madeyê lînk neke" }, { key: "nekatpalîndrom", label: "nekatpalîndrom — kategoriya palîndromê neyîne" }, { key: "neformtr", label: "neformtr — transliterasyona forman neyîne" } ], function (_, p) { var cb = $("<input type='checkbox'>") .attr("id", "wiktku-posparams-opt-" + p.key).val(p.key).on("change", safeRebuild); var lbl = $("<label></label>").attr("for", "wiktku-posparams-opt-" + p.key).text(" " + p.label); optPanel.append($("<div class='wiktku-posparams-opt-row'></div>").append(cb).append(lbl)); }); advPanel.append(optPanel); var optToggle = $("<a href='#' class='wiktku-posparams-opt-toggle wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tercîhên pêşketî</span>")); optToggle.on("click", function (e) { e.preventDefault(); var open = advPanel.is(":visible"); advPanel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); helpers.append($("<div class='wiktku-adv-toggle-row'></div>") .append(optToggle)); helpers.append(advPanel); wrap.append(helpers).append(ta); // Typing directly in textarea keeps cinsiyet/jimar hidden // fields in sync, but does NOT call refresh() — preserves // manual edits. ta.on("input", function () { var text = $(this).val(); var cMatch = text.match(/\|c=([^|}\s]+)/); $("#wiktku-start-cinsiyet-field").val(cMatch ? cMatch[1] : ""); var jMatch = text.match(/\|j=([^|}\s]+)/); $("#wiktku-start-jimar-field").val(jMatch ? jMatch[1] : ""); }); stepDiv.append(wrap); return null; }, /** Reads all helper widget values and rewrites the textarea. * Called only by safeRebuild (user interaction) — never by syncHelpers, * so manual textarea edits are never overwritten by a refresh cycle. */ rebuildTa: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; if (!pos || !lang) return; var cinsiyet = stepDiv.find(".wiktku-posparams-cinsiyet-sel").val() || ""; var jimar = stepDiv.find(".wiktku-posparams-jimar-sel").val() || ""; // Two dropdowns, one code: "gh" / "ngh" on their own, or // prefixed with the structural form ("x-gh", "b-ngh", …). var lekturBase = stepDiv.find(".wiktku-posparams-lektur-sel").val() || ""; var lekturForm = stepDiv.find(".wiktku-posparams-lekturform-sel").val() || ""; var lektur = lekturBase ? (lekturForm ? lekturForm + "-" + lekturBase : lekturBase) : ""; function v(key) { return $.trim(stepDiv.find(".wiktku-posparams-field[data-pp-key='" + key + "']").val()); } var out = "{{" + pos + "|" + lang; if (pos === "navdêr" || pos === "serenav") { out += cinsiyet ? "|c=" + cinsiyet : (lang === "ku" ? "|c=?" : ""); // Number is its own j= param, separate from c= (which // holds gender, including compounds like m-p/n-p). if (jimar) out += "|j=" + jimar; } else if (/^lêker/.test(pos) && lektur) { out += "|c=" + lektur; } if (v("cuda")) out += "|" + v("cuda"); if (v("tr")) out += "|tr=" + v("tr"); if (v("ts")) out += "|ts=" + v("ts"); $.each(["m","n","p","y"], function (_, k) { if (v(k)) out += "|" + k + "=" + v(k); if (v(k+"tr")) out += "|" + k + "tr=" + v(k+"tr"); }); if (v("sûp")) out += "|sûp=" + v("sûp"); if (v("sûptr")) out += "|sûptr=" + v("sûptr"); if (v("komp")) out += "|komp=" + v("komp"); if (v("komptr")) out += "|komptr=" + v("komptr"); if (v("gir")) out += "|gir=" + v("gir"); if (v("girtr")) out += "|girtr=" + v("girtr"); if (v("hûr")) out += "|hûr=" + v("hûr"); if (v("hûrtr")) out += "|hûrtr=" + v("hûrtr"); if (v("hanja")) out += "|hanja=" + v("hanja"); if (v("hanjaTr")) out += "|hanjaTr=" + v("hanjaTr"); if (v("niha")) out += "|niha=" + v("niha"); if (v("nihatr")) out += "|nihatr=" + v("nihatr"); if (v("borî")) out += "|borî=" + v("borî"); if (v("borîtr")) out += "|borîtr=" + v("borîtr"); if (v("subj")) out += "|subj=" + v("subj"); if (v("subjtr")) out += "|subjtr=" + v("subjtr"); stepDiv.find(".wiktku-posparams-opt-panel input:checked").each(function () { var key = $(this).val(); // "form" marks this entry as a form-of/inflected entry — it // takes "erê" rather than the plain "1" the other boolean // opt params use. out += "|" + key + "=" + (key === "form" ? "erê" : "1"); }); out += "}}"; stepDiv.find(".wiktku-posparams-text").val(out); $("#wiktku-start-cinsiyet-field").val(cinsiyet); $("#wiktku-start-jimar-field").val(jimar); }, /** Called from refresh() — controls row visibility only. * Does NOT rewrite textarea so user edits are preserved. * Rebuilds only when textarea is empty (first pos selection). */ syncHelpers: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; var needsTr = needsTransliteration(lang); var isNom = pos === "navdêr" || pos === "serenav" || pos === "rengdêr"; var isAdj = pos === "rengdêr"; var isTîp = pos === "tîp"; var isJa = lang === "ja"; var isLeker = /^lêker/.test(pos); // Kurmancî verbs are conjugated from the present/past roots // alone — there's no separate subjunctive root the way some // other languages have — so this pair of fields is noise for // lang=ku specifically, unlike niha/borî which every lêker // language needs. var isLekerSubj = isLeker && lang !== "ku"; // metadata[lang].g lists gender AND number codes together — // split them here (see isNumberCode) so Cîns only ever offers // gender codes (and gender+plural compounds like m-p/n-p, // which aren't NUMBER_LABELS keys) and Jimar only offers number codes. var meta = metadata[lang]; var allCodes = (meta && meta.g) || []; var genderCodes = $.grep(allCodes, function (c) { return !isNumberCode(c); }); var jimarCodes = $.grep(allCodes, function (c) { return isNumberCode(c); }); var showC = (pos === "navdêr" || pos === "serenav") && genderCodes.length > 0; var cRow = stepDiv.find("#wiktku-posparams-row-c"); cRow.toggle(showC); if (showC) { var sel = cRow.find(".wiktku-posparams-cinsiyet-sel"); // Prefer the select's own current value (normal in-session // use); fall back to the shared hidden field, which is how // a cache/section restore communicates a saved gender // before this select has any <option>s to hold it. var prev = sel.val() || $("#wiktku-start-cinsiyet-field").val() || ""; sel.find("option[value!='']").remove(); $.each(genderCodes, function (_, code) { sel.append($("<option></option>").val(code).text(genderLabel(code))); }); if (prev) sel.val(prev); } var showJimar = (pos === "navdêr" || pos === "serenav") && jimarCodes.length > 0; var jimarRowEl = stepDiv.find("#wiktku-posparams-row-jimar"); jimarRowEl.toggle(showJimar); if (showJimar) { var jimarSelEl = jimarRowEl.find(".wiktku-posparams-jimar-sel"); var prevJimar = jimarSelEl.val() || $("#wiktku-start-jimar-field").val() || ""; jimarSelEl.find("option[value!='']").remove(); $.each(jimarCodes, function (_, code) { var def = NUMBER_LABELS[code] || {}; var opt = $("<option></option>").val(code).text(numberOptionLabel(code)); // The explanation (cat, e.g. "dualia tantum") shows as a // hover tooltip — <option> can't hold richer markup. if (def.cat) opt.attr("title", def.cat); jimarSelEl.append(opt); }); if (prevJimar) jimarSelEl.val(prevJimar); } stepDiv.find("#wiktku-posparams-row-lektur").toggle(isLeker); // Only ask for the structural form once gerguhêz/negerguhêz is answered. stepDiv.find("#wiktku-posparams-row-lekturform") .toggle(isLeker && !!stepDiv.find(".wiktku-posparams-lektur-sel").val()); stepDiv.find("#wiktku-posparams-row-tr").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-ts").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-m").toggle(isNom); stepDiv.find("#wiktku-posparams-row-mtr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-n").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ntr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-p").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ptr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-y").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ytr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-sûp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-sûptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-komp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-komptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-gir").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-girtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hûr").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-hûrtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hanja").toggle(isJa); stepDiv.find("#wiktku-posparams-row-hanjaTr").toggle(isJa); stepDiv.find("#wiktku-posparams-row-niha").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-nihatr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-borî").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-borîtr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-subj").toggle(isLekerSubj); stepDiv.find("#wiktku-posparams-row-subjtr").toggle(isLekerSubj && needsTr); if (!$.trim(stepDiv.find(".wiktku-posparams-text").val())) { steps.posparams.rebuildTa(stepDiv); } }, output: function () { return ""; } // pos.output reads the textarea directly }, dfn: { id: "dfn", name: "Mane", // Field types that live behind "Malûmatên pêşketî". Kept as one // list so the collapse CSS, the count badge and the allGroups // adv: flags below can't drift apart. ADV_SUBGROUPS: [ "wiktku-dfn-etiket", "wiktku-dfn-kategori", "wiktku-dfn-alternativ", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ], question_fmt: function (values) { var base = "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin!"; if (values.lang === "ku") { return base + " Ji bo tercimeyan beşa 'Werger' bi kar bîne!"; } return base; }, multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, // Builds one sense block (<li>): mane textarea, nimûne list, and // sub-lists for alternatîv/hevmane/dijmane/etc. buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // The full refresh() (which rebuilds Werger/Bi zaravayên din — // glossList()/build() re-reads every sense from the DOM) is // deferred to blur rather than run on every keystroke; see // onDfnInput for why that's safe. dfnArea.on("blur", function () { refresh(); }); // — Tercime + Îzah boxes (non-ku alternative to the plain mane box) — // Non-ku entries get a direct translation plus a {{îzah|…}}-wrapped // gloss instead of a Kurdish-style gloss. Rather than teach every // consumer (getSenses/getOutput/linkify) a second data shape, these // boxes just write their combined text into dfnArea and re-fire its // "input" event, so dfnArea stays the single source of truth. var tercimeArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-tercime-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-tercime") .attr("rows", 2) .attr("placeholder", "Tercimeyên rasterast ên kurmancî… Ji bo school-a îngilîzî li vir 'mekteb, medrese' binivîse"); var izahArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-izah-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-izah") .attr("rows", 3) .attr("placeholder", "Îzaha kurmancî… Ji bo school-a îngilîzî li vir 'cihê tehsîlgirtinê' binivîse"); var nonKuWrap = $("<div class='wiktku-dfn-nonku-wrap'></div>") .append(tercimeArea).append(izahArea) .hide(); function syncNonKuToMane() { var t = $.trim(tercimeArea.val()); var iz = $.trim(izahArea.val()); // if tercime is blank, use îzah as definition var combined = t ? (iz ? t + " {{îzah|" + iz + "}}" : t) : iz; dfnArea.val(combined); // Re-fires onDfnInput, as if this were typed directly into // the mane textarea. dfnArea.trigger("input"); } tercimeArea.on("input", syncNonKuToMane); izahArea.on("input", syncNonKuToMane); // Same deferred-refresh treatment as dfnArea itself — these two // feed into it (see syncNonKuToMane above). tercimeArea.on("blur", function () { refresh(); }); izahArea.on("blur", function () { refresh(); }); // Switches between the plain mane box and the tercime+îzah pair — // only for non-ku entries with no tplSelect selected. function updateManeMode() { var lang = getValues().lang || ""; var isTpl = !!tplSelect.val(); if (lang && lang !== "ku" && !isTpl) { dfnArea.hide(); nonKuWrap.show(); } else { nonKuWrap.hide(); if (!isTpl) dfnArea.show(); } } // Store on the block so refresh() can re-sync every block when // lang changes, and restoreDfn() can re-sync after restoring. block.data("updateManeMode", updateManeMode); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || {}; // Cache of all non-placeholder option elements, so updateTplOptions // can detach/re-attach them without losing the full list. var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.attr("data-placeholder", "Li şablonekê bigere"); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (name, tpl) { // Shows "name — tpl.desc" when a tplDefs entry has a desc // in data.json, same pattern as steps.pron's template picker. var opt = $("<option></option>") .val(name) .text(tpl.desc ? name + " — " + tpl.desc : name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); // Same status-dot / 🔗 / ⓘ row treatment as every other // template picker. This one carries the bare name in value=, // so the name mapper is the identity rather than a snippet // parse; descriptions come from each template's TemplateData. markTemplateOptions(tplSelect, function (opt) { return opt.val(); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible // ones — native <select> won't reliably hide options any other way. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); // Options that were detached when the descriptions arrived // missed that pass, so describe whatever is attached now. // The cache is warm by this point, so this is synchronous. applyTplDescriptions(tplSelect); tplSelect.trigger("wiktku:refresh"); if (currentVal && !currentStillValid) { tplSelect.val(""); tplTitleInput.hide().val(""); updateManeMode(); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpela hedefê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); tplTitleInput.on("blur", function () { refresh(); }); // Şablon senses have no plain gloss, so hide alternatîv/hevmane/ // dijmane/etc. Etîket, Nimûne and Jêgirtin stay visible either way. function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); nonKuWrap.hide(); tplTitleInput.show().focus(); } else { tplTitleInput.hide().val(""); updateManeMode(); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); // The template picker is an alternative to writing a // definition, not a step before it — so the box comes first // and this sits under it as a quiet link. It only expands // for the minority of senses that are a pointer at another // word (guharto, şaşnivîs, kevnbûyî) rather than a meaning. var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput) .hide(); var tplLink = $("<a href='#' class='wiktku-dfn-tpl-link'></a>") .text("Ev ne pênase ye — şablonek bi kar bîne"); tplLink.on("click", function (e) { e.preventDefault(); tplRow.show(); $(this).hide(); tplRow.find("input.wiktku-ac-input").first().focus(); }); /** Opens the picker without a click — used on restore, when a * sense already has a template and hiding it would make the * chosen value invisible. */ function revealTplRow() { tplRow.show(); tplLink.hide(); } block.data("revealTplRow", revealTplRow); block.append(dfnArea); block.append(nonKuWrap); block.append(tplLink); block.append(tplRow); // Apply lang filter on initial build. updateTplOptions(); updateManeMode(); // — Sub-field groups. — // The four most-used groups (Nimûne, Jêgirtin, Hevmane, Dijmane) // stay open; the rest sit behind the "Malûmatên pêşketî" toggle // (adv: true → .wiktku-dfn-subgroup-adv, keyed off by the collapse CSS). // Jêgirtin isn't in this array — it's a compound widget built // after the loop — but it's inserted right after Nimûne so the // visible order matches the list above. var allGroups = [ { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "wekî etîket lê xuya nabe tenê kategorîze dike", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê", adv: true }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in", adv: true }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e", adv: true }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e", adv: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); if (g.adv) groupDiv.addClass("wiktku-dfn-subgroup-adv"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } // The placeholder names the current language, but that's // often not chosen yet when this block is first built — // so keep a function around that refresh() (and onSubInput, // for newly-grown fields) can call again once lang is set // or changes. function subPlaceholder() { if (g.noLangSuffix) return g.label + "…"; var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return g.label + (langLabel ? " bi " + langLabel : "") + "…"; } function updateSubPlaceholders() { list.find("> li > textarea.wiktku-dfn-subfield").attr("placeholder", subPlaceholder()); } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": ") .append($("<span></span>").addClass("wiktku-dfn-sublabel-hint").text(g.izah)); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var useModifiers = !!MODIFIER_SUBGROUPS[g.cls]; list.data("updatePlaceholders", updateSubPlaceholders); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", subPlaceholder()); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow, useModifiers); }); list.append(useModifiers ? makeModifierLi(firstInput) : $("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder group — growing list, same structure as Nimûne. — (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text("Jêgirtin")) .append(": "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<textarea></textarea>") .addClass("wiktku-dfn-subfield wiktku-dfn-quote-citoid-input") .attr("rows", 1) .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi otomatîk tijî bike", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); // Fetches citation data from Citoid and fills this citation's // şablon + fields — only rebuilds fields on template change, // and never overwrites values the user already typed. function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoid.fetchJederFields(query).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only rebuild if switching şablon, so a repeat fetch // doesn't clear fields already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel wiktku-plain-select"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); srcSel.append($("<option></option>").val("__category__").text("Ji Kategorî:Çavkanî şablonekê hilbijêre")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); // Citoid is only useful before a source is chosen — // hide it once a selection is made, restore on reset. if (chosen) { citoidWrap.hide(); } else { citoidWrap.show(); return; } if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } if (chosen === "__category__") { // Search widget over the members of [[Kategorî:Çavkanî]]. // Picking a şablon here immediately switches the row to // "Bi destê xwe binivîsim" mode with {{Şablon}} pre-filled, var catWrap = $("<span></span>").addClass("wiktku-native-select-wrap wiktku-dfn-quote-src-cat"); var catInput = $("<input type='search' autocomplete='off'>") .addClass("wiktku-start-narrow wiktku-dfn-quote-src-cat-input") .attr("placeholder", "Li navê şablonê bigere…"); var catResults = $("<ul></ul>").addClass("wiktku-ac-results wiktku-dfn-quote-src-cat-results").hide(); var catStatus = $("<span></span>").addClass("wiktku-dfn-quote-src-cat-status").text("Şablon tên barkirin…"); var showCatResults = function (query) { var q = $.trim(query).toLowerCase(); catResults.empty(); var list = catSrcTemplates || []; var matched = q ? $.grep(list, function (name) { return name.toLowerCase().indexOf(q) !== -1; }) : list; if (!matched.length) { catResults.hide(); return; } $.each(matched.slice(0, 50), function (_, name) { var li = $("<li></li>").text(name).attr("data-value", name); var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; e.preventDefault(); selectCatTpl(name); }); li.on("mousedown", function (e) { e.preventDefault(); selectCatTpl(name); }); catResults.append(li); }); catResults.show(); }; // Wraps the chosen şablon as {{Name}}, drops it into the // manual textarea, and switches the row into manual mode // so the user can keep editing it (add params, etc.). var selectCatTpl = function (name) { catResults.hide(); srcSel.val("__manual__"); srcSel.trigger("change"); srcFields.find(".wiktku-dfn-quote-src-manual") .val("{{" + name + "}}") .trigger("focus"); }; catInput.on("input", function () { showCatResults($(this).val()); }); catInput.on("focus", function () { showCatResults($(this).val()); }); catInput.on("blur", function () { setTimeout(function () { catResults.hide(); }, 200); }); catWrap.append(catInput).append(catResults).append(catStatus); srcFields.append(catWrap); fetchCatSrcTemplates().then(function () { catStatus.text(""); }, function () { catStatus.text("Şablon nehatin barkirin."); }); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (key, label) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", key) .attr("placeholder", label + "…"); // "Sernav" / "Sernavê orjînal" (title fields, e.g. for // kitêb/kovar/malper) get a taller, draggable box; every // other field in the template stays as-is. Field labels // come from the on-wiki jederDefs data, so match on the // (diacritic-folded) label text rather than a fixed key. var foldedLabel = foldDiacritics(label); if (/^sernav$/.test(foldedLabel) || /orjin/.test(foldedLabel)) { inp.addClass("wiktku-dfn-quote-src-input--title"); } row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); jederGroupDiv.append(jederLbl).append(jederList); // Straight after Nimûne rather than last: Jêgirtin is the // same kind of thing (an attested use of the word) and the // two belong together — see the allGroups comment above. var nimuneGroup = block.find(".wiktku-dfn-nimune-group"); if (nimuneGroup.length) jederGroupDiv.insertAfter(nimuneGroup); else block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); // ── "Malûmatên pêşketî" — per sense, after Dijmane ─────── // One toggle per sense rather than one for the whole step: // the fields behind it (Etîket, Kategorî, Jornav…) belong to // a single meaning, so a global switch flipped them for every // sense at once and gave a count that answered "across all // senses" — not a question anybody was asking. (function () { block.addClass("wiktku-sense-adv-hidden"); var advRow = $("<div class='wiktku-adv-toggle-row wiktku-sense-adv-row'></div>"); var advToggle = $("<a href='#' class='wiktku-adv-toggle'></a>").attr("aria-expanded", "false"); var advLabel = $("<span class='wiktku-adv-toggle-text'></span>"); advToggle.append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")).append(advLabel); function syncAdv() { var hidden = block.hasClass("wiktku-sense-adv-hidden"); advLabel.text(hidden ? "Malûmatên pêşketî nîşan bide" : "Malûmatên pêşketî veşêre"); advToggle.attr("aria-expanded", hidden ? "false" : "true") .toggleClass("wiktku-adv-open", !hidden); } advToggle.on("click", function (e) { e.preventDefault(); block.toggleClass("wiktku-sense-adv-hidden"); syncAdv(); }); block.data("syncSenseAdv", syncAdv); advRow.append(advToggle); // After the last always-visible group (Dijmane) and before // the advanced ones, which sit below it in DOM order. var lastPrimary = block.find(".wiktku-dfn-dijmane-group"); if (lastPrimary.length) advRow.insertAfter(lastPrimary); else block.append(advRow); syncAdv(); }()); return block; }, /** Shows only `block` among the sense list; hides every other one. */ setOpenSense: function (stepDiv, block) { stepDiv.find("li.wiktku-dfn-sense").each(function () { $(this).toggleClass("wiktku-sense-collapsed", !$(this).is(block)); }); steps.dfn.renderSenseTabs(stepDiv); }, /** Rebuilds the "Mane 1 / Mane 2 / [trash] / + Mane zêde bike" tab row from the current sense list. */ renderSenseTabs: function (stepDiv) { var tabsDiv = stepDiv.find(".wiktku-dfn-sense-tabs"); if (!tabsDiv.length) return; tabsDiv.empty(); var blocks = stepDiv.find("li.wiktku-dfn-sense"); var openLi = null; blocks.each(function (i) { var li = $(this); var isOpen = !li.hasClass("wiktku-sense-collapsed"); if (isOpen) openLi = li; var tab = $("<span class='wiktku-dfn-sense-tab'></span>") .text("Mane " + (i + 1)) .toggleClass("wiktku-tab-active", isOpen); tab.on("click", function () { steps.dfn.setOpenSense(stepDiv, li); }); tabsDiv.append(tab); }); // One delete button for the whole bar — not one per tab — so // there's only ever a single, deliberate hit-target for a // destructive action, positioned away from the tabs people // click to switch senses. Always keep at least one Mane. if (blocks.length > 1 && openLi) { var openIdx = blocks.index(openLi); var trash = makeTrashButton("Vê maneyê jê bibe (Mane " + (openIdx + 1) + ")"); trash.on("click", function () { if (!window.confirm("Tu dixwazî Mane " + (openIdx + 1) + " jê bibî? Ev tişt nayê vegerandin.")) return; steps.dfn.removeSense(stepDiv, openLi); }); tabsDiv.append(trash.$element); } var addBtn = $("<button type='button' class='wiktku-add-sense'></button>") .append($("<span class='wiktku-add-sense-plus'>+</span>")) .append(document.createTextNode("Mane zêde bike")); addBtn.on("click", function (e) { e.preventDefault(); steps.dfn.addSense(stepDiv); }); tabsDiv.append(addBtn); }, // Deliberately does nothing on every keystroke. The only thing a // live Mane/template-title edit needs to propagate is the Werger/ // Bi zaravayên din gloss list (glossList()/build() re-read every // sense in the DOM, and get slow with more than one sense around) // — mane itself isn't a required step, so nothing else in // refresh() depends on it changing mid-keystroke. The callers // (dfnArea/tercimeArea/izahArea/tplTitleInput) run refresh() on // blur instead; getWikitext()/output() always re-read the DOM // fresh regardless, so the final wikitext is correct either way. onDfnInput: function (stepDiv, block, textarea) {}, /** Appends a sense, opens it, and hides the others. */ addSense: function (stepDiv) { var list = stepDiv.find("ol.wiktku-dfn-list"); var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); initSelects(newBlock); steps.dfn.setOpenSense(stepDiv, newBlock); newBlock.find("textarea.wiktku-dfn-mane").first().focus(); refresh(); return newBlock; }, /** Removes one sense block. Assumes the caller already confirmed * and already checked more than one sense remains. If the * removed sense was the open one, opens whichever sense ends up * taking its place (or the last one, if it was the last). */ removeSense: function (stepDiv, li) { var list = stepDiv.find("ol.wiktku-dfn-list"); var blocks = list.find("li.wiktku-dfn-sense"); var removedIdx = blocks.index(li); var wasOpen = !li.hasClass("wiktku-sense-collapsed"); li.remove(); if (wasOpen) { var remaining = list.find("li.wiktku-dfn-sense"); var next = remaining.eq(removedIdx); if (!next.length) next = remaining.last(); if (next.length) steps.dfn.setOpenSense(stepDiv, next); } steps.dfn.renderSenseTabs(stepDiv); refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow, modifiers) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow, modifiers); }); list.append(modifiers ? makeModifierLi(next) : $("<li></li>").append(next)); // New field starts with no placeholder — give it (and any // others in the list) the current one. var updatePlaceholders = list.data("updatePlaceholders"); if (typeof updatePlaceholders === "function") updatePlaceholders(); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: {}, posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; // One reassurance, shown once for the whole Mane step: the // "an jî şablonek hilbijêre" dropdown inside each sense is // optional — plain text is the normal path. if (!stepDiv.find(".wiktku-dfn-tpl-hint").length) { stepDiv.append( $("<p class='wiktku-step-hint wiktku-dfn-tpl-hint'></p>").text( "Ji bo her maneyekê, dropdown-a \"an jî şablonek hilbijêre\" ne mecbûrî ye — bi gelemperî tu tenê maneyê bi tîpên asayî dinivîsî. Ew şablon tenê ji bo rewşên taybet in (mînak: guherto, kevnbûyî, şaşnivîs); heke tu nizanî kîjan divê, vale bihêle." ) ); } var tabsDiv = $("<div class='wiktku-dfn-sense-tabs'></div>"); stepDiv.append(tabsDiv); var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); steps.dfn.renderSenseTabs(stepDiv); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName === "__category__") { // Reachable only if the user opened the category search but // never picked a şablon — picking one switches the row to // __manual__ (see selectCatTpl above), so there's nothing // meaningful to save here. } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: readList("wiktku-dfn-etiket"), kategori: readList("wiktku-dfn-kategori"), nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense var izahLines = []; // parallel — raw îzah gloss for that same sense // True only once some sense's *actual* dfn text (post tercime/îzah // split) is non-empty. var hasLinkableMane = false; $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("# " + (tplKatTpl ? tplKatTpl + " " : "") + (tplLabelTpl ? tplLabelTpl + " " : "") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(""); // template senses have no îzah return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty // Pull the îzah gloss (if any) out of the combined tercime+îzah // string — it's spliced back in separately below, after its // own linkify pass (see izahLines / the second linkifyText call). var izahRaw = null; var tercimeIzah = splitTercimeIzah(dfn); if (tercimeIzah) { dfn = tercimeIzah.tercime; izahRaw = stripWikilinks(tercimeIzah.izah); } if (dfn) { dfn = stripWikilinks(dfn); // Sentence-case + trailing period are for ku definitions, // which are written as full glosses. if (lang === "ku") { if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } // Real prose — this is what makes the sense worth running // through the main linkify pass. hasLinkableMane = true; } else if (izahRaw === null) { // No mane at all — this is just the "{{mane?|lang}}" // placeholder, a bare template call with no plain words // in it. Do NOT count it as linkable: sending nothing but // bracketed templates through the main linkify pass hangs // the linkify gadget (see the hasLinkableMane/hasIzah // check below). dfn = lang === "ku" ? "{{mane?|" + lang + "}}" : ""; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var out = "# " + (katTpl ? katTpl + " " : "") + (labelTpl ? labelTpl + " " : "") + dfn; var idx = defLines.length; var hasThisIzah = izahRaw !== null && $.trim(izahRaw) !== ""; // Bare {{...}} token — like {{wiktku-cite-N}}, this survives // linkify's first pass untouched (it treats template calls as // opaque), then gets swapped for {{îzah|…}} once the actual // gloss text has been linkified in its own separate pass. if (hasThisIzah) { out += (dfn ? " " : "") + "{{wiktku-izah-" + idx + "}}"; } function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(hasThisIzah ? izahRaw : ""); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } // Runs text through the linkify gadget if it's loaded, otherwise // just passes it through unchanged. Shared by both linkify passes // below (main mane text, and — separately — îzah glosses). function linkifyText(t, cb) { if (typeof $.kuLinkify === "function") { $.kuLinkify(t, cb); } else { cb(t); } } var hasIzah = izahLines.some(function (t) { return t && $.trim(t) !== ""; }); var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with nimûne?. text = "# {{mane?|" + lang + "}}\n#* {{nimûne?|" + lang + "}}\n"; callback(text); return; } // Runs the îzah-only linkify pass against `base` (either the raw // text, when there's no linkable mane to run the main pass on // first, or the already-linkified main text). Shared by both // branches below so the token-splice logic only lives once. function runIzahPass(base) { var izahJoined = $.map(izahLines, function (raw, idx) { if (!raw) return undefined; return "{{wiktku-izah-open-" + idx + "}}" + raw + "{{wiktku-izah-close-" + idx + "}}"; }).join("\n"); linkifyText(izahJoined, function (izahLinked) { var izahByIdx = {}; var re = /\{\{wiktku-izah-open-(\d+)\}\}([\s\S]*?)\{\{wiktku-izah-close-\1\}\}/g; var m; while ((m = re.exec(izahLinked)) !== null) { izahByIdx[parseInt(m[1], 10)] = m[2]; } var withIzah = base.replace(/\{\{wiktku-izah-(\d+)\}\}/g, function (_, n) { var linked = izahByIdx[parseInt(n, 10)]; return linked !== undefined ? "{{îzah|" + linked + "}}" : ""; }); callback(restoreCites(withIzah)); }); } if (!hasLinkableMane) { if (!hasIzah) { // All filled senses are template senses (or otherwise have // no plain text at all) — nothing here needs linkify. callback(restoreCites(text)); return; } // There's no plain mane text anywhere (e.g. tercime left blank // with only îzah filled in), so every defLine is just a bare // template call with nothing to word-link. Sending a line // like "# {{wiktku-izah-0}}" through the main linkify pass // gives it no plain words to work with, makes the linkify // gadget hang — so skip that pass entirely and run only // the îzah pass, splicing straight into the unlinkified text. var loadIzahOnly = function () { runIzahPass(text); }; mw.loader.using("ext.gadget.linkify", loadIzahOnly, loadIzahOnly); return; } var didTryToLoad = function () { // First pass: the main definition text (mane), same as before. linkifyText(text, function (mainLinked) { if (!hasIzah) { callback(restoreCites(mainLinked)); return; } // Second pass: îzah glosses, linkified via their own // separate call. Each gloss is wrapped in its own // {{wiktku-izah-open/close-N}} pair; like the existing // {{wiktku-cite-N}} tokens, these sit inside double // braces so linkify leaves the tokens themselves alone — // only the raw gloss text between each pair gets linked. runIzahPass(mainLinked); }); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, tewandin: { id: "tewandin", name: "tewandin", question_fmt: 'Tewandina "' + pageName + '" binivîse', visible: function (values) { return values.lang && values.pos; }, build: function (stepDiv) { if (stepDiv.find(".wiktku-tewandin-wrap").length) return null; var wrap = $("<div class='wiktku-tewandin-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-tewandin-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-tewandin-text") .attr("rows", 4) .attr("placeholder", "{{ku-tewîn-nav|nêr}}"); wrap.append(ta); stepDiv.append(wrap); function autoPopulate() { if (!ta.length) return; var vals = getValues(); var c = vals.cinsiyet || ""; var p = vals.pos || ""; if (!pageName.includes(" ") && c && GENDER_BASE_LABELS[c] && (p === "navdêr" || p === "serenav") && vals.lang === "ku" && c !== "mndudil") { var label = (c === "mnmane") ? "mê û nêr" : GENDER_BASE_LABELS[c]; var out = "{{ku-tewîn-nav|" + label; if (p === "serenav") out += "|y"; out += "}}"; if (!$.trim(ta.val())) ta.val(out); } } setTimeout(function () { autoPopulate(); $("#wiktku-start-form").on("change.tewandin", "#wiktku-start-lang-field, #wiktku-start-cinsiyet-field, #wiktku-start-pos-field", autoPopulate); }, 0); return ta; }, output: function () { var manualText = $.trim($("#wiktku-start-tewandin .wiktku-tewandin-text").val()); if (manualText) { return "\n==== Tewandin ====\n" + manualText + "\n"; } return ""; } }, // resim — one or more images resim: { id: "resim", name: "resim", question_fmt: "Resmekê lê zêde bike", visible: function (values) { return !!(values.lang && values.pos); }, /** Builds one image row: filename + caption + alt text. */ buildItem: function (stepDiv) { var item = $("<li class='wiktku-resim-item'></li>"); var fileRow = $("<div class='wiktku-posparams-row'></div>"); var fileInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-file") .attr("placeholder", "navê_dosyayê.jpg"); fileRow.append($("<label></label>").text("Navê dosyayê: ")).append(fileInp); var capRow = $("<div class='wiktku-posparams-row'></div>"); var capInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-caption") .attr("placeholder", "Danasîna resimê…"); capRow.append($("<label></label>").text("Danasîn: ")).append(capInp); // Alt text: what a screen reader announces for this image var altRow = $("<div class='wiktku-posparams-row'></div>"); var altInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-alt") .attr("placeholder", "Ji bo kesên nabînin, çi tê dîtin? (ne mecbûrî)"); altRow.append($("<label></label>").text("Nivîsa alternatîf: ")).append(altInp); // Auto-fill the caption with the plain page name when a filename // is typed fileInp.on("input", function () { var file = $.trim($(this).val()); var curCap = $.trim(capInp.val()); var isDefault = !curCap || curCap === pageName; if (file && isDefault) { capInp.val(pageName); } else if (!file && isDefault) { capInp.val(""); } steps.resim.onFileInput(stepDiv, item, this); }); item.append(fileRow).append(capRow).append(altRow); return item; }, /** Grows the image list when the last row's filename gets content. */ onFileInput: function (stepDiv, item, input) { var val = $.trim($(input).val()); var list = stepDiv.find("ol.wiktku-resim-list"); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { list.append(steps.resim.buildItem(stepDiv)); } }, build: function (stepDiv) { if (stepDiv.find(".wiktku-resim-wrap").length) return null; var wrap = $("<div class='wiktku-resim-wrap'></div>"); var list = $("<ol class='wiktku-resim-list'></ol>"); list.append(steps.resim.buildItem(stepDiv)); wrap.append(list); stepDiv.append(wrap); return null; }, /** Reads every filled row from the DOM into an array of {file, caption, alt} * objects — blank rows (missing filename or caption) are skipped. * Non-Kurdish captions get wrapped in {{zim|lang|…}} here, unless * the user already typed their own {{zim|…}} template. Alt text is * optional and left as plain text either way. */ getImages: function (values) { var lang = (values && values.lang) || getValues().lang || ""; var images = []; $("#wiktku-start-resim li.wiktku-resim-item").each(function () { var file = $.trim($(this).find(".wiktku-resim-file").val()); var caption = $.trim($(this).find(".wiktku-resim-caption").val()); var alt = $.trim($(this).find(".wiktku-resim-alt").val()); if (!file || !caption) return; // Strip leading "Wêne:" or "File:" if the user typed it — we add it ourselves. file = file.replace(/^(wêne|file|image)\s*:\s*/i, ""); if (lang && lang !== "ku" && !/^\{\{zim\s*\|/i.test(caption)) { caption = "{{zim|" + lang + "|" + caption + "}}"; } images.push({ file: file, caption: caption, alt: alt }); }); return images; }, output: function (values) { var images = steps.resim.getImages(values); if (!images.length) return ""; return images.map(function (img) { var altPart = img.alt ? "|alt=" + img.alt : ""; return "[[Wêne:" + img.file + "|thumb" + altPart + "|" + img.caption + "]]"; }).join("\n") + "\n"; } }, // bnr-h — {{bnr-h|Page1|Page2|…}} prepended before the lang section (shared, not per-section) bnrh: { id: "bnrh", name: "binêre herwiha (bnr-h)", question_fmt: "Şablona bnr-h li qismê herî jor a rûpelê", //visible: function (values) { return !!values.lang; }, multiple: true, narrow: true, placeholder: "Ji bo 'test' bnr 'Test', 'teşt'", output: function (values) { var pages = $.grep(values.bnrh || [], function (p) { return !!$.trim(p); }); if (!pages.length) return ""; return "{{bnr-h|" + pages.map(function (p) { return $.trim(p); }).join("|") + "}}\n"; } }, bikaranin: { id: "bikaranin", name: "Notên bikaranînê", question_fmt: "Notên bikaranînê yên li ser vê kelîmeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, output: function (values) { var text = $.trim(values.bikaranin || ""); if (!text) return ""; return "\n==== Notên bikaranînê ====\n" + text + "\n"; }, }, xwendin: { id: "xwendin", name: "Bêhtir bixwîne", question_fmt: "Lînkên derveyî eleqedarî vê madeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: function (values) { if (!values || !values.lang) { return `* {{wpedî}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; } const ziman = values.lang === "ku" ? "" : `|ziman=${values.lang}`; return `* {{wpedî${ziman}}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; }, output: function (values) { var text = $.trim(values.xwendin || ""); if (!text) return ""; return "\n==== Bêhtir bixwîne ====\n" + text + "\n"; }, }, alfabeyendin: { id: "alfabeyendin", name: "Bi alfabeyên din", question_fmt: function (values) { var base = "Nivîsîna vê kelîmeyê bi alfabeyên din" var langLabel = values.lang ? getLangLabel(values.lang) : ""; if (langLabel) { return base + " ên " + langLabel; } return base; }, visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: "Ji bo kurmancî: * {{ku-ar|şiklê alfaba erebî}}", output: function (values) { var text = $.trim(values.alfabeyendin || ""); if (!text) return ""; return "\n==== Bi alfabeyên din ====\n" + text + "\n"; }, }, formalt: makeWordListStep("formalt", "formên alternatîv", "Formên alternatîv ên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), hevmane: makeWordListStep("hevmane", "hevmane", "Hevmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), dijmane: makeWordListStep("dijmane", "dijmane", "Dijmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jornav: makeWordListStep("jornav", "jornav", "Jornavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jernav: makeWordListStep("jernav", "jêrnav", "Jêrnavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse"), binereherwiha: makeWordListStep("binereherwiha", "herwiha binêre", "Kelîmeyên din ên eleqedar binivîse"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: {}, visible: function (values) { return values.lang && values.pos; }, // Fills the insert-dropdown from the current etymTpls object. refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(ta); stepDiv.append(wrap); initSelects(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder. // Skip it only when every filled sense is a şablon sense // a completely empty entry with no şablon chosen still gets the placeholder var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasFilledTplSense = dfnSenses.some(function (s) { return !!s.tpl && !!s.tplTitle; }); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (hasFilledTplSense && !hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: function (values) { return {"navz": true, [values.lang]: true} }, // Language dropdown + growing word-input list; a new row appends // when the dropdown gets a value. Mirrors steps.trans, but flat. buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/build below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Attach the searchable picker now the select is in the DOM. initSelects(list); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", question_fmt: "'"+ pageName + "' di zaravayên din de çawa tê gotin?", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: {}, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zaravayekî bigere"); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; // A completely empty entry still gets a placeholder section // to fill in later; an individual placeholder gloss is only // skipped once some other sense already has real content. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", question_fmt: "Tercimeyên vê maneyê bi zimanên din binivîse", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide only when every sense is a filled template sense (no plain // gloss to attach translations to). A mix, or nothing filled in // yet, still shows Werger. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, // Language dropdown + growing word-input list, scoped to one gloss's // group (each gloss has its own group and row list). buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/buildGroup below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, // Builds (or fetches) the .wiktku-trans-group for one gloss. buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, // Syncs one .wiktku-trans-group per current gloss, keyed by // data-gloss-pos so groups stay matched across rebuilds. build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, // Reads all translation rows, grouped by gloss position. getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, // Builds the numbered "{ index, gloss }" list, one per dfn sense // with a real mane (skips template senses). index is 1-based and // matches the sense's position in the "#" definition list. // When nothing's filled in, returns one placeholder entry so // Werger still has a group to attach to; when every sense is a // filled template sense, stays empty (matches trans.visible()). glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane, but other fields are filled — still gets a // gloss group since dfn.getOutput() emits {{mane?}} for it. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // A completely empty entry (nothing filled in dfn at all, no // şablon chosen either) still gets a placeholder Werger section // to fill in later. Only // skip an individual placeholder gloss below when some other // sense actually has real content, making that particular // placeholder redundant. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it. If some other sense already has real // content, this placeholder is redundant — skip it. If the // whole entry is empty, keep it so Werger still gets a // section to fill in. if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, cavkani: { id: "cavkani", name: "çavkanî", question_fmt: "Çavkaniyên din (ne jêgirtin) lê zêde bike", visible: function (values) { return !!values.pos; }, // Fills the insert-dropdown from the members of [[Kategorî:Çavkanî]]. refreshTplSelect: function () { var sel = $("#wiktku-start-cavkani .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(catSrcTemplates || [], function (_, name) { sel.append($("<option></option>").val(name).text(name)); }); markTemplateOptions(sel, function (opt) { return opt.val(); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-cavkani-wrap").length) return null; var wrap = $("<div class='wiktku-cavkani-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-cavkani-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-cavkani-text") .attr("rows", 4) .attr("placeholder", "Şablonekî ji lîsteyê hilbijêre an rasterast binivîse…"); // Template insert dropdown, populated from [[Kategorî:Çavkanî]] — // options refreshed once the category members are fetched. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var status = $("<span class='wiktku-cavkani-status'></span>"); sel.on("change", function () { var name = $(this).val(); if (!name) return; insertAtCursor(ta[0], "\n* {{" + name + "}}"); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(status).append(ta); stepDiv.append(wrap); // build() runs again for every new beş (see the "+ Beş zêde bike" // handler), after the initial page-wide pass — so this select needs // its own init or it stays a plain, unsearchable native <select>. initSelects(wrap); if (catSrcTemplates) { steps.cavkani.refreshTplSelect(); } else { status.text("Şablon tên barkirin…"); fetchCatSrcTemplates().then(function () { steps.cavkani.refreshTplSelect(); status.text(""); }, function () { status.text("Şablon nehatin barkirin."); }); } return ta; }, output: function () { var text = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); if (!text) return ""; return "\n==== Çavkanî ====\n" + text + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); // This array only controls DOM build order — nothing else keys off it // (see the comment above stepIdToGroup). Mane tab order: Mane (senses, // with malûmatên pêşketî nested inside each, see steps.dfn.build) → // Wêne → Bi zaravayên din → Werger, so dfn/resim/zarava/trans sit // adjacent to each other in that order. var ordered_steps = [ steps.lang, steps.pos, steps.posparams, steps.cinsiyet, steps.jimar, steps.lektur, steps.tr, // Mane tab, in reading order: the senses, then the two things that // belong to the entry as a whole rather than to one sense. steps.dfn, steps.tewandin, steps.alfabeyendin, steps.zarava, steps.trans, // Etîmolojî tab. steps.etym, steps.dunde, // Eleqedar tab — three lists of the same shape. steps.je, steps.tekildar, steps.binereherwiha, // Bilêvkirin isn't part of any STEP_GROUPS tab, but still needs a // slot here because this array is what builds the DOM. steps.pron, // Beşên din fields — behind the picker inside the Eleqedar tab. steps.resim, steps.bnrh, steps.bikaranin, steps.formalt, steps.hevmane, steps.dijmane, steps.jornav, steps.jernav, steps.cavkani, steps.xwendin]; // ── Step-group tabs ────────────────────────────────────────────────────── // Three tabs: "Mane" holds the senses (whose own blocks carry Nimûne, // Jêgirtin, Hevmane and Dijmane — see steps.dfn.allGroups), Tewandin, // alfabeyendin, zarava and trans; "Etîmolojî" splits out that topical // cluster; "Eleqedar" holds je/tekildar/binereherwiha plus — behind the // "Beşên din" picker, which lives inside this tab rather than as its // own — everything else (resim, formalt, hevmane, dijmane, jornav, // jernav, bikaranin, cavkani, xwendin, bnrh). A newly-picked section is // inserted right after the picker (see renderBesenDinPicker()), which // sits above je/tekildar/binereherwiha in the DOM — so picking one // pushes those down rather than the other way around. "mane" stays // first as the default-active tab since Mane is required content. // Tewandin keeps its own free-text {{ku-tewîn-nav}} field and does NOT // absorb the Cins/zayend form parameters (m=/n=/p=), which stay on the // headword template. // Steps that live behind the "Beşên din" picker inside Eleqedar — only // these need an explicit "open" before they're shown, even once // Eleqedar's tab is active. var BESENDIN_STEP_IDS = ["resim", "formalt", "hevmane", "dijmane", "jornav", "jernav", "bikaranin", "cavkani", "xwendin", "bnrh"]; var STEP_GROUPS = [ { id: "mane", label: "Mane", steps: ["dfn", "tewandin", "alfabeyendin", "zarava", "trans"] }, { id: "etimoloji", label: "Etîmolojî", steps: ["etym", "dunde"] }, { id: "eleqedar", label: "Eleqedar", steps: ["je", "tekildar", "binereherwiha"].concat(BESENDIN_STEP_IDS) }, ]; // Reverse lookup: step id -> index into STEP_GROUPS (undefined for // ungrouped steps — now only lang/pos/posparams/cinsiyet/lektur/tr, // which stay always-visible since they're required to get to everything // else). var stepIdToGroup = {}; $.each(STEP_GROUPS, function (gi, g) { $.each(g.steps, function (_, sid) { stepIdToGroup[sid] = gi; }); }); // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "posparams", "cinsiyet", "jimar", "lektur", "tr", "resim", "dfn", "tewandin", "formalt", "bikaranin", "alfabeyendin", "hevmane", "dijmane", "jornav", "jernav", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans", "cavkani", "xwendin" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; // ── Bilêvkirin as a standalone section ─────────────────────────────── // Pronunciation belongs to the word, not to one part of speech, so it // sits beside Navdêr/Lêker in the tab bar rather than inside any of them. // Modelled as a flag rather than an entry in `sections` since // activeSection is used as an array index in many places — viewing // Bilêvkirin leaves activeSection pointing at the POS section you were on. var viewingPron = false; // is it the tab currently on screen // Which STEP_GROUPS tab is currently shown. Lives out here (like // activeSection above) so refresh() — which is not nested inside build() // — can read it and so renderGroupTabs()/updateGroupTabIndicators() below // can be called from refresh() too. Both operate on the tab bar via its // #wiktku-group-tabs id rather than a closured element reference, for the // same reason. var activeGroup = 0; // Unsaved-changes / autosave state. Lives out here (same reason as // activeGroup above) so destroy() — which runs on final submit and on // switching to the source editor, and is not nested inside build() — // can clear the timers and the beforeunload warning. build() assigns // into these; it doesn't re-declare them. var formDirty = false; var autosaveDebounceTimer = null; var autosaveInterval = null; /** Re-renders the step-group tab bar to reflect the current activeGroup. */ function renderGroupTabs() { var groupTabsDiv = $("#wiktku-group-tabs"); if (!groupTabsDiv.length) return; groupTabsDiv.empty(); $.each(STEP_GROUPS, function (i, g) { var tab = $("<span></span>") .addClass("wiktku-group-tab") .attr("data-group-idx", i) .text(g.label) .toggleClass("wiktku-tab-active", i === activeGroup); (function (idx) { tab.on("click", function () { if (idx === activeGroup) return; activeGroup = idx; renderGroupTabs(); if (idx === ELEQEDAR_GROUP_IDX) renderBesenDinPicker(); refresh(); // Switching tabs can shorten the page (e.g. leaving a long // "Beşên din" field), and the browser may clamp the scroll // position on its own timing before our measurement runs. // Deferring one frame lets that settle first, so the // offsetTop read below is the final, post-refresh one. window.requestAnimationFrame(function () { var bar = document.getElementById("wiktku-group-tabs"); if (!bar) return; var form = document.getElementById("wiktku-start-form"); var stabsH = form ? (parseFloat(form.style.getPropertyValue("--wiktku-stabs-h")) || 0) : 0; var siteHeaderH = form ? (parseFloat(form.style.getPropertyValue("--wiktku-siteheader-h")) || 0) : 0; var top = bar.getBoundingClientRect().top + window.pageYOffset - stabsH - siteHeaderH; $("html, body").animate({ scrollTop: Math.max(0, top) }, 200); }); }); }(i)); groupTabsDiv.append(tab); }); } /** * Toggles a "needs attention" dot on any group tab that still has a * required, unfilled field hidden inside it — so switching tabs doesn't * leave the person wondering why "Bişîne" stays disabled. */ function updateGroupTabIndicators(values) { var tabs = $("#wiktku-group-tabs .wiktku-group-tab"); if (!tabs.length) return; $.each(STEP_GROUPS, function (i, g) { var missing = false; $.each(g.steps, function (_, sid) { var step = steps[sid]; if (!step || !step.required) return; var val = values[sid]; if (val === "" || (step.multiple && $.isArray(val) && val.join("") === "")) { missing = true; } }); tabs.eq(i).toggleClass("wiktku-tab-missing", missing && i !== activeGroup); }); } // "Beşên din" reveals one field at a time via a picker rather than // stacking them all. Per-section state, snapshotted in // saveCurrentSection() and restored in restoreSection() below, and // auto-seeded from any field that already has content (so a returning // draft doesn't hide something already filled in). var openedOtherSections = {}; var BESENDIN_SET = {}; $.each(BESENDIN_STEP_IDS, function (_, sid) { BESENDIN_SET[sid] = true; }); // "eleqedar"'s index in STEP_GROUPS — the Beşên din picker now renders // inside this tab rather than having its own. Derived rather than // hardcoded — this was once a literal 2 and silently pointed at the // wrong tab the moment Etîmolojî and Eleqedar were reordered. var ELEQEDAR_GROUP_IDX = (function () { for (var i = 0; i < STEP_GROUPS.length; i++) { if (STEP_GROUPS[i].id === "eleqedar") return i; } return STEP_GROUPS.length - 1; }()); /** Re-renders the "Beşên din" picker to list only the not-yet-opened sections. */ function renderBesenDinPicker() { var wrap = $("#wiktku-besendin-picker"); if (!wrap.length) return; wrap.empty(); var pickerValues = getValues(); var unopened = $.grep(BESENDIN_STEP_IDS, function (sid) { if (openedOtherSections[sid]) return false; // Don't offer a section that would open onto nothing: several of // these are gated (Bi zaravayên din / Werger need lang=ku, most // need a pos). refresh() would hide it again straight away, so // picking it would read as a broken dropdown. var step = steps[sid]; if (step && typeof step.visible === "function") { try { if (!step.visible(pickerValues)) return false; } catch (e) { /* a step whose visible() needs DOM we lack yet — offer it */ } } return true; }); if (!unopened.length) return; // everything's open — nothing left to pick var sel = $("<select class='wiktku-besendin-select'></select>"); sel.attr("data-placeholder", "— beşek hilbijêre —"); sel.append($("<option value=''>— beşek hilbijêre —</option>")); $.each(unopened, function (_, sid) { var step = steps[sid]; if (!step) return; sel.append($("<option></option>").val(sid).text(capitalize(step.name))); }); sel.on("change", function () { var sid = $(this).val(); if (!sid) return; openedOtherSections[sid] = true; // Newly opened section moves right under the picker, ahead of // whatever's already open, instead of wherever it happened to // sit in the fixed step order. $("#wiktku-start-" + sid).insertAfter(wrap); renderBesenDinPicker(); refresh(); }); wrap.append(sel); initSelects(wrap); } /** Marks any BESENDIN_STEP_IDS field that already has real content as * "opened", so restoring a draft doesn't bury filled-in sections behind * the picker. Reuses each step's own output() as the emptiness check — * it already knows what "empty" means per field, and it reads the DOM * the restore just populated. Call this AFTER the DOM has the restored * values in it. */ function seedOpenedFromContent() { var values = getValues(); $.each(BESENDIN_STEP_IDS, function (_, sid) { if (openedOtherSections[sid]) return; var step = steps[sid]; if (!step || typeof step.output !== "function") return; try { if (step.output(values)) openedOtherSections[sid] = true; } catch (e) { /* a step whose output() needs more state than we have yet — skip it */ } }); } function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } // Rebuilds the dfn DOM from a previously snapshotted senses array. function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing tab bar + list so build() recreates them cleanly. stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); // The picker is collapsed behind a link by default; a restored // sense that already uses a template has to show it, or the // chosen template is invisible and looks lost. var reveal = block.data("revealTplRow"); if (typeof reveal === "function") reveal(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // dfnArea is the only thing actually saved, so split it back into // tercime/îzah for editing (mirrors syncNonKuToMane's join format). var maneParts = splitTercimeIzah(sense.mane); block.find(".wiktku-dfn-tercime").val(maneParts ? maneParts.tercime : (sense.mane || "")); block.find(".wiktku-dfn-izah").val(maneParts ? maneParts.izah : ""); // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Same for the mane-box mode (plain vs tercime+îzah), since this // also depends on tplSelect's (and lang's) value. var updateMane = block.data("updateManeMode"); if (updateMane) updateMane(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found var useModifiers = !!MODIFIER_SUBGROUPS[cls]; // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true, useModifiers); }); subList.append(useModifiers ? makeModifierLi(ta) : $("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text).each(function () { highlightLinebreak(this); }); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder entries — accepts current array shape or a legacy // single object (older saved sections) for backwards compat. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote).each(function () { highlightLinebreak(this); }); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederCatTpl) { // Legacy format from before the şablon search switched rows to // manual mode directly — convert it the same way now, so it's // editable like any other free-form source. var catSelEl = li.find(".wiktku-dfn-quote-src-sel"); catSelEl.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val("{{" + j.jederCatTpl + "}}"); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); // Restoring a draft opens the first sense's tab by default. steps.dfn.setOpenSense(stepDiv, list.find("li.wiktku-dfn-sense").first()); } // Snapshots simple (non-dfn) per-section steps from the DOM into obj. function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } if (id === "cavkani") { snap.cavkani = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); return; } if (id === "posparams") { snap.posparams = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); return; } if (id === "resim") { // One entry per row, including blank ones, so a mid-edit draft // (e.g. a filename typed but no caption yet) survives a cache // restore instead of being silently dropped. snap.resim = $("#wiktku-start-resim li.wiktku-resim-item").map(function () { return { file: $.trim($(this).find(".wiktku-resim-file").val()), caption: $.trim($(this).find(".wiktku-resim-caption").val()), alt: $.trim($(this).find(".wiktku-resim-alt").val()) }; }).get(); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); // Which "Beşên din" sub-sections this section has already opened // via the picker — per-section, like everything else here. snap.openedOtherSections = $.extend({}, openedOtherSections); sections[activeSection] = snap; } // Restores a previously saved snapshot into the form DOM. function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); $("#wiktku-start-cavkani .wiktku-cavkani-text").val(snap.cavkani || ""); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); steps.posparams.build(ppDiv); var savedTa = snap.posparams || ""; ppDiv.find(".wiktku-posparams-text").val(savedTa); // Re-parse saved textarea to restore helper widget states. if (savedTa) { var cMatch = savedTa.match(/\|c=([^|}\s]+)/); var jMatch = savedTa.match(/\|j=([^|}\s]+)/); var trMatch = savedTa.match(/\|tr=([^|}\s]+)/); // Write into the shared hidden field (not the visible // select, which has no <option>s yet) — syncHelpers() // below reads it back to restore the dropdown once the // gender/number options for this language are populated. if (cMatch) $("#wiktku-start-cinsiyet-field").val(cMatch[1]); if (jMatch) $("#wiktku-start-jimar-field").val(jMatch[1]); if (trMatch) ppDiv.find(".wiktku-posparams-field[data-pp-key='tr']").val(trMatch[1]); // For lêker, c= holds the verb-type code instead of a // gender — split it back across the two dropdowns it is // now assembled from ("x-gh" → form "x" + base "gh"). if (cMatch && /^lêker/.test(snap.pos || "")) { var lekturParts = /^(?:([xphb])-)?(n?gh)$/.exec(cMatch[1]); if (lekturParts) { ppDiv.find(".wiktku-posparams-lektur-sel").val(lekturParts[2]); ppDiv.find(".wiktku-posparams-lekturform-sel").val(lekturParts[1] || ""); } } // Restore checked optional params. "form" is stored as // "erê" rather than "1" (see rebuildTa), so it needs its // own check here. ppDiv.find(".wiktku-posparams-opt-panel input[type='checkbox']").each(function () { var key = $(this).val(); var expected = key === "form" ? "erê" : "1"; $(this).prop("checked", savedTa.indexOf("|" + key + "=" + expected) !== -1); }); } steps.posparams.syncHelpers(ppDiv); return; } if (id === "resim") { var resimDiv = $("#wiktku-start-resim"); resimDiv.find(".wiktku-resim-wrap").remove(); steps.resim.build(resimDiv); // Accept both the new array-of-rows format and the older // single {file, caption} object saved before multi-image // support existed. var resimSnap = snap.resim; var rows = $.isArray(resimSnap) ? resimSnap : (resimSnap ? [resimSnap] : []); if (rows.length) { var list = resimDiv.find("ol.wiktku-resim-list"); list.empty(); $.each(rows, function (_, r) { var item = steps.resim.buildItem(resimDiv); item.find(".wiktku-resim-file").val(r.file || ""); item.find(".wiktku-resim-caption").val(r.caption || ""); item.find(".wiktku-resim-alt").val(r.alt || ""); list.append(item); }); // Always keep a blank trailing row, same as Nimûne/Dûnde. var lastItem = list.children("li.wiktku-resim-item").last(); if ($.trim(lastItem.find(".wiktku-resim-file").val())) { list.append(steps.resim.buildItem(resimDiv)); } } return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Tell the pickers about the programmatic value change. fields.filter("select").trigger("wiktku:refresh"); }); // Restore which "Beşên din" sub-sections were already opened for // this section, then seed in anything the DOM restore above just // filled in but that wasn't marked opened yet. openedOtherSections = $.extend({}, snap.openedOtherSections || {}); seedOpenedFromContent(); renderBesenDinPicker(); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); // Bilêvkirin is NOT emitted here — it is one shared field for the // whole word, so emitting it per section duplicated it. getWikitext() // prints it once, above the POS sections. steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.tewandin.output(values); entry += steps.bikaranin.output(values); entry += steps.alfabeyendin.output(values); entry += steps.formalt.output(values); entry += steps.hevmane.output(values); entry += steps.dijmane.output(values); entry += steps.jornav.output(values); entry += steps.jernav.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); entry += steps.cavkani.output(values); entry += steps.xwendin.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { // Each hop through here can be reached asynchronously: the dfn // step waits on mw.loader.using("ext.gadget.linkify") before // calling back, so from that point on the submit handler's own // try/catch is no longer on the stack. Guard every hop instead, // or a throw after linkify loads vanishes into an unhandled // rejection and the form just sits there looking busy. try { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } catch (e) { if (typeof onSubmitError === "function") onSubmitError(e); else throw e; } } processSection(0); } // Assembles wikitext for all sections plus the shared lang header. function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var bnrh = steps.bnrh.output(sharedValues); var entry = steps.lang.output(sharedValues); // One pronunciation per word, printed once between the language // header and the POS sections — see steps.pron.output. entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // bnr-h goes before the language section — only prepended when // generating fresh wikitext (not addLangMode, which handles it separately). if (!addLangMode && bnrh) entry = bnrh + entry; // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { if (s.mane) return s.mane; // Template sense (e.g. {{guharto|ku|somepage}}) — same // construction as the tplCall built in getOutput, so the // summary shows what actually gets written to the entry // instead of going blank. if (s.tpl && s.tplTitle) { return s.tplNoLang ? "{{" + s.tpl + "|" + s.tplTitle + "}}" : "{{" + s.tpl + "|" + sharedValues.lang + "|" + s.tplTitle + "}}"; } return ""; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; // Set by build() to its submitFailed(). Lives out here because the // wikitext-assembly functions below are outside build()'s closure but // still need a way to report a failure to the person rather than dying // silently in the console. var onSubmitError = null; // Whether Mane/Bi zaravayên din/Werger has anything in it — kept // outside refresh() so the click handler can read the latest value. var wiktkuContentGateOk = true; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues, placeholderText) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>").text(placeholderText || "")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice.label); if (choice.sortKey !== undefined) { // This is a language choice {code, label, sortKey} — show code. displayText = capitalize(choice.label) + " (" + choice.code + ")"; } var option = $(mw.html.element("option", { value: choice.code }, displayText)); if (disabledValues[choice.code]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } // Keys to disable for a key menu: already-taken or explicitly disabled. function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); populateMenus(input, step.keys, getDisabledKeys(step)); // Keep the key menus mutually exclusive: whatever one row selects is // disabled in every other row. Recomputed from the DOM on each change. input.on("change", function () { var all = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield"); var taken = {}; all.each(function () { var v = $(this).val(); if (v) taken[v] = true; }); all.not(this).each(function () { var self = $(this), own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (code) $(this).prop("disabled", !!taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }); // Return the wrapper; the select lives inside it and still fires change. return wrapNativeSelect(input); } // Adds another text field to the list if the last one now has text. function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); if (step.placeholder) { nextInput.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = step.modifiers ? makeModifierLi(nextInput).prepend(nextKeyInput || "") : $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) initSelects(nextItem); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } // Shows/hides steps based on whether their prerequisites are met, and // updates placeholders where applicable. function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); steps.cavkani.refreshTplSelect(); // Re-render any step's question label that depends on current values // (e.g. dfn's Werger-section reminder, which only applies to ku). $.each(steps, function (stepId, step) { if (typeof step.question_fmt === "function") { $("#wiktku-start-" + stepId + " .wiktku-start-step-question") .text(step.question_fmt(values)); } }); // Sync every sense block's mane-box mode (plain mane vs tercime+îzah) // to the current language, in case lang changes after blocks exist. $("#wiktku-start-dfn li.wiktku-dfn-sense").each(function () { var updateMane = $(this).data("updateManeMode"); if (updateMane) updateMane(); }); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Re-sync the "<label> bi <ziman>…" placeholder on every always-visible // sub-field list (etîket, kategorî, hevmane, …), since the language may // not have been chosen yet when these lists were first built, or may // have changed since. $("#wiktku-start-dfn .wiktku-dfn-sublist").each(function () { var upd = $(this).data("updatePlaceholders"); if (typeof upd === "function") upd(); }); // Same idea for word-list steps (jê, têkildar, binêre herwiha, …) // whose placeholder is a function of the current language. $.each(steps, function (stepId, step) { if (typeof step.placeholder === "function") { $("#wiktku-start-" + stepId + " textarea.wiktku-start-step-field") .attr("placeholder", step.placeholder()); } }); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // Insert after the quote textarea's resize-wrap (if the manual // resize handle has already been attached to it), not after the // bare textarea -- otherwise this lands *inside* that wrap, // between the textarea and its own grip, breaking jêgirtin's // handle and nesting the tr/t boxes inside it. var quoteTa = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap = quoteTa.closest(".wiktku-resize-wrap"); (quoteResizeWrap.length ? quoteResizeWrap : quoteTa).after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // See the tr-field branch above for why this targets the // resize-wrap instead of the bare textarea. var quoteTa2 = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap2 = quoteTa2.closest(".wiktku-resize-wrap"); (quoteResizeWrap2.length ? quoteResizeWrap2 : quoteTa2).after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { var groupIdx = stepIdToGroup[stepId]; var hiddenByTab = (groupIdx !== undefined && groupIdx !== activeGroup) || // Beşên din picker: stays hidden even while its tab is // active until explicitly opened from the dropdown. (BESENDIN_SET[stepId] && !openedOtherSections[stepId]); // Bilêvkirin is its own section now, so the two views are // mutually exclusive: on it, only pron shows (plus Ziman, which // is shared and stays above every section); off it, pron is // hidden no matter which tab is active. pron is deliberately // ungrouped — stepIdToGroup has no entry for it — so without // this branch it would show on all four tabs at once. if (stepId === "pron") { hiddenByTab = hiddenByTab || !viewingPron; } else if (viewingPron && stepId !== "lang") { hiddenByTab = true; } if (hiddenByTab || (typeof(step.visible) === "function" && !step.visible(values))) { $("#wiktku-start-" + stepId).hide(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } // After build, sync the posparams helper widgets whenever pos or lang changes. if (step.id === "posparams" && typeof step.syncHelpers === "function") { step.syncHelpers(stepDiv); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } stepDiv.slideDown(); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); // The three content tabs belong to a POS section — Bilêvkirin has no // sub-tabs of its own, so the bar goes away while it's on screen. $("#wiktku-group-tabs").toggle(!!values.pos && !viewingPron); var besenDinActive = activeGroup === ELEQEDAR_GROUP_IDX && !viewingPron; $("#wiktku-besendin-picker").toggle(besenDinActive); // The option list is filtered by each step's visible(), which depends // on lang/pos — so it has to be rebuilt when those change, not just // when a section is opened. Safe to call from here: rendering the // picker doesn't itself call refresh(), only picking an option does. if (besenDinActive) renderBesenDinPicker(); updateGroupTabIndicators(values); continueBtn.setDisabled(!canContinue); // Soft gate: stays a real, clickable OOUI button — a hard // setDisabled(true) here would swallow the click entirely, leaving // no way to tell the person why nothing happened. The CSS-only // "looks disabled" class lets the click handler still run and show // wiktkuNotify's explanation. wiktkuContentGateOk = !canContinue || hasMinRequiredContent(values); continueBtn.$element.toggleClass("wiktku-btn-soft-disabled", !wiktkuContentGateOk); } function destroy() { if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); if (autosaveInterval) clearInterval(autosaveInterval); formDirty = false; $(window).off("beforeunload.wiktkuUnsaved"); $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard").slideDown(); // #editform was kept laid-out but off-screen (see build()) instead of // display:none, precisely so the editor never had to size itself // against a zero-width/height box. Just bring it back on-screen — // no slideDown needed since it was never actually collapsed. $("#editform").removeClass("wiktku-offscreen"); // Belt-and-braces: if WikiEditor/CodeMirror/mobile's auto-grow still // cached a stale size from some earlier point, nudge them to // recalculate now that the box is genuinely visible. $(window).trigger("resize"); if (window.CodeMirror) { var cm = $("#wpTextbox1").data("CodeMirror") || $("#wpTextbox1").data("cmInstance"); if (cm && typeof cm.refresh === "function") cm.refresh(); } $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and navz. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; // Inserts a new "== {{ziman|code}} ==" section at the correct sorted // position: navz, then ku/hac/sdh/lki/ckb/zza, then alphabetical by name. function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections — just write the new section. // Add \n\n only when there is real non-whitespace content above. var trimmed = existing.replace(/\s+$/, ""); return trimmed ? trimmed + "\n\n" + wikitext : wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // (?![\s\S]) matches only true end-of-string, since a bare "$" with // /m would stop at the section's first line break instead. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections, each separated by exactly \n\n. // Trim trailing whitespace off each section's content first so we // control the spacing precisely. var joined = sections.map(function (s) { return s.content.replace(/\s+$/, ""); }).join("\n\n"); // Only add a separator after the preamble when it has real content. var preambleTrimmed = preamble.replace(/\s+$/, ""); var prefix = preambleTrimmed ? preambleTrimmed + "\n\n" : ""; return prefix + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê zimanekî nû li rûpelê îlawe bikî. Eger ev ziman jixwe hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bike, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Muhtewaya rûpelê paqij bike (her tiştî jê bibe û rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); // Tab bar for switching between step-groups (topics) within a section. // renderGroupTabs()/updateGroupTabIndicators() (which populate and // maintain it) live outside build() — see near "var activeSection". var groupTabsDiv = $("<div id='wiktku-group-tabs'></div>"); // Both tab bars are sticky (CSS). group-tabs' sticky "top" has to sit // right below section-tabs' actual rendered height, which isn't a // fixed number since the bar can wrap onto a second line. Measured // here and published as a CSS custom property the stylesheet reads // back; recomputed on content changes and window resize. // // Vector 2022 has its own sticky header (.vector-sticky-header) that // pins to the real top:0 once you scroll past the page title, which // would otherwise sit directly behind (and hide) our section-tabs. // Fixed by measuring how much of the viewport Vector's header // currently occupies and offsetting both our bars below it, via // --wiktku-siteheader-h. Vector's header slides in/out with scroll // position, so this is re-measured on scroll too, not just resize. function siteHeaderOffset() { var el = document.querySelector(".vector-sticky-header"); if (!el) return 0; var rect = el.getBoundingClientRect(); // Present in the DOM at all times on Vector 2022, but only // actually occupying screen space once scrolled into place — // before that it sits translated above the viewport (negative/ // zero rect), which must not add a phantom gap under our bars. if (rect.bottom <= 0 || rect.top > 4) return 0; return Math.max(0, rect.bottom); } var stickyOffsetQueued = false; function syncStickyTabsOffset() { var h = sectionTabsDiv.is(":visible") ? (sectionTabsDiv.outerHeight() || 0) : 0; startForm.css("--wiktku-stabs-h", h + "px"); startForm.css("--wiktku-siteheader-h", siteHeaderOffset() + "px"); } function queueStickyTabsOffsetSync() { if (stickyOffsetQueued) return; stickyOffsetQueued = true; window.requestAnimationFrame(function () { stickyOffsetQueued = false; syncStickyTabsOffset(); }); } $(window).on("resize.wiktkuStickyTabs scroll.wiktkuStickyTabs", queueStickyTabsOffsetSync); // "Beşên din" picker — sits right under the group tab bar, only // shown while the Eleqedar tab is active (toggled in refresh(), see // ELEQEDAR_GROUP_IDX); renderBesenDinPicker() fills it. var besenDinPickerDiv = $("<div id='wiktku-besendin-picker' class='wiktku-besendin-picker'></div>"); /** Puts the form back in a usable state after a failed submit and * says what happened. Without this the button stays disabled and * the spinner spins forever on any exception — the person is left * staring at a form that looks busy but is dead, with the reason * visible only in the browser console. */ function submitFailed(err) { spinner.hide(); continueBtn.setDisabled(false); continueBtn.$element.removeClass("wiktku-btn-sending"); var detail = (err && (err.message || err.toString())) || "sedem nediyar"; mw.notify( "Şandin bi ser neket: " + detail + " — tiştê ku te nivîsî winda nebûye. Heke ev dubare bibe, " + "bi 'Edîtora çavkaniyê veke' berdewam bike.", { type: "error", tag: "wiktku-submit", autoHide: false } ); // Deliberately console.error as well: the notification is for the // person, this is for whoever they report the bug to. if (window.console && console.error) console.error("[wiktku] submit failed", err); } onSubmitError = submitFailed; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); continueBtn.$element.addClass("wiktku-btn-sending"); spinner.show(); try { getWikitext(function (wikitext) { try { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page — write fresh content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // ── bnr-h merge ────────────────────────────────────────── // If the user filled bnr-h inputs, either merge into the // existing {{bnr-h|…}} call or prepend a new one. var bnrhOut = steps.bnrh.output(getValues()); if (bnrhOut) { var newPages = bnrhOut.replace(/^\{\{bnr-h\|/, "").replace(/\}\}\n?$/, "").split("|"); var bnrhRe = /\{\{bnr-h\|([^}]*)\}\}/i; if (bnrhRe.test(existing)) { existing = existing.replace(bnrhRe, function (_, inner) { var existingPages = inner.split("|").map(function (p) { return p.trim(); }); $.each(newPages, function (_, p) { p = p.trim(); if (p && existingPages.indexOf(p) === -1) existingPages.push(p); }); return "{{bnr-h|" + existingPages.join("|") + "}}"; }); } else { existing = bnrhOut + existing; } } // If this language's section already exists (whitespace // differences aside), merge into it; otherwise insert new. var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); } catch (e) { // Thrown while writing the result into #wpTextbox1. submitFailed(e); } }); } catch (e) { // Catches anything thrown synchronously inside getWikitext. submitFailed(e); } }); // Tracks whether groupTabsDiv has been inserted yet. var groupTabsInserted = false; $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); var nameH3 = $("<h3></h3>").addClass("wiktku-start-step-name"); var nameLabel = $("<label></label>") .attr("for", "wiktku-start-" + step.id + "-field") .text(name); nameH3.append(nameLabel); stepDiv.append(nameH3); if (step.question_fmt) { // question_fmt can be a plain string, or a function of the // current values (used by steps whose question text depends // on e.g. the chosen language) — refresh() keeps it in sync // afterwards via the .wiktku-start-step-question class. var questionText = typeof step.question_fmt === "function" ? step.question_fmt(getValues()) : step.question_fmt; stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, questionText))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); // initSelects() runs over the whole form once it is in the DOM. stepDiv.append(input); } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.placeholder) { input.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append(step.modifiers ? makeModifierLi(input) : $("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Section tabs (switch between POS sections) sit above the // per-section fields, starting at "pos". if (step.id === "pos") { startForm.append(sectionTabsDiv); } // Step-group tabs sit just before the first grouped step in // ordered_steps. Derived from stepIdToGroup so this keeps // working no matter how STEP_GROUPS/ordered_steps get reordered. if (!groupTabsInserted && stepIdToGroup[step.id] !== undefined) { startForm.append(groupTabsDiv); startForm.append(besenDinPickerDiv); groupTabsInserted = true; } startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); /** Adds a new, empty POS section and switches to it. */ function addPosSection() { saveCurrentSection(); viewingPron = false; sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); return; } if (id === "resim") { $("#wiktku-start-resim .wiktku-resim-wrap").remove(); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); stepDiv.find("select.wiktku-start-step-field").trigger("wiktku:refresh"); }); // Fresh section — no "Beşên din" sub-section has been opened yet. openedOtherSections = {}; renderBesenDinPicker(); renderSectionTabs(); refresh(); } addSectionBtn.on("click", addPosSection); /** Removes one POS section. Assumes the caller already confirmed and * already checked more than one section remains. If the removed * section was the one on screen, its in-progress DOM edits are * discarded along with it (never saved back into sections[]) and a * neighboring section is restored in its place. */ function removePosSection(idx) { sections.splice(idx, 1); if (idx === activeSection) { viewingPron = false; activeSection = Math.min(idx, sections.length - 1); restoreSection(sections[activeSection]); refresh(); } else if (idx < activeSection) { activeSection -= 1; } renderSectionTabs(); } /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); syncStickyTabsOffset(); return; } sectionTabsDiv.show(); // Bilêvkirin leads the bar, ahead of the POS sections. var pronTab = $("<span></span>") .addClass("wiktku-section-tab wiktku-section-tab-pron") .text("Bilêvkirin") .toggleClass("wiktku-tab-active", viewingPron); pronTab.on("click", function () { if (viewingPron) return; saveCurrentSection(); viewingPron = true; refresh(); renderSectionTabs(); }); sectionTabsDiv.append(pronTab); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection && !viewingPron); (function (idx) { tab.on("click", function () { if (idx === activeSection && !viewingPron) return; // Leaving Bilêvkirin doesn't need a save — its field // is shared and never part of a section snapshot. if (!viewingPron) saveCurrentSection(); viewingPron = false; activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // One delete button for the whole bar — not one per tab — same // reasoning as the Mane tabs' trash button: deletes whichever // Beş is currently open, so there's only one thing a click on it // can possibly remove. Not shown on Bilêvkirin (nothing to // delete there) or when it's the only Beş left. if (sections.length > 1 && !viewingPron) { var activeTabLabel = sections[activeSection] && sections[activeSection].pos ? capitalize(sections[activeSection].pos) : ("Beş " + (activeSection + 1)); var sectionTrash = makeTrashButton("Vê beşê jê bibe (" + activeTabLabel + ")"); sectionTrash.on("click", function () { if (!window.confirm("Tu dixwazî \"" + activeTabLabel + "\" jê bibî? Ev tişt nayê vegerandin.")) return; removePosSection(activeSection); }); sectionTabsDiv.append(sectionTrash.$element); } // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); syncStickyTabsOffset(); } renderSectionTabs(); /** * Re-populates a dynamically-growing "multiple" field list (bnrh, je, * tekildar, …) from a saved array of strings. Sets each value via * .val() + a triggered "input" event rather than touching the DOM * structure directly, so the normal refreshForTextField() growth * logic adds exactly as many rows as needed — the same thing that * happens when a person types into the last (empty) row. */ function restoreMultiField(id, values) { var container = $("#wiktku-start-" + id); $.each(values || [], function (i, v) { var field = container.find(".wiktku-start-step-field").eq(i); if (!field.length || !v) return; field.val(v).trigger("input"); }); } /** * Restores a full cached draft: shared lang/pron/bnrh fields, then * every section (via the same restoreSection()/refresh()/ * renderSectionTabs() sequence already used when switching tabs). * @param cached {{lang: string, pron: string, bnrh: Array, sections: Array, activeSection: number}} */ function restoreFromCache(cached) { if (cached.lang) { $("#wiktku-start-lang-field").val(cached.lang); $("#wiktku-start-lang-field").trigger("wiktku:refresh"); } // Rebuild dependent steps (pos, pron wrap, etc.) now that lang is set. refresh(); if (cached.pron !== undefined) { $("#wiktku-start-pron .wiktku-pron-text").val(cached.pron); } if (cached.bnrh) { restoreMultiField("bnrh", cached.bnrh); } sections = (cached.sections && cached.sections.length) ? cached.sections : [{}]; activeSection = (typeof cached.activeSection === "number" && cached.activeSection >= 0 && cached.activeSection < sections.length) ? cached.activeSection : 0; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); updateLastSavedIndicator(cached.savedAt || null); formDirty = false; wiktkuNotify("Danûstandina berê ya qeydkirî ji cache hate barkirin.", { type: "info", tag: "wiktku-cache-restore" }); } // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { // renderSectionTabs() labels each tab from sections[i].pos, which // is only synced from the DOM by saveCurrentSection() (on tab // switch/section add). Without this, the active tab's own label // stays on the previous pos (or "Beş N") until the user switches // away and back. Update it directly so the rename is immediate. if (sections[activeSection]) sections[activeSection].pos = $(this).val(); renderSectionTabs(); // A new cureyê rêzimanî means any previously chosen cinsiyet/ // cureyê lêkerê no longer applies — clear both selections (and // the shared hidden cinsiyet field, since rebuildTa()/syncHelpers() // fall back to it) before wiping the textarea, so nothing stale // gets carried over into the rebuilt template. var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-cinsiyet-sel").val(""); ppDiv.find(".wiktku-posparams-jimar-sel").val(""); ppDiv.find(".wiktku-posparams-lektur-sel").prop("selectedIndex", 0); ppDiv.find(".wiktku-posparams-lekturform-sel").prop("selectedIndex", 0); $("#wiktku-start-cinsiyet-field").val(""); $("#wiktku-start-jimar-field").val(""); ppDiv.find(".wiktku-posparams-text").val(""); // refresh() runs steps.posparams.syncHelpers(), which toggles the // param rows for the new pos and — since the textarea is now // empty — calls rebuildTa() to repopulate it. refresh(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { // Immediate feedback that the click registered continueBtn.$element.addClass("wiktku-btn-flash"); setTimeout(function () { continueBtn.$element.removeClass("wiktku-btn-flash"); }, 500); // Ziman/Cureyê rêzimanî already block submission via the real // OOUI setDisabled (see canContinue in refresh()) — this is a // second, softer check that still lets the click through so we // can explain why, instead of the button just silently doing nothing. if (!wiktkuContentGateOk) { wiktkuNotify( "Berî şandinê, tiştekî binivîse: Mane, Bi zaravayên din, an jî Werger — kêmasî yek ji van sê beşan divê tijî be.", { type: "warn", tag: "wiktku-mincontent" } ); return; } wiktkuNotify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", flags: [ "destructive" ], }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Cache save/clear buttons ───────────────────────────────────────── // Manual, page-scoped save of the entire wizard (all sections, not // just the active one) via [[MediaWiki:Gadget-StorageUtils.js]]'s // ObjectStorage. Restoring happens silently on load at the end of // build(), once the full language list is available. // // Saving also happens automatically (debounced while typing, plus a // periodic fallback) — see "Autosave" below — since relying on the // person to remember to click "Li cache qeyd bike" before an // accidental tab close/reload defeats the point of having a cache // at all. function buildCacheSnapshot() { return { lang: getValues().lang || "", pron: $("#wiktku-start-pron .wiktku-pron-text").val() || "", // bnrh is shared (page-level), same as lang/pron above — not // per-section, so it doesn't live in sections[]. bnrh: getValuesForStep("bnrh"), sections: sections, activeSection: activeSection, savedAt: Date.now() }; } // ── Last-saved indicator ───────────────────────────────────────────── var lastSavedEl = $("<span id='wiktku-last-saved'></span>"); function formatSavedTime(ts) { try { return new Date(ts).toLocaleTimeString(mw.config.get("wgUserLanguage"), { hour: "2-digit", minute: "2-digit" }); } catch (e) { return new Date(ts).toLocaleTimeString(); } } function updateLastSavedIndicator(ts) { lastSavedEl.text(ts ? ("Cache: qeydkirî di saet " + formatSavedTime(ts) + " de") : ""); } // ── Dirty-state tracking + autosave ────────────────────────────────── // formDirty mirrors "does the live form differ from what's in cache". // Anything the person types/selects sets it; a successful save (auto // or manual) clears it; destroy() (final submit, or switching to the // source editor) also clears it since the wizard's job is over at // that point either way. formDirty/autosaveDebounceTimer/autosaveInterval // are declared in the outer scope (near activeGroup) — assigned here, // not re-declared — so destroy() can reach them too. var AUTOSAVE_DEBOUNCE_MS = 8000; // save shortly after typing pauses var AUTOSAVE_INTERVAL_MS = 60000; // …and at least this often regardless function performAutosave() { if (!formDirty) return; saveCurrentSection(); try { formCache.Set(buildCacheSnapshot()); formDirty = false; updateLastSavedIndicator(Date.now()); } catch (e) { // Silent on autosave failure (storage blocked/full, etc.) — the // manual button still surfaces a proper error if the person // tries it directly, no need to interrupt typing with a toast. } } function scheduleAutosave() { formDirty = true; if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = setTimeout(performAutosave, AUTOSAVE_DEBOUNCE_MS); } startForm.on("input change", "input, textarea, select", scheduleAutosave); autosaveInterval = setInterval(performAutosave, AUTOSAVE_INTERVAL_MS); // Warn on accidental tab close/reload while there's anything unsaved. $(window).on("beforeunload.wiktkuUnsaved", function (e) { if (!formDirty) return undefined; e.preventDefault(); e.returnValue = ""; return ""; }); var saveCacheBtn = new OO.ui.ButtonWidget({ label: "Li cache qeyd bike", title: "Halê vê formê yê niha (ziman, bilêvkirin û hemû beş) li cache (localStorage) qeyd bike, da ku eger rûpel bêyî xwestin were girtin an ji nû ve were barkirin, tu karibî berdewam bikî." }); saveCacheBtn.on("click", function () { saveCurrentSection(); // ObjectStorage.Set() doesn't return a success/failure value, so // the only way to detect a real failure (storage blocked, quota // exceeded, JSON.stringify choking on something unexpected) is to // catch it here rather than inspect a (nonexistent) return value. try { var snapshot = buildCacheSnapshot(); formCache.Set(snapshot); formDirty = false; updateLastSavedIndicator(snapshot.savedAt); wiktkuNotify("Halê formê li cache hate qeydkirin.", { type: "success", tag: "wiktku-cache-save" }); } catch (e) { mw.notify("Qeydkirina li cache bi ser neket.", { type: "error", tag: "wiktku-cache-save" }); } }); var clearCacheBtn = new OO.ui.ButtonWidget({ label: "Cache paqij bike", flags: [ "destructive" ], title: "Datayên qeydkirî yên vê rûpelê ji cache jê bibe (forma ku niha xuya dike naguherîne)." }); clearCacheBtn.on("click", function () { formCache.Set({}); // Cancel any autosave already scheduled from typing before this // click — left alone, it fires a few seconds later (or the // unconditional periodic autosave does, within a minute) using // the still-unblanked live form, silently re-writing the very // cache just cleared. That's why "clear cache, refresh later" // could still show the old data. Not marking the form dirty here // means autosave stays off until the person actually edits // something again, at which point it resumes normally. if (autosaveDebounceTimer) { clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = null; } formDirty = false; updateLastSavedIndicator(null); wiktkuNotify("Cache hate paqijkirin.", { type: "success", tag: "wiktku-cache-clear" }); }); // ── "⋯" overflow ───────────────────────────────────────────── // One primary action and one secondary stay on the bar; everything // else moves in here, to avoid four same-weight buttons crowding // (and wrapping to three rows on a phone). var moreBtn = $("<button type='button' class='wiktku-more-btn' title='Vebijarkên din'>⋯</button>"); var moreMenu = $("<div class='wiktku-more-menu'></div>").hide(); /** Moves an existing OOUI button into the overflow menu, keeping its * handlers — the widgets already carry the behaviour, so this is * purely about where they are shown. */ function intoMenu(btn, extraClass) { var row = $("<div class='wiktku-more-item'></div>"); if (extraClass) row.addClass(extraClass); btn.$element.on("click", function () { moreMenu.hide(); }); row.append(btn.$element); moreMenu.append(row); } intoMenu(saveCacheBtn); intoMenu(clearCacheBtn, "wiktku-more-item-danger"); moreMenu.append($("<div class='wiktku-more-sep'></div>")); moreMenu.append($("<div class='wiktku-more-item wiktku-more-note'></div>").append(lastSavedEl)); moreBtn.on("click", function (e) { e.preventDefault(); e.stopPropagation(); var open = moreMenu.is(":visible"); moreMenu.toggle(!open); if (!open) { setTimeout(function () { $(document).one("click.wiktkuMore", function () { moreMenu.hide(); }); }, 0); } }); var moreWrap = $("<span class='wiktku-more-wrap'></span>").append(moreBtn).append(moreMenu); footer.append(moreWrap); // Icon-only settings button — opens the Tercîh dialog. Plain OOUI // icon names depend on which icon-pack module happens to be loaded, // so this uses the actual Codex "settings" (color-subtle) SVG from // Commons directly, the same way the spinner above hotlinks its gif. var prefsBtn = $("<button></button>", { type: "button", "class": "wiktku-prefs-btn", title: "Tercîh — sazkariyên vê amûrê biguherîne" }); prefsBtn.on("click", function (e) { e.preventDefault(); wiktkuOpenPrefsDialog(); }); // The gear is icon-only on the bar; inside a text menu it needs a // label like everything else around it. prefsBtn.on("click", function () { moreMenu.hide(); }); moreMenu.prepend($("<div class='wiktku-more-sep'></div>")); moreMenu.prepend($("<div class='wiktku-more-item wiktku-more-item-prefs'></div>") .append(prefsBtn) .append($("<span class='wiktku-more-item-label'></span>").text("Tercîh"))); startForm.append(footer); // NOTE: deliberately NOT .hide() (display:none). WikiEditor/CodeMirror/ // the mobile editor's auto-grow logic measure #wpTextbox1's real // dimensions during their own init, which happens while the wizard is // up. A display:none ancestor reports 0 for offsetWidth/offsetHeight/ // scrollHeight, so those scripts bake in a near-zero height that never // gets recalculated later — slideDown() in destroy() only animates the // outer box, it doesn't re-trigger their sizing. Pushing #editform // off-screen instead keeps it laid out (real width/height available to // measure) without being visible, so the editbox opens at full size. $("#editform").addClass("wiktku-offscreen").before(startForm); // renderGroupTabs() looks up #wiktku-group-tabs via a live DOM // selector, so it must run after startForm is actually in the document. renderGroupTabs(); renderBesenDinPicker(); // One pass over the whole form: every select that hasn't already been // initialised, and isn't opted out with .wiktku-plain-select, gets // the searchable picker. initSelects(startForm); refresh(); // Give every draggable textarea a custom resize grip (works // consistently on Safari/iOS, unlike the native corner grip — see // the "Manual drag-to-resize handle" comment in styles.css), and // keep applying it to textareas added later on (new sense blocks, // quote-source fields, nimûne rows, …). wiktkuInitManualResize(startForm); new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { $(mutation.addedNodes).each(function () { if (this.nodeType !== 1) return; wiktkuInitManualResize(this); }); }); }).observe(startForm[0], { childList: true, subtree: true }); // Now that the full language list is loaded, silently restore any // draft the editor previously saved for this page. var cachedDraft = formCache.Get(); if (cachedDraft && cachedDraft.sections && cachedDraft.sections.length) { restoreFromCache(cachedDraft); } } // "oojs-ui.styles.icons-moderation" carries the "trash" glyph used by // makeTrashButton() below — without it the delete buttons on the Mane // and Beş tab bars would render as blank icon-less buttons. mw.loader.using(["oojs-ui-core", "oojs-ui.styles.icons-moderation"], function () { function wiktkuProceedWithData(wiktkuData) { var d = wiktkuData || {}; // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Jimar (number) code definitions — same shape as the wiki's // own Lua number-type table (code -> {cat, display[, req]}). if (d.numberLabels) $.extend(NUMBER_LABELS, d.numberLabels); // Populate lang choices (pinned list). if (d.langChoices) steps.lang.choices = choicesFromObject(d.langChoices, true); // Populate langsByCode and merge full language list from d.ziman. // d.ziman is a {code: name} object with all known languages. $.each(steps.lang.choices, function (i, choice) { if (choice.sortKey === undefined) choice.sortKey = choice.label; langsByCode[choice.code] = choice; }); if (d.ziman) { var pinnedCodes = {}; $.each(steps.lang.choices, function (i, c) { pinnedCodes[c.code] = true; }); var extraChoices = []; $.each(d.ziman, function (code, name) { if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; if (pinnedCodes[code]) return; var choice = { code: code, label: name, sortKey: name }; extraChoices.push(choice); langsByCode[code] = choice; }); extraChoices.sort(function (a, b) { return a.sortKey.localeCompare(b.sortKey, userLang); }); steps.lang.choices = steps.lang.choices.concat(extraChoices); } // Keep the full merged list around for trans/dunde/zarava — those // should still be able to reference any language even when the // Tercîh panel restricts the main "ziman" step below — then, if // the user set a restriction there, narrow steps.lang.choices // itself to just those codes. var wiktkuFullLangChoices = steps.lang.choices; if (wiktkuPrefs.langCodes && wiktkuPrefs.langCodes.length) { var wiktkuAllowedLangSet = {}; $.each(wiktkuPrefs.langCodes, function (i, code) { wiktkuAllowedLangSet[code] = true; }); var wiktkuRestrictedChoices = $.grep(wiktkuFullLangChoices, function (c) { return !!wiktkuAllowedLangSet[c.code]; }); // Fall back to the full list instead of showing an empty // dropdown if none of the saved codes matched anything // (typo'd code, data.json changed since, …). steps.lang.choices = wiktkuRestrictedChoices.length ? wiktkuRestrictedChoices : wiktkuFullLangChoices; } // Populate POS choices — also a plain {code: label} object in data.json. if (d.posChoices) steps.pos.choices = choicesFromObject(d.posChoices, false); // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the full language list // (not the possibly Tercîh-restricted steps.lang.choices). steps.trans.keys = wiktkuFullLangChoices; steps.dunde.keys = wiktkuFullLangChoices; steps.zarava.keys = getZaravaKeys(wiktkuFullLangChoices); build(); } // data.json ships inside this package module, so it is already parsed // and in memory — no action=raw round trip, and no Testing switch to // forget to flip back before deploying. wiktkuProceedWithData(require("./start/data.json")); }); }); //</nowiki> j80dh3j8furckeie9dp9d2qst21vx45 Bikarhêner:Wikihez/Gadget-test/loader.js 2 1358398 6333823 6333750 2026-08-15T15:03:28Z Wikihez 7344 6333823 javascript text/javascript // Fetches start.js/data.json/styles.css as raw text and registers them via // mw.loader.implement as a real package module, so require() in start.js // works without interface-admin rights on the test files. (function () { "use strict"; // Subpage segments are case-sensitive (MediaWiki only capitalizes the // first character of the title), so BASE must match the pages exactly. var BASE = "Bikarhêner:Wikihez/Gadget-test"; var MODULE = "ext.wiktkuTest"; // Force dataType "text" -- otherwise jQuery infers "script" from // action=raw's Content-Type and eval()s the response as a global script // before it reaches mw.loader.implement. function raw(title) { return $.get({ url: mw.util.getUrl(title, { action: "raw" }), dataType: "text" }); } $.when( raw(BASE + ".js"), raw(BASE + "/data.json"), raw(BASE + ".css"), raw(BASE + "/util.js") ).done(function (startRes, dataRes, cssRes, utilRes) { var startSrc = startRes[0]; var cssText = cssRes[0]; var utilSrc = utilRes[0]; var dataJson; try { dataJson = JSON.parse(dataRes[0]); } catch (e) { mw.notify("data.json nederbasdar e (JSON parse ket): " + e.message, { type: "error" }); return; } // JS files become function(require, module, exports); JSON files pass // through parsed. Keys must match start.js's require("./start/...") calls. mw.loader.implement( MODULE, { main: "start.js", files: { "start.js": new Function("require", "module", "exports", startSrc), "start/util.js": new Function("require", "module", "exports", utilSrc), "start/data.json": dataJson } }, { css: [cssText] } ); // Declaring oojs-ui-core/mediawiki.api here surfaces a loud failure // early instead of a silent one deep inside start.js. mw.loader.using(["oojs-ui-core", "mediawiki.api", MODULE]).then( function () { mw.notify(MODULE + " hate barkirin — require() dixebite.", { type: "success" }); }, function (err) { mw.notify("Xeta barkirinê: " + err, { type: "error" }); } ); }).fail(function () { mw.notify( "Nikarî " + BASE + "{.js,/util.js,/data.json,.css} bixwîne. " + "Kontrol bike ku her sê rûpel hene û navên wan rast in.", { type: "error" } ); }); })(); 9uz1w34y57graoh8nyfpljvkjr6tpj5 6333828 6333823 2026-08-15T15:06:41Z Wikihez 7344 6333828 javascript text/javascript // Fetches start.js/data.json/styles.css as raw text and registers them via // mw.loader.implement as a real package module, so require() in start.js // works without interface-admin rights on the test files. (function () { "use strict"; // Subpage segments are case-sensitive (MediaWiki only capitalizes the // first character of the title), so BASE must match the pages exactly. var BASE = "Bikarhêner:Wikihez/Gadget-test"; var MODULE = "ext.wiktkuTest"; // Force dataType "text" -- otherwise jQuery infers "script" from // action=raw's Content-Type and eval()s the response as a global script // before it reaches mw.loader.implement. function raw(title) { return $.get({ url: mw.util.getUrl(title, { action: "raw" }), dataType: "text" }); } $.when( raw(BASE + ".js"), raw(BASE + "/data.json"), raw(BASE + ".css"), raw(BASE + "/util.js") ).done(function (startRes, dataRes, cssRes, utilRes) { var startSrc = startRes[0]; var cssText = cssRes[0]; var utilSrc = utilRes[0]; var dataJson; try { dataJson = JSON.parse(dataRes[0]); } catch (e) { mw.notify("data.json nederbasdar e (JSON parse ket): " + e.message, { type: "error" }); return; } // JS files become function(require, module, exports); JSON files pass // through parsed. Keys must match start.js's require("./start/...") calls. mw.loader.implement( MODULE, { main: "start.js", files: { "start.js": new Function("require", "module", "exports", startSrc), "start/util.js": new Function("require", "module", "exports", utilSrc), "start/data.json": dataJson } }, { css: [cssText] } ); // Declaring oojs-ui-core/mediawiki.api here surfaces a loud failure // early instead of a silent one deep inside start.js. mw.loader.using(["oojs-ui-core", "mediawiki.api", MODULE]).then( function () { console.log(MODULE + " hate barkirin — require() dixebite."); }, function (err) { mw.notify("Xeta barkirinê: " + err, { type: "error" }); } ); }).fail(function () { mw.notify( "Nikarî " + BASE + "{.js,/util.js,/data.json,.css} bixwîne. " + "Kontrol bike ku her sê rûpel hene û navên wan rast in.", { type: "error" } ); }); })(); i1kvmmr3oyknki42a098wvx0snspd0t 6333857 6333828 2026-08-15T17:47:56Z Wikihez 7344 [[Special:PermanentLink/6333850]] 6333857 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. // implicit dependencies: StorageUtils (ObjectStorage) //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var addLangMode = mw.util.getParamValue("wiktkuaddlang") === "1"; // ── Tercîh (user settings) panel stored via mw.storage (localStorage), globally var WIKTKU_PREFS_KEY = "wiktku_start_prefs"; var WIKTKU_PREFS_DEFAULTS = { // [] = show the full language list in the "ziman" step; otherwise // only these codes are shown there (data.json codes, not names). langCodes: [], // true = never auto-open on a new/empty page — only via the // "+Ziman/beşeke din" portlet link. onlyOnClick: false, // "auto" | "p-cactions" | "p-tb" | "p-views" — where the // "+Ziman/beşeke din" portlet link is added. portlet: "auto", // true = suppress routine/informational mw.notify toasts (page // loading, cache auto-restored, cache saved/cleared, "tê şandin…"). // Errors and direct results of an explicit action (like saving // Tercîh itself) always show regardless of this setting. quiet: false }; function wiktkuLoadPrefs() { if (!(window.mw && mw.storage)) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var raw; try { raw = mw.storage.get(WIKTKU_PREFS_KEY); } catch (e) { raw = null; } if (!raw) return $.extend({}, WIKTKU_PREFS_DEFAULTS); var parsed; try { parsed = JSON.parse(raw); } catch (e) { parsed = {}; } return $.extend({}, WIKTKU_PREFS_DEFAULTS, parsed); } function wiktkuSavePrefs(prefs) { if (!(window.mw && mw.storage)) return false; try { mw.storage.set(WIKTKU_PREFS_KEY, JSON.stringify(prefs)); return true; } catch (e) { return false; } } var wiktkuPrefs = wiktkuLoadPrefs(); // Routine/informational notices go through here so "quiet mode" can // suppress them; errors and explicit-action confirmations (like the // Tercîh save toast) call mw.notify directly instead, and always show. function wiktkuNotify(message, options) { if (wiktkuPrefs.quiet) return; mw.notify(message, options); } // Lazily built the first time it's opened; reused after that (see // wiktkuOpenPrefsDialog below, defined once we know OOUI is available). var wiktkuPrefsWindowManager = null; var wiktkuPrefsDialog = null; function wiktkuOpenPrefsDialog() { mw.loader.using(["oojs-ui-core", "oojs-ui-windows"], function () { function WiktkuPrefsDialog(config) { WiktkuPrefsDialog.super.call(this, config); } if (!wiktkuPrefsDialog) { OO.inheritClass(WiktkuPrefsDialog, OO.ui.ProcessDialog); WiktkuPrefsDialog.static.name = "wiktkuPrefsDialog"; WiktkuPrefsDialog.static.title = "Tercîhên min"; WiktkuPrefsDialog.static.actions = [ { action: "save", label: "Qeyd bike", flags: ["primary", "progressive"] }, { action: "cancel", label: "Betal bike", flags: "safe" } ]; WiktkuPrefsDialog.prototype.initialize = function () { WiktkuPrefsDialog.super.prototype.initialize.call(this); this.langCodesInput = new OO.ui.TextInputWidget({ placeholder: "ku, zza, ckb (vala bihêle ji bo hemû zimanan)" }); this.onlyOnClickCheckbox = new OO.ui.CheckboxInputWidget({}); this.quietCheckbox = new OO.ui.CheckboxInputWidget({}); this.portletDropdown = new OO.ui.DropdownInputWidget({ options: [ { data: "auto", label: "Otomatîk (li gorî rûyê wîkiyê)" }, { data: "p-cactions", label: "p-cactions - Li qismê Amûran" }, { data: "left-navigation", label: "left-navigation - Li qismê Gotar-Gotûbêj" }, { data: "p-tb", label: "p-tb - Li qismê Giştî" }, { data: "p-views", label: "p-views - Li qismê Bixwîne" } ] }); var fieldset = new OO.ui.FieldsetLayout({ label: "Eyar" }); fieldset.addItems([ new OO.ui.FieldLayout(this.langCodesInput, { label: "Kodên zimanan ku tê xuyakirin li qismê \"ziman\"", align: "top", help: "Kodan bi virgulê (,) ji hev veqetîne. Vala bihêle da ku hemû ziman were nîşandan.", helpInline: true }), new OO.ui.FieldLayout(this.onlyOnClickCheckbox, { label: "Tenê veke wextê \"+Ziman/beşeke din\" were tikandin", align: "inline", help: "Eger were hilbijartin, ev amûr êdî otomatîk li ser rûpelên nû/vala dest pê nake — divê meriv her carê pêl \"+Ziman/beşeke din\" bike.", helpInline: true }), new OO.ui.FieldLayout(this.portletDropdown, { label: "Cihê lînka \"+Ziman/beşeke din\"", align: "top", help: "\"Otomatîk\" li gorî rûyê wîkiyê hildibijêre.", helpInline: true }), new OO.ui.FieldLayout(this.quietCheckbox, { label: "Moda bêdeng (kêmtir agahdarî nîşan bide)", align: "inline", help: "Agahdariyên normal nîşan nede. Xeta her tim tên xuyakirin.", helpInline: true }) ]); this.$body.addClass("wiktku-prefs-dialog-body").append(fieldset.$element); }; WiktkuPrefsDialog.prototype.getSetupProcess = function (data) { return WiktkuPrefsDialog.super.prototype.getSetupProcess.call(this, data) .next(function () { this.langCodesInput.setValue(wiktkuPrefs.langCodes.join(", ")); this.onlyOnClickCheckbox.setSelected(!!wiktkuPrefs.onlyOnClick); this.portletDropdown.setValue(wiktkuPrefs.portlet || "auto"); this.quietCheckbox.setSelected(!!wiktkuPrefs.quiet); }, this); }; WiktkuPrefsDialog.prototype.getActionProcess = function (action) { var dialog = this; if (action === "save") { return new OO.ui.Process(function () { var codes = dialog.langCodesInput.getValue() .split(/[,\s]+/) .map(function (c) { return c.trim().toLowerCase(); }) .filter(function (c) { return !!c; }); wiktkuPrefs = { langCodes: codes, onlyOnClick: dialog.onlyOnClickCheckbox.isSelected(), portlet: dialog.portletDropdown.getValue() || "auto", quiet: dialog.quietCheckbox.isSelected() }; wiktkuSavePrefs(wiktkuPrefs); mw.notify( "Tercîh hatin qeydkirin. Rûpelê ji nû ve bar bike (F5).", { type: "success", tag: "wiktku-prefs-save" } ); dialog.close({ action: "save" }); }); } if (action === "cancel") { return new OO.ui.Process(function () { dialog.close({ action: "cancel" }); }); } return WiktkuPrefsDialog.super.prototype.getActionProcess.call(this, action); }; wiktkuPrefsWindowManager = new OO.ui.WindowManager(); $(document.body).append(wiktkuPrefsWindowManager.$element); wiktkuPrefsDialog = new WiktkuPrefsDialog(); wiktkuPrefsWindowManager.addWindows([wiktkuPrefsDialog]); } wiktkuPrefsWindowManager.openWindow(wiktkuPrefsDialog); }); } var targetContainer; var skin = mw.config.get('skin'); if (wiktkuPrefs.portlet && wiktkuPrefs.portlet !== "auto") { targetContainer = wiktkuPrefs.portlet; } else if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Li vê rûpelê, ziman an jî beşeke nû zêde bike"); // If "onlyOnClick" is set, the wizard should ONLY ever open via the // "+Ziman/beşeke din" link — never automatically var wiktkuNewPageDetected = $(".mw-newarticletext, .mw-newarticletextanon").length > 0; if (wiktkuPrefs.onlyOnClick ? !addLangMode : (!addLangMode && !wiktkuNewPageDetected)) { return; } // ── Shared helpers ─────────────────────────────────────────────────── // Generic text/UI utilities live in their own package file now — see the // header of util.js for why. Aliased to bare names here so the ~400 call // sites below read exactly as they did when these were local functions. var wiktkuUtil = require("./start/util.js"); var capitalize = wiktkuUtil.capitalize; var decapitalize = wiktkuUtil.decapitalize; var escapeRegExp = wiktkuUtil.escapeRegExp; var stripWikilinks = wiktkuUtil.stripWikilinks; var splitTercimeIzah = wiktkuUtil.splitTercimeIzah; var insertAtCursor = wiktkuUtil.insertAtCursor; var foldDiacritics = wiktkuUtil.foldDiacritics; var wrapNativeSelect = wiktkuUtil.wrapNativeSelect; var initSelects = wiktkuUtil.initSelects; var wiktkuInitManualResize = wiktkuUtil.initManualResize; function langHeaderSource(codePattern) { return "\n?==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } // Trash icon (OOjs UI's "trash" glyph, simplified) shared by the Mane // sense tabs and the Beş (POS section) tabs, so deleting a tab looks // and behaves the same in both places. Kept as a <button> separate from // the tab's own click target — and given its own click handler that // stops propagation — specifically because clicking directly on a tab // switches to it; without a distinct hit-target for delete, a stray // click meant to open a sense/section would delete it instead. function makeTrashButton(title) { return $("<button type='button' class='wiktku-trash-btn'></button>") .attr("title", title) .attr("aria-label", title) .html( "<svg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'>" + "<path d='M7 3a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v1h4v2h-1.05l-.9 11.1A2 2 0 0 1 13.06 19H6.94a2 2 0 0 1-1.99-1.9L4.05 6H3V4h4V3zm2 1h2V4H9v0zM6.06 6l.88 11h6.12l.88-11H6.06zM8 8h1.5v7H8V8zm2.5 0H12v7h-1.5V8z'/>" + "</svg>" ); } function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } var catSrcTemplates = null; var catSrcTemplatesPromise = null; function fetchCatSrcTemplates() { if (catSrcTemplatesPromise) return catSrcTemplatesPromise; catSrcTemplatesPromise = new mw.Api().get({ action: "query", list: "categorymembers", cmtitle: "Kategorî:Çavkanî", cmnamespace: 10, cmlimit: "max", formatversion: 2 }).then(function (data) { var members = (data.query && data.query.categorymembers) || []; catSrcTemplates = $.map(members, function (m) { // Pêşgira navî ya "Şablon:" rake. return m.title.replace(/^[^:]+:/, ""); }); catSrcTemplates.sort(function (a, b) { return a.localeCompare(b, userLang); }); return catSrcTemplates; }, function () { catSrcTemplates = []; return catSrcTemplates; }); return catSrcTemplatesPromise; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var formCache = new ObjectStorage("wiktku_start_draft_" + mw.config.get("wgPageName"), 1); var langsByCode = {}; // Looks up the display label for a language code, falling back to the // code itself if it isn't known yet (e.g. langsByCode not loaded). function getLangLabel(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; // Converts a {code: label} object (langChoices/posChoices in data.json) // into the {code, label[, sortKey]} array the rest of the script uses. // isLang: true adds a sortKey and shows "(code)" after the label — // language choices only. function choicesFromObject(obj, isLang) { var result = []; $.each(obj || {}, function (code, label) { var choice = { code: code, label: label }; if (isLang) choice.sortKey = label; result.push(choice); }); return result; } function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c.code] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Number codes (y, s, d, p, p+, tp, j, j+, j/nj, nj, nj+, hj!, hj?) from // data.json's "numberLabels". Same {code: {cat, display[, req]}} shape as // the wiki's Lua number-type table; "display" can contain HTML (<abbr>) // or wikilinks, so it's only used as-is in wikitext output, never dropped // straight into an <option> (see stripMarkupForOption below). var NUMBER_LABELS = {}; // Distinguishes the Jimar dropdown (j= param) from the Cîns dropdown // (c= param): a code that's a key in NUMBER_LABELS is a number code, // everything else is a gender code. Compound codes like "m-p"/"n-p" are // gender+plural pairs and correctly stay on the gender side. function isNumberCode(code) { return Object.prototype.hasOwnProperty.call(NUMBER_LABELS, code); } // Strips the bit of markup "display" is allowed to contain so it's safe // to use as plain <option> text (options can't render HTML or wikilinks): // <abbr title="X">Y</abbr> -> "Y (X)", [[a|b]] -> "b", [[a]] -> "a". function stripMarkupForOption(html) { if (!html) return ""; return $.trim( String(html) .replace(/<abbr[^>]*title="([^"]*)"[^>]*>([\s\S]*?)<\/abbr>/gi, "$2 ($1)") .replace(/\[\[[^\]|]*\|([^\]]*)\]\]/g, "$1") .replace(/\[\[([^\]]*)\]\]/g, "$1") .replace(/<[^>]+>/g, "") ); } // Builds the Jimar dropdown's <option> text for one code: "j — jimarbar". function numberOptionLabel(code) { var def = NUMBER_LABELS[code]; if (!def) return code; var text = stripMarkupForOption(def.display); return text ? (code + " — " + text) : code; } // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } // ── Template explanations ──────────────────────────────────────────── // Every place a template can be picked shows the same row: a status // dot, the name, a link to the template page, and an ⓘ. This is the ⓘ. // // Text comes from the template's own TemplateData where it has any, so // the explanation stays right without anyone maintaining a second copy // by hand — with the desc already in data.json as the fallback for // templates that have none. var wiktkuTplDataCache = {}; // name -> {desc, params[]} or null when absent /** Fetches TemplateData for one template. Resolves to null if the * template has none (a plain, undocumented template — very common). */ function fetchTemplateData(name) { if (Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, name)) { return $.Deferred().resolve(wiktkuTplDataCache[name]).promise(); } return new mw.Api().get({ action: "templatedata", titles: "Şablon:" + name, redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; var first = null; $.each(pages, function (_, p) { if (!first) first = p; }); var out = null; if (first) { var desc = first.description; // TemplateData descriptions are language maps when the // template is documented in more than one language. if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(first.params || {}, function (key, p) { var label = p && p.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(p && p.required) }); }); out = { desc: desc || "", params: params }; } wiktkuTplDataCache[name] = out; return out; }, function () { // No TemplateData, or the API is unhappy — cache the miss so a // repeated ⓘ click doesn't re-request it every time. wiktkuTplDataCache[name] = null; return null; }); } /** Fetches TemplateData for many templates in one request and fills the * cache; resolves either way, a template with no TemplateData caches as null. */ function prefetchTemplateData(names) { var missing = $.grep(names || [], function (n) { return n && !Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n); }); if (!missing.length) return $.Deferred().resolve().promise(); // The API caps a titles list at 50 for normal users. missing = missing.slice(0, 50); return new mw.Api().get({ action: "templatedata", titles: $.map(missing, function (n) { return "Şablon:" + n; }).join("|"), redirects: 1, formatversion: 2 }).then(function (data) { var pages = (data && data.pages) || {}; $.each(pages, function (_, page) { if (!page || !page.title) return; var name = String(page.title).replace(/^[^:]+:/, ""); var desc = page.description; if (desc && typeof desc === "object") desc = desc[userLang] || desc.en || desc[Object.keys(desc)[0]]; var params = []; $.each(page.params || {}, function (key, prm) { var label = prm && prm.label; if (label && typeof label === "object") label = label[userLang] || label.en || label[Object.keys(label)[0]]; params.push({ name: key, label: label || "", required: !!(prm && prm.required) }); }); wiktkuTplDataCache[name] = { desc: desc || "", params: params }; }); // Anything the API didn't answer for simply has none — cache the // miss so the per-row ⓘ doesn't re-request it one at a time. $.each(missing, function (_, n) { if (!Object.prototype.hasOwnProperty.call(wiktkuTplDataCache, n)) wiktkuTplDataCache[n] = null; }); }, function () { $.each(missing, function (_, n) { wiktkuTplDataCache[n] = null; }); }); } /** Rewrites each tagged <option> in `sel` as "name — description", using * TemplateData. Only fills rows that have no description yet, so the * hand-written ones in data.json (which carry usage examples the API * does not) are left exactly as they are. */ function applyTplDescriptions(sel) { if (!sel || !sel.length) return; var changed = false; sel.find("option[data-tpl]").each(function () { var opt = $(this); var name = opt.attr("data-tpl"); if (opt.text().indexOf(" — ") !== -1) return; // already described var td = wiktkuTplDataCache[name]; var desc = (td && td.desc) || localTplDesc(name); if (!desc) return; // One line: TemplateData descriptions can run to a paragraph. desc = $.trim(String(desc).split("\n")[0]); if (desc.length > 90) desc = desc.slice(0, 90) + "…"; opt.text(name + " — " + desc); changed = true; }); // The picker caches option text for searching, so it has to re-read. if (changed) sel.trigger("wiktku:refresh"); } /** Hand-written fallback description, from data.json. * * This is the escape hatch for templates with no TemplateData on the * wiki: add a "desc" to the entry in data.json and it shows up in the * dropdown and in the ⓘ immediately, no code change. TemplateData is * still the better place — VisualEditor and every other tool reads it * too — but this keeps the picker useful in the meantime. * * Works for any pool: pronTpls, etymTpls, tplDefs, jederDefs. */ function localTplDesc(name) { var pools = [steps.pron.pronTpls, steps.etym.etymTpls, steps.dfn.tplDefs, steps.dfn.jederDefs]; var found = ""; $.each(pools, function (_, pool) { if (pool && pool[name] && pool[name].desc) { found = pool[name].desc; return false; } }); return found; } /** Opens the inline explanation panel for `name`, anchored under the * picker it was opened from. */ function showTemplateInfo(name, anchorWrap) { $(".wiktku-tpl-info").remove(); var panel = $("<div class='wiktku-tpl-info'></div>"); panel.append($("<div class='wiktku-tpl-info-name'></div>").text("{{" + name + "}}")); var body = $("<div class='wiktku-tpl-info-desc'></div>").text("Tê barkirin…"); panel.append(body); var params = $("<div class='wiktku-tpl-info-params'></div>"); panel.append(params); panel.append($("<a class='wiktku-tpl-info-link' target='_blank' rel='noopener'></a>") .attr("href", wiktkuUtil.tplPageUrl(name)) .text("Rûpela şablonê veke →")); var close = $("<button type='button' class='wiktku-tpl-info-close' title='Bigire'>✕</button>"); close.on("click", function () { panel.remove(); }); panel.prepend(close); $(anchorWrap).after(panel); fetchTemplateData(name).then(function (td) { var desc = (td && td.desc) || localTplDesc(name); body.text(desc || "Ji bo vê şablonê ravek nehatiye nivîsandin."); if (td && td.params && td.params.length) { params.append($("<div class='wiktku-tpl-info-params-title'></div>").text("Parametre:")); var listEl = $("<ul></ul>"); $.each(td.params, function (_, p) { var line = p.name + (p.label ? " — " + p.label : "") + (p.required ? " (pêwîst)" : ""); listEl.append($("<li></li>").text(line)); }); params.append(listEl); } }); } /** Marks a picker's <option>s as template rows so the searchable widget * renders them with the dot / 🔗 / ⓘ affordances, and wires the ⓘ * handler for that picker. `nameOf` maps an <option> to a template * name — the pickers store different things in value= (a snippet for * the insert dropdowns, the bare name for the sense selector). */ function markTemplateOptions(sel, nameOf) { if (!sel || !sel.length) return; var names = []; sel.find("option").each(function () { var opt = $(this); var name = nameOf(opt); if (!name) return; opt.attr("data-tpl", name); // Deprecated/typo templates are the "special cases only" ones. opt.attr("data-tpl-status", /kevnbûyî|şaşnivîs|kêmpeyda/i.test(opt.text()) ? "yellow" : "green"); names.push(name); }); sel.data("wiktkuTplInfo", showTemplateInfo); // Fill in the descriptions. Matters most for the Mane picker, whose // entries in data.json are names with no desc at all — "rastnivîs", // "ku-Latn", "guharto" on their own. One request covers every // template in the picker, cached for the per-row ⓘ as well. prefetchTemplateData(names).always(function () { applyTplDescriptions(sel); }); } /** Pulls the template name out of a snippet like "* {{ku-IPA}}" or * "{{ji|SOURCELANG|CODE|…}}". */ function tplNameFromSnippet(snippet) { var m = /\{\{\s*([^|}\n]+)/.exec(snippet || ""); return m ? $.trim(m[1]) : ""; } // True if a sense has content beyond mane worth keeping (etîket, word // lists, nimûne, jêder) — so it's still emitted with {{mane?}} if empty. function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } // A technically-"complete" entry (Ziman + Cureyê rêzimanî filled) with // nothing in Mane, Bi zaravayên din or Werger is still meaningfully // empty, so this is checked separately at submit-click time with its // own message. function hasMinRequiredContent(values) { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasMane = dfnSenses.some(function (s) { return (s.tpl && s.tplTitle) || (!s.tpl && (s.mane !== "" || senseHasExtraContent(s))); }); if (hasMane) return true; if (values.lang === "ku") { var hasWerger = false; $("#wiktku-start-trans .wiktku-trans-group").each(function () { if (steps.trans.getGroupTranslations($(this)).length) hasWerger = true; }); if (hasWerger) return true; var hasZarava = false; $("#wiktku-start-zarava .wiktku-zarava-group").each(function () { if (steps.zarava.getGroupTranslations($(this)).length) hasZarava = true; }); if (hasZarava) return true; } return false; } // Bolds the *first* occurrence of the page name function boldPageNameOnce(text) { if (!text || !pageNameRe) return text; var re = new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "i"); return text.replace(re, "'''$1'''"); } // Converts literal line breaks typed into a nimûne/jêgirtin box into // wikitext <br> tags, function nlToBr(text) { return text ? text.replace(/\r\n|\r|\n/g, "<br>") : text; } function escapeHtmlForBackdrop(str) { return String(str) .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;"); } // Mirrors a textarea's text, with a small highlighted marker placed // right after each line that's followed by an actual typed/pasted // linebreak. Rendered into a transparent backdrop layer behind the // textarea (see ensureLinebreakBackdrop()), so only the point of the // break is marked instead of the whole box. function buildLinebreakBackdropHtml(text) { var lines = text.split(/\r\n|\r|\n/); return $.map(lines, function (line, i) { var isLast = i === lines.length - 1; return escapeHtmlForBackdrop(line) + (isLast ? "" : "<mark class='wiktku-linebreak-mark'>↵</mark>\n"); }).join(""); } // Copies the metrics that affect where text wraps/lands (font, line // height, padding, border) from the real textarea onto its backdrop, // via computed style rather than shared CSS classes — most of the // box's own rules are written as "textarea.foo", which a <div> with // the same class wouldn't match. Re-run on every update in case a // responsive breakpoint changed the textarea's own font-size. function syncLinebreakBackdropMetrics(textarea, backdrop) { var cs = window.getComputedStyle(textarea[0]); backdrop.css({ "box-sizing": cs.boxSizing, "padding-top": cs.paddingTop, "padding-right": cs.paddingRight, "padding-bottom": cs.paddingBottom, "padding-left": cs.paddingLeft, "border-width": cs.borderWidth, "border-style": "solid", "font-family": cs.fontFamily, "font-size": cs.fontSize, "font-weight": cs.fontWeight, "line-height": cs.lineHeight, "letter-spacing": cs.letterSpacing }); } // Lazily wraps a textarea in its own positioning anchor (independent // of .wiktku-resize-wrap, so this doesn't depend on load order versus // wiktkuMakeManualResizable) and inserts the transparent backdrop // layer used to mark the exact point of a linebreak. Safe to call // more than once on the same textarea — the backdrop is cached. function ensureLinebreakBackdrop(textarea) { var existing = textarea.data("wiktkuLinebreakBackdrop"); if (existing) return existing; textarea.wrap("<div class='wiktku-linebreak-wrap'></div>"); var backdrop = $("<div aria-hidden='true'></div>").addClass("wiktku-linebreak-backdrop"); textarea.before(backdrop); textarea.data("wiktkuLinebreakBackdrop", backdrop); textarea.on("scroll.wiktkuLinebreak", function () { backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); }); return backdrop; } // Flags a nimûne/jêgirtin textarea (via CSS class, for the border // tint + tooltip) while it contains a typed/pasted linebreak, so the // user notices before it's silently turned into <br> on output. // Marks only the exact point of the break via a mirrored backdrop, // rather than tinting the whole box. function highlightLinebreak(el) { var textarea = $(el); var text = textarea.val(); var hasBreak = /\r|\n/.test(text); textarea .toggleClass("wiktku-has-linebreak", hasBreak) .attr("title", hasBreak ? "Xeta nû dê wek <br> bê nivîsandin" : ""); if (!hasBreak) { var cached = textarea.data("wiktkuLinebreakBackdrop"); if (cached) cached.hide(); textarea.removeClass("wiktku-has-linebreak-source"); return; } var backdrop = ensureLinebreakBackdrop(textarea); textarea.addClass("wiktku-has-linebreak-source"); syncLinebreakBackdropMetrics(textarea, backdrop); backdrop.html(buildLinebreakBackdropHtml(text)).show(); backdrop.scrollTop(textarea.scrollTop()).scrollLeft(textarea.scrollLeft()); } // Each nimûne item can be { text, tr, t }: text, transliteration, translation. function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{nimûne?|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = nlToBr(boldPageNameOnce(text)); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + nlToBr(n.tr); // Translation as third positional param (no key needed). if (n.t) tpl += "|" + nlToBr(n.t); } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 60 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } // Formats jêder (citation) entries into "#* {{jêder…|…}}" lines; skips // entries with no quote text. Falls back to the generic {{jêder}} // template when no specific template was chosen. function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; var quote = nlToBr(boldPageNameOnce(jeder.quote)); var quoteTr = nlToBr(jeder.quoteTr); var quoteT = nlToBr(jeder.quoteT); if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + quote; if (quoteTr) cite += "|tr=" + quoteTr; if (quoteT) cite += "|tercime=" + quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + quote; if (quoteTr) out += "|tr=" + quoteTr; if (quoteT) out += "|tercime=" + quoteT; // A şablon picked from Kategorî:Çavkanî is transcluded as the // source param (e.g. |{{Kovara X}}); manual text is used as-is. var srcParam = jeder.jederCatTpl ? ("{{" + jeder.jederCatTpl + "}}") : (jeder.jederManual ? jeder.jederManual : "çavkanî?"); // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } // True if a sense has at least one jêder entry with quote text. function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } // Builds "{{tplName|lang|part1|part2|…}}" from a sense field (kategori, // etiket), wrapped inline (" {{…}} ") or on its own line ("\n#: {{…}}"). function buildSenseTpl(sense, field, lang, tplName) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return call } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } // ── Inline modifier system ─────────────────────────────────────────────── // Appends a ⊕ button to a word input <li>. Clicking it shows a compact // modifier picker; selecting one prompts for the value and appends // <modifier:value> to the textarea's current content. 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îf" }, { 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: qualifier (li pêşiyê)", hint: "Wesf li pêşiya kelîmeyê" }, { key: "qq", label: "qq: qualifier (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î" } ]; // Sub-groups (inside a sense/definition block) that get the same ⊕ // modifier button as makeWordListStep fields. var MODIFIER_SUBGROUPS = { "wiktku-dfn-alternativ": true, "wiktku-dfn-hevmane": true, "wiktku-dfn-dijmane": true, "wiktku-dfn-koordine": true, "wiktku-dfn-jornav": true, "wiktku-dfn-jernav": true }; /** * Wraps a freshly-created textarea in a <li> with a ⊕ modifier button. * `ta` — the jQuery textarea element. * Returns the <li>. */ function makeModifierLi(ta) { var li = $("<li class='wiktku-word-li'></li>"); var btn = $("<button type='button' class='wiktku-mod-btn' title='Modifiyerê lê zêde bike'>⊕</button>"); var picker = $("<div class='wiktku-mod-picker'></div>").hide(); // Which modifier keys are already present in the textarea's current // text — e.g. "<t:...>" → "t" used. Each modifier can only be // applied once per word, so its pill gets disabled once used. function usedKeys() { var used = {}; var re = /<([a-zA-Z]+):/g; var val = ta.val() || ""; var m; while ((m = re.exec(val)) !== null) used[m[1]] = true; return used; } $.each(WORD_MODIFIERS, function (_, mod) { var pill = $("<button type='button' class='wiktku-mod-pill'></button>").text(mod.label); pill.attr("title", mod.hint); pill.data("mod-key", mod.key); pill.on("click", function (e) { e.preventDefault(); if (pill.prop("disabled")) return; // already used on this word picker.hide(); // Show a tiny inline input for the modifier value. var valWrap = $("<span class='wiktku-mod-val-wrap'></span>"); var valInp = $("<input type='text' class='wiktku-mod-val-input'>") .attr("placeholder", mod.hint + "…") .attr("size", 20); var confirm = $("<button type='button' class='wiktku-mod-confirm'>✓</button>"); var cancel = $("<button type='button' class='wiktku-mod-cancel'>✕</button>"); function applyModifier() { var v = $.trim(valInp.val()); if (v) { ta.val(ta.val() + "<" + mod.key + ":" + v + ">"); ta.trigger("input"); } valWrap.remove(); ta.focus(); } confirm.on("click", applyModifier); cancel.on("click", function () { valWrap.remove(); ta.focus(); }); valInp.on("keydown", function (e) { if (e.which === 13) { e.preventDefault(); applyModifier(); } if (e.which === 27) { valWrap.remove(); ta.focus(); } }); valWrap.append(valInp).append(confirm).append(cancel); li.append(valWrap); valInp.focus(); }); picker.append(pill); }); btn.on("click", function (e) { e.preventDefault(); // Close any other open pickers in the same list. li.closest("ol, ul").find(".wiktku-mod-picker").not(picker).hide(); // Grey out modifiers already used on this word — refreshed on // every open since the text (and thus what's "used") can change. var used = usedKeys(); picker.find(".wiktku-mod-pill").each(function () { var isUsed = !!used[$(this).data("mod-key")]; $(this).prop("disabled", isUsed).toggleClass("wiktku-mod-pill-used", isUsed); }); picker.toggle(); }); // Close picker when focus leaves the li entirely. li.on("focusout", function () { setTimeout(function () { if (!$.contains(li[0], document.activeElement)) picker.hide(); }, 150); }); li.append(ta).append(btn).append(picker); return li; } function makeWordListStep(id, name, question_fmt) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, modifiers: true, // Function instead of a plain string so it can name the current // language — computed fresh at build time and re-applied by // refresh() whenever the language changes. placeholder: function () { var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return "Kelîme" + (langLabel ? " bi " + langLabel : "") + "…"; }, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); var header = capitalize(name); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: {}, visible: function (values) { if (!values.lang) return false; // addLangMode: skip pron only if this lang already has a section. if (addLangMode) { // Clearing the page makes existing content irrelevant. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, // Fills the insert-dropdown from pronTpls, filtered by language. refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); // Reassures the user this field is optional — the dropdown // below writes the template for them, no syntax needed up front. wrap.append( $("<p class='wiktku-step-hint'></p>").text( "Ev qad ne mecbûrî ye. Heke tu nizanî kîjan şablonî hilbijêrî, vale bihêle — an ji pêşkêşkariya jêrîn şablonekî hilbijêre, ew ê bixweber li vir were nivîsandin." ) ); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike "); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (name, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); // Clear the picker's search box sel.trigger("wiktku:refresh"); ta.focus(); return; } // The noLang templates (ku-IPA, ku-kîte, zza-IPA, zza-kîte) // auto-generate content from a Lua module reading the page // title, so show a live preview and require confirmation // before inserting. var tplLabel = selectedOption.text(); $(this).val(""); sel.trigger("wiktku:refresh"); steps.pron.showTplPreview(stepDiv, ta, snippet, tplLabel); }); wrap.append(sel).append(ta); stepDiv.append(wrap); steps.pron.buildIpaPalette(wrap, ta); initSelects(wrap); return ta; }, // ── IPA character palette ────────────────────────────────── // Modelled on fr.wiktionary's: every character is a button that // drops itself in at the cursor. Two sub-tabs, because the full // IPA chart is ~180 symbols and roughly twenty of them ever // appear in Kurmancî — "IPA (kurdî)" opens by default and the // full chart is one click away for loanwords and other // languages. Grouped with a label down the left so it reads as // a chart rather than one long line of glyphs. IPA_KU: [ { label: "Kît/stres", chars: ["ˈ", "ˌ", "ː"] }, { label: "Bêdeng", chars: ["d͡ʒ", "t͡ʃ", "ʒ", "ʃ", "ɫ", "ŋ", "ɾ", "r", "ʋ", "ħ", "ʕ", "ɣ", "χ", "ʔ"] }, { label: "Dengdêr", chars: ["ɑː", "eː", "ɛ", "ɪ", "iː", "ɯ", "ʊ", "uː", "yː", "ø", "œ"] } ], IPA_FULL: [ { label: "Bêdeng 1", chars: ["m", "ɱ", "n", "ɳ", "ɲ", "ŋ", "ɴ", "p", "b", "t", "d", "t̪", "d̪", "ʈ", "ɖ", "c", "ɟ", "k", "ɡ", "q", "ɢ", "ʡ", "ʔ"] }, { label: "Bêdeng 2", chars: ["ɸ", "β", "f", "v", "θ", "ð", "s", "z", "ʃ", "ʒ", "ʂ", "ʐ", "ɕ", "ʑ", "ç", "ʝ", "x", "ɣ", "χ", "ʁ", "ħ", "ʕ", "h", "ɦ", "ʜ", "ʢ", "ɧ"] }, { label: "Bêdeng 3", chars: ["ʋ", "ɹ", "ɻ", "j", "ɥ", "ɰ", "ʍ", "w", "ʙ", "ⱱ", "ɾ", "ɽ", "r", "ʀ", "ɺ", "l", "ɫ", "ɬ", "ɮ", "ɭ", "ʎ", "ʟ"] }, { label: "Bêdeng 4", chars: ["ɓ", "ɗ", "ᶑ", "ʄ", "ɠ", "ʛ", "ʘ", "ǀ", "ǃ", "ǂ", "ǁ"] }, { label: "Dengdêr", chars: ["i", "y", "ɪ", "ʏ", "ɨ", "ʉ", "ɯ", "u", "ʊ", "e", "ø", "ɘ", "ɵ", "ɤ", "o", "ə", "ɚ", "ɛ", "œ", "ɜ", "ɝ", "ɞ", "ʌ", "ɔ", "æ", "ɶ", "ɐ", "a", "ɑ", "ɒ"] }, { label: "Suprasegmental", chars: ["ˈ", "ˌ", "ː", "ˑ", "ʼ", "ˀ", "ˤ", "ᵝ", "ᵊ", "ˠ", "ʰ", "ʱ", "ʲ", "ˡ", "ⁿ", "ᵑ", "ʷ", "ᶣ", "˞", "‿"] }, { label: "Dîakrîtîk", chars: ["̚", "̪", "̺", "̻", "̼", "̬", "̊", "̥", "̞", "̝", "̘", "̙", "̽", "̟", "̠", "̈", "̤", "̹", "̜", "̍", "̩", "̆", "̯", "̃", "̰", "͡", "͜"] }, { label: "Ton", chars: ["̋", "́", "̄", "̀", "̏", "̌", "̂", "˥", "˦", "˧", "˨", "˩", "ꜛ", "ꜜ", "↗", "↘", "‖"] } ], /** Builds the two-sub-tab character palette under the textarea. */ buildIpaPalette: function (wrap, ta) { if (wrap.find(".wiktku-ipa-palette").length) return; var panel = $("<div class='wiktku-ipa-panel'></div>").hide(); var toggle = $("<a href='#' class='wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tîpên bilêvkirinê</span>")); toggle.on("click", function (e) { e.preventDefault(); var open = panel.is(":visible"); panel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); wrap.append($("<div class='wiktku-adv-toggle-row'></div>").append(toggle)); // Sub-tab bar, with the two template buttons pinned right. var subTabs = $("<div class='wiktku-ipa-subtabs'></div>"); var kuTab = $("<span class='wiktku-ipa-subtab wiktku-tab-active'>IPA (kurdî)</span>"); var fullTab = $("<span class='wiktku-ipa-subtab'>IPA</span>"); subTabs.append(kuTab).append(fullTab); var tplBtns = $("<span class='wiktku-ipa-tplbtns'></span>"); $.each([ { label: "{{ku-IPA|+}}", snippet: "{{ku-IPA|}}", back: 2 }, { label: "{{IPA|+}}", snippet: "{{IPA|ku|}}", back: 2 } ], function (_, t) { var b = $("<button type='button' class='wiktku-ipa-tplbtn'></button>").text(t.label); b.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], t.snippet); // Park the cursor inside the braces, where the value goes. var pos = ta[0].selectionStart - t.back; ta[0].selectionStart = ta[0].selectionEnd = pos; ta.focus(); }); tplBtns.append(b); }); subTabs.append(tplBtns); panel.append(subTabs); function buildGrid(groups) { var grid = $("<div class='wiktku-ipa-grid'></div>"); $.each(groups, function (_, g) { var row = $("<div class='wiktku-ipa-row'></div>"); row.append($("<span class='wiktku-ipa-rowlabel'></span>").text(g.label)); var keys = $("<span class='wiktku-ipa-keys'></span>"); $.each(g.chars, function (_, ch) { var btn = $("<button type='button' class='wiktku-ipa-key'></button>"); // A combining mark on its own renders as a stray // accent floating over whatever precedes it, so // show it on a dotted circle — but insert only // the mark itself. var combining = /^[̀-ͯ҃-҉]$/.test(ch); btn.text(combining ? "◌" + ch : ch); if (combining) btn.addClass("wiktku-ipa-key-combining"); btn.attr("title", ch); btn.on("click", function (e) { e.preventDefault(); insertAtCursor(ta[0], ch); ta.focus(); }); keys.append(btn); }); row.append(keys); grid.append(row); }); return grid; } var kuGrid = buildGrid(steps.pron.IPA_KU); var fullGrid = buildGrid(steps.pron.IPA_FULL).hide(); panel.append(kuGrid).append(fullGrid); kuTab.on("click", function () { kuTab.addClass("wiktku-tab-active"); fullTab.removeClass("wiktku-tab-active"); kuGrid.show(); fullGrid.hide(); }); fullTab.on("click", function () { fullTab.addClass("wiktku-tab-active"); kuTab.removeClass("wiktku-tab-active"); fullGrid.show(); kuGrid.hide(); }); panel.addClass("wiktku-ipa-palette"); wrap.append(panel); }, /** Inline preview + confirm panel for a "noLang" (auto-content) * pronunciation template — fetches what the snippet expands to * for this page and only inserts it if the user confirms. */ showTplPreview: function (stepDiv, ta, snippet, tplLabel) { // Only one preview panel open at a time. stepDiv.find(".wiktku-pron-preview").remove(); var panel = $("<div class='wiktku-pron-preview'></div>"); panel.append($("<div class='wiktku-pron-preview-label'></div>") .text("Pêşdîtina " + tplLabel + ":")); var body = $("<div class='wiktku-pron-preview-body'></div>").text("Tê barkirin…"); panel.append(body); var actions = $("<div class='wiktku-pron-preview-actions'></div>"); var confirmBtn = $("<button type='button' class='wiktku-pron-preview-confirm'>✓ Tevlî bike</button>") .prop("disabled", true); var cancelBtn = $("<button type='button' class='wiktku-pron-preview-cancel'>✕ Betal bike</button>"); actions.append(confirmBtn).append(cancelBtn); panel.append(actions); ta.before(panel); confirmBtn.on("click", function () { insertAtCursor(ta[0], snippet); panel.remove(); ta.focus(); }); cancelBtn.on("click", function () { panel.remove(); }); // action=parse, not action=expandtemplates. expandtemplates // returns *expanded wikitext*, so the preview read as // [[IPA]]<sup>([[Wîkîferheng:IPA kurmancî|kilîd]])</sup>: // <span class="IPA">/-{kshhe}-/</span>[[Kategorî:…]] — which // is exactly what the person is trying to avoid having to // read. parse hands back the rendered HTML the page will // actually show. // // Drop the leading "* " first: it is wikitext list syntax // wrapping the template, and keeping it would render the // preview as a bulleted list rather than the line itself. new mw.Api().post({ action: "parse", title: pageName, text: snippet.replace(/^\*\s*/, ""), prop: "text", wrapoutputclass: "", disablelimitreport: 1, disableeditsection: 1, contentmodel: "wikitext", formatversion: 2 }).done(function (data) { var html = (data && data.parse && data.parse.text) || ""; if ($.trim($("<div>").html(html).text())) { body.html(html); // Category links render as nothing but still exist; // and any real link inside a preview should not // navigate away from a half-filled form. body.find("a").attr("target", "_blank").attr("rel", "noopener"); } else { body.text("(vala — ji bo vê rûpelê tiştek nehate afirandin)"); } confirmBtn.prop("disabled", false); }).fail(function () { body.text("Pêşdîtin nehate barkirin — tu dikarî hîn jî wê tevlî bikî."); confirmBtn.prop("disabled", false); }); }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line; }).join("\n"); // "===" heading under Ziman and above the POS sections; the // field is shared across sections, so it's emitted once by // getWikitext() rather than per-POS-section (would otherwise // print the pronunciation twice for a two-POS entry). return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var capitalizedPos = capitalize(pos); // "form" opt-param (checked in posparams) marks this as a // form-of/inflected entry — the section title becomes // "Formeke <pos>ê" instead of the plain pos name. The // template call itself still uses the unchanged pos name. var isForm = $("#wiktku-posparams-opt-form").is(":checked"); var header = isForm ? "\n=== Formeke " + pos + "ê ===\n" : "\n=== " + capitalizedPos + " ===\n"; // Image line (between header and template call) var imageLine = steps.resim.output(values); // Read the live wikitext from the posparams textarea. // Fall back to a plain {{pos|lang}} if the step hasn't been built yet. var tplLine = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); if (!tplLine) { tplLine = "{{" + pos + "|" + (values.lang || "") + "}}"; } return header + imageLine + tplLine + "\n"; } }, // cinsiyet (gender) — shown for navdêr/serenav only, with choices built // from metadata[lang].g since not every language has grammatical gender. cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams // Single source of truth for the selected gender code. The visible // dropdown lives inside the posparams step (see steps.posparams), // but it must always read/write THIS hidden field — not a field of // its own — since getValuesForStep("cinsiyet") reads from here. build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-cinsiyet-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // jimar (grammatical number) — same hidden-field pattern as cinsiyet // above, but writes into its own j= template parameter instead of // sharing c=. Shown for navdêr/serenav only, with choices built from // whichever of metadata[lang].g are number codes (see isNumberCode). jimar: { id: "jimar", name: "jimar", question_fmt: 'Jimara "' + pageName + '" çi ye?', question_br: true, visible: function () { return false; }, // handled inside posparams build: function (stepDiv) { var field = stepDiv.find(".wiktku-start-step-field"); if (field.length) return field; field = $("<input type='hidden'>") .addClass("wiktku-start-step-field") .attr("id", "wiktku-start-jimar-field") .val(""); stepDiv.append(field); return field; }, output: function () { return ""; } // consumed by posparams/pos.output }, // Lêker transitivity — hidden step, handled inside posparams lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function () { return false; }, choices: [ { code: "gh", label: "gerguhêz" }, { code: "x-gh", label: "xwerû-gerguhêz" }, { code: "p-gh", label: "pêkhatî-gerguhêz" }, { code: "h-gh", label: "hevedudanî-gerguhêz" }, { code: "b-gh", label: "biwêjî-gerguhêz" }, { code: "ngh", label: "negerguhêz" }, { code: "x-ngh", label: "xwerû-negerguhêz" }, { code: "p-ngh", label: "pêkhatî-negerguhêz" }, { code: "h-ngh", label: "hevedudanî-negerguhêz" }, { code: "b-ngh", label: "biwêjî-negerguhêz" } ], output: function () { return ""; } }, // tr — hidden step, handled inside posparams tr: { id: "tr", name: "transliterasyon", question_fmt: "Transliterasyona vê kelîmeyê", multiple: false, narrow: true, visible: function () { return false; } }, posparams: { id: "posparams", // Fused onto the "pos" card visually (see #wiktku-start-posparams // in styles.css) so the two read as ONE question — this name is // only a no-CSS/no-JS fallback, since the h3 that would show it // is hidden by CSS. name: "taybetmendî", // Shows what's actually being asked for: gender for nouns, verb // type for verbs, a generic fallback otherwise. question_fmt: function (values) { var pos = values.pos || ""; // Cinsiyet/Jimar fields below are self-labelled, so no title needed here. if (pos === "navdêr" || pos === "serenav") return ""; if (/^lêker/.test(pos)) return "Cureyê lêkerê"; return "Taybetmendî"; }, visible: function (values) { return !!(values.lang && values.pos); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-posparams-wrap").length) return null; var wrap = $("<div class='wiktku-posparams-wrap'></div>"); var helpers = $("<div class='wiktku-posparams-helpers'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-posparams-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-posparams-text") .attr("rows", 2); var _rebuilding = false; function safeRebuild() { if (_rebuilding) return; _rebuilding = true; steps.posparams.rebuildTa(stepDiv); _rebuilding = false; refresh(); } // Generic text-input row factory function makeTextRow(key, labelText, placeholder) { var row = $("<div class='wiktku-posparams-row'></div>") .attr("id", "wiktku-posparams-row-" + key).hide(); var inp = $("<input type='text'>") .addClass("wiktku-start-narrow wiktku-posparams-field") .attr("data-pp-key", key) .attr("placeholder", placeholder || ""); inp.on("input", safeRebuild); row.append($("<label></label>").text(labelText + ": ")).append(inp); return row; } // cinsiyet var cinsiyetRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-c'></div>") .append($("<label></label>").text("Cinsiyet: ")).hide(); var cinsiyetSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-cinsiyet-sel") .append($("<option value=''>— hilbijêre —</option>")); // Writes into the real, shared #wiktku-start-cinsiyet-field (owned by // steps.cinsiyet) rather than a field of its own — see the comment // on steps.cinsiyet.build for why that matters. cinsiyetSel.on("change", function () { $("#wiktku-start-cinsiyet-field").val($(this).val()).trigger("change"); safeRebuild(); }); cinsiyetRow.append(cinsiyetSel); // jimar (number) — second dropdown next to Cinsiyet, writes // into the shared hidden #wiktku-start-jimar-field, into its // own j= param instead of sharing c=. Options + tooltip are // built in syncHelpers once the language's number codes are known. var jimarRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-jimar'></div>") .append($("<label></label>").text("Jimar: ")).hide(); var jimarSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-jimar-sel") .append($("<option value=''>— hilbijêre —</option>")); jimarSel.on("change", function () { $("#wiktku-start-jimar-field").val($(this).val()).trigger("change"); safeRebuild(); }); jimarRow.append(jimarSel); // lektur: two plain questions (transitivity + structural form) // instead of one 10-option dropdown. Emitted code: base alone // ("gh"), or prefix + "-" + base ("x-gh"). var lekturRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lektur'></div>") .append($("<label></label>").text("Lêker derbasdar e? ")).hide(); var lekturSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lektur-sel") .append($("<option value=''>— hilbijêre —</option>")) .append($("<option value='gh'>gerguhêz (bireser digire)</option>")) .append($("<option value='ngh'>negerguhêz (bireser nagire)</option>")); lekturSel.on("change", safeRebuild); lekturRow.append(lekturSel); // Second half of the same question — the structural form. // Blank = xwerû/sade, which is the common case. var lekturFormRow = $("<div class='wiktku-posparams-row' id='wiktku-posparams-row-lekturform'></div>") .append($("<label></label>").text("Şiklê lêkerê: ")).hide(); var lekturFormSel = $("<select></select>") .addClass("wiktku-plain-select wiktku-start-narrow wiktku-posparams-lekturform-sel") .append($("<option value=''>sade (asayî)</option>")) .append($("<option value='x'>xwerû</option>")) .append($("<option value='p'>pêkhatî</option>")) .append($("<option value='h'>hevedudanî</option>")) .append($("<option value='b'>biwêjî</option>")); lekturFormSel.on("change", safeRebuild); lekturFormRow.append(lekturFormSel); helpers.append(cinsiyetRow).append(jimarRow).append(lekturRow).append(lekturFormRow); // ── Everything below here is "Tercîhên pêşketî" ────────────── // These rows live inside a collapsed panel, so the default // view of this card is two dropdowns instead of twenty-odd fields. // Transliteration is a primary field, not an advanced one, for // any language not written in Latin script: for those, an // entry without it is incomplete. syncHelpers already gates // the row on needsTransliteration(lang), so for Kurmancî and // other Latin-script languages it simply never appears. helpers.append(makeTextRow("tr", "Transliterasyon (tr)", "Transliterasyon…")); var advPanel = $("<div class='wiktku-posparams-adv-panel'></div>").hide(); advPanel .append(makeTextRow("cuda", "nîşankirina alternatîv", "cuda…")) .append(makeTextRow("ts", "Transkrîpsiyon (ts)", "Transkrîpsiyon…")) .append(makeTextRow("m", "Forma mê (m)", "Forma mê…")) .append(makeTextRow("mtr", "Translit. mê (mtr)", "Transliterasyona mê…")) .append(makeTextRow("n", "Forma nêr (n)", "Forma nêr…")) .append(makeTextRow("ntr", "Translit. nêr (ntr)", "Transliterasyona nêr…")) .append(makeTextRow("p", "Forma pirjimar (p)", "Forma pirjimar…")) .append(makeTextRow("ptr", "Translit. pirjimar", "Transliterasyona pirjimar…")) .append(makeTextRow("y", "Forma yekjimar (y)", "Forma yekjimar…")) .append(makeTextRow("ytr", "Translit. yekjimar", "Transliterasyona yekjimar…")) .append(makeTextRow("sûp", "Forma sûperlatîv (sûp)", "Forma sûperlatîv…")) .append(makeTextRow("sûptr", "Translit. sûperlatîv", "Transliterasyona sûperlatîv…")) .append(makeTextRow("komp", "Forma komparatîv (komp)", "Forma komparatîv…")) .append(makeTextRow("komptr", "Translit. komparatîv", "Transliterasyona komparatîv…")) .append(makeTextRow("gir", "Forma girdêk (gir)", "gir=…")) .append(makeTextRow("girtr", "Translit. gir", "girtr=…")) .append(makeTextRow("hûr", "Forma hûrek (hûr)", "hûr=…")) .append(makeTextRow("hûrtr", "Translit. hûr", "hûrtr=…")) .append(makeTextRow("hanja", "Forma hanja", "hanja=…")) .append(makeTextRow("hanjaTr","Translit. hanja", "hanjaTr=…")) // Lêker rehên demê (only shown when pos is lêker — see syncHelpers) .append(makeTextRow("niha", "Rehê dema niha (niha)", "Rehê dema niha…")) .append(makeTextRow("nihatr", "Translit. rehê dema niha", "Transliterasyona rehê dema niha…")) .append(makeTextRow("borî", "Rehê dema borî (borî)", "Rehê dema borî…")) .append(makeTextRow("borîtr", "Translit. rehê dema borî", "Transliterasyona rehê dema borî…")) .append(makeTextRow("subj", "Rehê dema bilanî (subj)", "Rehê dema bilanî…")) .append(makeTextRow("subjtr", "Translit. rehê dema bilanî", "Transliterasyona rehê dema bilanî…")); // Optional boolean params — nested inside the advanced panel // (they were already the most niche thing on the card). var optPanel = $("<div class='wiktku-posparams-opt-panel'></div>"); $.each([ { key: "form", label: "form — ev made forma tewandî ye" }, { key: "formaalt", label: "formaalt — vê madeyê bike forma alternatîv" }, { key: "nekatcure", label: "nekatcure — sinifa rêzimanî kategorîze neke" }, { key: "nekatcins", label: "nekatcins — kategoriya cinsiyetê neyîne" }, { key: "nekatçendterm", label: "nekatçendterm — kategoriya çend-term neyîne" }, { key: "serlînkneke", label: "serlînkneke — sernavê madeyê lînk neke" }, { key: "nekatpalîndrom", label: "nekatpalîndrom — kategoriya palîndromê neyîne" }, { key: "neformtr", label: "neformtr — transliterasyona forman neyîne" } ], function (_, p) { var cb = $("<input type='checkbox'>") .attr("id", "wiktku-posparams-opt-" + p.key).val(p.key).on("change", safeRebuild); var lbl = $("<label></label>").attr("for", "wiktku-posparams-opt-" + p.key).text(" " + p.label); optPanel.append($("<div class='wiktku-posparams-opt-row'></div>").append(cb).append(lbl)); }); advPanel.append(optPanel); var optToggle = $("<a href='#' class='wiktku-posparams-opt-toggle wiktku-adv-toggle'></a>") .attr("aria-expanded", "false") .append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")) .append($("<span class='wiktku-adv-toggle-text'>Tercîhên pêşketî</span>")); optToggle.on("click", function (e) { e.preventDefault(); var open = advPanel.is(":visible"); advPanel.toggle(!open); $(this).attr("aria-expanded", open ? "false" : "true") .toggleClass("wiktku-adv-open", !open); }); helpers.append($("<div class='wiktku-adv-toggle-row'></div>") .append(optToggle)); helpers.append(advPanel); wrap.append(helpers).append(ta); // Typing directly in textarea keeps cinsiyet/jimar hidden // fields in sync, but does NOT call refresh() — preserves // manual edits. ta.on("input", function () { var text = $(this).val(); var cMatch = text.match(/\|c=([^|}\s]+)/); $("#wiktku-start-cinsiyet-field").val(cMatch ? cMatch[1] : ""); var jMatch = text.match(/\|j=([^|}\s]+)/); $("#wiktku-start-jimar-field").val(jMatch ? jMatch[1] : ""); }); stepDiv.append(wrap); return null; }, /** Reads all helper widget values and rewrites the textarea. * Called only by safeRebuild (user interaction) — never by syncHelpers, * so manual textarea edits are never overwritten by a refresh cycle. */ rebuildTa: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; if (!pos || !lang) return; var cinsiyet = stepDiv.find(".wiktku-posparams-cinsiyet-sel").val() || ""; var jimar = stepDiv.find(".wiktku-posparams-jimar-sel").val() || ""; // Two dropdowns, one code: "gh" / "ngh" on their own, or // prefixed with the structural form ("x-gh", "b-ngh", …). var lekturBase = stepDiv.find(".wiktku-posparams-lektur-sel").val() || ""; var lekturForm = stepDiv.find(".wiktku-posparams-lekturform-sel").val() || ""; var lektur = lekturBase ? (lekturForm ? lekturForm + "-" + lekturBase : lekturBase) : ""; function v(key) { return $.trim(stepDiv.find(".wiktku-posparams-field[data-pp-key='" + key + "']").val()); } var out = "{{" + pos + "|" + lang; if (pos === "navdêr" || pos === "serenav") { out += cinsiyet ? "|c=" + cinsiyet : (lang === "ku" ? "|c=?" : ""); // Number is its own j= param, separate from c= (which // holds gender, including compounds like m-p/n-p). if (jimar) out += "|j=" + jimar; } else if (/^lêker/.test(pos) && lektur) { out += "|c=" + lektur; } if (v("cuda")) out += "|" + v("cuda"); if (v("tr")) out += "|tr=" + v("tr"); if (v("ts")) out += "|ts=" + v("ts"); $.each(["m","n","p","y"], function (_, k) { if (v(k)) out += "|" + k + "=" + v(k); if (v(k+"tr")) out += "|" + k + "tr=" + v(k+"tr"); }); if (v("sûp")) out += "|sûp=" + v("sûp"); if (v("sûptr")) out += "|sûptr=" + v("sûptr"); if (v("komp")) out += "|komp=" + v("komp"); if (v("komptr")) out += "|komptr=" + v("komptr"); if (v("gir")) out += "|gir=" + v("gir"); if (v("girtr")) out += "|girtr=" + v("girtr"); if (v("hûr")) out += "|hûr=" + v("hûr"); if (v("hûrtr")) out += "|hûrtr=" + v("hûrtr"); if (v("hanja")) out += "|hanja=" + v("hanja"); if (v("hanjaTr")) out += "|hanjaTr=" + v("hanjaTr"); if (v("niha")) out += "|niha=" + v("niha"); if (v("nihatr")) out += "|nihatr=" + v("nihatr"); if (v("borî")) out += "|borî=" + v("borî"); if (v("borîtr")) out += "|borîtr=" + v("borîtr"); if (v("subj")) out += "|subj=" + v("subj"); if (v("subjtr")) out += "|subjtr=" + v("subjtr"); stepDiv.find(".wiktku-posparams-opt-panel input:checked").each(function () { var key = $(this).val(); // "form" marks this entry as a form-of/inflected entry — it // takes "erê" rather than the plain "1" the other boolean // opt params use. out += "|" + key + "=" + (key === "form" ? "erê" : "1"); }); out += "}}"; stepDiv.find(".wiktku-posparams-text").val(out); $("#wiktku-start-cinsiyet-field").val(cinsiyet); $("#wiktku-start-jimar-field").val(jimar); }, /** Called from refresh() — controls row visibility only. * Does NOT rewrite textarea so user edits are preserved. * Rebuilds only when textarea is empty (first pos selection). */ syncHelpers: function (stepDiv) { var values = getValues(); var pos = values.pos || ""; var lang = values.lang || ""; var needsTr = needsTransliteration(lang); var isNom = pos === "navdêr" || pos === "serenav" || pos === "rengdêr"; var isAdj = pos === "rengdêr"; var isTîp = pos === "tîp"; var isJa = lang === "ja"; var isLeker = /^lêker/.test(pos); // metadata[lang].g lists gender AND number codes together — // split them here (see isNumberCode) so Cîns only ever offers // gender codes (and gender+plural compounds like m-p/n-p, // which aren't NUMBER_LABELS keys) and Jimar only offers number codes. var meta = metadata[lang]; var allCodes = (meta && meta.g) || []; var genderCodes = $.grep(allCodes, function (c) { return !isNumberCode(c); }); var jimarCodes = $.grep(allCodes, function (c) { return isNumberCode(c); }); var showC = (pos === "navdêr" || pos === "serenav") && genderCodes.length > 0; var cRow = stepDiv.find("#wiktku-posparams-row-c"); cRow.toggle(showC); if (showC) { var sel = cRow.find(".wiktku-posparams-cinsiyet-sel"); // Prefer the select's own current value (normal in-session // use); fall back to the shared hidden field, which is how // a cache/section restore communicates a saved gender // before this select has any <option>s to hold it. var prev = sel.val() || $("#wiktku-start-cinsiyet-field").val() || ""; sel.find("option[value!='']").remove(); $.each(genderCodes, function (_, code) { sel.append($("<option></option>").val(code).text(genderLabel(code))); }); if (prev) sel.val(prev); } var showJimar = (pos === "navdêr" || pos === "serenav") && jimarCodes.length > 0; var jimarRowEl = stepDiv.find("#wiktku-posparams-row-jimar"); jimarRowEl.toggle(showJimar); if (showJimar) { var jimarSelEl = jimarRowEl.find(".wiktku-posparams-jimar-sel"); var prevJimar = jimarSelEl.val() || $("#wiktku-start-jimar-field").val() || ""; jimarSelEl.find("option[value!='']").remove(); $.each(jimarCodes, function (_, code) { var def = NUMBER_LABELS[code] || {}; var opt = $("<option></option>").val(code).text(numberOptionLabel(code)); // The explanation (cat, e.g. "dualia tantum") shows as a // hover tooltip — <option> can't hold richer markup. if (def.cat) opt.attr("title", def.cat); jimarSelEl.append(opt); }); if (prevJimar) jimarSelEl.val(prevJimar); } stepDiv.find("#wiktku-posparams-row-lektur").toggle(isLeker); // Only ask for the structural form once gerguhêz/negerguhêz is answered. stepDiv.find("#wiktku-posparams-row-lekturform") .toggle(isLeker && !!stepDiv.find(".wiktku-posparams-lektur-sel").val()); stepDiv.find("#wiktku-posparams-row-tr").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-ts").toggle(needsTr); stepDiv.find("#wiktku-posparams-row-m").toggle(isNom); stepDiv.find("#wiktku-posparams-row-mtr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-n").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ntr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-p").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ptr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-y").toggle(isNom); stepDiv.find("#wiktku-posparams-row-ytr").toggle(isNom && needsTr); stepDiv.find("#wiktku-posparams-row-sûp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-sûptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-komp").toggle(isAdj); stepDiv.find("#wiktku-posparams-row-komptr").toggle(isAdj && needsTr); stepDiv.find("#wiktku-posparams-row-gir").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-girtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hûr").toggle(isTîp); stepDiv.find("#wiktku-posparams-row-hûrtr").toggle(isTîp && needsTr); stepDiv.find("#wiktku-posparams-row-hanja").toggle(isJa); stepDiv.find("#wiktku-posparams-row-hanjaTr").toggle(isJa); stepDiv.find("#wiktku-posparams-row-niha").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-nihatr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-borî").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-borîtr").toggle(isLeker && needsTr); stepDiv.find("#wiktku-posparams-row-subj").toggle(isLeker); stepDiv.find("#wiktku-posparams-row-subjtr").toggle(isLeker && needsTr); if (!$.trim(stepDiv.find(".wiktku-posparams-text").val())) { steps.posparams.rebuildTa(stepDiv); } }, output: function () { return ""; } // pos.output reads the textarea directly }, dfn: { id: "dfn", name: "Mane", // Field types that live behind "Malûmatên pêşketî". Kept as one // list so the collapse CSS, the count badge and the allGroups // adv: flags below can't drift apart. ADV_SUBGROUPS: [ "wiktku-dfn-etiket", "wiktku-dfn-kategori", "wiktku-dfn-alternativ", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ], question_fmt: function (values) { var base = "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin!"; if (values.lang === "ku") { return base + " Ji bo tercimeyan beşa 'Werger' bi kar bîne!"; } return base; }, multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, // Builds one sense block (<li>): mane textarea, nimûne list, and // sub-lists for alternatîv/hevmane/dijmane/etc. buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Tercime + Îzah boxes (non-ku alternative to the plain mane box) — // Non-ku entries get a direct translation plus a {{îzah|…}}-wrapped // gloss instead of a Kurdish-style gloss. Rather than teach every // consumer (getSenses/getOutput/linkify) a second data shape, these // boxes just write their combined text into dfnArea and re-fire its // "input" event, so dfnArea stays the single source of truth. var tercimeArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-tercime-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-tercime") .attr("rows", 2) .attr("placeholder", "Tercimeyên rasterast ên kurmancî… Ji bo school-a îngilîzî li vir 'mekteb, medrese' binivîse"); var izahArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-izah-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-dfn-subfield wiktku-dfn-izah") .attr("rows", 3) .attr("placeholder", "Îzaha kurmancî… Ji bo school-a îngilîzî li vir 'cihê tehsîlgirtinê' binivîse"); var nonKuWrap = $("<div class='wiktku-dfn-nonku-wrap'></div>") .append(tercimeArea).append(izahArea) .hide(); function syncNonKuToMane() { var t = $.trim(tercimeArea.val()); var iz = $.trim(izahArea.val()); // if tercime is blank, use îzah as definition var combined = t ? (iz ? t + " {{îzah|" + iz + "}}" : t) : iz; dfnArea.val(combined); // Re-fires onDfnInput, as if this were typed directly into // the mane textarea. dfnArea.trigger("input"); } tercimeArea.on("input", syncNonKuToMane); izahArea.on("input", syncNonKuToMane); // Switches between the plain mane box and the tercime+îzah pair — // only for non-ku entries with no tplSelect selected. function updateManeMode() { var lang = getValues().lang || ""; var isTpl = !!tplSelect.val(); if (lang && lang !== "ku" && !isTpl) { dfnArea.hide(); nonKuWrap.show(); } else { nonKuWrap.hide(); if (!isTpl) dfnArea.show(); } } // Store on the block so refresh() can re-sync every block when // lang changes, and restoreDfn() can re-sync after restoring. block.data("updateManeMode", updateManeMode); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || {}; // Cache of all non-placeholder option elements, so updateTplOptions // can detach/re-attach them without losing the full list. var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.attr("data-placeholder", "Li şablonekê bigere"); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (name, tpl) { // Shows "name — tpl.desc" when a tplDefs entry has a desc // in data.json, same pattern as steps.pron's template picker. var opt = $("<option></option>") .val(name) .text(tpl.desc ? name + " — " + tpl.desc : name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); // Same status-dot / 🔗 / ⓘ row treatment as every other // template picker. This one carries the bare name in value=, // so the name mapper is the identity rather than a snippet // parse; descriptions come from each template's TemplateData. markTemplateOptions(tplSelect, function (opt) { return opt.val(); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible // ones — native <select> won't reliably hide options any other way. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); // Options that were detached when the descriptions arrived // missed that pass, so describe whatever is attached now. // The cache is warm by this point, so this is synchronous. applyTplDescriptions(tplSelect); tplSelect.trigger("wiktku:refresh"); if (currentVal && !currentStillValid) { tplSelect.val(""); tplTitleInput.hide().val(""); updateManeMode(); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpela hedefê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // Şablon senses have no plain gloss, so hide alternatîv/hevmane/ // dijmane/etc. Etîket, Nimûne and Jêgirtin stay visible either way. function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); nonKuWrap.hide(); tplTitleInput.show().focus(); } else { tplTitleInput.hide().val(""); updateManeMode(); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); // The template picker is an alternative to writing a // definition, not a step before it — so the box comes first // and this sits under it as a quiet link. It only expands // for the minority of senses that are a pointer at another // word (guharto, şaşnivîs, kevnbûyî) rather than a meaning. var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput) .hide(); var tplLink = $("<a href='#' class='wiktku-dfn-tpl-link'></a>") .text("Ev ne pênase ye — şablonek bi kar bîne"); tplLink.on("click", function (e) { e.preventDefault(); tplRow.show(); $(this).hide(); tplRow.find("input.wiktku-ac-input").first().focus(); }); /** Opens the picker without a click — used on restore, when a * sense already has a template and hiding it would make the * chosen value invisible. */ function revealTplRow() { tplRow.show(); tplLink.hide(); } block.data("revealTplRow", revealTplRow); block.append(dfnArea); block.append(nonKuWrap); block.append(tplLink); block.append(tplRow); // Apply lang filter on initial build. updateTplOptions(); updateManeMode(); // — Sub-field groups. — // The four most-used groups (Nimûne, Jêgirtin, Hevmane, Dijmane) // stay open; the rest sit behind the "Malûmatên pêşketî" toggle // (adv: true → .wiktku-dfn-subgroup-adv, keyed off by the collapse CSS). // Jêgirtin isn't in this array — it's a compound widget built // after the loop — but it's inserted right after Nimûne so the // visible order matches the list above. var allGroups = [ { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "wekî etîket lê xuya nabe tenê kategorîze dike", noLangSuffix: true, adv: true }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê", adv: true }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in", adv: true }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e", adv: true }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e", adv: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); if (g.adv) groupDiv.addClass("wiktku-dfn-subgroup-adv"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } // The placeholder names the current language, but that's // often not chosen yet when this block is first built — // so keep a function around that refresh() (and onSubInput, // for newly-grown fields) can call again once lang is set // or changes. function subPlaceholder() { if (g.noLangSuffix) return g.label + "…"; var lang = getValues().lang || ""; var langLabel = lang ? getLangLabel(lang) : ""; return g.label + (langLabel ? " bi " + langLabel : "") + "…"; } function updateSubPlaceholders() { list.find("> li > textarea.wiktku-dfn-subfield").attr("placeholder", subPlaceholder()); } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text(g.label)) .append(": ") .append($("<span></span>").addClass("wiktku-dfn-sublabel-hint").text(g.izah)); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var useModifiers = !!MODIFIER_SUBGROUPS[g.cls]; list.data("updatePlaceholders", updateSubPlaceholders); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", subPlaceholder()); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow, useModifiers); }); list.append(useModifiers ? makeModifierLi(firstInput) : $("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder group — growing list, same structure as Nimûne. — (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel") .append($("<span></span>").addClass("wiktku-dfn-sublabel-term").text("Jêgirtin")) .append(": "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { highlightLinebreak(this); var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<textarea></textarea>") .addClass("wiktku-dfn-subfield wiktku-dfn-quote-citoid-input") .attr("rows", 1) .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi otomatîk tijî bike", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); // Fetches citation data from Citoid and fills this citation's // şablon + fields — only rebuilds fields on template change, // and never overwrites values the user already typed. function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoid.fetchJederFields(query).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only rebuild if switching şablon, so a repeat fetch // doesn't clear fields already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel wiktku-plain-select"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); srcSel.append($("<option></option>").val("__category__").text("Ji Kategorî:Çavkanî şablonekê hilbijêre")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); // Citoid is only useful before a source is chosen — // hide it once a selection is made, restore on reset. if (chosen) { citoidWrap.hide(); } else { citoidWrap.show(); return; } if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } if (chosen === "__category__") { // Search widget over the members of [[Kategorî:Çavkanî]]. // Picking a şablon here immediately switches the row to // "Bi destê xwe binivîsim" mode with {{Şablon}} pre-filled, var catWrap = $("<span></span>").addClass("wiktku-native-select-wrap wiktku-dfn-quote-src-cat"); var catInput = $("<input type='search' autocomplete='off'>") .addClass("wiktku-start-narrow wiktku-dfn-quote-src-cat-input") .attr("placeholder", "Li navê şablonê bigere…"); var catResults = $("<ul></ul>").addClass("wiktku-ac-results wiktku-dfn-quote-src-cat-results").hide(); var catStatus = $("<span></span>").addClass("wiktku-dfn-quote-src-cat-status").text("Şablon tên barkirin…"); var showCatResults = function (query) { var q = $.trim(query).toLowerCase(); catResults.empty(); var list = catSrcTemplates || []; var matched = q ? $.grep(list, function (name) { return name.toLowerCase().indexOf(q) !== -1; }) : list; if (!matched.length) { catResults.hide(); return; } $.each(matched.slice(0, 50), function (_, name) { var li = $("<li></li>").text(name).attr("data-value", name); var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; e.preventDefault(); selectCatTpl(name); }); li.on("mousedown", function (e) { e.preventDefault(); selectCatTpl(name); }); catResults.append(li); }); catResults.show(); }; // Wraps the chosen şablon as {{Name}}, drops it into the // manual textarea, and switches the row into manual mode // so the user can keep editing it (add params, etc.). var selectCatTpl = function (name) { catResults.hide(); srcSel.val("__manual__"); srcSel.trigger("change"); srcFields.find(".wiktku-dfn-quote-src-manual") .val("{{" + name + "}}") .trigger("focus"); }; catInput.on("input", function () { showCatResults($(this).val()); }); catInput.on("focus", function () { showCatResults($(this).val()); }); catInput.on("blur", function () { setTimeout(function () { catResults.hide(); }, 200); }); catWrap.append(catInput).append(catResults).append(catStatus); srcFields.append(catWrap); fetchCatSrcTemplates().then(function () { catStatus.text(""); }, function () { catStatus.text("Şablon nehatin barkirin."); }); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (key, label) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", key) .attr("placeholder", label + "…"); // "Sernav" / "Sernavê orjînal" (title fields, e.g. for // kitêb/kovar/malper) get a taller, draggable box; every // other field in the template stays as-is. Field labels // come from the on-wiki jederDefs data, so match on the // (diacritic-folded) label text rather than a fixed key. var foldedLabel = foldDiacritics(label); if (/^sernav$/.test(foldedLabel) || /orjin/.test(foldedLabel)) { inp.addClass("wiktku-dfn-quote-src-input--title"); } row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); jederGroupDiv.append(jederLbl).append(jederList); // Straight after Nimûne rather than last: Jêgirtin is the // same kind of thing (an attested use of the word) and the // two belong together — see the allGroups comment above. var nimuneGroup = block.find(".wiktku-dfn-nimune-group"); if (nimuneGroup.length) jederGroupDiv.insertAfter(nimuneGroup); else block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); // ── "Malûmatên pêşketî" — per sense, after Dijmane ─────── // One toggle per sense rather than one for the whole step: // the fields behind it (Etîket, Kategorî, Jornav…) belong to // a single meaning, so a global switch flipped them for every // sense at once and gave a count that answered "across all // senses" — not a question anybody was asking. (function () { block.addClass("wiktku-sense-adv-hidden"); var advRow = $("<div class='wiktku-adv-toggle-row wiktku-sense-adv-row'></div>"); var advToggle = $("<a href='#' class='wiktku-adv-toggle'></a>").attr("aria-expanded", "false"); var advLabel = $("<span class='wiktku-adv-toggle-text'></span>"); advToggle.append($("<span class='wiktku-adv-toggle-chevron'>▾</span>")).append(advLabel); function syncAdv() { var hidden = block.hasClass("wiktku-sense-adv-hidden"); advLabel.text(hidden ? "Malûmatên pêşketî nîşan bide" : "Malûmatên pêşketî veşêre"); advToggle.attr("aria-expanded", hidden ? "false" : "true") .toggleClass("wiktku-adv-open", !hidden); } advToggle.on("click", function (e) { e.preventDefault(); block.toggleClass("wiktku-sense-adv-hidden"); syncAdv(); }); block.data("syncSenseAdv", syncAdv); advRow.append(advToggle); // After the last always-visible group (Dijmane) and before // the advanced ones, which sit below it in DOM order. var lastPrimary = block.find(".wiktku-dfn-dijmane-group"); if (lastPrimary.length) advRow.insertAfter(lastPrimary); else block.append(advRow); syncAdv(); }()); return block; }, /** Shows only `block` among the sense list; hides every other one. */ setOpenSense: function (stepDiv, block) { stepDiv.find("li.wiktku-dfn-sense").each(function () { $(this).toggleClass("wiktku-sense-collapsed", !$(this).is(block)); }); steps.dfn.renderSenseTabs(stepDiv); }, /** Rebuilds the "Mane 1 / Mane 2 / + Mane zêde bike" tab row from the current sense list. */ renderSenseTabs: function (stepDiv) { var tabsDiv = stepDiv.find(".wiktku-dfn-sense-tabs"); if (!tabsDiv.length) return; tabsDiv.empty(); var senseCount = stepDiv.find("li.wiktku-dfn-sense").length; stepDiv.find("li.wiktku-dfn-sense").each(function (i) { var li = $(this); var tab = $("<span class='wiktku-dfn-sense-tab'></span>") .toggleClass("wiktku-tab-active", !li.hasClass("wiktku-sense-collapsed")); tab.append($("<span class='wiktku-tab-label'></span>").text("Mane " + (i + 1))); tab.on("click", function () { steps.dfn.setOpenSense(stepDiv, li); }); // Always keep at least one Mane — no delete button when // it's the only sense left. if (senseCount > 1) { var trash = makeTrashButton("Vê maneyê jê bibe"); trash.on("click", function (e) { // Stop this from also reaching the tab's own click // handler above (which would just re-open it). e.preventDefault(); e.stopPropagation(); if (!window.confirm("Tu dixwazî Mane " + (i + 1) + " jê bibî? Ev tişt nayê vegerandin.")) return; steps.dfn.removeSense(stepDiv, li); }); tab.append(trash); } tabsDiv.append(tab); }); var addBtn = $("<button type='button' class='wiktku-add-sense'></button>") .append($("<span class='wiktku-add-sense-plus'>+</span>")) .append(document.createTextNode("Mane zêde bike")); addBtn.on("click", function (e) { e.preventDefault(); steps.dfn.addSense(stepDiv); }); tabsDiv.append(addBtn); }, onDfnInput: function (stepDiv, block, textarea) { refresh(); }, /** Appends a sense, opens it, and hides the others. */ addSense: function (stepDiv) { var list = stepDiv.find("ol.wiktku-dfn-list"); var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); initSelects(newBlock); steps.dfn.setOpenSense(stepDiv, newBlock); newBlock.find("textarea.wiktku-dfn-mane").first().focus(); refresh(); return newBlock; }, /** Removes one sense block. Assumes the caller already confirmed * and already checked more than one sense remains. If the * removed sense was the open one, opens whichever sense ends up * taking its place (or the last one, if it was the last). */ removeSense: function (stepDiv, li) { var list = stepDiv.find("ol.wiktku-dfn-list"); var blocks = list.find("li.wiktku-dfn-sense"); var removedIdx = blocks.index(li); var wasOpen = !li.hasClass("wiktku-sense-collapsed"); li.remove(); if (wasOpen) { var remaining = list.find("li.wiktku-dfn-sense"); var next = remaining.eq(removedIdx); if (!next.length) next = remaining.last(); if (next.length) steps.dfn.setOpenSense(stepDiv, next); } steps.dfn.renderSenseTabs(stepDiv); refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow, modifiers) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow, modifiers); }); list.append(modifiers ? makeModifierLi(next) : $("<li></li>").append(next)); // New field starts with no placeholder — give it (and any // others in the list) the current one. var updatePlaceholders = list.data("updatePlaceholders"); if (typeof updatePlaceholders === "function") updatePlaceholders(); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: {}, posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; // One reassurance, shown once for the whole Mane step: the // "an jî şablonek hilbijêre" dropdown inside each sense is // optional — plain text is the normal path. if (!stepDiv.find(".wiktku-dfn-tpl-hint").length) { stepDiv.append( $("<p class='wiktku-step-hint wiktku-dfn-tpl-hint'></p>").text( "Ji bo her maneyekê, dropdown-a \"an jî şablonek hilbijêre\" ne mecbûrî ye — bi gelemperî tu tenê maneyê bi tîpên asayî dinivîsî. Ew şablon tenê ji bo rewşên taybet in (mînak: guherto, kevnbûyî, şaşnivîs); heke tu nizanî kîjan divê, vale bihêle." ) ); } var tabsDiv = $("<div class='wiktku-dfn-sense-tabs'></div>"); stepDiv.append(tabsDiv); var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); steps.dfn.renderSenseTabs(stepDiv); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName === "__category__") { // Reachable only if the user opened the category search but // never picked a şablon — picking one switches the row to // __manual__ (see selectCatTpl above), so there's nothing // meaningful to save here. } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: readList("wiktku-dfn-etiket"), kategori: readList("wiktku-dfn-kategori"), nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense var izahLines = []; // parallel — raw îzah gloss for that same sense // True only once some sense's *actual* dfn text (post tercime/îzah // split) is non-empty. var hasLinkableMane = false; $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("# " + (tplKatTpl ? tplKatTpl + " " : "") + (tplLabelTpl ? tplLabelTpl + " " : "") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(""); // template senses have no îzah return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty // Pull the îzah gloss (if any) out of the combined tercime+îzah // string — it's spliced back in separately below, after its // own linkify pass (see izahLines / the second linkifyText call). var izahRaw = null; var tercimeIzah = splitTercimeIzah(dfn); if (tercimeIzah) { dfn = tercimeIzah.tercime; izahRaw = stripWikilinks(tercimeIzah.izah); } if (dfn) { dfn = stripWikilinks(dfn); // Sentence-case + trailing period are for ku definitions, // which are written as full glosses. if (lang === "ku") { if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } // Real prose — this is what makes the sense worth running // through the main linkify pass. hasLinkableMane = true; } else if (izahRaw === null) { // No mane at all — this is just the "{{mane?|lang}}" // placeholder, a bare template call with no plain words // in it. Do NOT count it as linkable: sending nothing but // bracketed templates through the main linkify pass hangs // the linkify gadget (see the hasLinkableMane/hasIzah // check below). dfn = lang === "ku" ? "{{mane?|" + lang + "}}" : ""; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var out = "# " + (katTpl ? katTpl + " " : "") + (labelTpl ? labelTpl + " " : "") + dfn; var idx = defLines.length; var hasThisIzah = izahRaw !== null && $.trim(izahRaw) !== ""; // Bare {{...}} token — like {{wiktku-cite-N}}, this survives // linkify's first pass untouched (it treats template calls as // opaque), then gets swapped for {{îzah|…}} once the actual // gloss text has been linkified in its own separate pass. if (hasThisIzah) { out += (dfn ? " " : "") + "{{wiktku-izah-" + idx + "}}"; } function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); izahLines.push(hasThisIzah ? izahRaw : ""); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } // Runs text through the linkify gadget if it's loaded, otherwise // just passes it through unchanged. Shared by both linkify passes // below (main mane text, and — separately — îzah glosses). function linkifyText(t, cb) { if (typeof $.kuLinkify === "function") { $.kuLinkify(t, cb); } else { cb(t); } } var hasIzah = izahLines.some(function (t) { return t && $.trim(t) !== ""; }); var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with nimûne?. text = "# {{mane?|" + lang + "}}\n#* {{nimûne?|" + lang + "}}\n"; callback(text); return; } // Runs the îzah-only linkify pass against `base` (either the raw // text, when there's no linkable mane to run the main pass on // first, or the already-linkified main text). Shared by both // branches below so the token-splice logic only lives once. function runIzahPass(base) { var izahJoined = $.map(izahLines, function (raw, idx) { if (!raw) return undefined; return "{{wiktku-izah-open-" + idx + "}}" + raw + "{{wiktku-izah-close-" + idx + "}}"; }).join("\n"); linkifyText(izahJoined, function (izahLinked) { var izahByIdx = {}; var re = /\{\{wiktku-izah-open-(\d+)\}\}([\s\S]*?)\{\{wiktku-izah-close-\1\}\}/g; var m; while ((m = re.exec(izahLinked)) !== null) { izahByIdx[parseInt(m[1], 10)] = m[2]; } var withIzah = base.replace(/\{\{wiktku-izah-(\d+)\}\}/g, function (_, n) { var linked = izahByIdx[parseInt(n, 10)]; return linked !== undefined ? "{{îzah|" + linked + "}}" : ""; }); callback(restoreCites(withIzah)); }); } if (!hasLinkableMane) { if (!hasIzah) { // All filled senses are template senses (or otherwise have // no plain text at all) — nothing here needs linkify. callback(restoreCites(text)); return; } // There's no plain mane text anywhere (e.g. tercime left blank // with only îzah filled in), so every defLine is just a bare // template call with nothing to word-link. Sending a line // like "# {{wiktku-izah-0}}" through the main linkify pass // gives it no plain words to work with, makes the linkify // gadget hang — so skip that pass entirely and run only // the îzah pass, splicing straight into the unlinkified text. var loadIzahOnly = function () { runIzahPass(text); }; mw.loader.using("ext.gadget.linkify", loadIzahOnly, loadIzahOnly); return; } var didTryToLoad = function () { // First pass: the main definition text (mane), same as before. linkifyText(text, function (mainLinked) { if (!hasIzah) { callback(restoreCites(mainLinked)); return; } // Second pass: îzah glosses, linkified via their own // separate call. Each gloss is wrapped in its own // {{wiktku-izah-open/close-N}} pair; like the existing // {{wiktku-cite-N}} tokens, these sit inside double // braces so linkify leaves the tokens themselves alone — // only the raw gloss text between each pair gets linked. runIzahPass(mainLinked); }); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, tewandin: { id: "tewandin", name: "tewandin", question_fmt: 'Tewandina "' + pageName + '" binivîse', visible: function (values) { return values.lang && values.pos; }, build: function (stepDiv) { if (stepDiv.find(".wiktku-tewandin-wrap").length) return null; var wrap = $("<div class='wiktku-tewandin-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-tewandin-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-tewandin-text") .attr("rows", 4) .attr("placeholder", "{{ku-tewîn-nav|nêr}}"); wrap.append(ta); stepDiv.append(wrap); function autoPopulate() { if (!ta.length) return; var vals = getValues(); var c = vals.cinsiyet || ""; var p = vals.pos || ""; if (!pageName.includes(" ") && c && GENDER_BASE_LABELS[c] && (p === "navdêr" || p === "serenav") && vals.lang === "ku" && c !== "mndudil") { var label = (c === "mnmane") ? "mê û nêr" : GENDER_BASE_LABELS[c]; var out = "{{ku-tewîn-nav|" + label; if (p === "serenav") out += "|y"; out += "}}"; if (!$.trim(ta.val())) ta.val(out); } } setTimeout(function () { autoPopulate(); $("#wiktku-start-form").on("change.tewandin", "#wiktku-start-lang-field, #wiktku-start-cinsiyet-field, #wiktku-start-pos-field", autoPopulate); }, 0); return ta; }, output: function () { var manualText = $.trim($("#wiktku-start-tewandin .wiktku-tewandin-text").val()); if (manualText) { return "\n==== Tewandin ====\n" + manualText + "\n"; } return ""; } }, // resim — one or more images resim: { id: "resim", name: "resim", question_fmt: "Resmekê lê zêde bike", visible: function (values) { return !!(values.lang && values.pos); }, /** Builds one image row: filename + caption + alt text. */ buildItem: function (stepDiv) { var item = $("<li class='wiktku-resim-item'></li>"); var fileRow = $("<div class='wiktku-posparams-row'></div>"); var fileInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-file") .attr("placeholder", "navê_dosyayê.jpg"); fileRow.append($("<label></label>").text("Navê dosyayê: ")).append(fileInp); var capRow = $("<div class='wiktku-posparams-row'></div>"); var capInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-caption") .attr("placeholder", "Danasîna resimê…"); capRow.append($("<label></label>").text("Danasîn: ")).append(capInp); // Alt text: what a screen reader announces for this image var altRow = $("<div class='wiktku-posparams-row'></div>"); var altInp = $("<input type='text'>") .addClass("wiktku-start-step-field wiktku-start-narrow wiktku-resim-alt") .attr("placeholder", "Ji bo kesên nabînin, çi tê dîtin? (ne mecbûrî)"); altRow.append($("<label></label>").text("Nivîsa alternatîf: ")).append(altInp); // Auto-fill the caption with the plain page name when a filename // is typed fileInp.on("input", function () { var file = $.trim($(this).val()); var curCap = $.trim(capInp.val()); var isDefault = !curCap || curCap === pageName; if (file && isDefault) { capInp.val(pageName); } else if (!file && isDefault) { capInp.val(""); } steps.resim.onFileInput(stepDiv, item, this); }); item.append(fileRow).append(capRow).append(altRow); return item; }, /** Grows the image list when the last row's filename gets content. */ onFileInput: function (stepDiv, item, input) { var val = $.trim($(input).val()); var list = stepDiv.find("ol.wiktku-resim-list"); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { list.append(steps.resim.buildItem(stepDiv)); } }, build: function (stepDiv) { if (stepDiv.find(".wiktku-resim-wrap").length) return null; var wrap = $("<div class='wiktku-resim-wrap'></div>"); var list = $("<ol class='wiktku-resim-list'></ol>"); list.append(steps.resim.buildItem(stepDiv)); wrap.append(list); stepDiv.append(wrap); return null; }, /** Reads every filled row from the DOM into an array of {file, caption, alt} * objects — blank rows (missing filename or caption) are skipped. * Non-Kurdish captions get wrapped in {{zim|lang|…}} here, unless * the user already typed their own {{zim|…}} template. Alt text is * optional and left as plain text either way. */ getImages: function (values) { var lang = (values && values.lang) || getValues().lang || ""; var images = []; $("#wiktku-start-resim li.wiktku-resim-item").each(function () { var file = $.trim($(this).find(".wiktku-resim-file").val()); var caption = $.trim($(this).find(".wiktku-resim-caption").val()); var alt = $.trim($(this).find(".wiktku-resim-alt").val()); if (!file || !caption) return; // Strip leading "Wêne:" or "File:" if the user typed it — we add it ourselves. file = file.replace(/^(wêne|file|image)\s*:\s*/i, ""); if (lang && lang !== "ku" && !/^\{\{zim\s*\|/i.test(caption)) { caption = "{{zim|" + lang + "|" + caption + "}}"; } images.push({ file: file, caption: caption, alt: alt }); }); return images; }, output: function (values) { var images = steps.resim.getImages(values); if (!images.length) return ""; return images.map(function (img) { var altPart = img.alt ? "|alt=" + img.alt : ""; return "[[Wêne:" + img.file + "|thumb" + altPart + "|" + img.caption + "]]"; }).join("\n") + "\n"; } }, // bnr-h — {{bnr-h|Page1|Page2|…}} prepended before the lang section (shared, not per-section) bnrh: { id: "bnrh", name: "binêre herwiha (bnr-h)", question_fmt: "Şablona bnr-h li qismê herî jor a rûpelê", //visible: function (values) { return !!values.lang; }, multiple: true, narrow: true, placeholder: "Ji bo 'test' bnr 'Test', 'teşt'", output: function (values) { var pages = $.grep(values.bnrh || [], function (p) { return !!$.trim(p); }); if (!pages.length) return ""; return "{{bnr-h|" + pages.map(function (p) { return $.trim(p); }).join("|") + "}}\n"; } }, bikaranin: { id: "bikaranin", name: "Notên bikaranînê", question_fmt: "Notên bikaranînê yên li ser vê kelîmeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, output: function (values) { var text = $.trim(values.bikaranin || ""); if (!text) return ""; return "\n==== Notên bikaranînê ====\n" + text + "\n"; }, }, xwendin: { id: "xwendin", name: "Bêhtir bixwîne", question_fmt: "Lînkên derveyî eleqedarî vê madeyê", visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: function (values) { if (!values || !values.lang) { return `* {{wpedî}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; } const ziman = values.lang === "ku" ? "" : `|ziman=${values.lang}`; return `* {{wpedî${ziman}}} ji bo ku meqaleya Wîkîpediyayê lînk bidî`; }, output: function (values) { var text = $.trim(values.xwendin || ""); if (!text) return ""; return "\n==== Bêhtir bixwîne ====\n" + text + "\n"; }, }, alfabeyendin: { id: "alfabeyendin", name: "Bi alfabeyên din", question_fmt: function (values) { var base = "Nivîsîna vê kelîmeyê bi alfabeyên din" var langLabel = values.lang ? getLangLabel(values.lang) : ""; if (langLabel) { return base + " ên " + langLabel; } return base; }, visible: function (values) { return values.lang && values.pos; }, multiple: false, narrow: false, placeholder: "Ji bo kurmancî: * {{ku-ar|şiklê alfaba erebî}}", output: function (values) { var text = $.trim(values.alfabeyendin || ""); if (!text) return ""; return "\n==== Bi alfabeyên din ====\n" + text + "\n"; }, }, formalt: makeWordListStep("formalt", "formên alternatîv", "Formên alternatîv ên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), hevmane: makeWordListStep("hevmane", "hevmane", "Hevmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), dijmane: makeWordListStep("dijmane", "dijmane", "Dijmaneyên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jornav: makeWordListStep("jornav", "jornav", "Jornavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), jernav: makeWordListStep("jernav", "jêrnav", "Jêrnavên vê kelîmeyê ji bo hemû maneyan eger te li binê maneyê nenivîsandibe"), je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse"), binereherwiha: makeWordListStep("binereherwiha", "herwiha binêre", "Kelîmeyên din ên eleqedar binivîse"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: {}, visible: function (values) { return values.lang && values.pos; }, // Fills the insert-dropdown from the current etymTpls object. refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); markTemplateOptions(sel, function (opt) { return tplNameFromSnippet(opt.val()); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (name, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(ta); stepDiv.append(wrap); initSelects(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder. // Skip it only when every filled sense is a şablon sense // a completely empty entry with no şablon chosen still gets the placeholder var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasFilledTplSense = dfnSenses.some(function (s) { return !!s.tpl && !!s.tplTitle; }); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (hasFilledTplSense && !hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: function (values) { return {"navz": true, [values.lang]: true} }, // Language dropdown + growing word-input list; a new row appends // when the dropdown gets a value. Mirrors steps.trans, but flat. buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/build below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Attach the searchable picker now the select is in the DOM. initSelects(list); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", question_fmt: "'"+ pageName + "' di zaravayên din de çawa tê gotin?", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: {}, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zaravayekî bigere"); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; // A completely empty entry still gets a placeholder section // to fill in later; an individual placeholder gloss is only // skipped once some other sense already has real content. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", question_fmt: "Tercimeyên vê maneyê bi zimanên din binivîse", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide only when every sense is a filled template sense (no plain // gloss to attach translations to). A mix, or nothing filled in // yet, still shows Werger. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, // Language dropdown + growing word-input list, scoped to one gloss's // group (each gloss has its own group and row list). buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — the searchable picker is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Li zimanekî bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); // The searchable picker is attached by initSelects() once the row // is in the DOM (see onLangChange/buildGroup below). row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Attach the searchable picker now the row is in the DOM. initSelects(newRow); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }, // Builds (or fetches) the .wiktku-trans-group for one gloss. buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Attach the searchable picker now the select is in the DOM. initSelects(list); return group; }, // Syncs one .wiktku-trans-group per current gloss, keyed by // data-gloss-pos so groups stay matched across rebuilds. build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, // Reads all translation rows, grouped by gloss position. getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, // Builds the numbered "{ index, gloss }" list, one per dfn sense // with a real mane (skips template senses). index is 1-based and // matches the sense's position in the "#" definition list. // When nothing's filled in, returns one placeholder entry so // Werger still has a group to attach to; when every sense is a // filled template sense, stays empty (matches trans.visible()). glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane, but other fields are filled — still gets a // gloss group since dfn.getOutput() emits {{mane?}} for it. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // A completely empty entry (nothing filled in dfn at all, no // şablon chosen either) still gets a placeholder Werger section // to fill in later. Only // skip an individual placeholder gloss below when some other // sense actually has real content, making that particular // placeholder redundant. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it. If some other sense already has real // content, this placeholder is redundant — skip it. If the // whole entry is empty, keep it so Werger still gets a // section to fill in. if (!gloss.text && !rows.length && hasRegularMane) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || {}; var bLang = langsByCode[b[0]] || {}; return (aLang.sortKey || "").localeCompare(bLang.sortKey || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, cavkani: { id: "cavkani", name: "çavkanî", question_fmt: "Çavkaniyên din (ne jêgirtin) lê zêde bike", visible: function (values) { return !!values.pos; }, // Fills the insert-dropdown from the members of [[Kategorî:Çavkanî]]. refreshTplSelect: function () { var sel = $("#wiktku-start-cavkani .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(catSrcTemplates || [], function (_, name) { sel.append($("<option></option>").val(name).text(name)); }); markTemplateOptions(sel, function (opt) { return opt.val(); }); // Tell the picker the option list changed. sel.trigger("wiktku:refresh"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-cavkani-wrap").length) return null; var wrap = $("<div class='wiktku-cavkani-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-cavkani-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-cavkani-text") .attr("rows", 4) .attr("placeholder", "Şablonekî ji lîsteyê hilbijêre an rasterast binivîse…"); // Template insert dropdown, populated from [[Kategorî:Çavkanî]] — // options refreshed once the category members are fetched. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.attr("data-placeholder", "Şablonek lê zêde bike…"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var status = $("<span class='wiktku-cavkani-status'></span>"); sel.on("change", function () { var name = $(this).val(); if (!name) return; insertAtCursor(ta[0], "\n* {{" + name + "}}"); $(this).val(""); sel.trigger("wiktku:refresh"); ta.focus(); }); wrap.append(sel); wrap.append(status).append(ta); stepDiv.append(wrap); // build() runs again for every new beş (see the "+ Beş zêde bike" // handler), after the initial page-wide pass — so this select needs // its own init or it stays a plain, unsearchable native <select>. initSelects(wrap); if (catSrcTemplates) { steps.cavkani.refreshTplSelect(); } else { status.text("Şablon tên barkirin…"); fetchCatSrcTemplates().then(function () { steps.cavkani.refreshTplSelect(); status.text(""); }, function () { status.text("Şablon nehatin barkirin."); }); } return ta; }, output: function () { var text = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); if (!text) return ""; return "\n==== Çavkanî ====\n" + text + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); // This array only controls DOM build order — nothing else keys off it // (see the comment above stepIdToGroup). Mane tab order: Mane (senses, // with malûmatên pêşketî nested inside each, see steps.dfn.build) → // Wêne → Bi zaravayên din → Werger, so dfn/resim/zarava/trans sit // adjacent to each other in that order. var ordered_steps = [ steps.lang, steps.pos, steps.posparams, steps.cinsiyet, steps.jimar, steps.lektur, steps.tr, // Mane tab, in reading order: the senses, then the two things that // belong to the entry as a whole rather than to one sense. steps.dfn, steps.tewandin, steps.alfabeyendin, steps.zarava, steps.trans, // Etîmolojî tab. steps.etym, steps.dunde, // Eleqedar tab — three lists of the same shape. steps.je, steps.tekildar, steps.binereherwiha, // Bilêvkirin isn't part of any STEP_GROUPS tab, but still needs a // slot here because this array is what builds the DOM. steps.pron, // Beşên din, behind the picker. steps.resim, steps.bnrh, steps.bikaranin, steps.formalt, steps.hevmane, steps.dijmane, steps.jornav, steps.jernav, steps.cavkani, steps.xwendin]; // ── Step-group tabs ────────────────────────────────────────────────────── // Four tabs: "Mane" holds the senses (whose own blocks carry Nimûne, // Jêgirtin, Hevmane and Dijmane — see steps.dfn.allGroups), Tewandin, // alfabeyendin, zarava and trans; "Etîmolojî" and "Eleqedar" split out // the two other topical clusters; everything else lives behind the // "Beşên din" picker. "mane" stays first as the default-active tab // since Mane is required content. Tewandin keeps its own free-text // {{ku-tewîn-nav}} field and does NOT absorb the Cins/zayend form // parameters (m=/n=/p=), which stay on the headword template. var STEP_GROUPS = [ { id: "mane", label: "Mane", steps: ["dfn", "tewandin", "alfabeyendin", "zarava", "trans"] }, { id: "etimoloji", label: "Etîmolojî", steps: ["etym", "dunde"] }, { id: "eleqedar", label: "Eleqedar", steps: ["je", "tekildar", "binereherwiha"] }, { id: "besendin", label: "Beşên din", steps: ["resim", "formalt", "hevmane", "dijmane", "jornav", "jernav", "bikaranin", "cavkani", "xwendin", "bnrh"] }, ]; // Steps that live behind the "Beşên din" picker — only these need an // explicit "open" before they're shown, even when their tab is active. // Derived from the group above so it can't drift out of sync. var BESENDIN_STEP_IDS = STEP_GROUPS[3].steps; // Reverse lookup: step id -> index into STEP_GROUPS (undefined for // ungrouped steps — now only lang/pos/posparams/cinsiyet/lektur/tr, // which stay always-visible since they're required to get to everything // else). var stepIdToGroup = {}; $.each(STEP_GROUPS, function (gi, g) { $.each(g.steps, function (_, sid) { stepIdToGroup[sid] = gi; }); }); // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "posparams", "cinsiyet", "jimar", "lektur", "tr", "resim", "dfn", "tewandin", "formalt", "bikaranin", "alfabeyendin", "hevmane", "dijmane", "jornav", "jernav", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans", "cavkani", "xwendin" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; // ── Bilêvkirin as a standalone section ─────────────────────────────── // Pronunciation belongs to the word, not to one part of speech, so it // sits beside Navdêr/Lêker in the tab bar rather than inside any of them. // Modelled as a flag rather than an entry in `sections` since // activeSection is used as an array index in many places — viewing // Bilêvkirin leaves activeSection pointing at the POS section you were on. var viewingPron = false; // is it the tab currently on screen // Which STEP_GROUPS tab is currently shown. Lives out here (like // activeSection above) so refresh() — which is not nested inside build() // — can read it and so renderGroupTabs()/updateGroupTabIndicators() below // can be called from refresh() too. Both operate on the tab bar via its // #wiktku-group-tabs id rather than a closured element reference, for the // same reason. var activeGroup = 0; // Unsaved-changes / autosave state. Lives out here (same reason as // activeGroup above) so destroy() — which runs on final submit and on // switching to the source editor, and is not nested inside build() — // can clear the timers and the beforeunload warning. build() assigns // into these; it doesn't re-declare them. var formDirty = false; var autosaveDebounceTimer = null; var autosaveInterval = null; /** Re-renders the step-group tab bar to reflect the current activeGroup. */ function renderGroupTabs() { var groupTabsDiv = $("#wiktku-group-tabs"); if (!groupTabsDiv.length) return; groupTabsDiv.empty(); $.each(STEP_GROUPS, function (i, g) { var tab = $("<span></span>") .addClass("wiktku-group-tab") .attr("data-group-idx", i) .text(g.label) .toggleClass("wiktku-tab-active", i === activeGroup); (function (idx) { tab.on("click", function () { if (idx === activeGroup) return; activeGroup = idx; renderGroupTabs(); if (idx === BESENDIN_GROUP_IDX) renderBesenDinPicker(); refresh(); // Switching tabs can shorten the page (e.g. leaving a long // "Beşên din" field), and the browser may clamp the scroll // position on its own timing before our measurement runs. // Deferring one frame lets that settle first, so the // offsetTop read below is the final, post-refresh one. window.requestAnimationFrame(function () { var bar = document.getElementById("wiktku-group-tabs"); if (!bar) return; var form = document.getElementById("wiktku-start-form"); var stabsH = form ? (parseFloat(form.style.getPropertyValue("--wiktku-stabs-h")) || 0) : 0; var siteHeaderH = form ? (parseFloat(form.style.getPropertyValue("--wiktku-siteheader-h")) || 0) : 0; var top = bar.getBoundingClientRect().top + window.pageYOffset - stabsH - siteHeaderH; $("html, body").animate({ scrollTop: Math.max(0, top) }, 200); }); }); }(i)); groupTabsDiv.append(tab); }); } /** * Toggles a "needs attention" dot on any group tab that still has a * required, unfilled field hidden inside it — so switching tabs doesn't * leave the person wondering why "Bişîne" stays disabled. */ function updateGroupTabIndicators(values) { var tabs = $("#wiktku-group-tabs .wiktku-group-tab"); if (!tabs.length) return; $.each(STEP_GROUPS, function (i, g) { var missing = false; $.each(g.steps, function (_, sid) { var step = steps[sid]; if (!step || !step.required) return; var val = values[sid]; if (val === "" || (step.multiple && $.isArray(val) && val.join("") === "")) { missing = true; } }); tabs.eq(i).toggleClass("wiktku-tab-missing", missing && i !== activeGroup); }); } // "Beşên din" reveals one field at a time via a picker rather than // stacking them all. Per-section state, snapshotted in // saveCurrentSection() and restored in restoreSection() below, and // auto-seeded from any field that already has content (so a returning // draft doesn't hide something already filled in). var openedOtherSections = {}; var BESENDIN_SET = {}; $.each(BESENDIN_STEP_IDS, function (_, sid) { BESENDIN_SET[sid] = true; }); // "besendin"'s index in STEP_GROUPS. Derived rather than hardcoded — // this was a literal 2 and silently pointed at the wrong tab the moment // Etîmolojî and Eleqedar were inserted ahead of it. var BESENDIN_GROUP_IDX = (function () { for (var i = 0; i < STEP_GROUPS.length; i++) { if (STEP_GROUPS[i].id === "besendin") return i; } return STEP_GROUPS.length - 1; }()); /** Re-renders the "Beşên din" picker to list only the not-yet-opened sections. */ function renderBesenDinPicker() { var wrap = $("#wiktku-besendin-picker"); if (!wrap.length) return; wrap.empty(); var pickerValues = getValues(); var unopened = $.grep(BESENDIN_STEP_IDS, function (sid) { if (openedOtherSections[sid]) return false; // Don't offer a section that would open onto nothing: several of // these are gated (Bi zaravayên din / Werger need lang=ku, most // need a pos). refresh() would hide it again straight away, so // picking it would read as a broken dropdown. var step = steps[sid]; if (step && typeof step.visible === "function") { try { if (!step.visible(pickerValues)) return false; } catch (e) { /* a step whose visible() needs DOM we lack yet — offer it */ } } return true; }); if (!unopened.length) return; // everything's open — nothing left to pick var sel = $("<select class='wiktku-besendin-select'></select>"); sel.attr("data-placeholder", "— beşek hilbijêre —"); sel.append($("<option value=''>— beşek hilbijêre —</option>")); $.each(unopened, function (_, sid) { var step = steps[sid]; if (!step) return; sel.append($("<option></option>").val(sid).text(capitalize(step.name))); }); sel.on("change", function () { var sid = $(this).val(); if (!sid) return; openedOtherSections[sid] = true; // Newly opened section moves right under the picker, ahead of // whatever's already open, instead of wherever it happened to // sit in the fixed step order. $("#wiktku-start-" + sid).insertAfter(wrap); renderBesenDinPicker(); refresh(); }); wrap.append(sel); initSelects(wrap); } /** Marks any BESENDIN_STEP_IDS field that already has real content as * "opened", so restoring a draft doesn't bury filled-in sections behind * the picker. Reuses each step's own output() as the emptiness check — * it already knows what "empty" means per field, and it reads the DOM * the restore just populated. Call this AFTER the DOM has the restored * values in it. */ function seedOpenedFromContent() { var values = getValues(); $.each(BESENDIN_STEP_IDS, function (_, sid) { if (openedOtherSections[sid]) return; var step = steps[sid]; if (!step || typeof step.output !== "function") return; try { if (step.output(values)) openedOtherSections[sid] = true; } catch (e) { /* a step whose output() needs more state than we have yet — skip it */ } }); } function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } // Rebuilds the dfn DOM from a previously snapshotted senses array. function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing tab bar + list so build() recreates them cleanly. stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); // The picker is collapsed behind a link by default; a restored // sense that already uses a template has to show it, or the // chosen template is invisible and looks lost. var reveal = block.data("revealTplRow"); if (typeof reveal === "function") reveal(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // dfnArea is the only thing actually saved, so split it back into // tercime/îzah for editing (mirrors syncNonKuToMane's join format). var maneParts = splitTercimeIzah(sense.mane); block.find(".wiktku-dfn-tercime").val(maneParts ? maneParts.tercime : (sense.mane || "")); block.find(".wiktku-dfn-izah").val(maneParts ? maneParts.izah : ""); // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Same for the mane-box mode (plain vs tercime+îzah), since this // also depends on tplSelect's (and lang's) value. var updateMane = block.data("updateManeMode"); if (updateMane) updateMane(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found var useModifiers = !!MODIFIER_SUBGROUPS[cls]; // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true, useModifiers); }); subList.append(useModifiers ? makeModifierLi(ta) : $("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text).each(function () { highlightLinebreak(this); }); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder entries — accepts current array shape or a legacy // single object (older saved sections) for backwards compat. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote).each(function () { highlightLinebreak(this); }); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederCatTpl) { // Legacy format from before the şablon search switched rows to // manual mode directly — convert it the same way now, so it's // editable like any other free-form source. var catSelEl = li.find(".wiktku-dfn-quote-src-sel"); catSelEl.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val("{{" + j.jederCatTpl + "}}"); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); // Restoring a draft opens the first sense's tab by default. steps.dfn.setOpenSense(stepDiv, list.find("li.wiktku-dfn-sense").first()); } // Snapshots simple (non-dfn) per-section steps from the DOM into obj. function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } if (id === "cavkani") { snap.cavkani = $.trim($("#wiktku-start-cavkani .wiktku-cavkani-text").val()); return; } if (id === "posparams") { snap.posparams = $.trim($("#wiktku-start-posparams .wiktku-posparams-text").val()); return; } if (id === "resim") { // One entry per row, including blank ones, so a mid-edit draft // (e.g. a filename typed but no caption yet) survives a cache // restore instead of being silently dropped. snap.resim = $("#wiktku-start-resim li.wiktku-resim-item").map(function () { return { file: $.trim($(this).find(".wiktku-resim-file").val()), caption: $.trim($(this).find(".wiktku-resim-caption").val()), alt: $.trim($(this).find(".wiktku-resim-alt").val()) }; }).get(); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); // Which "Beşên din" sub-sections this section has already opened // via the picker — per-section, like everything else here. snap.openedOtherSections = $.extend({}, openedOtherSections); sections[activeSection] = snap; } // Restores a previously saved snapshot into the form DOM. function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); $("#wiktku-start-cavkani .wiktku-cavkani-text").val(snap.cavkani || ""); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); steps.posparams.build(ppDiv); var savedTa = snap.posparams || ""; ppDiv.find(".wiktku-posparams-text").val(savedTa); // Re-parse saved textarea to restore helper widget states. if (savedTa) { var cMatch = savedTa.match(/\|c=([^|}\s]+)/); var jMatch = savedTa.match(/\|j=([^|}\s]+)/); var trMatch = savedTa.match(/\|tr=([^|}\s]+)/); // Write into the shared hidden field (not the visible // select, which has no <option>s yet) — syncHelpers() // below reads it back to restore the dropdown once the // gender/number options for this language are populated. if (cMatch) $("#wiktku-start-cinsiyet-field").val(cMatch[1]); if (jMatch) $("#wiktku-start-jimar-field").val(jMatch[1]); if (trMatch) ppDiv.find(".wiktku-posparams-field[data-pp-key='tr']").val(trMatch[1]); // For lêker, c= holds the verb-type code instead of a // gender — split it back across the two dropdowns it is // now assembled from ("x-gh" → form "x" + base "gh"). if (cMatch && /^lêker/.test(snap.pos || "")) { var lekturParts = /^(?:([xphb])-)?(n?gh)$/.exec(cMatch[1]); if (lekturParts) { ppDiv.find(".wiktku-posparams-lektur-sel").val(lekturParts[2]); ppDiv.find(".wiktku-posparams-lekturform-sel").val(lekturParts[1] || ""); } } // Restore checked optional params. "form" is stored as // "erê" rather than "1" (see rebuildTa), so it needs its // own check here. ppDiv.find(".wiktku-posparams-opt-panel input[type='checkbox']").each(function () { var key = $(this).val(); var expected = key === "form" ? "erê" : "1"; $(this).prop("checked", savedTa.indexOf("|" + key + "=" + expected) !== -1); }); } steps.posparams.syncHelpers(ppDiv); return; } if (id === "resim") { var resimDiv = $("#wiktku-start-resim"); resimDiv.find(".wiktku-resim-wrap").remove(); steps.resim.build(resimDiv); // Accept both the new array-of-rows format and the older // single {file, caption} object saved before multi-image // support existed. var resimSnap = snap.resim; var rows = $.isArray(resimSnap) ? resimSnap : (resimSnap ? [resimSnap] : []); if (rows.length) { var list = resimDiv.find("ol.wiktku-resim-list"); list.empty(); $.each(rows, function (_, r) { var item = steps.resim.buildItem(resimDiv); item.find(".wiktku-resim-file").val(r.file || ""); item.find(".wiktku-resim-caption").val(r.caption || ""); item.find(".wiktku-resim-alt").val(r.alt || ""); list.append(item); }); // Always keep a blank trailing row, same as Nimûne/Dûnde. var lastItem = list.children("li.wiktku-resim-item").last(); if ($.trim(lastItem.find(".wiktku-resim-file").val())) { list.append(steps.resim.buildItem(resimDiv)); } } return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Tell the pickers about the programmatic value change. fields.filter("select").trigger("wiktku:refresh"); }); // Restore which "Beşên din" sub-sections were already opened for // this section, then seed in anything the DOM restore above just // filled in but that wasn't marked opened yet. openedOtherSections = $.extend({}, snap.openedOtherSections || {}); seedOpenedFromContent(); renderBesenDinPicker(); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); // Bilêvkirin is NOT emitted here — it is one shared field for the // whole word, so emitting it per section duplicated it. getWikitext() // prints it once, above the POS sections. steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.tewandin.output(values); entry += steps.bikaranin.output(values); entry += steps.alfabeyendin.output(values); entry += steps.formalt.output(values); entry += steps.hevmane.output(values); entry += steps.dijmane.output(values); entry += steps.jornav.output(values); entry += steps.jernav.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); entry += steps.cavkani.output(values); entry += steps.xwendin.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { // Each hop through here can be reached asynchronously: the dfn // step waits on mw.loader.using("ext.gadget.linkify") before // calling back, so from that point on the submit handler's own // try/catch is no longer on the stack. Guard every hop instead, // or a throw after linkify loads vanishes into an unhandled // rejection and the form just sits there looking busy. try { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } catch (e) { if (typeof onSubmitError === "function") onSubmitError(e); else throw e; } } processSection(0); } // Assembles wikitext for all sections plus the shared lang header. function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var bnrh = steps.bnrh.output(sharedValues); var entry = steps.lang.output(sharedValues); // One pronunciation per word, printed once between the language // header and the POS sections — see steps.pron.output. entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // bnr-h goes before the language section — only prepended when // generating fresh wikitext (not addLangMode, which handles it separately). if (!addLangMode && bnrh) entry = bnrh + entry; // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { if (s.mane) return s.mane; // Template sense (e.g. {{guharto|ku|somepage}}) — same // construction as the tplCall built in getOutput, so the // summary shows what actually gets written to the entry // instead of going blank. if (s.tpl && s.tplTitle) { return s.tplNoLang ? "{{" + s.tpl + "|" + s.tplTitle + "}}" : "{{" + s.tpl + "|" + sharedValues.lang + "|" + s.tplTitle + "}}"; } return ""; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; // Set by build() to its submitFailed(). Lives out here because the // wikitext-assembly functions below are outside build()'s closure but // still need a way to report a failure to the person rather than dying // silently in the console. var onSubmitError = null; // Whether Mane/Bi zaravayên din/Werger has anything in it — kept // outside refresh() so the click handler can read the latest value. var wiktkuContentGateOk = true; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues, placeholderText) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>").text(placeholderText || "")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice.label); if (choice.sortKey !== undefined) { // This is a language choice {code, label, sortKey} — show code. displayText = capitalize(choice.label) + " (" + choice.code + ")"; } var option = $(mw.html.element("option", { value: choice.code }, displayText)); if (disabledValues[choice.code]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } // Keys to disable for a key menu: already-taken or explicitly disabled. function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); populateMenus(input, step.keys, getDisabledKeys(step)); // Keep the key menus mutually exclusive: whatever one row selects is // disabled in every other row. Recomputed from the DOM on each change. input.on("change", function () { var all = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield"); var taken = {}; all.each(function () { var v = $(this).val(); if (v) taken[v] = true; }); all.not(this).each(function () { var self = $(this), own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (code) $(this).prop("disabled", !!taken[code] && code !== own); }); self.trigger("wiktku:refresh"); }); }); // Return the wrapper; the select lives inside it and still fires change. return wrapNativeSelect(input); } // Adds another text field to the list if the last one now has text. function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); if (step.placeholder) { nextInput.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = step.modifiers ? makeModifierLi(nextInput).prepend(nextKeyInput || "") : $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) initSelects(nextItem); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } // Shows/hides steps based on whether their prerequisites are met, and // updates placeholders where applicable. function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); steps.cavkani.refreshTplSelect(); // Re-render any step's question label that depends on current values // (e.g. dfn's Werger-section reminder, which only applies to ku). $.each(steps, function (stepId, step) { if (typeof step.question_fmt === "function") { $("#wiktku-start-" + stepId + " .wiktku-start-step-question") .text(step.question_fmt(values)); } }); // Sync every sense block's mane-box mode (plain mane vs tercime+îzah) // to the current language, in case lang changes after blocks exist. $("#wiktku-start-dfn li.wiktku-dfn-sense").each(function () { var updateMane = $(this).data("updateManeMode"); if (updateMane) updateMane(); }); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transliterasyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Re-sync the "<label> bi <ziman>…" placeholder on every always-visible // sub-field list (etîket, kategorî, hevmane, …), since the language may // not have been chosen yet when these lists were first built, or may // have changed since. $("#wiktku-start-dfn .wiktku-dfn-sublist").each(function () { var upd = $(this).data("updatePlaceholders"); if (typeof upd === "function") upd(); }); // Same idea for word-list steps (jê, têkildar, binêre herwiha, …) // whose placeholder is a function of the current language. $.each(steps, function (stepId, step) { if (typeof step.placeholder === "function") { $("#wiktku-start-" + stepId + " textarea.wiktku-start-step-field") .attr("placeholder", step.placeholder()); } }); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // Insert after the quote textarea's resize-wrap (if the manual // resize handle has already been attached to it), not after the // bare textarea -- otherwise this lands *inside* that wrap, // between the textarea and its own grip, breaking jêgirtin's // handle and nesting the tr/t boxes inside it. var quoteTa = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap = quoteTa.closest(".wiktku-resize-wrap"); (quoteResizeWrap.length ? quoteResizeWrap : quoteTa).after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transliterasyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); // See the tr-field branch above for why this targets the // resize-wrap instead of the bare textarea. var quoteTa2 = li.find(".wiktku-dfn-nimune-quote"); var quoteResizeWrap2 = quoteTa2.closest(".wiktku-resize-wrap"); (quoteResizeWrap2.length ? quoteResizeWrap2 : quoteTa2).after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { var groupIdx = stepIdToGroup[stepId]; var hiddenByTab = (groupIdx !== undefined && groupIdx !== activeGroup) || // Beşên din picker: stays hidden even while its tab is // active until explicitly opened from the dropdown. (BESENDIN_SET[stepId] && !openedOtherSections[stepId]); // Bilêvkirin is its own section now, so the two views are // mutually exclusive: on it, only pron shows (plus Ziman, which // is shared and stays above every section); off it, pron is // hidden no matter which tab is active. pron is deliberately // ungrouped — stepIdToGroup has no entry for it — so without // this branch it would show on all four tabs at once. if (stepId === "pron") { hiddenByTab = hiddenByTab || !viewingPron; } else if (viewingPron && stepId !== "lang") { hiddenByTab = true; } if (hiddenByTab || (typeof(step.visible) === "function" && !step.visible(values))) { $("#wiktku-start-" + stepId).hide(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } // After build, sync the posparams helper widgets whenever pos or lang changes. if (step.id === "posparams" && typeof step.syncHelpers === "function") { step.syncHelpers(stepDiv); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } stepDiv.slideDown(); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); // The four content tabs belong to a POS section — Bilêvkirin has no // sub-tabs of its own, so the bar goes away while it's on screen. $("#wiktku-group-tabs").toggle(!!values.pos && !viewingPron); var besenDinActive = activeGroup === BESENDIN_GROUP_IDX && !viewingPron; $("#wiktku-besendin-picker").toggle(besenDinActive); // The option list is filtered by each step's visible(), which depends // on lang/pos — so it has to be rebuilt when those change, not just // when a section is opened. Safe to call from here: rendering the // picker doesn't itself call refresh(), only picking an option does. if (besenDinActive) renderBesenDinPicker(); updateGroupTabIndicators(values); continueBtn.setDisabled(!canContinue); // Soft gate: stays a real, clickable OOUI button — a hard // setDisabled(true) here would swallow the click entirely, leaving // no way to tell the person why nothing happened. The CSS-only // "looks disabled" class lets the click handler still run and show // wiktkuNotify's explanation. wiktkuContentGateOk = !canContinue || hasMinRequiredContent(values); continueBtn.$element.toggleClass("wiktku-btn-soft-disabled", !wiktkuContentGateOk); } function destroy() { if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); if (autosaveInterval) clearInterval(autosaveInterval); formDirty = false; $(window).off("beforeunload.wiktkuUnsaved"); $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard").slideDown(); // #editform was kept laid-out but off-screen (see build()) instead of // display:none, precisely so the editor never had to size itself // against a zero-width/height box. Just bring it back on-screen — // no slideDown needed since it was never actually collapsed. $("#editform").removeClass("wiktku-offscreen"); // Belt-and-braces: if WikiEditor/CodeMirror/mobile's auto-grow still // cached a stale size from some earlier point, nudge them to // recalculate now that the box is genuinely visible. $(window).trigger("resize"); if (window.CodeMirror) { var cm = $("#wpTextbox1").data("CodeMirror") || $("#wpTextbox1").data("cmInstance"); if (cm && typeof cm.refresh === "function") cm.refresh(); } $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and navz. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; // Inserts a new "== {{ziman|code}} ==" section at the correct sorted // position: navz, then ku/hac/sdh/lki/ckb/zza, then alphabetical by name. function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections — just write the new section. // Add \n\n only when there is real non-whitespace content above. var trimmed = existing.replace(/\s+$/, ""); return trimmed ? trimmed + "\n\n" + wikitext : wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // (?![\s\S]) matches only true end-of-string, since a bare "$" with // /m would stop at the section's first line break instead. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry.label : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections, each separated by exactly \n\n. // Trim trailing whitespace off each section's content first so we // control the spacing precisely. var joined = sections.map(function (s) { return s.content.replace(/\s+$/, ""); }).join("\n\n"); // Only add a separator after the preamble when it has real content. var preambleTrimmed = preamble.replace(/\s+$/, ""); var prefix = preambleTrimmed ? preambleTrimmed + "\n\n" : ""; return prefix + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê zimanekî nû li rûpelê îlawe bikî. Eger ev ziman jixwe hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bike, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Muhtewaya rûpelê paqij bike (her tiştî jê bibe û rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); // Tab bar for switching between step-groups (topics) within a section. // renderGroupTabs()/updateGroupTabIndicators() (which populate and // maintain it) live outside build() — see near "var activeSection". var groupTabsDiv = $("<div id='wiktku-group-tabs'></div>"); // Both tab bars are sticky (CSS). group-tabs' sticky "top" has to sit // right below section-tabs' actual rendered height, which isn't a // fixed number since the bar can wrap onto a second line. Measured // here and published as a CSS custom property the stylesheet reads // back; recomputed on content changes and window resize. // // Vector 2022 has its own sticky header (.vector-sticky-header) that // pins to the real top:0 once you scroll past the page title, which // would otherwise sit directly behind (and hide) our section-tabs. // Fixed by measuring how much of the viewport Vector's header // currently occupies and offsetting both our bars below it, via // --wiktku-siteheader-h. Vector's header slides in/out with scroll // position, so this is re-measured on scroll too, not just resize. function siteHeaderOffset() { var el = document.querySelector(".vector-sticky-header"); if (!el) return 0; var rect = el.getBoundingClientRect(); // Present in the DOM at all times on Vector 2022, but only // actually occupying screen space once scrolled into place — // before that it sits translated above the viewport (negative/ // zero rect), which must not add a phantom gap under our bars. if (rect.bottom <= 0 || rect.top > 4) return 0; return Math.max(0, rect.bottom); } var stickyOffsetQueued = false; function syncStickyTabsOffset() { var h = sectionTabsDiv.is(":visible") ? (sectionTabsDiv.outerHeight() || 0) : 0; startForm.css("--wiktku-stabs-h", h + "px"); startForm.css("--wiktku-siteheader-h", siteHeaderOffset() + "px"); } function queueStickyTabsOffsetSync() { if (stickyOffsetQueued) return; stickyOffsetQueued = true; window.requestAnimationFrame(function () { stickyOffsetQueued = false; syncStickyTabsOffset(); }); } $(window).on("resize.wiktkuStickyTabs scroll.wiktkuStickyTabs", queueStickyTabsOffsetSync); // "Beşên din" picker — sits right under the group tab bar, only // shown while that tab is active (toggled in refresh(), see // BESENDIN_GROUP_IDX); renderBesenDinPicker() fills it. var besenDinPickerDiv = $("<div id='wiktku-besendin-picker' class='wiktku-besendin-picker'></div>"); /** Puts the form back in a usable state after a failed submit and * says what happened. Without this the button stays disabled and * the spinner spins forever on any exception — the person is left * staring at a form that looks busy but is dead, with the reason * visible only in the browser console. */ function submitFailed(err) { spinner.hide(); continueBtn.setDisabled(false); continueBtn.$element.removeClass("wiktku-btn-sending"); var detail = (err && (err.message || err.toString())) || "sedem nediyar"; mw.notify( "Şandin bi ser neket: " + detail + " — tiştê ku te nivîsî winda nebûye. Heke ev dubare bibe, " + "bi 'Edîtora çavkaniyê veke' berdewam bike.", { type: "error", tag: "wiktku-submit", autoHide: false } ); // Deliberately console.error as well: the notification is for the // person, this is for whoever they report the bug to. if (window.console && console.error) console.error("[wiktku] submit failed", err); } onSubmitError = submitFailed; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); continueBtn.$element.addClass("wiktku-btn-sending"); spinner.show(); try { getWikitext(function (wikitext) { try { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page — write fresh content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // ── bnr-h merge ────────────────────────────────────────── // If the user filled bnr-h inputs, either merge into the // existing {{bnr-h|…}} call or prepend a new one. var bnrhOut = steps.bnrh.output(getValues()); if (bnrhOut) { var newPages = bnrhOut.replace(/^\{\{bnr-h\|/, "").replace(/\}\}\n?$/, "").split("|"); var bnrhRe = /\{\{bnr-h\|([^}]*)\}\}/i; if (bnrhRe.test(existing)) { existing = existing.replace(bnrhRe, function (_, inner) { var existingPages = inner.split("|").map(function (p) { return p.trim(); }); $.each(newPages, function (_, p) { p = p.trim(); if (p && existingPages.indexOf(p) === -1) existingPages.push(p); }); return "{{bnr-h|" + existingPages.join("|") + "}}"; }); } else { existing = bnrhOut + existing; } } // If this language's section already exists (whitespace // differences aside), merge into it; otherwise insert new. var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); } catch (e) { // Thrown while writing the result into #wpTextbox1. submitFailed(e); } }); } catch (e) { // Catches anything thrown synchronously inside getWikitext. submitFailed(e); } }); // Tracks whether groupTabsDiv has been inserted yet. var groupTabsInserted = false; $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); var nameH3 = $("<h3></h3>").addClass("wiktku-start-step-name"); var nameLabel = $("<label></label>") .attr("for", "wiktku-start-" + step.id + "-field") .text(name); nameH3.append(nameLabel); stepDiv.append(nameH3); if (step.question_fmt) { // question_fmt can be a plain string, or a function of the // current values (used by steps whose question text depends // on e.g. the chosen language) — refresh() keeps it in sync // afterwards via the .wiktku-start-step-question class. var questionText = typeof step.question_fmt === "function" ? step.question_fmt(getValues()) : step.question_fmt; stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, questionText))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); // initSelects() runs over the whole form once it is in the DOM. stepDiv.append(input); } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.placeholder) { input.attr("placeholder", typeof step.placeholder === "function" ? step.placeholder() : step.placeholder); } if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append(step.modifiers ? makeModifierLi(input) : $("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Section tabs (switch between POS sections) sit above the // per-section fields, starting at "pos". if (step.id === "pos") { startForm.append(sectionTabsDiv); } // Step-group tabs sit just before the first grouped step in // ordered_steps. Derived from stepIdToGroup so this keeps // working no matter how STEP_GROUPS/ordered_steps get reordered. if (!groupTabsInserted && stepIdToGroup[step.id] !== undefined) { startForm.append(groupTabsDiv); startForm.append(besenDinPickerDiv); groupTabsInserted = true; } startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); /** Adds a new, empty POS section and switches to it. */ function addPosSection() { saveCurrentSection(); viewingPron = false; sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find(".wiktku-dfn-sense-tabs").remove(); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "cavkani") { $("#wiktku-start-cavkani .wiktku-cavkani-wrap").remove(); steps.cavkani.build($("#wiktku-start-cavkani")); return; } if (id === "posparams") { var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-wrap").remove(); return; } if (id === "resim") { $("#wiktku-start-resim .wiktku-resim-wrap").remove(); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); stepDiv.find("select.wiktku-start-step-field").trigger("wiktku:refresh"); }); // Fresh section — no "Beşên din" sub-section has been opened yet. openedOtherSections = {}; renderBesenDinPicker(); renderSectionTabs(); refresh(); } addSectionBtn.on("click", addPosSection); /** Removes one POS section. Assumes the caller already confirmed and * already checked more than one section remains. If the removed * section was the one on screen, its in-progress DOM edits are * discarded along with it (never saved back into sections[]) and a * neighboring section is restored in its place. */ function removePosSection(idx) { sections.splice(idx, 1); if (idx === activeSection) { viewingPron = false; activeSection = Math.min(idx, sections.length - 1); restoreSection(sections[activeSection]); refresh(); } else if (idx < activeSection) { activeSection -= 1; } renderSectionTabs(); } /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); syncStickyTabsOffset(); return; } sectionTabsDiv.show(); // Bilêvkirin leads the bar, ahead of the POS sections. var pronTab = $("<span></span>") .addClass("wiktku-section-tab wiktku-section-tab-pron") .text("Bilêvkirin") .toggleClass("wiktku-tab-active", viewingPron); pronTab.on("click", function () { if (viewingPron) return; saveCurrentSection(); viewingPron = true; refresh(); renderSectionTabs(); }); sectionTabsDiv.append(pronTab); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .toggleClass("wiktku-tab-active", i === activeSection && !viewingPron); tab.append($("<span class='wiktku-tab-label'></span>").text(tabLabel)); (function (idx) { tab.on("click", function () { if (idx === activeSection && !viewingPron) return; // Leaving Bilêvkirin doesn't need a save — its field // is shared and never part of a section snapshot. if (!viewingPron) saveCurrentSection(); viewingPron = false; activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); // Always keep at least one Beş — no delete button when // it's the only section left. if (sections.length > 1) { var trash = makeTrashButton("Vê beşê jê bibe"); trash.on("click", function (e) { // Stop this from also reaching the tab's own // click handler above (which would just switch // to it instead of deleting it). e.preventDefault(); e.stopPropagation(); if (!window.confirm("Tu dixwazî \"" + tabLabel + "\" jê bibî? Ev tişt nayê vegerandin.")) return; removePosSection(idx); }); tab.append(trash); } }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); syncStickyTabsOffset(); } renderSectionTabs(); /** * Re-populates a dynamically-growing "multiple" field list (bnrh, je, * tekildar, …) from a saved array of strings. Sets each value via * .val() + a triggered "input" event rather than touching the DOM * structure directly, so the normal refreshForTextField() growth * logic adds exactly as many rows as needed — the same thing that * happens when a person types into the last (empty) row. */ function restoreMultiField(id, values) { var container = $("#wiktku-start-" + id); $.each(values || [], function (i, v) { var field = container.find(".wiktku-start-step-field").eq(i); if (!field.length || !v) return; field.val(v).trigger("input"); }); } /** * Restores a full cached draft: shared lang/pron/bnrh fields, then * every section (via the same restoreSection()/refresh()/ * renderSectionTabs() sequence already used when switching tabs). * @param cached {{lang: string, pron: string, bnrh: Array, sections: Array, activeSection: number}} */ function restoreFromCache(cached) { if (cached.lang) { $("#wiktku-start-lang-field").val(cached.lang); $("#wiktku-start-lang-field").trigger("wiktku:refresh"); } // Rebuild dependent steps (pos, pron wrap, etc.) now that lang is set. refresh(); if (cached.pron !== undefined) { $("#wiktku-start-pron .wiktku-pron-text").val(cached.pron); } if (cached.bnrh) { restoreMultiField("bnrh", cached.bnrh); } sections = (cached.sections && cached.sections.length) ? cached.sections : [{}]; activeSection = (typeof cached.activeSection === "number" && cached.activeSection >= 0 && cached.activeSection < sections.length) ? cached.activeSection : 0; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); updateLastSavedIndicator(cached.savedAt || null); formDirty = false; wiktkuNotify("Danûstandina berê ya qeydkirî ji cache hate barkirin.", { type: "info", tag: "wiktku-cache-restore" }); } // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); // A new cureyê rêzimanî means any previously chosen cinsiyet/ // cureyê lêkerê no longer applies — clear both selections (and // the shared hidden cinsiyet field, since rebuildTa()/syncHelpers() // fall back to it) before wiping the textarea, so nothing stale // gets carried over into the rebuilt template. var ppDiv = $("#wiktku-start-posparams"); ppDiv.find(".wiktku-posparams-cinsiyet-sel").val(""); ppDiv.find(".wiktku-posparams-jimar-sel").val(""); ppDiv.find(".wiktku-posparams-lektur-sel").prop("selectedIndex", 0); ppDiv.find(".wiktku-posparams-lekturform-sel").prop("selectedIndex", 0); $("#wiktku-start-cinsiyet-field").val(""); $("#wiktku-start-jimar-field").val(""); ppDiv.find(".wiktku-posparams-text").val(""); // refresh() runs steps.posparams.syncHelpers(), which toggles the // param rows for the new pos and — since the textarea is now // empty — calls rebuildTa() to repopulate it. refresh(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { // Immediate feedback that the click registered continueBtn.$element.addClass("wiktku-btn-flash"); setTimeout(function () { continueBtn.$element.removeClass("wiktku-btn-flash"); }, 500); // Ziman/Cureyê rêzimanî already block submission via the real // OOUI setDisabled (see canContinue in refresh()) — this is a // second, softer check that still lets the click through so we // can explain why, instead of the button just silently doing nothing. if (!wiktkuContentGateOk) { wiktkuNotify( "Berî şandinê, tiştekî binivîse: Mane, Bi zaravayên din, an jî Werger — kêmasî yek ji van sê beşan divê tijî be.", { type: "warn", tag: "wiktku-mincontent" } ); return; } wiktkuNotify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", flags: [ "destructive" ], }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Cache save/clear buttons ───────────────────────────────────────── // Manual, page-scoped save of the entire wizard (all sections, not // just the active one) via [[MediaWiki:Gadget-StorageUtils.js]]'s // ObjectStorage. Restoring happens silently on load at the end of // build(), once the full language list is available. // // Saving also happens automatically (debounced while typing, plus a // periodic fallback) — see "Autosave" below — since relying on the // person to remember to click "Li cache qeyd bike" before an // accidental tab close/reload defeats the point of having a cache // at all. function buildCacheSnapshot() { return { lang: getValues().lang || "", pron: $("#wiktku-start-pron .wiktku-pron-text").val() || "", // bnrh is shared (page-level), same as lang/pron above — not // per-section, so it doesn't live in sections[]. bnrh: getValuesForStep("bnrh"), sections: sections, activeSection: activeSection, savedAt: Date.now() }; } // ── Last-saved indicator ───────────────────────────────────────────── var lastSavedEl = $("<span id='wiktku-last-saved'></span>"); function formatSavedTime(ts) { try { return new Date(ts).toLocaleTimeString(mw.config.get("wgUserLanguage"), { hour: "2-digit", minute: "2-digit" }); } catch (e) { return new Date(ts).toLocaleTimeString(); } } function updateLastSavedIndicator(ts) { lastSavedEl.text(ts ? ("Cache: qeydkirî di saet " + formatSavedTime(ts) + " de") : ""); } // ── Dirty-state tracking + autosave ────────────────────────────────── // formDirty mirrors "does the live form differ from what's in cache". // Anything the person types/selects sets it; a successful save (auto // or manual) clears it; destroy() (final submit, or switching to the // source editor) also clears it since the wizard's job is over at // that point either way. formDirty/autosaveDebounceTimer/autosaveInterval // are declared in the outer scope (near activeGroup) — assigned here, // not re-declared — so destroy() can reach them too. var AUTOSAVE_DEBOUNCE_MS = 8000; // save shortly after typing pauses var AUTOSAVE_INTERVAL_MS = 60000; // …and at least this often regardless function performAutosave() { if (!formDirty) return; saveCurrentSection(); try { formCache.Set(buildCacheSnapshot()); formDirty = false; updateLastSavedIndicator(Date.now()); } catch (e) { // Silent on autosave failure (storage blocked/full, etc.) — the // manual button still surfaces a proper error if the person // tries it directly, no need to interrupt typing with a toast. } } function scheduleAutosave() { formDirty = true; if (autosaveDebounceTimer) clearTimeout(autosaveDebounceTimer); autosaveDebounceTimer = setTimeout(performAutosave, AUTOSAVE_DEBOUNCE_MS); } startForm.on("input change", "input, textarea, select", scheduleAutosave); autosaveInterval = setInterval(performAutosave, AUTOSAVE_INTERVAL_MS); // Warn on accidental tab close/reload while there's anything unsaved. $(window).on("beforeunload.wiktkuUnsaved", function (e) { if (!formDirty) return undefined; e.preventDefault(); e.returnValue = ""; return ""; }); var saveCacheBtn = new OO.ui.ButtonWidget({ label: "Li cache qeyd bike", title: "Halê vê formê yê niha (ziman, bilêvkirin û hemû beş) li cache (localStorage) qeyd bike, da ku eger rûpel bêyî xwestin were girtin an ji nû ve were barkirin, tu karibî berdewam bikî." }); saveCacheBtn.on("click", function () { saveCurrentSection(); // ObjectStorage.Set() doesn't return a success/failure value, so // the only way to detect a real failure (storage blocked, quota // exceeded, JSON.stringify choking on something unexpected) is to // catch it here rather than inspect a (nonexistent) return value. try { var snapshot = buildCacheSnapshot(); formCache.Set(snapshot); formDirty = false; updateLastSavedIndicator(snapshot.savedAt); wiktkuNotify("Halê formê li cache hate qeydkirin.", { type: "success", tag: "wiktku-cache-save" }); } catch (e) { mw.notify("Qeydkirina li cache bi ser neket.", { type: "error", tag: "wiktku-cache-save" }); } }); var clearCacheBtn = new OO.ui.ButtonWidget({ label: "Cache paqij bike", flags: [ "destructive" ], title: "Datayên qeydkirî yên vê rûpelê ji cache jê bibe (forma ku niha xuya dike naguherîne)." }); clearCacheBtn.on("click", function () { formCache.Set({}); // The live form still has whatever the person typed — it's just no // longer backed up anywhere, so treat this like a fresh unsaved edit. formDirty = true; updateLastSavedIndicator(null); wiktkuNotify("Cache hate paqijkirin.", { type: "success", tag: "wiktku-cache-clear" }); }); // ── "⋯" overflow ───────────────────────────────────────────── // One primary action and one secondary stay on the bar; everything // else moves in here, to avoid four same-weight buttons crowding // (and wrapping to three rows on a phone). var moreBtn = $("<button type='button' class='wiktku-more-btn' title='Vebijarkên din'>⋯</button>"); var moreMenu = $("<div class='wiktku-more-menu'></div>").hide(); /** Moves an existing OOUI button into the overflow menu, keeping its * handlers — the widgets already carry the behaviour, so this is * purely about where they are shown. */ function intoMenu(btn, extraClass) { var row = $("<div class='wiktku-more-item'></div>"); if (extraClass) row.addClass(extraClass); btn.$element.on("click", function () { moreMenu.hide(); }); row.append(btn.$element); moreMenu.append(row); } intoMenu(saveCacheBtn); intoMenu(clearCacheBtn, "wiktku-more-item-danger"); moreMenu.append($("<div class='wiktku-more-sep'></div>")); moreMenu.append($("<div class='wiktku-more-item wiktku-more-note'></div>").append(lastSavedEl)); moreBtn.on("click", function (e) { e.preventDefault(); e.stopPropagation(); var open = moreMenu.is(":visible"); moreMenu.toggle(!open); if (!open) { setTimeout(function () { $(document).one("click.wiktkuMore", function () { moreMenu.hide(); }); }, 0); } }); var moreWrap = $("<span class='wiktku-more-wrap'></span>").append(moreBtn).append(moreMenu); footer.append(moreWrap); // Icon-only settings button — opens the Tercîh dialog. Plain OOUI // icon names depend on which icon-pack module happens to be loaded, // so this uses the actual Codex "settings" (color-subtle) SVG from // Commons directly, the same way the spinner above hotlinks its gif. var prefsBtn = $("<button></button>", { type: "button", "class": "wiktku-prefs-btn", title: "Tercîh — sazkariyên vê amûrê biguherîne" }); prefsBtn.on("click", function (e) { e.preventDefault(); wiktkuOpenPrefsDialog(); }); // The gear is icon-only on the bar; inside a text menu it needs a // label like everything else around it. prefsBtn.on("click", function () { moreMenu.hide(); }); moreMenu.prepend($("<div class='wiktku-more-sep'></div>")); moreMenu.prepend($("<div class='wiktku-more-item wiktku-more-item-prefs'></div>") .append(prefsBtn) .append($("<span class='wiktku-more-item-label'></span>").text("Tercîh"))); startForm.append(footer); // NOTE: deliberately NOT .hide() (display:none). WikiEditor/CodeMirror/ // the mobile editor's auto-grow logic measure #wpTextbox1's real // dimensions during their own init, which happens while the wizard is // up. A display:none ancestor reports 0 for offsetWidth/offsetHeight/ // scrollHeight, so those scripts bake in a near-zero height that never // gets recalculated later — slideDown() in destroy() only animates the // outer box, it doesn't re-trigger their sizing. Pushing #editform // off-screen instead keeps it laid out (real width/height available to // measure) without being visible, so the editbox opens at full size. $("#editform").addClass("wiktku-offscreen").before(startForm); // renderGroupTabs() looks up #wiktku-group-tabs via a live DOM // selector, so it must run after startForm is actually in the document. renderGroupTabs(); renderBesenDinPicker(); // One pass over the whole form: every select that hasn't already been // initialised, and isn't opted out with .wiktku-plain-select, gets // the searchable picker. initSelects(startForm); refresh(); // Give every draggable textarea a custom resize grip (works // consistently on Safari/iOS, unlike the native corner grip — see // the "Manual drag-to-resize handle" comment in styles.css), and // keep applying it to textareas added later on (new sense blocks, // quote-source fields, nimûne rows, …). wiktkuInitManualResize(startForm); new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { $(mutation.addedNodes).each(function () { if (this.nodeType !== 1) return; wiktkuInitManualResize(this); }); }); }).observe(startForm[0], { childList: true, subtree: true }); // Now that the full language list is loaded, silently restore any // draft the editor previously saved for this page. var cachedDraft = formCache.Get(); if (cachedDraft && cachedDraft.sections && cachedDraft.sections.length) { restoreFromCache(cachedDraft); } } mw.loader.using(["oojs-ui-core"], function () { function wiktkuProceedWithData(wiktkuData) { var d = wiktkuData || {}; // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Jimar (number) code definitions — same shape as the wiki's // own Lua number-type table (code -> {cat, display[, req]}). if (d.numberLabels) $.extend(NUMBER_LABELS, d.numberLabels); // Populate lang choices (pinned list). if (d.langChoices) steps.lang.choices = choicesFromObject(d.langChoices, true); // Populate langsByCode and merge full language list from d.ziman. // d.ziman is a {code: name} object with all known languages. $.each(steps.lang.choices, function (i, choice) { if (choice.sortKey === undefined) choice.sortKey = choice.label; langsByCode[choice.code] = choice; }); if (d.ziman) { var pinnedCodes = {}; $.each(steps.lang.choices, function (i, c) { pinnedCodes[c.code] = true; }); var extraChoices = []; $.each(d.ziman, function (code, name) { if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; if (pinnedCodes[code]) return; var choice = { code: code, label: name, sortKey: name }; extraChoices.push(choice); langsByCode[code] = choice; }); extraChoices.sort(function (a, b) { return a.sortKey.localeCompare(b.sortKey, userLang); }); steps.lang.choices = steps.lang.choices.concat(extraChoices); } // Keep the full merged list around for trans/dunde/zarava — those // should still be able to reference any language even when the // Tercîh panel restricts the main "ziman" step below — then, if // the user set a restriction there, narrow steps.lang.choices // itself to just those codes. var wiktkuFullLangChoices = steps.lang.choices; if (wiktkuPrefs.langCodes && wiktkuPrefs.langCodes.length) { var wiktkuAllowedLangSet = {}; $.each(wiktkuPrefs.langCodes, function (i, code) { wiktkuAllowedLangSet[code] = true; }); var wiktkuRestrictedChoices = $.grep(wiktkuFullLangChoices, function (c) { return !!wiktkuAllowedLangSet[c.code]; }); // Fall back to the full list instead of showing an empty // dropdown if none of the saved codes matched anything // (typo'd code, data.json changed since, …). steps.lang.choices = wiktkuRestrictedChoices.length ? wiktkuRestrictedChoices : wiktkuFullLangChoices; } // Populate POS choices — also a plain {code: label} object in data.json. if (d.posChoices) steps.pos.choices = choicesFromObject(d.posChoices, false); // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the full language list // (not the possibly Tercîh-restricted steps.lang.choices). steps.trans.keys = wiktkuFullLangChoices; steps.dunde.keys = wiktkuFullLangChoices; steps.zarava.keys = getZaravaKeys(wiktkuFullLangChoices); build(); } // data.json ships inside this package module, so it is already parsed // and in memory — no action=raw round trip, and no Testing switch to // forget to flip back before deploying. wiktkuProceedWithData(require("./start/data.json")); }); }); //</nowiki> 2h6eyy0aeg02hs5uxbz4sqlqwlwrxul 6333858 6333857 2026-08-15T17:48:04Z Wikihez 7344 Restored revision 6333828 by [[Special:Contributions/Wikihez|Wikihez]] ([[User talk:Wikihez|talk]]) ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]]) 6333858 javascript text/javascript // Fetches start.js/data.json/styles.css as raw text and registers them via // mw.loader.implement as a real package module, so require() in start.js // works without interface-admin rights on the test files. (function () { "use strict"; // Subpage segments are case-sensitive (MediaWiki only capitalizes the // first character of the title), so BASE must match the pages exactly. var BASE = "Bikarhêner:Wikihez/Gadget-test"; var MODULE = "ext.wiktkuTest"; // Force dataType "text" -- otherwise jQuery infers "script" from // action=raw's Content-Type and eval()s the response as a global script // before it reaches mw.loader.implement. function raw(title) { return $.get({ url: mw.util.getUrl(title, { action: "raw" }), dataType: "text" }); } $.when( raw(BASE + ".js"), raw(BASE + "/data.json"), raw(BASE + ".css"), raw(BASE + "/util.js") ).done(function (startRes, dataRes, cssRes, utilRes) { var startSrc = startRes[0]; var cssText = cssRes[0]; var utilSrc = utilRes[0]; var dataJson; try { dataJson = JSON.parse(dataRes[0]); } catch (e) { mw.notify("data.json nederbasdar e (JSON parse ket): " + e.message, { type: "error" }); return; } // JS files become function(require, module, exports); JSON files pass // through parsed. Keys must match start.js's require("./start/...") calls. mw.loader.implement( MODULE, { main: "start.js", files: { "start.js": new Function("require", "module", "exports", startSrc), "start/util.js": new Function("require", "module", "exports", utilSrc), "start/data.json": dataJson } }, { css: [cssText] } ); // Declaring oojs-ui-core/mediawiki.api here surfaces a loud failure // early instead of a silent one deep inside start.js. mw.loader.using(["oojs-ui-core", "mediawiki.api", MODULE]).then( function () { console.log(MODULE + " hate barkirin — require() dixebite."); }, function (err) { mw.notify("Xeta barkirinê: " + err, { type: "error" }); } ); }).fail(function () { mw.notify( "Nikarî " + BASE + "{.js,/util.js,/data.json,.css} bixwîne. " + "Kontrol bike ku her sê rûpel hene û navên wan rast in.", { type: "error" } ); }); })(); i1kvmmr3oyknki42a098wvx0snspd0t Modul:quote doc 828 1358569 6333892 6333684 2026-08-15T19:35:32Z Wikihez 7344 ([[m:Special:MyLanguage/User:Jon Harald Søby/diffedit|diffedit]]) 6333892 Scribunto text/plain --[=[ This module contains functions to generate documentation for {{quote-*}} templates. The module contains the actual implementation, meant to be called from other Lua code . See [[Module:quote doc/templates]] for the function meant to be called directly from templates. Author : Benwing2 ]=] local export = {} local m_table = require("Module:table") local rfind = mw.ustring.find local rsplit = mw.text.split local rsubn = mw.ustring.gsub local u = mw.ustring.char local unpack = unpack or table.unpack -- Lua 5.2 compatibility local TEMP_DOUBLE_LBRACE = u(0xFFF0) local TEMP_DOUBLE_RBRACE = u(0xFFF1) -- version of rsubn() that discards all but the first return value local function rsub(term, foo, bar) local retval = rsubn(term, foo, bar) return retval end local function preprocess(desc) if desc:find("{") then desc = mw.getCurrentFrame():preprocess(desc) end return desc end local ku_vowels = {a = true, e = true, ["ê"] = true, i = true, ["î"] = true, o = true, u = true, ["û"] = true} -- Add the Kurdish oblique indefinite suffix (-ekê after a consonant, -yekê after a vowel, to break hiatus) to -- `word`, since Kurdish marks indefiniteness with a suffix rather than a prefix word like English "a"/"an". The -- oblique form is used (rather than bare -ek/-yek) because every <<item:a>> substitution in this module's text -- follows the ezafe linker "ya", which puts the following noun in the oblique case. local function ku_add_indefinite(word) local last_char = mw.ustring.sub(word, -1) if ku_vowels[last_char] then return word .. "yekê" else return word .. "ekê" end end local function generate_param_intro_text(ty) return [=[ Beşên li jêr parametreyên heyî îzah dikin. Ji ber ku pir parametre hene, ew di nav koman de hatine teqsîmkirin. Hin parametre mecbûrî ne ku bi şiklê '''(mecbûrî)''' (heke neyên dayîn, xetayek dide) hatine nîşankirin û yên bi nîşana '''(nîv-mecbûrî)''' tê maneyê ku eger neyên dayîn, mesajeke kontrolkirinê dide. Parametreyên bi '''herfên stûr''' ji bo şablona {{şx|]=] .. ty .. [=[}} xisûsî ne û bi şablonên din ên {{şx|jêder-*}} re nayên bikaranîn, an jî bikaranîneke wan a cuda heye. Hemû kom ji xeynî ya ewil qismê jêderê kontrol dikin. Koma ewil rêzên jêgirtinê kontrol dike (rêzên ku nivîsa jêgirtinê, tercime, latînîzekirin, standardîzekirin, hwd. nîşan didin). Di hin parametreyên wekî sernav, nivîskar, weşanxane, hwd. de dikare nivîsa biyanî hebe. Wextê nivîsên biyanî tê de hebin divê ev parametre ''guherkerên pêşiyê (annotations)'' an jî ''guherkerên paşiyê (inline modifiers)'' bi kar bînin. ''Guherkerên pêşiyê (annotations)'' wekî pêşgireke koda zimanî (wek {ar:} ji bo erebî, {zh:} ji bo çînî an {ru:} ji bo rûsî) dikevin pêşiya nivîsa biyanî. ''Guherkerên paşiyê (inline modifiers)'' dikevin li paşiya nivîsa biyanî. Nimûneyek ku her duyan dihewîne: <code>ru:Баллада о королевском бутерброде<t:Şiîra Nanê Qiralî></code> wek {{zim|ru|Баллада о королевском бутерброде}} [''Ballada o korolevskom buterbrode, Şiîra Nanê Qiralî''] xuya dike. Koda zimanî dibe alîkar ku fonta munasib were bikaranîn dema nivîs tê nîşandan (her çend naskirina skrîpta nivîsê bêyî van kodan jî çêdibe), û transliterasyona otomatîk çêdike heke mimkûn be. Guherkerên paşiyê tercime, translîterasyona manuel û tiştên bi vî rengî diyar dikin. Kodên taybet ên jêrîn li şûna kodên zimên jî tên naskirin: * {w:``link``}: Lînk bi Wîkîpediyaya îngilîzî, wek nimûne {w:William Shakespeare}. Ev wek {``link``} xuya dike. Ev wek nivîsandina {{şx|w|William Shakespeare}} e, ku ew jî dikare were bikaranîn. * {w:``lang``:``link``}: Lînk bi Wîkîpediyayeke bi zimanekî din, wek nimûne {w:fr:Jeanne d'Arc}. Ev wek {``link``} xuya dike. Ev wek nivîsandina {{şx|w|2=lang=fr|3=Jeanne d'Arc}} e, ku ew jî dikare were bikaranîn. * {lw:``lang``:``link``}: Lînk bi Wîkîpediyayeke bi zimanekî din û {``link``} li gorî koda zimên a bi {``lang``} hatiye dayîn were formatkirin, wek nimûne {lw:zh:毛泽东} (forma nivîskî ya çînî ya {{w|Mao Zedong}}). Ev pêdivî ye ku {``lang``} kodeke zimên be ku li Wîkîpediyayê û Wîkîferhengê heman wateyê bide (ev ji bo piraniya kodên zimên ên Wîkîpediyayê derbasdar e, lê ne ji bo hr ji bo Wîkîpediyaya xirwatî û sr ji bo Wîkîpediyaya sirbî, û ne jî ji bo hin zimanên din ên kêmzanîn). Ev wek nivîsandina {zh:&#123;&#123;w|lang=zh|毛泽东}}} e. Ev dê naskirin û formatkirina taybet a xeta nivîsê ya li gorî ziman bike û forma xuyayî bi çîna CSS a munasib a li gorî ziman nîşan bide. Heke latînîzekirina otomatîk ji bo zimanê diyarkirî çalak be, ew latînîzekirin dê xuya bibe, ji bilî ku latînîzekirineke din bi {<tr:...>} were dayîn an nîşandana latînîzekirinê bi {<tr:->} were vemirandin. Bala xwe bide ku bikaranîna wek {lw:ru:Лев Толстой} (forma nivîskî ya rûsî ya {{w|Leo Tolstoy}}) hinekî dişibihe nivîsandina {{şx|lw|ru|Лев Толстой}} (ji ber vê ye pêşgir dişibihe navê şablonê), lê ya duyem latînîzekirinan wek {{şx|l}} nîşan dide (di kevanan de ne di parantezan de), û bikaranîna {{şx|lw}} destûrê nade guherkerên paşiyê, ji ber ku ew bo HTML'ê tê formatkirin. * {lw:``lang``:&#91;&#91;``link``|``display``&#93;&#93;}: Lînk bi {``link``} bi Wîkîpediyayeke bi zimanekî din, lê wek {``display``} xuya bike, li gorî koda zimên a bi {``lang``} hatiye dayîn were formatkirin. Ev wek {lw:...} ya li jor dixebite, lê destûrê dide ku lînk û xuyabûn cuda werin diyarkirin, wek nimûne {lw:ru:&#91;&#91;Маркс, Карл|Карл Ге́нрих Маркс&#93;&#93;}, ku forma xuyayî forma nivîskî ya rûsî ya {{w|Karl Marx|Karl Heinrich Marx}} e û forma lînkê jî ew e ku nav çawa di madeya Wîkîpediyaya rûsî de tê bikaranîn (bi paşnav pêşî). * {w:&#91;&#91;``link``|``display``&#93;&#93;} û {w:``lang``:&#91;&#91;``link``|``display``&#93;&#93;}: Lînk bi Wîkîpediyaya îngilîzî an bi zimanekî din, lînk ji forma xuyayî cuda were diyarkirin. Ev kêmtir kêrhatî ne ji ya {lw:...} çimkî tu dikarî lînka Wîkîpediyayê rasterast jî diyar bikî, wek nimûne bi {{code||[[w:William Shakespeare|W(illiam) Shakespeare]]}} an {{code||[[w:fr:Jeanne d'Arc|Joan of Arc]]}} bi heman hejmara herfan. * {s:``link``}: Lînk bi rûpela Wîkîçavkaniya îngilîzî ya {``link``}, wek nimûne {s:The Rainbow Trail} (romanek ji {{w|Zane Grey}}). * {s:``lang``:``link``}: Lînk bi Wîkîçavkaniyeke bi zimanekî din. Ev bi mahiyet dişibihe {w:``lang``:``link``} ji bo Wîkîpediyayê. * {ls:``lang``:``link``}: Lînk bi Wîkîçavkaniyeke bi zimanekî din û {``link``} li gorî koda zimên a bi {``lang``} hatiye dayîn were formatkirin. Ev bi mahiyet dişibihe {lw:``lang``:``link``} ji bo Wîkîpediyayê. * {ls:``lang``:&#91;&#91;``link``|``display``&#93;&#93;}: Lînk bi {``link``} bi Wîkîçavkaniyeke bi zimanekî din, lê wek {``display``} xuya bike, li gorî koda zimên a bi {``lang``} hatiye dayîn were formatkirin, wek nimûne {ls:ko:&#91;&#91;조선_독립의_서#一._槪論|조선 독립의 서&#93;&#93;} (belgeyek li ser serxwebûna Kore di dema dagirkirina Japonî de). Ev bi mahiyet dişibihe {lw:``lang``:&#91;&#91;``link``|``display``&#93;&#93;} ji bo Wîkîpediyayê. * {s:&#91;&#91;``link``|``display``&#93;&#93;} û {s:``lang``:&#91;&#91;``link``|``display``&#93;&#93;}: Lînk bi Wîkîçavkaniya îngilîzî an bi zimanekî din, lînk ji forma xuyayî cuda were diyarkirin. Ev kêmtir kêrhatî ne ji ya {ls:...} çimkî tu dikarî lînka Wîkîçavkaniyê rasterast jî diyar bikî, wek nimûne bi {{code||[[s:The Tempest (Shakespeare)|The Tempest]]}} an {{code||[[s:fr:Fables de La Fontaine (édition originale)|Fables de La Fontaine]]}} bi heman hejmara herfan. Herwiha, hin parametre dikarin çend ''hebûnên'' bi niqteya bi virgul (;) ji hev cuda hebin (nivîskar, weşanxane, hwd.). Ev bi giştî ji bo hemû parametreyên kesan (nivîskar, terciman, edîtor, hwd.) derbasdar e, herwiha ji bo hin parametreyên din jî, wek li jêr hatiye nîşandan. Di van parametreyan de, her hebûn dikare guherkerên pêşiyê û/an guherkerên paşiyê hebe, wek li jor. Nimûneyek <code>zh:張福運<t:Chang Fu-yun>; zh:張景文<t:Chang Ching-wen></code> e, ku du navên bi çînî diyar dike, her yek bi latînîzekirinekê. Bi giştî, van parametreyan bi niqteyên bi virgul neyên nîşandan, lê bi gelemperî bi kome (,) û/an kelîmeya ''û'' — ev bi parametreya taybet û cihê wê yê di jêderê de girêdayî ye. Niqteya bi virgul tenê ji bo cudakirina hebûnan di têketinê de tên bikaranîn; kome nayên bikaranîn ji ber ku nav dikarin kome tê de hebin, wek {Sammy Davis, Jr.} an {Alfred, Lord Tennyson}. Niqteyên bi virgul di nava kevan an kevanên çargoşe de nayên hesibandin wekî sînorker; ji ber vê yekê, nirxeke parametreyê wek {George Orwell [pseudonym; Eric Blair]} yek hebûnê diyar dike, ne du. Bi heman rengî, hebûnên HTML'ê yên bi niqteya bi virgul a dawî wek {&amp;oacute;} jî tên naskirin û ne wekî sînorker. Ji bo parametreyên ku kesan diyar dikin (wek {{para|nivîskar}}, {{para|terciman}}, {{para|edîtor}}), li dû niqteya bi virgul {et al.} binivîse wek kesekî normal. Koda binesaziyê vê taybet dihesibîne, bi herfên xar nîşan dide û sînorkera ku normal berî wê were xuya nake. Wek îstisnayeke sînorkirina hebûnan bi niqteyên bi virgul, heke tu komê wek herfa yekem a parametreyeke pirhebûnî bicîh bikî, ew kom tê paşguhkirin û mayîya nirxê li gorî koman tê dabeşkirin, ne li gorî niqteyên bi virgul. Wek nimûne, {,Joe Bloggs, Mary Worth, et al.} wek {Joe Bloggs; Mary Worth; et al.} tê hesibandin. Bi giştî ev şêwe nayê tewsiyekirin, lê dema meriv rêzeke dirêj a bi kome ji hev cuda ya nivîskaran ji cihekî din (wek Google Scholar) kopî dike, dikare bibe alîkar. Guherkerên paşiyê yên jêrîn tên naskirin:]=] end local function generate_inline_modifiers(ty) return { {"t", [=[Tercimeya parametreyê an hebûna behskirî. Di kevanên çargoşe de li dû nirxê tê nîşandan. Ji bo nivîskar an hebûnên din ên ku behsa kesan dikin, tê tewsiyekirin ku parametreya <code><t:...></code> ji bo nivîsandina forma "asayî" an ne-zanistî ya navî were bikaranîn, û bi îxtiyarî parametreya <code><tr:...></code> jî ji bo latînîzekirina zanistî. Wek nimûne, navê rûsî {{qal|ru||Пётр Чайко́вский|tr=-}} dibe ku wek {{w|Pyotr Tchaikovsky}} were tercimekirin lê wek ''Pjotr Čajkóvskij'' were latînîzekirin. Girêdanên Wîkîpediyayê li gorî hewceyê bi {{şx|w}} an rasterast bi {{code||[[w:LINK|NAME]]}} zêde bike.]=]}, {"gloss", [=[Bernavê <code><t:...></code>. Bi giştî, <code><t:...></code> tê tercihkirin.]=]}, {"alt", [=[Forma xuyayî ya parametreyê an hebûna behskirî. Bi giştî ev ne lazim e, çimkî tu her tim dikarî girêdaneke du-perçeyî wek {{code||[[Dennis Robertson (economist)|D.H. Robertson]]}} bikar bînî.]=]}, {"tr", [=[Latînîzekirina parametreyê an hebûna behskirî, heke ne bi herfên latînî be. {{para|t}} ya jorîn ji bo kengî tercime, kengî latînîzekirin ji bo navên kesan were bikaranîn binêre. Heke pêşgireke koda zimên hatibe dayîn û nivîs ne bi herfên latînî be, latînîzekirineke otomatîk dê were peydakirin heke ziman vê piştgirî bike û ev guherker neyê dayîn. Di wê rewşê de, {<tr:-}> bikar bîne da ku latînîzekirina otomatîk neyê xuyakirin.]=]}, {"subst", [=[Şêwaz(ên) cîguherînê ku têne bikaranîn ji bo mîna kirina latînîzekirineke rast, li şûna diyarkirina latînîzekirineke bi dest. Ev guherker bi awayekî wekhev bi parametreya {{para|subst}} dixebite, lê ji bo hebûna behskirî ne ji bo nivîsa giştî ya jêgirtinê. Nimûneyên bikaranînê li nimûneyên {{şx|jêder-kitêb}} binêre.]=]}, {"ts", [=[Nivîsandina fonetîk a parametreyê an hebûna behskirî, heke ne bi herfên latînî be û di zimanekî de ku latînîzekirin ji telafuza rastîn pir cuda ye (wek akadî an tîbetî). Vê tenê ji bo dayîna telafuza IPA'yê bikar neyîne. Heke were dayîn, ev di navbera du xêzikan de tê nîşandan, wek <code>[``latînîzekirin`` /``nivîsandina fonetîk``/, ``tercime``]</code>.]=]}, {"sc", [=[Koda xeta nivîsê ya nivîsa parametreyê an hebûna behskirî, heke ne bi xeta latînî be. Li [[Wiktionary:Scripts]] binêre. Kêm caran lazim e ev were diyarkirin, çimkî koda xeta nivîsê bi xwe (bi giştî bi rastî) ji nivîsê tê naskirin.]=]}, {"f", [=[Guhertoya "biyanî" ya parametreyê an hebûna behskirî, ango guhertoya bi xeteke nivîsê ya cuda ji ya nirxê bixwe. Ev çend awayan hene: # {<f:``biyanî``>}: Awayê herî sade. Nivîsa biyanî dê naskirina xeta nivîsê ya serbixwe ji zimanan bistîne û wek xwe, di hundirê kevanan de berî tercimeyê were nîşandan. Bi giştî bikaranîna vê awayî nayê tewsiyekirin ji ber ku girîngiya nivîsê dibe ku ne diyar be; guhertoya jêrîn a bi etîket bikar bîne. # {<f:/``xeta nivîsê``:``biyanî``>}: Wek ya berê, lê koda xeta nivîsê eşkere hatiye dayîn, ji bo rewşa ku naskirin xelet dixebite. # {<f:``etîket``:``biyanî``>}: Etîketek zêde bike ku berî nivîsa biyanî were nîşandan. Etîket dikare kodeke zimên be (bi zimanên etîmolojiyê ve jî), kodeke xeta nivîsê, an nivîseke azad. Heke wek kodeke zimên were naskirin, navê resmî yê ziman wek etîket tê nîşandan û ziman ji bo naskirina xeta nivîsê ya nivîsa biyanî, li gorî xeta nivîsê ya destûrdayî ya wî ziman, tê bikaranîn. Heke etîket wek kodeke xeta nivîsê were naskirin, ew wek xeta nivîsê ya nivîsa biyanî tê bikaranîn dema nivîs tê nîşandan, û navê resmî yê xeta nivîsê wek etîket tê nîşandan. Wekî din, etîket dikare nivîseke azad be (wek pergaleke latînîzekirinê wek `Pinyin`), û wek xwe tê nîşandan, bi naskirina xeta nivîsê ya serbixwe ji zimanan li ser nivîsa biyanî. # {<f:``etîket``/``xeta nivîsê``:``biyanî``>}: Wek ya berê, lê koda xeta nivîsê eşkere hatiye dayîn, ji bo rewşa ku naskirin xelet dixebite. # {<f:``etîket``,``etîket``,...:``biyanî``>}: Ji bo nivîseke biyanî çend etîketan zêde bike. Hemû etîket bi xêzika dabeşker ji hev cuda tên nîşandan wek li jor, lê tenê etîketa yekem ji bo naskirina xeta nivîsê tê bikaranîn. # {<f:``etîket``,``etîket``,.../``xeta nivîsê``:``biyanî``>}: Wek ya berê, lê koda xeta nivîsê eşkere hatiye dayîn, ji bo rewşa ku naskirin xelet dixebite. Berevajî guherkerên din ên paşiyê, guherkera {<f:...>} dikare çend caran were dayîn ji bo nîşandana guhertoyên cuda yên biyanî yên hebûneke diyarkirî. Nimûneyeke kêrhatî ev e: * {Liou Kia-hway<f:Hant:劉家槐><f:Pinyin:Liú Jiāhuái>} Li vir, em navê nivîskar wek di çavkaniyê de hatiye dayîn diyar dikin, li dû wê guhertoya orîjînal a bi çînî û herwiha guhertoyeke standard a Pinyin.]=]}, {"q", [=[Etîketa çepê ya parametreyê an hebûna behskirî, berî wê wiha tê nîşandan: {{q|etîketa çepê}}.]=]}, {"qq", [=[Etîketa rastê ya parametreyê an hebûna behskirî, li dû wê wiha tê nîşandan: {{q|etîketa rastê}}.]=]}, } end --[===[ Ravekirina parametreyên takekesî ji bo perçeya jêderê ya jêgirtinê (ango rêza yekem). Ji ber ku pir parametre hene, em wan bi koman dabeş dikin. Nirxa ya jêrîn lîsteyeke koman e, her kom bi vî rengî ye: 1. Perçeya yekem sernavê koma parametreyan e. 2. Perçeya duyem a îxtiyarî, heke rêzik be, nivîsa pêşgotinê ye ku komê bi hûrgilî rave dike, û dê berî tabloya parametreyan were nîşandan. Rêzik dikare pirrêzî be (bi [=[...]=] bicîh bike), û rêzên domdar taybetmendiyek hene; li jêr binêre. 3. Hemû perçeyên din parametreyên takekesî rave dikin. Ravekirina parametreyeke takekesî bi vî rengî ye: 1. Perçeya yekem nav an navên parametreyê ye. Heke rêzik be, tenê navê gengaz ê parametreyê diyar dike, û wek lîsteyeke yek-perçeyî ya bi navê parametreyê tê hesibandin. Lîsteyeke rêzikan bikar bîne ji bo diyarkirina çend bernavên bi heman wateyê, wek {"tlr", "translator", "translators"}. Tu dikarî herwiha lîsteyeke parametreyên girêdayî yên mantiqî jî diyar bikî, ku hemû parametre bi rave kirineke yekane têne şirovekirin. Di vê rewşê de, <code>useand = true</code> li dû navên parametreyan binivîse, ku dibe sedem parametre bi "û" li şûna "an" werin girêdan (wek normal ji bo bernavan). Heke <code>useand</code> hatibe dayîn, perçeyên takekesî yên lîsteyê bixwe dikarin lîsteyên bernavan bin, ku bi xêzika dabeşker ji hev cuda tên nîşandan. Her perçe dikare, li şûna rêzikekê, tabloyek bi forma {param = "PARAM", non_generic = BOOLEAN} jî be, ku heke <code>non_generic = true</code>, parametre taybet e ji bo pêkanîneke {{şx|quote-*}} ya diyarkirî, ne giştî. Wek nimûne: * {"tlr", "translator", "translators"} wek "|tlr=, |translator= an |translators=" tê nîşandan, behsa sê bernavan dike. * {"chapter_series", "chapter_seriesvolume", useand = true} wek "|chapter_series= û |chapter_seriesvolume=" tê nîşandan, behsa parametreyên girêdayî yên mantiqî dike. * {{"chapter_series", {param = "entry_series", non_generic = true}}, {"chapter_seriesvolume", {param = "entry_seriesvolume", non_generic = true}}, useand = true} wek "|chapter_series=/<b>|entry_series=</b> û |chapter_seriesvolume=/<b>|entry_seriesvolume=</b>" tê nîşandan, behsa komên bernavan ên parametreyên girêdayî yên mantiqî dike, hinek ji wan ne giştî ne (li vir, parametreyên {{para|entry_*}} bernavên taybet ên {{şx|jêder-kitêb}} in). Qadên din ên navdar jî gengaz in: * <code>useand = true</code>: Parametreyan bi "û" li şûna "an" girêbide; li jor binêre. * <code>annotated = true</code>: Diyar dike ku parametre(yên) dikarin bi guherkerên pêşiyê û/an guherkerên paşiyê werin nîşankirin. * <code>multientity = true</code>: Diyar dike ku parametre(yên) dikarin ji çend hebûnên bi niqteya bi virgul ji hev cuda pêk bên (wek nivîskar, terciman, edîtor, weşanxane an cih), her yek dikare bi guherkerên pêşiyê û/an guherkerên paşiyê were nîşankirin. * <code>boolean = true</code>: Parametre(yên) nirxa wan boolean e, û wek nimûne {{para|bêtarîx|1}} tê nîşandan, ne bi tenê wek {{para|tarîx}}. * <code>required = true</code>: Parametre(yên) lazim in, û wek nimûne {{para|sernav|req=1}} tê nîşandan, ne bi tenê wek {{para|nivîskar}}. * <code>literal = true</code>: Nirxa parametreyê (ku divê tenê yek hebe) ravekirinên parametreyên jixwe-formatkirî dihewîne û divê wek xwe were nîşandan, ne bêtir were formatkirin. 2. Perçeya duyem ravekirina parametreyê/parametreyan e. Rêzik dikare pirrêzî be (bi [=[...]=] bicîh bike), û rêzên domdar taybetmendiyek hene. Bi taybetî, xêzikeke nû û valahiya li dû wê bi gelemperî dibe valahiyeke yekane, da ku rêzeke dirêj bikare bi çend rêzan û bi navbereke munasib were nivîsandin. Ev nabe dema ji yek xêzikeke nû zêdetir li pey hev hebin (di wê rewşê de, hemû xêzikên nû wek xwe dimînin). Heke herfa yekem a rêzekê nîşana lîsteyekê be (<code>#</code> an <code>*</code>), valahiya berî wê tê rakirin lê xêzika nû ya berê wek xwe dimîne. Ev destûrê dide ku lîste di ravekirinên parametreyan de bên dayîn. ]===] local function generate_params(ty) return { {"Parametreyên nivîsa jêgirtî", [=[Parametreyên jêrîn nivîsa jêgirtî bixwe rave dikin. Ev kom digel koma jêrîn (ji bo nivîsa jêgirtî ya orîjînal) nivîsa jêgirtinê rave dikin, dema hemû komên din ên parametreyan rêza jêderê kontrol dikin. Parametreyên vê koma dikarin neyên dayîn heke nivîsa jêgirtî cuda were nîşandan (wek nimûne di hin zimanên rojhilata Asyayê de, ku şablonên xwe hene ji bo nîşandana nivîsa jêgirtî, wek {{şx|ja-x}} ji bo japonî, {{şx|zh-x}} ji bo çînî, {{şx|ko-x}} ji bo koreyî, {{şx|th-x}} ji bo tayî û {{şx|km-x}} ji bo khmerî). Tevî wê jî, {{para|1}} divê were dayîn da ku zimanê jêgirtinê diyar bike.]=], {{"1", required = true}, [=[Lîsteyeke kodên zimên ên bi kome ji hev cuda, ku zimanê/zimanên nivîsa jêgirtî diyar dike; ji bo lîsteya kodan, li [[Wiktionary:List of languages]] binêre. Heke ziman ne îngilîzî be, şablon vê rastiyê bi nîşandana {(bi ``ziman``)} (ji bo yek zimanî), an {(bi ``ziman`` û ``ziman``)} (ji bo du zimanan), an {(bi ``ziman``, ``ziman`` ... û ``ziman``)} (ji bo sê an zêdetir zimanan) diyar dike. Rûpela madeyê dê herwiha li kategoriyeke bi forma {Kategorî:Jêgirtinên bi ``ziman``} were zêdekirin, ji bo zimanê yekem ê lîsteyê (ji bilî ku {{para|zimanê-termê}} hatibe dayîn, di wê rewşê de ew ziman ji bo kategoriyê tê bikaranîn, an {{para|nekat|1}} hatibe dayîn, di wê rewşê de rûpel nakeve tu kategoriyekê). Zimanê yekem ê lîsteyê herwiha fonta tê bikaranîn û latînîzekirina munasib jî diyar dike, heke nivîs ne bi herfên latînî be. {{para|zimanê-eserê}} bikar bîne ji bo diyarkirina zimanê/zimanên ku <<collection>> bixwe pê hatiye nivîsandin: li jêr binêre. <small>Parametreya {{para|lang}} bernaveke kevin e ji bo vê parametreyê; ji kerema xwe bikar neyîne. Heke ev were bikaranîn, hemû parametreyên hejmarî yek ji dor tên xwarê.</small>]=]}, {{"jêgirtin", "jg"}, [=[Nivîsa ku tê jêgirtin. Tîpên qalind bikar bîne ji bo diyarkirina termê ku tê îzahkirin, wiha: {{code||<nowiki>'''mirovnasî'''</nowiki>}}.]=]}, {"zimanê-eserê", [=[Lîsteyeke kodên zimên ên bi kome ji hev cuda, ku zimanê/zimanên ku kitêb pê hatiye nivîsandin diyar dike, heke ji nivîsa jêgirtî cuda be; ji bo lîsteya kodan, li [[Wiktionary:List of languages]] binêre.]=]}, {"zimanê-termê", [=[Kodeke zimên ku zimanê termê tê îzahkirin diyar dike, heke ji nivîsa jêgirtî cuda be; ji bo lîsteya kodan, li [[Wiktionary:List of languages]] binêre. Heke were dayîn, ev ziman ew e ku dema rûpel li kategoriyeke bi forma {Kategorî:Jêgirtinên bi ``ziman``} tê zêdekirin tê bikaranîn; wekî din, zimanê yekem ê bi {{para|1}} hatiye dayîn tê bikaranîn. Vê parametreyê tenê bide heke zimanê jêgirtinê ji zimanê termê cuda be, wek nimûne jêgirtineke îngilîziya navîn ku ji bo termeke îngilîziya nûjen tê bikaranîn, an tarîfeke îngilîzî ya termeke viyetnamî di ferhengeke viyetnamî-îngilîzî de.]=]}, {{"parantez", boolean = true}, [=[Jêgirtinekê bi [[bracket|kevanan]] dorpêç bike. Ev nîşan dide ku jêgirtin an behskirineke termekê ye (wek nimûne, "hin kes dibêjin kelîmeya '''''manoeuvre''''' zehmet e meriv rast binivîse") li şûna bikaranîneke rastîn a wê (wek nimûne, "divê em bi baldarî '''manoeuvre''' bikin da ku aloziyê çênekin"), an jî nimûneeke rastîn a termekê nade lê agahiyan li ser kelîmeyên eleqedar pêşkêş dike.]=]}, {{"tercime", "werger"}, [=[Heke nivîsa jêgirtî bi îngilîzî/kurmancî nebe, ev parametre dikare ji bo pêşkêşkirina [[wergêr|tercimeyek]]ê were bikaranîn.]=]}, {"hrf", [=[Heke nivîsa jêgirtî bi îngilîzî/kurmancî nebe û tercimeya bi {{para|tercime}} hatiye dayîn îdyomatîk be, ev parametre dikare ji bo pêşkêşkirina tercimeyeke [[herfî]] were bikaranîn.]=]}, {"footer", [=[Ev parametre dikare ji bo diyarkirina nivîseke serbixwe li binî, wek şirove an têbînî, were bikaranîn. (Bi zanebûn wek "footer" maye, kurmancîkirin nehatiye kirin.)]=]}, {"norm", [=[Heke nivîsa jêgirtî bi rastnivîsîna ne-standard hatibe nivîsandin, ev parametre guhertoya standardkirî ya nivîsê peyda dike. Ev bi taybetî ji bo jêgirtinên kevn e. Wek nimûne, ji bo poloniya kevn, ev parametre dikare guhertoyeke li gorî rastnivîsîna poloniya nûjen peyda bike, û ji bo nivîsa rûsî ya berî reforma rastnivîsînê ya 1917an, dikare rastnivîsîna reforma nû peyda bike.]=]}, {"tr", [=[Heke nivîsa jêgirtî {{w|pergaleke nivîsandinê}} ya cuda ji {{w|alfabeya latînî}} (alfabeya normal a bi îngilîzî tê bikaranîn) bikar tîne, ev parametre dikare ji bo pêşkêşkirina [[latînîzekirin]]eke wê were bikaranîn. Bala xwe bide ku gelek ziman latînîzekirineke otomatîk peyda dikin heke ev arguman neyê dayîn. Heke guhertoyeke standardkirî ya nivîsê bi {{para|norm}} hatibe dayîn, latînîzekirin dê li ser vê guhertoyê be, heke gengaz be (heke latînîzekirina guhertoya standardkirî têk biçe an standardkirin bi herfên latînî û orîjînal ne bi herfên latînî be, dê li ser nivîsa rastîn a jêgirtî be).]=]}, {"subst", [=[Cîguherînên fonetîk ku têne bikaranîn ji bo çareserkirina latînîzekirinên nerêbaz di hin zimanan de bi pergaleke nivîsandinê ya ne-latînî û latînîzekirina otomatîk (wek rûsî û yîdî). Fikra bingehîn ev e ku nivîsa jêgirtî berî latînîzekirinê bi awayekî fonetîk ji nû ve were nivîsandin, da ku latînîzekirin bi rastî telafuzê nîşan bide ne rastnivîsîna nerêbaz. Heke were dayîn, divê yek an çend rêzikên cîguherînê bin, bi kome ji hev cuda, her rêzika cîguherînê bi forma {JI//BO} ye ({JI/BO} jî tê qebûlkirin), ku {JI} nivîsa çavkaniyê ya bi xeta nivîsê ya çavkaniyê (wek kîrîlî an îbranî) diyar dike û {BO} jî nivîsa cîguherîner e, ew jî bi xeta nivîsê ya çavkaniyê. Cîguherîn bi rêzê tên bikaranîn û ne mecbûr in bi kelîmeyek tevayî re li hev bên. Bala xwe bide ku şêwazên Lua dikarin li şûna nivîsa rasterast di {JI} û {BO} de werin bikaranîn; li [[WT:LUA]] binêre. Ev tê wê wateyê ku bi taybetî, xêzikên di {JI} de divê wek {%-} bên nivîsandin da ku neyên şîrovekirin wekî hejmarkera şêwaza Lua ya ne-çavdar. Ji bo nimûneyên bikaranîna vê parametreyê li nimûneyên {{şx|jêder-kitêb}} binêre. Nimûneyên din di belgekirina {{şx|ux}} de têne dîtin; bikaranîn wek şablonê wekhev e. Heke {{para|norm}} ji bo peydakirina guhertoyeke standardkirî ya nivîsê tê bikaranîn, cîguherîn dê ji bo vê guhertoyê jî bên bikaranîn dema ew tê latînîzekirin.]=]}, {"ts", [=[Nivîsandina fonetîk a nivîsa jêgirtî, heke ne bi herfên latînî be di zimanekî de ku latînîzekirin ji telafuza rastîn pir cuda ye (wek akadî, misrî ya kevn û tîbetî). Ev nebe tenê ji bo dayîna telafuza IPA'yê were bikaranîn.]=]}, {"sc", [=[Koda xeta nivîsê ya nivîsa jêgirtî, heke ne bi xeta latînî be. Ji bo agahiyên zêdetir li [[Wiktionary:Scripts]] binêre. Kêm caran lazim e ev were diyarkirin çimkî xeta nivîsê ji nivîsa jêgirtî tê naskirin.]=]}, {"normsc", [=[Koda xeta nivîsê ya nivîsa standardkirî di {{para|norm}} de, heke ne bi xeta latînî be. Heke neyê dayîn, û nirxek di {{para|sc}} de hatibe dayîn, ev nirx dê ji bo diyarkirina xeta nivîsê ya nivîsa standardkirî were bikaranîn; wekî din (an heke {{para|normsc|auto}} hatibe dayîn), xeta nivîsê ya nivîsa standardkirî ji nivîsê bixwe tê naskirin.]=]}, {"e", [=[Etîket(ên) nivîsa jêgirtî. Etîket heman etîketên di {{şx|lb}}, {{şx|alt}}, {{şx|desc}} û {{şx|syn}}/{{şx|ant}}/hwd. de ne, û li gorî ziman cuda ne. Ji bo dîtina etîketên diyarkirî yên zimanekî, li belgekirina {{şx|lb}} binêre. Heke etîketek neyê naskirin, wek xwe tê nîşandan. Çend etîket dikarin werin dayîn, bi kome ji hev cuda bêyî valahî di navbera etîketan de (komeke bi valahiyeke li dûv wê nayê hesibandin wekî sînorker, lê wek perçeyeke etîketê tê hesibandin). Etîket wek etîketên rastê tên nîşandan, ango bi herfên xar, di kevanan de û li rastê nivîsa jêgirtî.]=]}, }, {"Parametreyên nivîsa jêgirtî ya orîjînal", [=[Parametreyên jêrîn nivîsa jêgirtî ya orîjînal rave dikin, dema nivîsa jêgirtî ya termê ku tê îzahkirin tercimeyek e.]=], {"zimanê-orîjînal", [=[Lîsteyeke kodên zimên ên bi kome ji hev cuda, ku zimanê/zimanên orîjînal ê ku nivîsa jêgirtî jê hatiye tercimekirin diyar dike; ji bo lîsteya kodan, li [[Wiktionary:List of languages]] binêre. Şablon vê rastiyê bi nîşandana {tercimeya orîjînala bi ``ziman``} (ji bo yek zimanî), an {tercimeya orîjînala bi ``ziman`` û ``ziman``} (ji bo du zimanan), an {tercimeya orîjînala bi ``ziman``, ``ziman`` ... û ``ziman``} (ji bo sê an zêdetir zimanan) diyar dike.]=]}, {"metna-orîjînal", [=[Guhertoya orîjînal a nivîsa jêgirtî, ku nivîsa di {{para|jêgirtin}} de jê hatiye tercimekirin. Ev nivîs divê bi koda zimên a zimanê nivîsê pêşgir bike, wek nimûne {<nowiki>gl:O teito é de '''pedra'''.</nowiki>} ji bo nivîsa orîjînal a bi galîsî. Dema nivîsa jêgirtî ya sereke ji îngilîzî hatibe tercimekirin, çêtir e nivîsa îngilîzî ya li hev were di {{para|metna-orîjînal}} de bête danîn, ne di {{para|tercime}} de; ya duyem ji bo tercimeyeke dubare bo îngilîzî ya nivîsa tercimekirî bikar bîne (ji bilî ku nivîsa jêgirtî tercimeyeke azad a orîjînal be, ne lazim e).]=]}, {"norm-orîjînal", [=[Heke nivîsa jêgirtî ya orîjînal bi rastnivîsîna ne-standard hatibe nivîsandin, ev parametre guhertoya standardkirî peyda dike. Ev dişibihe parametreya {{para|norm}} ji bo nivîsa jêgirtî ya sereke.]=]}, {"tr-orîjînal", [=[Heke nivîsa jêgirtî ya orîjînal {{w|pergaleke nivîsandinê}} ya cuda ji {{w|alfabeya latînî}} bikar tîne, ev parametre dikare ji bo pêşkêşkirina latînîzekirineke wê were bikaranîn. Ev dişibihe parametreya {{para|tr}} ji bo nivîsa jêgirtî ya sereke.]=]}, {"subst-orîjînal", [=[Cîguherînên fonetîk ku têne bikaranîn ji bo çareserkirina latînîzekirinên nerêbaz ên nivîsa jêgirtî ya orîjînal di hin zimanan de bi pergaleke nivîsandinê ya ne-latînî û latînîzekirina otomatîk (wek rûsî û yîdî). Ev dişibihe parametreya {{para|subst}} ji bo nivîsa jêgirtî ya sereke.]=]}, {"ts-orîjînal", [=[Nivîsandina fonetîk a nivîsa jêgirtî ya orîjînal, heke ne bi herfên latînî be di zimanekî de ku latînîzekirin ji telafuza rastîn pir cuda ye (wek akadî, misrî ya kevn û tîbetî). Ev dişibihe parametreya {{para|ts}} ji bo nivîsa jêgirtî ya sereke û nebe tenê ji bo dayîna telafuza IPA'yê were bikaranîn.]=]}, {"sc-orîjînal", [=[Koda xeta nivîsê ya nivîsa jêgirtî ya orîjînal, heke ne bi xeta latînî be. Ji bo agahiyên zêdetir li [[Wiktionary:Scripts]] binêre. Kêm caran lazim e ev were diyarkirin çimkî xeta nivîsê ji nivîsa jêgirtî tê naskirin.]=]}, {"normsc-orîjînal", [=[Koda xeta nivîsê ya nivîsa standardkirî di {{para|norm-orîjînal}} de, heke ne bi xeta latînî be. Heke neyê dayîn, û nirxek di {{para|sc-orîjînal}} de hatibe dayîn, ev nirx dê were bikaranîn; wekî din (an heke {{para|normsc-orîjînal|auto}} hatibe dayîn), xeta nivîsê ji nivîsê bixwe tê naskirin.]=]}, {"e-orîjînal", [=[Etîket(ên) nivîsa jêgirtî ya orîjînal. Ev dişibihe parametreya {{para|e}} ji bo nivîsa jêgirtî ya sereke.]=]}, }, {"Parametreyên li gorî tarîxê", {"tarîx", [=[Tarîxa ku <<work>> hatiye weşandin. An {{para|sal}} (û bi îxtiyarî {{para|meh}}), an {{para|tarîx}} bikar bîne, ne herduyan. Nirxa {{para|tarîx}} divê tarîxeke rastîn be, bi an bêyî roj, ne nivîseke azad. Çend format tên qebûlkirin; tê tewsiyekirin ku an bi forma ISO 8601 (''SAL''-''MEH''-''ROJ'') binivîse, wek nimûne {2023-08-11}, an jî mehê bi tevahî binivîse, wek nimûne {2023 tebax 11} (guhertoyên vê jî tên qebûlkirin, wek {tebax 11 2023} an {11 tebax 2023}). Tu dikarî rojê derxî û koda dê hewl bide tarîxê tenê bi meh û salê nîşan bide. Bêyî girêdana bi forma têketinê, derana wê dê bi forma {'''''SAL''''' ''Meh'' ''ROJ''} (an tenê {'''''SAL''''' ''Meh''}) were nîşandan, wek {'''2023''' tebax 11} (an {'''2023''' tebax} heke roj nehatibe dayîn).]=]}, {{"sal", "meh", annotated = true, useand = true}, [=[Sal û (bi îxtiyarî) meha ku <<work>> hatiye weşandin. Nirxên van parametreyan neyên şîrovekirin, û heke lazim be nivîseke azad dikare were dayîn. Heke berî salê {c.} hebe, wek nimûne {c. 1665}, ev nîşan dide ku sala weşandinê {{lg|c.|nêzîkî}} sala diyarkirî ye; bi heman rengî {a.} nîşan dide sala weşandinê {{lg|a.|berî}} sala diyarkirî ye, û {p.} nîşan dide sala weşandinê {{lg|p.|piştî}} sala diyarkirî ye. Sal bi herfên qalind tê nîşandan ji bilî ku nirxa parametreya {{para|sal}} bixwe jixwe herfên qalind tê de hebin, û meh (heke were dayîn) li dû wê tê. Heke ne tarîx û ne jî sal/meh hatibe dayîn, şablon peyama "(Tu dikarî [[:Category:Requests for date|tarîxa]] vê jêgirtinê binivîsî?)" nîşan dide û rûpelê li kategoriya [[:Category:Requests for date in LANG entries]] zêde dike, bi zimanê di {{para|1}} de hatiye dayîn. Peyam û zêdekirina kategoriyê dikarin bi {{para|bêtarîx|1}} werin vemirandin, lê tê tewsiyekirin ku tu hewl bidî tarîxek an tarîxeke texmînî bidî li şûna vê. Zêdekirina kategoriyê bi tenê dikare bi {{para|nekat|1}} were vemirandin, lê bi giştî ev nayê tewsiyekirin.]=]}, {"tarîxa-destpêkê", [=[Heke weşandin di nava rêzeyeke tarîxan de bûbe, tarîxa destpêkê bixe {{para|tarîxa-destpêkê}} (an {{para|sala-destpêkê}}/{{para|meha-destpêkê}}) û tarîxa dawî jî bixe {{para|tarîx}} (an {{para|sal}}/{{para|meh}}). Forma {{para|tarîxa-destpêkê}} wek ya {{para|tarîx}} e. Heke tarîx heman salê hebin lê meh û roja wan cuda be, sal tenê carekê tê nîşandan, bi heman rengî heke tenê roj cuda be. Tenê yekê ji {{para|tarîxa-destpêkê}} an {{para|sala-destpêkê}}/{{para|meha-destpêkê}} bikar bîne, ne herduyan.]=]}, {{"sala-destpêkê", "meha-destpêkê", annotated = true, useand = true}, [=[Wekî din, rêzeyekê bi bicîhkirina sal û meha destpêkê di {{para|sala-destpêkê}} û (bi îxtiyarî) {{para|meha-destpêkê}} de diyar bike. Ev dikarin nivîseke azad hebin, wek {{para|sal}} û {{para|meh}}. Ji bo diyarkirina ku weşandin nêzîkî, berî an piştî rêzeyeke diyarkirî ye, nîşanera munasib ({c.}, {a.} an {p.}) berî nirxa {{para|sal}} bicîh bike, ne berî nirxa {{para|sala-destpêkê}}.]=]}, {{"bêtarîx", boolean = true}, [=[Heke <<work>> bêtarîx be û tu tarîx (heta ya texmînî) bi awayekî maqûl neyê destnîşankirin, {{para|bêtarîx|1}} diyar bike. Ev rêza lênêrînê ya ku bi giştî tê nîşandan heke tarîx neyê dayîn, vedimirîne. Vê tenê ji ber ku tu tarîxê nizanî bikar neyîne; li şûna wê, tarîxê derxe û bihêle rêza lênêrînê were nîşandan û rûpel li kategoriya munasib a lênêrînê were zêdekirin, da ku kesekî din bikaribe alîkariyê bike.]=],}, }, {"Parametreyên li gorî nivîskar", {{"nivîskar", list = true, multientity = true}, [=[Nav(ên) nivîskar(an) ê/ên <<work>> ya jêgirtî. Çend nivîskaran bi niqteya bi virgul ji hev cuda bike, an parametreyên zêde {{para|nivîskar2}}, {{para|nivîskar3}}, hwd. bikar bîne. Wekî din, {{para|paşnav}} û {{para|pêşnav}} bikar bîne (ji bo pêşnav, û navên navîn an herfên pêşî), digel {{para|paşnav2}}/{{para|pêşnav2}} ji bo nivîskarên zêde. Herduyan bi hev re bikar neyîne.]=]}, {{"paşnav", "pêşnav", useand = true, list = true}, [=[Pêşnav (digel navên navîn an herfên pêşî) û paşnav(ên) nivîskar(an) ê/ên <<work>> ya jêgirtî. Ji bo nivîskarên zêde {{para|paşnav2}}/{{para|pêşnav2}}, {{para|paşnav3}}/{{para|pêşnav3}}, hwd. bikar bîne. Tê tercihkirin ku {{para|nivîskar}} li şûna {{para|paşnav}}/{{para|pêşnav}} were bikaranîn, bi taybetî ji bo navên axaftvanên zimanên biyanî, ku dibe hêsan nebe ew bikevin pêşnav û paşnavan. Bala xwe bide ku van parametreyan guherkerên paşiyê an guherkerên pêşiyê piştgirî nakin, û naskirina xeta nivîsê ya otomatîk nakin; ji ber vê yekê ew tenê dikarin ji bo navên bi herfên latînî werin bikaranîn.]=]}, {{"lînka-nivîskar", list = true}, [=[Navê meqaleyeke [https://en.wikipedia.org Wîkîpediyaya îngilîzî] li ser nivîskar, ku dê bi nav(ên) di {{para|nivîskar}} an {{para|paşnav}}/{{para|pêşnav}} de hatine dayîn ve were girêdan. Meqaleyên zêde dikarin bi navên nivîskarên din ve bi parametreyên {{para|lînka-nivîskar2}}, {{para|lînka-nivîskar3}}, hwd. werin girêdan. Pêşgira {:en:} an {w:} zêde neke. Wekî din, navê her kesî rasterast girêbide, wiha: {{para|nivîskar|<nowiki>[[w:Kathleen Taylor (biologist)|Kathleen Taylor]]</nowiki>}} an {{para|nivîskar|<nowiki>{{w|Samuel Johnson}}</nowiki>}}.]=]}, {{"hevnivîskar", multientity = true}, "Nav(ên) hevnivîskar(ên) <<work>>. Çend navan bi niqteya bi virgul ji hev cuda bike."}, {{"nivîskarê-sereke", multientity = true}, [=[Heke tu dixwazî diyar bikî ku perçeyek ji <<work:a>>, wek pêşgotin an destpêk, ji hêla kê ve hatiye nivîsandin, {{para|nivîskar}} bikar bîne, û {{para|nivîskarê-sereke}} jî bikar bîne ji bo diyarkirina nivîskar(ên) perçeya sereke ya <<work>>. Çend nivîskaran bi niqteya bi virgul ji hev cuda bike.]=]}, {{"terciman", multientity = true}, [=[Nav(ên) terciman(ên) <<collection>>. Çend navan bi niqteya bi virgul ji hev cuda bike. Xuyabûna rastîn girêdayî ye ka nivîskar an hevnivîskar berî wê hatine nîşandan an na. Heke ne, forma {John Doe, Mary Bloggs, wergêr} an {John Doe, Mary Bloggs, Richard Roe, wergêr} tê bikaranîn, bi navan pêşî. Wekî din, forma {tercimekirina John Doe û Mary Bloggs} an {tercimekirina John Doe, Mary Bloggs û Richard Roe} tê bikaranîn, da ku nivîskar(an) ji terciman(an) baştir cuda bike. Bala xwe bide ku di her du rewşan de jî niqteya bi virgul di derana wê de nayên bikaranîn wek sînorker.]=]}, {{"edîtor", multientity = true}, [=[Nav(ên) edîtor(ên) <<collection>>. Çend navan bi niqteya bi virgul ji hev cuda bike. Ev bi prensîbên dişibihin ên tercimanan, wek li jor: bêyî nivîskar, hevnivîskar an terciman berî wê, forma {John Doe, edîtor} an {John Doe, Mary Bloggs, Richard Roe, edîtor} (heke ji edîtorekî zêdetir hebe) tê bikaranîn. Wekî din, forma {bi edîtoriya John Doe û Mary Bloggs} an {bi edîtoriya John Doe, Mary Bloggs û Richard Roe} tê bikaranîn.]=],}, {{"editors", multientity = true}, [=[Nav(ên) edîtorên <<collection>>. Çend navan bi niqteya bi virgul ji hev cuda bike. Ferqa vê ya digel {{para|edîtor}} ev e ku dema nivîskar, hevnivîskar an terciman berî wê tune, ev parametre her tim "edîtor" nîşan dide, dema {{para|edîtor}} li gorî hejmara hebûnên diyarkirî "edîtor" an "edîtor" nîşan dide. (Hîna bernavek kurmancî ji bo dîtina vê cudatiyê bi taybetî nehatiye çêkirin; "editors" bikar bîne.)]=]}, {{"berhevkar", multientity = true}, [=[Nav(ên) berhevkar(ên) <<collection>>. Çend navan bi niqteya bi virgul ji hev cuda bike. Berhevkar dişibihin edîtoran lê bi taybetî ji bo berhevokên ji materyalên çavkaniyê (wek çîrokên devkî, stranên gelêrî, nameyên kesekî navdar, hwd.) têne bikaranîn. Ev qad wek {{para|edîtor}} dixebite lê "berhevkirin" li şûna "edîtorî" û "berhevkar(an)" li şûna "edîtor(an)" nîşan dide.]=]}, {{"compilers", multientity = true}, [=[Nav(ên) berhevkarên <<collection>>. Çend navan bi niqteya bi virgul ji hev cuda bike. Ji bo kengî ev bête bikaranîn li {{para|berhevkar}} binêre. (Hîna bernavek kurmancî ji bo vê cudatiyê nehatiye çêkirin; "compilers" bikar bîne.)]=]}, {{"jê-tê-girtin", multientity = true}, [=[Navê kesê tê jêgirtin, heke hemû nivîsa jêgirtî jêgirtina kesekî din e ne ya nivîskar bixwe.]=]}, }, {"Parametreyên li gorî sernav", {{"sernav", annotated = true, required = true}, [=[Sernavê <<collection>>.]=]}, {"tercimeya-sernav", [=[Heke sernavê <<collection>> bi îngilîzî/kurmancî nebe, ev parametre dikare ji bo pêşkêşkirina tercimeyeke sernav were bikaranîn, wekî alternatîfek ji bo diyarkirina tercimeyê bi guherkereke paşiyê (li jor binêre).]=]}, {{"serî", annotated = true}, [=[{{w|Rêzefirotina kitêban|Serî}}ya ku <<collection>> endamê wê ye.]=]}, {{"cildê-seriyê", annotated = true}, [=[Hejmara cildê <<collection>> di nava seriyê de ku endamê wê ye.]=]}, {"url", [=[URL'ya an navnîşana webê ya malperekê derveyî ku nivîsa tam a <<work>> tê de heye. ''Bi hîç malperekê ku muhtewaya wê mafê telîfê xera dike ve negire''.]=]}, {"urls", [=[Nivîseke azad, ji bo çend URL'yan. Berevajî {{para|url}}, edîtor divê bixwe kevanên URL'ê {[]} zêde bike.]=]}, }, {"Parametreyên li gorî beşê", {{"beş", annotated = true}, [=[Beşa <<collection>> ya jêgirtî. Tu dikarî an hejmareke beşê bi hejmarên erebî an romayî diyar bikî (wek nimûne, {{para|beş|7}} an {{para|beş|VII}}), an jî sernavekî beşê (wek nimûne, {{para|beş|Destpêk}}). Beşeke bi hejmarên erebî an romayî ya diyarkirî bi kelîmeya "beş" tê pêşgirtin, dema sernavekî beşê di "gîrçikên nîşandanê" de tê girtin.]=]}, {{"hejmara-beşê", annotated = true}, [=[Heke navê beşê di {{para|beş}} de hatibe dayîn, {{para|hejmara-beşê}} bikar bîne ji bo dayîna hejmara beşê ya li hev, ku dê di kevanan de li dû kelîmeya "beş" were nîşandan, wek nimûne {"Ceribandin" (beş 4)}.]=]}, {{"beş-sade", annotated = true}, [=[Nirxa tam a beşê, ku wek xwe tê nîşandan. Peyva "beş" û her gîrçikên xwestî zêde bike. Heke hem {{para|beş}} hem jî {{para|beş-sade}} hatibin dayîn, nirxa {{para|beş-sade}} li dû beşê, di kevanan de, tê nîşandan. Ev kêrhatî ye heke beşên vê <<collection>>ê bi kelîmeyek din a ji "beş" cuda werin binavkirin.]=]}, {"urlya-beşê", [=[[[w:Universal Resource Locator|URL]]'ya an navnîşana webê ya rûpeleke derveyî ku beş pê ve tê girêdan. Bala xwe bide ku bi giştî çêtir e {{para|urlya-rûpelê}} bikar bînî ji bo girêdana rasterast bi rûpela nivîsa jêgirtî, heke gengaz be. ''Bi hîç malperekê ku muhtewaya wê mafê [[w:copyright|telîfê]] xera dike ve negire''.]=]}, {"tercimeya-beş", [=[Heke beşa <<collection>> bi îngilîzî/kurmancî nebe, ev parametre dikare ji bo pêşkêşkirina tercimeyeke navê beşê were bikaranîn, wekî alternatîfek ji bo diyarkirina tercimeyê bi guherkereke paşiyê (li jor binêre).]=]}, {{"tercimanê-beşê", multientity = true}, [=[Tercimanê beşê, heke ji tercimanê giştî yê <<collection>> cuda be (bi {{para|terciman}} hatiye diyarkirin).]=]}, {{"seriya-beşê", "cildê-seriya-beşê", useand = true, annotated = true}, [=[Heke ev beş perçeyek e ji seriyeke beşên dişibihin, {{para|seriya-beşê}} dikare ji bo diyarkirina navê seriyê were bikaranîn, û {{para|cildê-seriya-beşê}} jî ji bo diyarkirina jimareya seriyê, heke hebe. Parametreyên {{para|serî}} û {{para|cildê-seriyê}} yên ji bo <<collection>> bi tevahî bide ber hev. Ev parametre bi taybetî ji bo stûnên dubareyî yên di rojnameyekê an tiştekî bi vî rengî de têne bikaranîn. Di {{şx|jêder-kovar}} de, parametreya {{para|beş}} wek {{para|sernav}} an {{para|meqale}} tê binavkirin û ji bo navê meqaleyeke kovarê, kovarê an rojnameyê tê bikaranîn, û parametreya {{para|seriya-beşê}} jî wek {{para|seriya-meqaleyê}} tê binavkirin û ji bo navê stûn an seriya meqaleyan a ku meqale perçeyek ji wê ye tê bikaranîn.]=]}, }, {"Parametreyên li gorî qismê", {{"qisim", annotated = true}, [=[Vê parametreyê bikar bîne ji bo diyarkirina perçeyeke (bi giştî bi hejmar) ji <<work:a>>, wekî alternatîf an temamkerê diyarkirina beşekê. Wek nimûne, di lîstikeke şanoyê de, {{para|qisim|perde II, dîmen iv}} bikar bîne, û di meqaleyeke kovareke teknîkî de, {{para|qisim|4}} bikar bîne. Heke nirxa vê parametreyê wek hejmareke romayî an erebî xuya bike, ew bi kelîmeya "qisim" tê pêşgirtin, wekî din wek xwe tê nîşandan (bide ber hev bi awayê wekhev ê {{para|beş}}).]=]}, {{"hejmara-qismê", annotated = true}, [=[Heke navê qismekê di {{para|qisim}} de hatibe dayîn, {{para|hejmara-qismê}} bikar bîne ji bo dayîna hejmara qismê ya li hev, ku dê di kevanan de li dû kelîmeya "qisim" were nîşandan, wek nimûne {Ceribandin (qisim 4)}.]=]}, {{"qisim-sade", annotated = true}, [=[Nirxa tam a qismê, ku wek xwe tê nîşandan; bide ber {{para|beş-sade}}. (Ev tenê ji bo temambûnê hatiye dayîn û bi giştî ne kêrhatî ye, çimkî nirxa {{para|qisim}} jî wek xwe tê nîşandan heke wek hejmarekê xuya nake.)]=]}, {"urlya-qismê", [=[[[w:Universal Resource Locator|URL]]'ya an navnîşana webê ya rûpeleke derveyî ku qisim pê ve tê girêdan. ''Bi hîç malperekê ku muhtewaya wê mafê [[w:copyright|telîfê]] xera dike ve negire''.]=]}, {"tercimeya-qism", [=[Heke qisma <<work>> bi îngilîzî/kurmancî nebe, ev parametre dikare ji bo pêşkêşkirina tercimeyeke qismê were bikaranîn, wekî alternatîfek ji bo diyarkirina tercimeyê bi guherkereke paşiyê (li jor binêre).]=]}, {{"rêzeya-qismê", "cildê-seriya-qismê", useand = true, annotated = true}, [=[Heke ev qisim perçeyek e ji seriyeke qismên dişibihin, {{para|rêzeya-qismê}} dikare ji bo diyarkirina navê seriyê were bikaranîn, û {{para|cildê-seriya-qismê}} jî ji bo diyarkirina jimareya seriyê, heke hebe. Parametreyên {{para|serî}} û {{para|cildê-seriyê}} yên ji bo <<collection>> bi tevahî, û {{para|seriya-beşê}} û {{para|cildê-seriya-beşê}} yên ji bo beşekê bide ber hev.]=]}, }, {"Parametreyên li gorî rûpel û rêzê", {{"rûpel", "rûpelên", annotated = true}, [=[Hejmara rûpel(an) an rêzeya rûpelan a <<work>>. Xeta dirêj (–) bikar bîne ji bo cudakirina hejmarên rûpelan a rêzeyê. Bi normal, {{para|rûpel}} û {{para|rûpelên}} bernavên hev in, û koda bixwe naskirin dike ka "rûpel" a yekjimar an "rûpelên" a pirjimar were nîşandan. Koda naskirinê "rûpelên" nîşan dide heke xeta dirêj (–), xeteke dirêjtir (—), xêzikek di navbera hejmaran de, an komek li dû valahiyekê û di navbera hejmaran de bibîne (valahî lazim e, da ku hejmar wek {1,478} bi cudakera hezaran neyên hesibandin wekî çend rûpel). Ji bo vemirandina vê naskirinê (wek nimûne, hin kitêb rûpelên xêzikî hene wek {3-16}), berî nirxê nîşana devnîgaşê ({!}) bicîh bike; heke ev were dayîn, navê parametreyê diyar dike ka "rûpel" an "rûpelên" were nîşandan. Wekî din, {{para|rûpel-sade}} bikar bîne. Wekî rewşeke taybet, nirxa {bêhejmar} dibe sedem {rûpela bêhejmar} were nîşandan.]=]}, {{"rûpel-sade", annotated = true}, [=[Nivîseke azad ku rûpel an rûpelên nivîsa jêgirtî diyar dike, wek nimûne {rûpela 8an} an {berga paşîn}. Tenê yekê ji {{para|rûpel}}, {{para|rûpelên}} û {{para|rûpel-sade}} bikar bîne.]=]}, {"urlya-rûpelê", [=[URL'ya an navnîşana webê ya rûpela ku rûpel(ên) <<work>> ê behskirî tê de ne. Hejmara rûpel(an) dê pê ve bê girêdan.]=]}, {{"rêz", "rêzên", annotated = true}, [=[Hejmara rêz(an) a nivîsa jêgirtî, wek nimûne {47} an {151–154}. Ev parametre wek {{para|rûpel}} û {{para|rûpelên}} dixebitin. Hejmara rêzan bi gelemperî di lîstikên şanoyê, helbestan û hin berhemên teknîkî de tên bikaranîn.]=]}, {{"rêz-sade", annotated = true}, [=[Nivîseke azad ku hejmara rêz(an) a nivîsa jêgirtî diyar dike, wek nimûne {beytên 44–45} an {jêrenot 3}. Tenê yekê ji {{para|rêz}}, {{para|rêzên}} û {{para|rêz-sade}} bikar bîne.]=]}, {"urlya-rêzê", [=[URL'ya an navnîşana webê ya rûpela ku rêz(ên) <<work>> ê behskirî tê de ne. Hejmara rêz(an) dê pê ve bê girêdan.]=]}, {{"stûn", "stûnên", "stûn-sade", useand = true, annotated = true}, [=[Hejmara stûn(an) a nivîsa jêgirtî. Ev parametre wek {{para|rûpel}}, {{para|rûpelên}} û {{para|rûpel-sade}} dixebitin.]=]}, {"urlya-stûnê", [=[URL'ya hejmara stûn(an) a nivîsa jêgirtî. Ev parametre wek {{para|urlya-rûpelê}} dixebite.]=]}, }, {"Parametreyên li gorî weşandinê", {{"weşanxane", multientity = true}, [=[Navê yek an çend weşanxaneyên <<collection>>. Heke ji weşanxaneyekê zêdetir hebe, navan bi niqteya bi virgul ji hev cuda bike.]=]}, {{"cih", multientity = true}, [=[Cihê ku <<collection>> lê hatiye weşandin. Heke ji cihekî zêdetir hebe, ciyan bi niqteya bi virgul ji hev cuda bike, wiha: {London; New York, N.Y.}.]=]}, {{"çap", annotated = true}, [=[Çapa <<collection>> ya jêgirtî, wek nimûne, {2an} an <code>3an a rastkirî û nûvekirî</code>. Li dû vê nivîsê kelîmeya "çap" tê zêdekirin (ji bo vemirandina vê {{para|çap-sade}} bikar bîne). Heke ji çapa yekem a <<collection>> tê jêgirtin, bi giştî ne lazim e ev rastî were diyarkirin.]=]}, {{"çap-sade", annotated = true}, [=[Nivîseke azad ku çapa <<collection>> ya jêgirtî diyar dike, wek nimûne {çapa 3an} an {çapa 5an, dîjîtalîzekirî} an {guhertoya 3.72}.]=]}, {{"sala-weşandinê", "meha-weşandinê", annotated = true, useand = true}, [=[Heke {{para|sal}} ji bo diyarkirina sala guhertoya orîjînal a <<issue>> tê bikaranîn, {{para|sala-weşandinê}} dikare ji bo diyarkirina sala guhertoya ku jê hatiye jêgirtin were bikaranîn, wek nimûne {|sal=1665|sala-weşandinê=2005}. {{para|meha-weşandinê}} dikare bi îxtiyarî ji bo diyarkirina meha weşandinê were bikaranîn. Sala weşandinê bi kelîmeya "weşandî" tê pêşgirtin. Ev parametre wek {{para|sal}} û {{para|meh}} têne xebitandin (ji bilî ku sal bi awayekî standard bi herfên qalind nayê nîşandan). Ev tê wê wateyê, wek nimûne, ku pêşgirên {c.}, {a.} û {p.} têne naskirin ji bo diyarkirina ku weşandin nêzîkî/berî/piştî tarîxeke diyarkirî bûye.]=]}, {"tarîxa-weşandinê", [=[Tarîxa ku guhertoya <<issue>> ya jêgirtî pê hatiye weşandin. An {{para|sala-weşandinê}} (û bi îxtiyarî {{para|meha-weşandinê}}), an {{para|tarîxa-weşandinê}} bikar bîne, ne herduyan. Wek {{para|tarîx}}, nirxa {{para|tarîxa-weşandinê}} divê tarîxeke rastîn be, bi an bêyî roj, ne nivîseke azad. Heman format wek yên {{para|tarîx}} tên naskirin.]=]}, {{"sala_destpêkê-weşandin", "meha-destpêkê-weşandin", annotated = true, useand = true}, [=[Heke weşandina guhertoya jêgirtî di nava rêzeyeke tarîxan de bûbe, sala destpêkê (û bi îxtiyarî meh) bi van parametreyan diyar bike û tarîxa dawî jî bixe {{para|sala-weşandinê}}/{{para|meha-weşandinê}} (an {{para|tarîxa-weşandinê}}). Ev bi awayekî wekhev bi {{para|sala-destpêkê}}/{{para|meha-destpêkê}} dixebite. Kêm caran lazim e van parametreyan bikar bînî.]=]}, {"tarîxa-destpêkê-weşandin", [=[Tarîxa destpêkê ya weşandina guhertoya jêgirtî, wekî alternatîfek ji bo diyarkirina {{para|sala_destpêkê-weşandin}}/{{para|meha-destpêkê-weşandin}}. Ev wek {{para|tarîxa-destpêkê}} dixebite. Kêm caran lazim e ev parametre were diyarkirin.]=]}, {{"sala-orîjînal", "meha-orîjînal", annotated = true, useand = true}, [=[Sala ku <<work>> cara pêşî hatiye weşandin, heke <<work>> ya jêgirtî guhertoyeke nû ya <<work:a>> ye (ne tenê çapeke nû). Wek nimûne, heke ji çapeke nûjen a Shakespeare an Milton tê jêgirtin, tarîxa çapa nûjen bixe {{para|sal}}/{{para|meh}} an {{para|tarîx}} û tarîxa çapa orîjînal jî bixe {{para|sala-orîjînal}}/{{para|meha-orîjînal}} an {{para|tarîxa-orîjînal}}. {{para|meha-orîjînal}} dikare bi îxtiyarî ji bo dayîna meha weşandina orîjînal were bikaranîn, an tarîxeke tam bi {{para|tarîxa-orîjînal}} were dayîn. An {{para|sala-orîjînal}}/{{para|meha-orîjînal}}, an {{para|tarîxa-orîjînal}} bikar bîne, ne herduyan. Ev parametre wek {{para|sal}} û {{para|meh}} têne xebitandin (ji bilî ku sal bi awayekî standard bi herfên qalind nayê nîşandan). Ev tê wê wateyê, wek nimûne, ku pêşgirên {c.}, {a.} û {p.} têne naskirin ji bo diyarkirina ku weşandina orîjînal nêzîkî/berî/piştî tarîxeke diyarkirî bûye.]=]}, {"tarîxa-orîjînal", [=[Tarîxa ku guhertoya orîjînal a <<work>> ya jêgirtî pê hatiye weşandin. An {{para|sala-orîjînal}} (û bi îxtiyarî {{para|meha-orîjînal}}), an {{para|tarîxa-orîjînal}} bikar bîne, ne herduyan. Wek {{para|tarîx}}, nirxa {{para|tarîxa-orîjînal}} divê tarîxeke rastîn be, bi an bêyî roj, ne nivîseke azad. Heman format wek yên {{para|tarîx}} tên naskirin.]=]}, {{"sala-destpêkê-orîjînal", "meha-destpêkê-orîjînal", annotated = true, useand = true}, [=[Sal/meha destpêkê ya guhertoya orîjînal a weşandinê, heke weşandin di nava rêzeyeke tarîxan de bûbe. An {{para|sala-destpêkê-orîjînal}} (û bi îxtiyarî {{para|meha-destpêkê-orîjînal}}), an {{para|tarîxa-destpêkê-orîjînal}} bikar bîne, ne herduyan. Ev bi awayekî wekhev bi {{para|sala-destpêkê}} û {{para|meha-destpêkê}} dixebite, û pir kêm caran lazim e were diyarkirin.]=]}, {"tarîxa-destpêkê-orîjînal", [=[Tarîxa destpêkê ya guhertoya orîjînal a weşandinê, heke weşandin di nava rêzeyeke tarîxan de bûbe. Ev wek {{para|tarîxa-destpêkê}} dixebite, û pir kêm caran lazim e were diyarkirin.]=]}, {{"platform", multientity = true}, [=[Platforma ku <<work>> lê hatiye weşandin. Ev ji bo platformên berhevkirina muhtewayê ne wek {{w|YouTube}}, {{w|Issuu}} û {{w|Magzter}}. (Hîna bernavek kurmancî ji bo vê parametreyê nehatiye çêkirin.) Ev wek "bi rêya PLATFORM" tê nîşandan.]=]}, {{"çavkanî", multientity = true}, [=[Çavkaniya muhtewaya <<work>>. Ev bi taybetî ji bo ajansên nûçeyan e wek {{w|Associated Press}}, {{w|Reuters}} û {{w|Agence France-Presse}} (AFP) (û ji ber vê yekê di {{şx|jêder-kovar}} de wek {{para|ajans}} tê binavkirin). Ev wek "ji ÇAVKANÎ hatiye wergirtin" tê nîşandan.]=]}, }, {"Parametreyên li gorî cildê", {{"cild", "cildên", annotated = true}, [=[Hejmara cild(an) a <<collection>>. Ev wek "cild CILD" tê nîşandan, an "cildên CILDÊN" heke rêzeyeke hejmaran were dayîn. Ka "cild" an "cildên" were nîşandan bi awayekî wekhev ê {{para|rûpel}} û {{para|rûpelên}} tê naskirin; {!} li destpêka nirxê bicîh bike ji bo vemirandina vê û rêzgirtina navê parametreyê. {{para|cild-sade}} bikar bîne heke tu nexwazî kelîmeya "cild" berî hejmara cildê xuya bibe.]=]}, {{"cild-sade", annotated = true}, [=[Nivîseke azad ku hejmara cild(an) a <<collection>> diyar dike, wek nimûne {kitêba II}. Tenê yekê ji {{para|cild}}, {{para|cildên}} û {{para|cild-sade}} bikar bîne.]=]}, {"urlya-cild", [=[URL'ya an navnîşana webê ya rûpela li hev a cildê ku nivîsa jêgirtî tê de ye, heke <<collection>> çend cild hebin bi URL'yên cuda. Hejmara cild(an) dê pê ve bê girêdan.]=]}, {{{"hejmar", "nimare"}, {"hejmarên", "nimareyên"}, {"hejmar-sade", "nimare-sade"}, useand = true, annotated = true}, [=[Hejmara/hejmarên nivîsa jêgirtî. Ev parametre wek {{para|rûpel}}, {{para|rûpelên}} û {{para|rûpel-sade}} dixebitin, ji bilî ku nivîsa xuyayî kelîmeya "hejmar" an "nimare" dihewîne (bêyî ferqa ka koma parametreyên {{para|hejmar}} an {{para|nimare}} têne bikaranîn; ew bernavên hev in). Nimûneyên bikaranîna {{para|hejmar-sade}} {kitêb 2} in (heke <<collection>> bi cildan hatibe dabeşkirin û cild jî bi kitêban) an {Hejmara Taybet 1} (ku têgeh ji almanî hatiye wergirtin, wateya "hejmareke taybet" dide).]=]}, {{{"urlya-hejmarê", "urlya-nimareyê"}, useand = true}, [=[URL'ya hejmara/hejmarên nivîsa jêgirtî. Ev parametre wek {{para|urlya-cild}} dixebite.]=]}, }, {"Parametreyên li gorî nasnameyê", {{"doi", "DOI"}, [=[[[w:Digital object identifier|Nasnameya berhema dîjîtal]] (DOI) ya <<work>>.]=]}, {{"isbn", "ISBN"}, [=[[[w:International Standard Book Number|Hejmara Standard a Navneteweyî ya Kitêbê]] (ISBN) ya <<collection>>. ISBN'ên 13-reqem tên tercihkirin li ser yên 10-reqem.]=]}, {{"issn", "ISSN"}, [=[[[w:International Standard Serial Number|Hejmara Rêzimalî ya Standard a Navneteweyî]] (ISSN) ya <<collection>>.]=]}, {{"jstor", "JSTOR"}, [=[Hejmara [[w:JSTOR|JSTOR]] ya <<work>>.]=]}, {{"lccn", "LCCN"}, [=[[[w:Library of Congress Control Number|Hejmara Kontrolê ya Pirtûkxaneya Kongreyê]] (LCCN) ya <<work>>.]=]}, {{"oclc", "OCLC"}, [=[Hejmara [[w:OCLC|Online Computer Library Center]] (OCLC) ya <<work>> (ku dikare li malpera [http://www.worldcat.org WorldCat] were lêgerandin).]=]}, {{"ol", "OL"}, [=[Hejmara [[w:Open Library|Open Library]] (bêyî "OL") ya <<work>>.]=]}, {{"pmid", "PMID"}, [=[Nasnameya [[w:PubMed#PubMed identifier|PubMed]] (PMID) ya <<work>>.]=]}, {{"pmcid", "PMCID"}, [=[Nasnameya [[w:PubMed Central#PMCID|PubMed Central]] (PMCID) ya <<work>>.]=]}, {{"ssrn", "SSRN"}, [=[Nasnameya [[w:Social Science Research Network|Social Science Research Network]] (SSRN) ya <<work>>.]=]}, {"bibcode", [=[{{w|Bibcode}}ya (koda bîbliyografîk, di pergalên daneyên stêrnasî de tê bikaranîn) <<work>>.]=]}, {"id", [=[Her nasnameyeke din a <<work>>.]=]}, }, {"Parametreyên li gorî arşîv û gihiştinê", {{"urlya-arşîvê", "tarîxa-arşîvê", useand = true}, [=[{{para|urlya-arşîvê}} û {{para|tarîxa-arşîvê}} (ku divê digel hev werin dayîn) bikar bîne ji bo diyarkirina URL'ya an navnîşana webê ya rûpeleke malperekê wek [https://archive.org Internet Archive] an [https://perma.cc Perma.cc] ku rûpel lê hatiye arşîvkirin, û tarîxa ku rûpel lê hatiye arşîvkirin.]=]}, {"tarîxa-gihiştinê", [=[Heke rûpel neyê arşîvkirin, {{para|tarîxa-gihiştinê}} bikar bîne ji bo diyarkirina tarîxa dawî ya ku rûpel hatiye gihiştin. Berevajî parametreyên din ên tarîxê, ev parametre nivîseke azad e. (Heke rûpel hatibe arşîvkirin, ne lazim e ev parametre were bikaranîn.)]=]}, }, {"Parametreyên cihêreng ên rêza jêderê", {"format", [=[Formata ku <<work>> lê ye, wek nimûne, {hardcover} an {paperback} ji bo kitêbekê an {blog} ji bo rûpeleke webê. (Hîna bernavek kurmancî ji bo vê parametreyê nehatiye çêkirin.)]=]}, {"janr", [=[{{w|Janra edebî}} ya <<work>>, wek nimûne {fiction} an {non-fiction}.]=]}, {"medium", [=[Medyaya qeydkirina <<work>>, wek nimûne, {Blu-ray}, {CD}, {DVD}, {fîlim}, {podcast}, {berhema televizyonê}, {qeyda dengî} an {kaseta vîdyoyê}. (Hîna bernavek kurmancî ji bo vê parametreyê nehatiye çêkirin.)]=]}, {{"nekat", boolean = true}, [=[{{para|nekat|1}} diyar bike ji bo vemirandina zêdekirina rûpelê li kategoriyeke bi forma {Kategorî:Jêgirtinên bi ``ziman``}. Ev bi normal nabe were kirin.]=]}, {{"nocolon", boolean = true}, [=[{{para|nocolon|1}} diyar bike ji bo vemirandina zêdekirina niqteya bi virgul li dawiya rêza jêderê. (Hîna bernavek kurmancî ji bo vê parametreyê nehatiye çêkirin.) Ev dikare were bikaranîn heke sernav bixwe (an kêm caran, nirxeke din a rêza jêderê) termê behskirî nîşan bide. Bawer bike ku tu herfên qalind ên sêalî bikar tînî di termê behskirî de, wek nimûne <code><nowiki>'''term'''</nowiki></code>, da ku diyar bike ka nivîsa jêgirtî kîjan e.]=]}, {{"wekçavkanî", boolean = true}, [=[{{para|wekçavkanî|1}} diyar bike ji bo zorkirina formata "çavkaniyê" (nivîskar pêşî).]=]}, {{"wekjêgirtin", boolean = true}, [=[{{para|wekjêgirtin|1}} diyar bike ji bo zorkirina formata "jêgirtinê" (sal pêşî).]=]}, }, {"Guhertoya nû ya <<work:a>> (parametreyên <code>*2</code>)", [=[Parametreyên jêrîn dikarin werin bikaranîn ji bo diyarkirina guhertoyeke nû ya <<work>>, wek çapeke nû, çapeke din, an guhertoyeke din a ji nû ve hatî weşandin. Awayê giştî yê vê ev e: # {{para|versiyona-nû|ji nû ve hatiye weşandin wekî}}, {{para|versiyona-nû|hate tercimekirin wekî}}, {{para|versiyona-nû|hate jêgirtin di}} an tiştên bi vî rengî diyar bike ji bo nîşandana ka guhertoya nû çi ye. (Di hin rewşan de, ev parametre dikare neyê dayîn; li jêr binêre.) # Nivîskar(ên) guhertoya nû bi {{para|2nivîskar}} diyar bike (çend nivîskaran bi niqteya bi virgul ji hev cuda bike) an {{para|2paşnav}}/{{para|2pêşnav}}. # Taybetmendiyên mayî yên guhertoya nû bi zêdekirina {2} li dû parametreyên li jor hatine diyarkirin bide, wek nimûne {{para|sernav2}} ji bo sernavê guhertoya nû, {{para|rûpel2}} ji bo hejmara rûpelê ya guhertoya nû, hwd. Hin parametreyên taybet wekî alternatîfek ji bo diyarkirina guhertoyeke nû bi vî rengî têne peyakirin. Wek nimûne, parametreyên {{para|orîjînal}} û {{para|ji-aliyê}} dikarin werin bikaranîn dema guhertoyeke tercimekirî ya <<work:a>> tê jêgirtin; li jêr binêre.]=], {"versiyona-nû", [=[Şablon dihesibîne ku guhertoyeke nû ya <<work>> tê behskirin heke {{para|versiyona-nû}} an {{para|cih2}} hatibin dayîn, an heke parametreyên nivîskarê guhertoya nû hatibin dayîn ({{para|2nivîskar}} an {{para|2paşnav}}), an heke parametreyeke din a sernav an nivîskarê guhertoya nû hatibe dayîn (her yek ji {{para|beş2}}, {{para|sernav2}}, {{para|terciman2}}, {{para|edîtor2}}). Paşê wiha tevdigere: * Heke nivîskar, edîtor û/an sernav hatibin dayîn, "ji nû ve hatiye weşandin wekî" nîşan dide. * Heke tenê cih, weşanxane û tarîxa weşandinê hatibin dayîn, "ji nû ve hatiye weşandin" nîşan dide. * Heke çapek hatibe dayîn, tu nivîs nayê nîşandan. {{para|versiyona-nû}} bikar bîne ji bo betalkirina vê tevgerê, wek nimûne, bi nîşandana "hate jêgirtin di" an "ji nû ve hatiye çapkirin wekî".]=]}, {{"2nivîskar", multientity = true}, [=[Nivîskarê guhertoya nû. Çend nivîskaran bi niqteya bi virgul ji hev cuda bike. Wekî din, {{para|2paşnav}} û {{para|2pêşnav}} bikar bîne.]=]}, {{"2paşnav", "2pêşnav", useand = true}, [=[Pêşnav (digel navên navîn an herfên pêşî) û paşnavê nivîskarê guhertoya nû. Tê tercihkirin ku {{para|2nivîskar}} li şûna {{para|2paşnav}}/{{para|2pêşnav}} were bikaranîn, ji ber çend sedeman: # Navên axaftvanên zimanên biyanî dibe hêsan nebe ew bikevin pêşnav û paşnavan. # Tenê yek nivîskar dikare bi {{para|2paşnav}}/{{para|2pêşnav}} were diyarkirin, dema çend nivîskarên bi niqteya bi virgul ji hev cuda dikarin bi {{para|2nivîskar}} werin dayîn. # Guherkerên paşiyê ji bo {{para|2paşnav}} û {{para|2pêşnav}} nayên piştgirîkirin û naskirina xeta nivîsê nayê kirin, tê wê wateyê ku tenê navên bi herfên latînî têne piştgirîkirin.]=]}, {"2lînka-nivîskar", [=[Navê meqaleyeke [https://en.wikipedia.org Wîkîpediyaya îngilîzî] li ser nivîskar, ku dê bi nav(ên) di {{para|2nivîskar}} an {{para|2paşnav}}/{{para|2pêşnav}} de hatine dayîn ve were girêdan. Pêşgira {:en:} an {w:} zêde neke. Wekî din, navê her kesî rasterast girêbide, wiha: {{para|2nivîskar|<nowiki>[[w:Kathleen Taylor (biologist)|Kathleen Taylor]]</nowiki>}}.]=]}, {{"{{para|sernav2}}, {{para|edîtor2}}, {{para|cih2}}, ''hwd.''", literal = true, multientity = true}, [=[Piraniya parametreyên li jor hatine navborîn dikarin li guhertoyeke nû ya <<work>> werin sepandin bi zêdekirina {2} li dû navê parametreyê. Tê tewsiyekirin ku bi kêmanî agahiyên çapkirinê yên guhertoya nû ya <<work>> bi {{para|cih2}}, {{para|weşanxane2}}, û {{para|tarîx2}} an {{para|sal2}} bêne dayîn.]=]}, }, {"Awayên taybet ên alternatîf ên diyarkirina guhertoyeke nû ya <<work:a>>", [=[Parametreyên jêrîn awayên alternatîf peyda dikin ji bo diyarkirina guhertoyeke nû ya <<work:a>>, wek çapeke nû an tercimeyek, an rewşeke ku perçeyek ji <<work:a>> di ya din de tê jêgirtin. Heke tu bibînî ku ev parametre têrê nakin ji bo diyarkirina hemû agahiyên li ser her du berheman, hewl nede agahiyên zêde bi zorê tê xin. Li şûna wê, awayê li jor hatiye rave kirin bikar bîne, bi {{para|versiyona-nû}} û {{para|2nivîskar}}, {{para|sernav2}}, hwd.]=], {{"orîjînal", annotated = true}, [=[Heke tu {{w|berhemeke derekî}} wek tercimeyekê jêgirî dikî, {{para|orîjînal}} bikar bîne ji bo diyarkirina sernavê berhema orîjînal, {{para|ji-aliyê}} ji bo diyarkirina nivîskarê berhema orîjînal û {{para|deriv}} ji bo diyarkirina cureyê berhema derekî. An {{para|orîjînal}}, an {{para|ji-aliyê}} divê were dayîn da ku ev awa kêrhatî be. Heke her sê hatibin dayîn, koda {``deriv`` ya ``orîjînal`` ji hêla ``ji-aliyê`` ve} nîşan dide. Heke {{para|orîjînal}} neyê dayîn, nivîsa xwerû {orîjînal} tê bikaranîn. Heke {{para|deriv}} neyê dayîn, nivîsa xwerû {tercime} tê bikaranîn. Heke {{para|ji-aliyê}} neyê dayîn, perçeya "ji hêla {``ji-aliyê``} ve" nayê nîşandan.]=]}, {{"ji-aliyê", multientity = true}, [=[Heke tu {{w|berhemeke derekî}} wek tercimeyekê jêgirî dikî, {{para|ji-aliyê}} bikar bîne ji bo diyarkirina nivîskar(ên) berhema orîjînal. Li {{para|orîjînal}} ya li jor binêre.]=]}, {"deriv", [=[Heke tu {{w|berhemeke derekî}} wek tercimeyekê jêgirî dikî, {{para|deriv}} bikar bîne ji bo diyarkirina cureyê berhema derekî. (Hîna bernavek kurmancî ji bo vê parametreyê nehatiye çêkirin.) Li {{para|orîjînal}} ya li jor binêre.]=]}, {{"cihê-jêgirtinê", annotated = true}, [=[Heke nivîsa jêgirtî ji kitêba A ye ku dibêje ev nivîs ji kitêbeke din a B hatiye wergirtin, van bike: * {{para|sernav}}, {{para|çap}}, û {{para|kesên-din}} bikar bîne ji bo dayîna agahiyan li ser kitêba B. (Wek nimûne, {{para|kesên-din}} dikare wiha were bikaranîn: {{para|kesên-din=1893, rûpel 72}}.) * {{para|cihê-jêgirtinê}} (ji bo sernavê kitêba A), {{para|cih}}, {{para|weşanxane}}, {{para|sal}}, {{para|rûpel}}, {{para|oclc}}, û parametreyên din ên standard bikar bîne ji bo dayîna agahiyan li ser kitêba A.]=]}, }, } end local quote_mods = { ["jêder-kitêb"] = { {"#substitute", work = "kitêb", collection = "kitêb", issue = "kitêb"}, {"sal", addalias = "2"}, {"nivîskar", addalias = "3"}, {"sernav", addalias = "4"}, {"url", addalias = "5"}, {"rûpel", addalias = "6"}, {"jêgirtin", addalias = "7"}, {"tercime", addalias = "8"}, {"beş", addalias = "made", append_desc = [=[Parametreya {{para|made}} dikare were bikaranîn heke ji ferhengekê tê jêgirtin.]=]}, {"tercimeya-beş", addalias = "tercimeya-made", replace_desc = [=[Heke beşa, an madeya, kitêbê bi îngilîzî/kurmancî nebe, ev parametre dikare ji bo pêşkêşkirina tercimeyeke navê beş an madeyê were bikaranîn, wekî alternatîfek ji bo diyarkirina tercimeyê bi guherkereke paşiyê (li jor binêre).]=]}, {"urlya-beşê", addalias = "urlya-madeyê", replace_desc = [=[[[w:Universal Resource Locator|URL]]'ya an navnîşana webê ya rûpeleke derveyî ku beş an made pê ve tê girêdan. Wek nimûne, heke kitêb hejmara rûpelan tune, rûpel dikare bi navê beş an madeyê ve, bi vê parametreyê, were girêdan. ''Bi hîç malperekê ku muhtewaya wê mafê [[w:copyright|telîfê]] xera dike ve negire''.]=]}, }, ["jêder-kovar"] = { {"#substitute", work = "meqale", collection = "kovar", issue = "hejmara kovarê"}, {"sal", addalias = "2"}, {"nivîskar", addalias = "3"}, {"sernav", replace_params = {"kovar", "kovar", "xezete", "xebat", "5", annotated = true}}, {"tercimeya-sernav", replace_params = {"tercimeya-kovar", "tercimeya-kovar", "tercimeya-xezete", "tercimeya-xebat"}}, {"url", addalias = "6"}, {"rûpel", addalias = "7"}, {"jêgirtin", addalias = "8"}, {"tercime", addalias = "9"}, {"çavkanî", addalias = "ajans"}, {"#replace_group", "Parametreyên li gorî beşê", {"Parametreyên li gorî meqaleyê", {{"sernav", "meqale", "4", annotated = true, semi_required = true}, [=[Sernavê meqaleya kovarê ya jêgirtî, ku dê di "gîrçikên nîşandanê yên xemilandî" de were girtin.]=]}, {{"sernav-sade", "meqale-sade", annotated = true}, [=[Sernavê meqaleyê, ku wek xwe tê nîşandan. Her gîrçikên xwestî û kelîmeyên din zêde bike. Heke hem {{para|sernav}} hem jî {{para|sernav-sade}} hatibin dayîn, nirxa {{para|sernav-sade}} li dû sernavî, di kevanan de, tê nîşandan. Ev kêrhatî ye wek nimûne ji bo diyarkirina hejmara meqaleyê an nasnameyeke din.]=]}, {{"urlya-sernav", "urlya-meqaleyê"}, [=[[[w:Universal Resource Locator|URL]]'ya an navnîşana webê ya rûpeleke derveyî ku meqale pê ve tê girêdan. Bala xwe bide ku bi giştî çêtir e {{para|urlya-rûpelê}} bikar bînî ji bo girêdana rasterast bi rûpela nivîsa jêgirtî, heke gengaz be. ''Bi hîç malperekê ku muhtewaya wê mafê [[w:copyright|telîfê]] xera dike ve negire''.]=]}, {{"tercimeya-sernav", "tercimeya-meqale"}, [=[Heke meqaleya kovarê bi îngilîzî/kurmancî nebe, ev parametre dikare ji bo pêşkêşkirina tercimeyeke sernav were bikaranîn, wekî alternatîfek ji bo diyarkirina tercimeyê bi guherkereke paşiyê (li jor binêre).]=]}, {{"tercimanê-meqaleyê", multientity = true}, [=[Tercimanê meqaleyê, heke ji tercimanê giştî yê kovarê cuda be (bi {{para|terciman}} hatiye diyarkirin).]=]}, {{"seriya-meqaleyê", "cildê-seriya-meqaleyê", annotated = true, useand = true}, [=[Heke ev meqale perçeyek e ji seriyeke meqaleyên dişibihin, {{para|seriya-meqaleyê}} dikare ji bo diyarkirina navê seriyê were bikaranîn, û {{para|cildê-seriya-meqaleyê}} jî ji bo diyarkirina jimareya seriyê, heke hebe. Parametreyên {{para|serî}} û {{para|cildê-seriyê}} yên ji bo kovarê bi tevahî bide ber hev. Ev parametre dikarin werin bikaranîn, wek nimûne, ji bo stûnên dubareyî yên di rojnameyekê de.]=]}, } }, }, } local function canonicalize_paramspec(paramspec, add_non_generic) -- Canonicalize a top-level string param to a list. if type(paramspec) == "string" then paramspec = {paramspec} end for j, paramset in ipairs(paramspec) do -- Canonicalize a second-level string param to a list. if type(paramset) ~= "table" or paramset.param then paramset = {paramset} paramspec[j] = paramset end for k, param in ipairs(paramset) do -- Canonicalize a single param to object form. if type(param) == "string" then param = {param = param} if add_non_generic and param.non_generic == nil then param.non_generic = true end paramset[k] = param end end end return paramspec end local function canonicalize_param_group(group, add_non_generic) local ind = 2 if type(group[2]) == "string" then ind = ind + 1 end for i = ind, #group do -- Canonicalize the parameter spec to the maximally-expressed form for easier processing. local paramspec, desc = unpack(group[i]) group[i][1] = canonicalize_paramspec(paramspec, add_non_generic) end end local function canonicalize_param_list(params, add_non_generic) -- Canonicalize an addalias= spec to a list for easier processing. if type(params) ~= "table" or params.param then params = {params} end for i, p in ipairs(params) do -- Canonicalize. if type(p) == "string" then p = {param = p} params[i] = p end if add_non_generic and p.non_generic == nil then p.non_generic = true end end return params end -- Apply the modifications specified in `mods` to the parameters in `params`. local function apply_mods(params, mods) local mod_table = {} local subvals -- First, convert the modifications to a dictionary for easy lookup as we traverse the existing parameters. for _, mod in ipairs(mods) do local param = mod[1] if param == "#substitute" then mod[1] = nil subvals = mod elseif param ~= "#replace_group" then -- Need to do replace_group after aliases because replace_group might introduce new params that we don't want aliases -- to touch (e.g. |title= in {{quote-journal}}). mod_table[param] = mod end end -- Process each group in turn. for _, group in ipairs(params) do canonicalize_param_group(group) local ind = 2 if type(group[2]) == "string" then ind = ind + 1 end for i = ind, #group do -- Go through each parameter group looking for modifications, and make them. To avoid problems -- side-effecting lists as we process them, we first clone the group and iterate over the clone, which -- remains unmodified. local paramspec, desc = unpack(group[i]) local specclone = m_table.deepCopy(paramspec) for j, paramset in ipairs(specclone) do for k, param in ipairs(paramset) do local mod = mod_table[param.param] if mod then if mod.addalias then -- Canonicalize an addalias= spec to a list for easier processing. local to_add = canonicalize_param_list(mod.addalias, "add non-generic") for _, ta in ipairs(to_add) do if paramspec.useand then -- Top level refers to logically-related params so alias goes at second level. table.insert(paramspec[j], ta) else table.insert(paramspec, {ta}) end end end if mod.replace_params then group[i][1] = canonicalize_paramspec(mod.replace_params, "add non-generic") end if mod.append_desc then group[i][2] = group[i][2] .. " " .. mod.append_desc end if mod.replace_desc then group[i][2] = mod.replace_desc end end end end end end for _, mod in ipairs(mods) do local param = mod[1] if param == "#replace_group" then local _, existing_group_name, new_group = unpack(mod) canonicalize_param_group(new_group) local ind = 2 if type(new_group[2]) == "string" then ind = ind + 1 end for i = ind, #new_group do local paramspec, desc = unpack(new_group[i]) for j, paramset in ipairs(paramspec) do for k, param in ipairs(paramset) do if param.non_generic == nil then param.non_generic = true end end end end local replaced = false for i, group in ipairs(params) do if group[1] == existing_group_name then params[i] = new_group replaced = true break end end if not replaced then error(("Internal error: Unable to locate existing group '%s'"):format(existing_group_name)) end end end return subvals end -- Format a param spec as found in the first element of a param description. local function format_param_spec(paramspec) if type(paramspec) ~= "table" or paramspec.param then paramspec = {paramspec} end local function format_one_param(param, non_generic) if non_generic then param = "<b>" .. param .. "</b>" end if paramspec.boolean then return ("<code>|%s=1</code>"):format(param) else return ("<code>|%s=</code>"):format(param) end end local function format_all_params_no_list(suffix) local formatted = {} for _, paramset in ipairs(paramspec) do if type(paramset) ~= "table" or paramset.param then paramset = {paramset} end local formatted_paramset = {} for _, p in ipairs(paramset) do if type(p) == "string" then p = {param = p} end -- Skip ...2 and ...3 versions of numeric params. if suffix == "" or not rfind(p.param, "^[0-9]+") then table.insert(formatted_paramset, format_one_param(p.param .. suffix, p.non_generic)) end end local to_insert = table.concat(formatted_paramset, "/") if to_insert ~= "" then table.insert(formatted, to_insert) end end return m_table.serialCommaJoin(formatted, {conj = paramspec.useand and "and" or "or"}) end local function format_all_params() if paramspec.list then local formatted = {} table.insert(formatted, format_all_params_no_list("")) table.insert(formatted, format_all_params_no_list("2")) table.insert(formatted, format_all_params_no_list("3")) table.insert(formatted, "hwd.") return table.concat(formatted, "; ") else return format_all_params_no_list("") end end local formatted_params if paramspec.literal then formatted_params = preprocess(paramspec[1][1].param) else formatted_params = format_all_params() end local reqtext = paramspec.required and " '''(lazim)'''" or "" return formatted_params .. reqtext end local function process_continued_string(desc, subvals) desc = rsub(desc, "{{", TEMP_DOUBLE_LBRACE) desc = rsub(desc, "}}", TEMP_DOUBLE_RBRACE) -- Join continuation lines. Do it twice in case of a single-character line (admittedly rare). desc = rsub(desc, "([^\n])\n[ \t]*([^ \t\n#*])", "%1 %2") desc = rsub(desc, "([^\n])\n[ \t]*([^ \t\n#*])", "%1 %2") -- Remove whitespace before list elements. desc = rsub(desc, "\n[ \t]*([#*])", "\n%1") desc = rsub(desc, "^[ \t]*([#*])", "%1") -- placeholder variable names between double backquotes desc = rsub(desc, "``([A-Za-z0-9_%-]+)``", "<var>%1</var>") -- variable/parameter names between backquotes desc = rsub(desc, "`([A-Za-z0-9_%-]+)`", '<code class="n">%1</code>') desc = rsub(desc, "%b{}", function(m0) -- {} blocks return "<code>" .. m0:sub(2, -2) .. "</code>" end) desc = rsub(desc, "<<([^><]+)>>", function(item) local parts = rsplit(item, ":") item = parts[1] if subvals[item] then if type(subvals[item]) == "string" then item = subvals[item] elseif type(subvals[item]) == "number" then item = "" .. subvals[item] else error("The item '<<" .. item .. ">>' is a " .. type(items[item]) .. " and can't be concatenated.") end else error("The item '" .. item .. "' was not found in the 'subvals' table.") end for i, part in ipairs(parts) do if i > 1 then if part == "a" then item = ku_add_indefinite(item) elseif part == "cap" then item = mw.getContentLanguage():ucfirst(item) end end end return item end) desc = rsub(desc, TEMP_DOUBLE_LBRACE, "{{") desc = rsub(desc, TEMP_DOUBLE_RBRACE, "}}") desc = preprocess(desc) return desc end local function format_parameter_group(group, subvals, level) local parts = {} local function ins(txt) table.insert(parts, txt) end local prefsuf = ("="):rep(level) ins(prefsuf .. process_continued_string(group[1], subvals) .. prefsuf) local ind = 2 if type(group[2]) == "string" then ins(process_continued_string(group[2], subvals)) ind = ind + 1 end ins('{| class="wikitable"') ins("! Parametre") ins("! Dikare bê etîketkirin") ins("! Dikare çend hebûnên bi niqteya bi virgul ji hev cuda bihewîne") ins("! Têbînî") for i = ind, #group do local paramspec, desc = unpack(group[i]) ins('|- style="vertical-align: top"') ins('| style="text-align: center" | ' .. format_param_spec(paramspec)) ins('| style="text-align: center" | ' .. ((paramspec.annotated or paramspec.multientity) and "'''Erê'''" or "Na")) ins('| style="text-align: center" | ' .. (paramspec.multientity and "'''Erê'''" or "Na")) ins("| " .. process_continued_string(desc, subvals)) end ins("|}") return table.concat(parts, "\n") end local function format_inline_modifiers(mods) local parts = {} local function ins(txt) table.insert(parts, txt) end ins('{| class="wikitable"') ins("! Guherker") ins("! Têbînî") for _, modspec in ipairs(mods) do local modifier, desc = unpack(modspec) ins('|- style="vertical-align: top"') ins('| style="text-align: center" | <code>' .. modifier .. "</code>") ins("| " .. process_continued_string(desc, {})) end ins("|}") return table.concat(parts, "\n") end local function format_introduction(template) local parts = {} local function ins(txt) table.insert(parts, txt) end ins("===Destpêk===") ins(process_continued_string(generate_param_intro_text(template), {})) ins("") ins('{| class="wikitable"') ins("! Guherker") ins("! Têbînî") for _, modspec in ipairs(generate_inline_modifiers(template)) do local modifier, desc = unpack(modspec) ins('|- style="vertical-align: top"') ins('| style="text-align: center" | <code>' .. modifier .. "</code>") ins("| " .. process_continued_string(desc, {})) end ins("|}") return table.concat(parts, "\n") end function export.show_doc(template) if type(template) == "table" then template = template.args[1] end local params = generate_params(template) local mods = quote_mods[template] if not mods then error(("No modifications found for template '%s'"):format(template)) end local subvals = apply_mods(params, mods) local parts = { format_introduction(template) } for _, group in ipairs(params) do table.insert(parts, format_parameter_group(group, subvals, 3)) end return table.concat(parts, "\n\n") end return export 668bvzxei8cu0jmkv8g27tmzqqetkp9 6333893 6333892 2026-08-15T19:35:56Z Wikihez 7344 6333893 Scribunto text/plain --[=[ This module contains functions to generate documentation for {{quote-*}} templates. The module contains the actual implementation, meant to be called from other Lua code. See [[Module:quote doc/templates]] for the function meant to be called directly from templates. Author: Benwing2 ]=] local export = {} local m_table = require("Module:table") local rfind = mw.ustring.find local rsplit = mw.text.split local rsubn = mw.ustring.gsub local u = mw.ustring.char local unpack = unpack or table.unpack -- Lua 5.2 compatibility local TEMP_DOUBLE_LBRACE = u(0xFFF0) local TEMP_DOUBLE_RBRACE = u(0xFFF1) -- version of rsubn() that discards all but the first return value local function rsub(term, foo, bar) local retval = rsubn(term, foo, bar) return retval end local function preprocess(desc) if desc:find("{") then desc = mw.getCurrentFrame():preprocess(desc) end return desc end local ku_vowels = {a = true, e = true, ["ê"] = true, i = true, ["î"] = true, o = true, u = true, ["û"] = true} -- Add the Kurdish oblique indefinite suffix (-ekê after a consonant, -yekê after a vowel, to break hiatus) to -- `word`, since Kurdish marks indefiniteness with a suffix rather than a prefix word like English "a"/"an". The -- oblique form is used (rather than bare -ek/-yek) because every <<item:a>> substitution in this module's text -- follows the ezafe linker "ya", which puts the following noun in the oblique case. local function ku_add_indefinite(word) local last_char = mw.ustring.sub(word, -1) if ku_vowels[last_char] then return word .. "yekê" else return word .. "ekê" end end local function generate_param_intro_text(ty) return [=[ Beşên li jêr parametreyên heyî îzah dikin. Ji ber ku pir parametre hene, ew di nav koman de hatine teqsîmkirin. Hin parametre mecbûrî ne ku bi şiklê '''(mecbûrî)''' (heke neyên dayîn, xetayek dide) hatine nîşankirin û yên bi nîşana '''(nîv-mecbûrî)''' tê maneyê ku eger neyên dayîn, mesajeke kontrolkirinê dide. Parametreyên bi '''herfên stûr''' ji bo şablona {{şx|]=] .. ty .. [=[}} xisûsî ne û bi şablonên din ên {{şx|jêder-*}} re nayên bikaranîn, an jî bikaranîneke wan a cuda heye. Hemû kom ji xeynî ya ewil qismê jêderê kontrol dikin. Koma ewil rêzên jêgirtinê kontrol dike (rêzên ku nivîsa jêgirtinê, tercime, latînîzekirin, standardîzekirin, hwd. nîşan didin). Di hin parametreyên wekî sernav, nivîskar, weşanxane, hwd. de dikare nivîsa biyanî hebe. Wextê nivîsên biyanî tê de hebin divê ev parametre ''guherkerên pêşiyê (annotations)'' an jî ''guherkerên paşiyê (inline modifiers)'' bi kar bînin. ''Guherkerên pêşiyê (annotations)'' wekî pêşgireke koda zimanî (wek {ar:} ji bo erebî, {zh:} ji bo çînî an {ru:} ji bo rûsî) dikevin pêşiya nivîsa biyanî. ''Guherkerên paşiyê (inline modifiers)'' dikevin li paşiya nivîsa biyanî. Nimûneyek ku her duyan dihewîne: <code>ru:Баллада о королевском бутерброде<t:Şiîra Nanê Qiralî></code> wek {{zim|ru|Баллада о королевском бутерброде}} [''Ballada o korolevskom buterbrode, Şiîra Nanê Qiralî''] xuya dike. Koda zimanî dibe alîkar ku fonta munasib were bikaranîn dema nivîs tê nîşandan (her çend naskirina skrîpta nivîsê bêyî van kodan jî çêdibe), û transliterasyona otomatîk çêdike heke mimkûn be. Guherkerên paşiyê tercime, translîterasyona manuel û tiştên bi vî rengî diyar dikin. Kodên taybet ên jêrîn li şûna kodên zimên jî tên naskirin: * {w:``link``}: Lînk bi Wîkîpediyaya îngilîzî, wek nimûne {w:William Shakespeare}. Ev wek {``link``} xuya dike. Ev wek nivîsandina {{şx|w|William Shakespeare}} e, ku ew jî dikare were bikaranîn. * {w:``lang``:``link``}: Lînk bi Wîkîpediyayeke bi zimanekî din, wek nimûne {w:fr:Jeanne d'Arc}. Ev wek {``link``} xuya dike. Ev wek nivîsandina {{şx|w|2=lang=fr|3=Jeanne d'Arc}} e, ku ew jî dikare were bikaranîn. * {lw:``lang``:``link``}: Lînk bi Wîkîpediyayeke bi zimanekî din û {``link``} li gorî koda zimên a bi {``lang``} hatiye dayîn were formatkirin, wek nimûne {lw:zh:毛泽东} (forma nivîskî ya çînî ya {{w|Mao Zedong}}). Ev pêdivî ye ku {``lang``} kodeke zimên be ku li Wîkîpediyayê û Wîkîferhengê heman wateyê bide (ev ji bo piraniya kodên zimên ên Wîkîpediyayê derbasdar e, lê ne ji bo hr ji bo Wîkîpediyaya xirwatî û sr ji bo Wîkîpediyaya sirbî, û ne jî ji bo hin zimanên din ên kêmzanîn). Ev wek nivîsandina {zh:&#123;&#123;w|lang=zh|毛泽东}}} e. Ev dê naskirin û formatkirina taybet a xeta nivîsê ya li gorî ziman bike û forma xuyayî bi çîna CSS a munasib a li gorî ziman nîşan bide. Heke latînîzekirina otomatîk ji bo zimanê diyarkirî çalak be, ew latînîzekirin dê xuya bibe, ji bilî ku latînîzekirineke din bi {<tr:...>} were dayîn an nîşandana latînîzekirinê bi {<tr:->} were vemirandin. Bala xwe bide ku bikaranîna wek {lw:ru:Лев Толстой} (forma nivîskî ya rûsî ya {{w|Leo Tolstoy}}) hinekî dişibihe nivîsandina {{şx|lw|ru|Лев Толстой}} (ji ber vê ye pêşgir dişibihe navê şablonê), lê ya duyem latînîzekirinan wek {{şx|l}} nîşan dide (di kevanan de ne di parantezan de), û bikaranîna {{şx|lw}} destûrê nade guherkerên paşiyê, ji ber ku ew bo HTML'ê tê formatkirin. * {lw:``lang``:&#91;&#91;``link``|``display``&#93;&#93;}: Lînk bi {``link``} bi Wîkîpediyayeke bi zimanekî din, lê wek {``display``} xuya bike, li gorî koda zimên a bi {``lang``} hatiye dayîn were formatkirin. Ev wek {lw:...} ya li jor dixebite, lê destûrê dide ku lînk û xuyabûn cuda werin diyarkirin, wek nimûne {lw:ru:&#91;&#91;Маркс, Карл|Карл Ге́нрих Маркс&#93;&#93;}, ku forma xuyayî forma nivîskî ya rûsî ya {{w|Karl Marx|Karl Heinrich Marx}} e û forma lînkê jî ew e ku nav çawa di madeya Wîkîpediyaya rûsî de tê bikaranîn (bi paşnav pêşî). * {w:&#91;&#91;``link``|``display``&#93;&#93;} û {w:``lang``:&#91;&#91;``link``|``display``&#93;&#93;}: Lînk bi Wîkîpediyaya îngilîzî an bi zimanekî din, lînk ji forma xuyayî cuda were diyarkirin. Ev kêmtir kêrhatî ne ji ya {lw:...} çimkî tu dikarî lînka Wîkîpediyayê rasterast jî diyar bikî, wek nimûne bi {{code||[[w:William Shakespeare|W(illiam) Shakespeare]]}} an {{code||[[w:fr:Jeanne d'Arc|Joan of Arc]]}} bi heman hejmara herfan. * {s:``link``}: Lînk bi rûpela Wîkîçavkaniya îngilîzî ya {``link``}, wek nimûne {s:The Rainbow Trail} (romanek ji {{w|Zane Grey}}). * {s:``lang``:``link``}: Lînk bi Wîkîçavkaniyeke bi zimanekî din. Ev bi mahiyet dişibihe {w:``lang``:``link``} ji bo Wîkîpediyayê. * {ls:``lang``:``link``}: Lînk bi Wîkîçavkaniyeke bi zimanekî din û {``link``} li gorî koda zimên a bi {``lang``} hatiye dayîn were formatkirin. Ev bi mahiyet dişibihe {lw:``lang``:``link``} ji bo Wîkîpediyayê. * {ls:``lang``:&#91;&#91;``link``|``display``&#93;&#93;}: Lînk bi {``link``} bi Wîkîçavkaniyeke bi zimanekî din, lê wek {``display``} xuya bike, li gorî koda zimên a bi {``lang``} hatiye dayîn were formatkirin, wek nimûne {ls:ko:&#91;&#91;조선_독립의_서#一._槪論|조선 독립의 서&#93;&#93;} (belgeyek li ser serxwebûna Kore di dema dagirkirina Japonî de). Ev bi mahiyet dişibihe {lw:``lang``:&#91;&#91;``link``|``display``&#93;&#93;} ji bo Wîkîpediyayê. * {s:&#91;&#91;``link``|``display``&#93;&#93;} û {s:``lang``:&#91;&#91;``link``|``display``&#93;&#93;}: Lînk bi Wîkîçavkaniya îngilîzî an bi zimanekî din, lînk ji forma xuyayî cuda were diyarkirin. Ev kêmtir kêrhatî ne ji ya {ls:...} çimkî tu dikarî lînka Wîkîçavkaniyê rasterast jî diyar bikî, wek nimûne bi {{code||[[s:The Tempest (Shakespeare)|The Tempest]]}} an {{code||[[s:fr:Fables de La Fontaine (édition originale)|Fables de La Fontaine]]}} bi heman hejmara herfan. Herwiha, hin parametre dikarin çend ''hebûnên'' bi niqteya bi virgul (;) ji hev cuda hebin (nivîskar, weşanxane, hwd.). Ev bi giştî ji bo hemû parametreyên kesan (nivîskar, terciman, edîtor, hwd.) derbasdar e, herwiha ji bo hin parametreyên din jî, wek li jêr hatiye nîşandan. Di van parametreyan de, her hebûn dikare guherkerên pêşiyê û/an guherkerên paşiyê hebe, wek li jor. Nimûneyek <code>zh:張福運<t:Chang Fu-yun>; zh:張景文<t:Chang Ching-wen></code> e, ku du navên bi çînî diyar dike, her yek bi latînîzekirinekê. Bi giştî, van parametreyan bi niqteyên bi virgul neyên nîşandan, lê bi gelemperî bi kome (,) û/an kelîmeya ''û'' — ev bi parametreya taybet û cihê wê yê di jêderê de girêdayî ye. Niqteya bi virgul tenê ji bo cudakirina hebûnan di têketinê de tên bikaranîn; kome nayên bikaranîn ji ber ku nav dikarin kome tê de hebin, wek {Sammy Davis, Jr.} an {Alfred, Lord Tennyson}. Niqteyên bi virgul di nava kevan an kevanên çargoşe de nayên hesibandin wekî sînorker; ji ber vê yekê, nirxeke parametreyê wek {George Orwell [pseudonym; Eric Blair]} yek hebûnê diyar dike, ne du. Bi heman rengî, hebûnên HTML'ê yên bi niqteya bi virgul a dawî wek {&amp;oacute;} jî tên naskirin û ne wekî sînorker. Ji bo parametreyên ku kesan diyar dikin (wek {{para|nivîskar}}, {{para|terciman}}, {{para|edîtor}}), li dû niqteya bi virgul {et al.} binivîse wek kesekî normal. Koda binesaziyê vê taybet dihesibîne, bi herfên xar nîşan dide û sînorkera ku normal berî wê were xuya nake. Wek îstisnayeke sînorkirina hebûnan bi niqteyên bi virgul, heke tu komê wek herfa yekem a parametreyeke pirhebûnî bicîh bikî, ew kom tê paşguhkirin û mayîya nirxê li gorî koman tê dabeşkirin, ne li gorî niqteyên bi virgul. Wek nimûne, {,Joe Bloggs, Mary Worth, et al.} wek {Joe Bloggs; Mary Worth; et al.} tê hesibandin. Bi giştî ev şêwe nayê tewsiyekirin, lê dema meriv rêzeke dirêj a bi kome ji hev cuda ya nivîskaran ji cihekî din (wek Google Scholar) kopî dike, dikare bibe alîkar. Guherkerên paşiyê yên jêrîn tên naskirin:]=] end local function generate_inline_modifiers(ty) return { {"t", [=[Tercimeya parametreyê an hebûna behskirî. Di kevanên çargoşe de li dû nirxê tê nîşandan. Ji bo nivîskar an hebûnên din ên ku behsa kesan dikin, tê tewsiyekirin ku parametreya <code><t:...></code> ji bo nivîsandina forma "asayî" an ne-zanistî ya navî were bikaranîn, û bi îxtiyarî parametreya <code><tr:...></code> jî ji bo latînîzekirina zanistî. Wek nimûne, navê rûsî {{qal|ru||Пётр Чайко́вский|tr=-}} dibe ku wek {{w|Pyotr Tchaikovsky}} were tercimekirin lê wek ''Pjotr Čajkóvskij'' were latînîzekirin. Girêdanên Wîkîpediyayê li gorî hewceyê bi {{şx|w}} an rasterast bi {{code||[[w:LINK|NAME]]}} zêde bike.]=]}, {"gloss", [=[Bernavê <code><t:...></code>. Bi giştî, <code><t:...></code> tê tercihkirin.]=]}, {"alt", [=[Forma xuyayî ya parametreyê an hebûna behskirî. Bi giştî ev ne lazim e, çimkî tu her tim dikarî girêdaneke du-perçeyî wek {{code||[[Dennis Robertson (economist)|D.H. Robertson]]}} bikar bînî.]=]}, {"tr", [=[Latînîzekirina parametreyê an hebûna behskirî, heke ne bi herfên latînî be. {{para|t}} ya jorîn ji bo kengî tercime, kengî latînîzekirin ji bo navên kesan were bikaranîn binêre. Heke pêşgireke koda zimên hatibe dayîn û nivîs ne bi herfên latînî be, latînîzekirineke otomatîk dê were peydakirin heke ziman vê piştgirî bike û ev guherker neyê dayîn. Di wê rewşê de, {<tr:-}> bikar bîne da ku latînîzekirina otomatîk neyê xuyakirin.]=]}, {"subst", [=[Şêwaz(ên) cîguherînê ku têne bikaranîn ji bo mîna kirina latînîzekirineke rast, li şûna diyarkirina latînîzekirineke bi dest. Ev guherker bi awayekî wekhev bi parametreya {{para|subst}} dixebite, lê ji bo hebûna behskirî ne ji bo nivîsa giştî ya jêgirtinê. Nimûneyên bikaranînê li nimûneyên {{şx|jêder-kitêb}} binêre.]=]}, {"ts", [=[Nivîsandina fonetîk a parametreyê an hebûna behskirî, heke ne bi herfên latînî be û di zimanekî de ku latînîzekirin ji telafuza rastîn pir cuda ye (wek akadî an tîbetî). Vê tenê ji bo dayîna telafuza IPA'yê bikar neyîne. Heke were dayîn, ev di navbera du xêzikan de tê nîşandan, wek <code>[``latînîzekirin`` /``nivîsandina fonetîk``/, ``tercime``]</code>.]=]}, {"sc", [=[Koda xeta nivîsê ya nivîsa parametreyê an hebûna behskirî, heke ne bi xeta latînî be. Li [[Wiktionary:Scripts]] binêre. Kêm caran lazim e ev were diyarkirin, çimkî koda xeta nivîsê bi xwe (bi giştî bi rastî) ji nivîsê tê naskirin.]=]}, {"f", [=[Guhertoya "biyanî" ya parametreyê an hebûna behskirî, ango guhertoya bi xeteke nivîsê ya cuda ji ya nirxê bixwe. Ev çend awayan hene: # {<f:``biyanî``>}: Awayê herî sade. Nivîsa biyanî dê naskirina xeta nivîsê ya serbixwe ji zimanan bistîne û wek xwe, di hundirê kevanan de berî tercimeyê were nîşandan. Bi giştî bikaranîna vê awayî nayê tewsiyekirin ji ber ku girîngiya nivîsê dibe ku ne diyar be; guhertoya jêrîn a bi etîket bikar bîne. # {<f:/``xeta nivîsê``:``biyanî``>}: Wek ya berê, lê koda xeta nivîsê eşkere hatiye dayîn, ji bo rewşa ku naskirin xelet dixebite. # {<f:``etîket``:``biyanî``>}: Etîketek zêde bike ku berî nivîsa biyanî were nîşandan. Etîket dikare kodeke zimên be (bi zimanên etîmolojiyê ve jî), kodeke xeta nivîsê, an nivîseke azad. Heke wek kodeke zimên were naskirin, navê resmî yê ziman wek etîket tê nîşandan û ziman ji bo naskirina xeta nivîsê ya nivîsa biyanî, li gorî xeta nivîsê ya destûrdayî ya wî ziman, tê bikaranîn. Heke etîket wek kodeke xeta nivîsê were naskirin, ew wek xeta nivîsê ya nivîsa biyanî tê bikaranîn dema nivîs tê nîşandan, û navê resmî yê xeta nivîsê wek etîket tê nîşandan. Wekî din, etîket dikare nivîseke azad be (wek pergaleke latînîzekirinê wek `Pinyin`), û wek xwe tê nîşandan, bi naskirina xeta nivîsê ya serbixwe ji zimanan li ser nivîsa biyanî. # {<f:``etîket``/``xeta nivîsê``:``biyanî``>}: Wek ya berê, lê koda xeta nivîsê eşkere hatiye dayîn, ji bo rewşa ku naskirin xelet dixebite. # {<f:``etîket``,``etîket``,...:``biyanî``>}: Ji bo nivîseke biyanî çend etîketan zêde bike. Hemû etîket bi xêzika dabeşker ji hev cuda tên nîşandan wek li jor, lê tenê etîketa yekem ji bo naskirina xeta nivîsê tê bikaranîn. # {<f:``etîket``,``etîket``,.../``xeta nivîsê``:``biyanî``>}: Wek ya berê, lê koda xeta nivîsê eşkere hatiye dayîn, ji bo rewşa ku naskirin xelet dixebite. Berevajî guherkerên din ên paşiyê, guherkera {<f:...>} dikare çend caran were dayîn ji bo nîşandana guhertoyên cuda yên biyanî yên hebûneke diyarkirî. Nimûneyeke kêrhatî ev e: * {Liou Kia-hway<f:Hant:劉家槐><f:Pinyin:Liú Jiāhuái>} Li vir, em navê nivîskar wek di çavkaniyê de hatiye dayîn diyar dikin, li dû wê guhertoya orîjînal a bi çînî û herwiha guhertoyeke standard a Pinyin.]=]}, {"q", [=[Etîketa çepê ya parametreyê an hebûna behskirî, berî wê wiha tê nîşandan: {{q|etîketa çepê}}.]=]}, {"qq", [=[Etîketa rastê ya parametreyê an hebûna behskirî, li dû wê wiha tê nîşandan: {{q|etîketa rastê}}.]=]}, } end --[===[ Ravekirina parametreyên takekesî ji bo perçeya jêderê ya jêgirtinê (ango rêza yekem). Ji ber ku pir parametre hene, em wan bi koman dabeş dikin. Nirxa ya jêrîn lîsteyeke koman e, her kom bi vî rengî ye: 1. Perçeya yekem sernavê koma parametreyan e. 2. Perçeya duyem a îxtiyarî, heke rêzik be, nivîsa pêşgotinê ye ku komê bi hûrgilî rave dike, û dê berî tabloya parametreyan were nîşandan. Rêzik dikare pirrêzî be (bi [=[...]=] bicîh bike), û rêzên domdar taybetmendiyek hene; li jêr binêre. 3. Hemû perçeyên din parametreyên takekesî rave dikin. Ravekirina parametreyeke takekesî bi vî rengî ye: 1. Perçeya yekem nav an navên parametreyê ye. Heke rêzik be, tenê navê gengaz ê parametreyê diyar dike, û wek lîsteyeke yek-perçeyî ya bi navê parametreyê tê hesibandin. Lîsteyeke rêzikan bikar bîne ji bo diyarkirina çend bernavên bi heman wateyê, wek {"tlr", "translator", "translators"}. Tu dikarî herwiha lîsteyeke parametreyên girêdayî yên mantiqî jî diyar bikî, ku hemû parametre bi rave kirineke yekane têne şirovekirin. Di vê rewşê de, <code>useand = true</code> li dû navên parametreyan binivîse, ku dibe sedem parametre bi "û" li şûna "an" werin girêdan (wek normal ji bo bernavan). Heke <code>useand</code> hatibe dayîn, perçeyên takekesî yên lîsteyê bixwe dikarin lîsteyên bernavan bin, ku bi xêzika dabeşker ji hev cuda tên nîşandan. Her perçe dikare, li şûna rêzikekê, tabloyek bi forma {param = "PARAM", non_generic = BOOLEAN} jî be, ku heke <code>non_generic = true</code>, parametre taybet e ji bo pêkanîneke {{şx|quote-*}} ya diyarkirî, ne giştî. Wek nimûne: * {"tlr", "translator", "translators"} wek "|tlr=, |translator= an |translators=" tê nîşandan, behsa sê bernavan dike. * {"chapter_series", "chapter_seriesvolume", useand = true} wek "|chapter_series= û |chapter_seriesvolume=" tê nîşandan, behsa parametreyên girêdayî yên mantiqî dike. * {{"chapter_series", {param = "entry_series", non_generic = true}}, {"chapter_seriesvolume", {param = "entry_seriesvolume", non_generic = true}}, useand = true} wek "|chapter_series=/<b>|entry_series=</b> û |chapter_seriesvolume=/<b>|entry_seriesvolume=</b>" tê nîşandan, behsa komên bernavan ên parametreyên girêdayî yên mantiqî dike, hinek ji wan ne giştî ne (li vir, parametreyên {{para|entry_*}} bernavên taybet ên {{şx|jêder-kitêb}} in). Qadên din ên navdar jî gengaz in: * <code>useand = true</code>: Parametreyan bi "û" li şûna "an" girêbide; li jor binêre. * <code>annotated = true</code>: Diyar dike ku parametre(yên) dikarin bi guherkerên pêşiyê û/an guherkerên paşiyê werin nîşankirin. * <code>multientity = true</code>: Diyar dike ku parametre(yên) dikarin ji çend hebûnên bi niqteya bi virgul ji hev cuda pêk bên (wek nivîskar, terciman, edîtor, weşanxane an cih), her yek dikare bi guherkerên pêşiyê û/an guherkerên paşiyê were nîşankirin. * <code>boolean = true</code>: Parametre(yên) nirxa wan boolean e, û wek nimûne {{para|bêtarîx|1}} tê nîşandan, ne bi tenê wek {{para|tarîx}}. * <code>required = true</code>: Parametre(yên) lazim in, û wek nimûne {{para|sernav|req=1}} tê nîşandan, ne bi tenê wek {{para|nivîskar}}. * <code>literal = true</code>: Nirxa parametreyê (ku divê tenê yek hebe) ravekirinên parametreyên jixwe-formatkirî dihewîne û divê wek xwe were nîşandan, ne bêtir were formatkirin. 2. Perçeya duyem ravekirina parametreyê/parametreyan e. Rêzik dikare pirrêzî be (bi [=[...]=] bicîh bike), û rêzên domdar taybetmendiyek hene. Bi taybetî, xêzikeke nû û valahiya li dû wê bi gelemperî dibe valahiyeke yekane, da ku rêzeke dirêj bikare bi çend rêzan û bi navbereke munasib were nivîsandin. Ev nabe dema ji yek xêzikeke nû zêdetir li pey hev hebin (di wê rewşê de, hemû xêzikên nû wek xwe dimînin). Heke herfa yekem a rêzekê nîşana lîsteyekê be (<code>#</code> an <code>*</code>), valahiya berî wê tê rakirin lê xêzika nû ya berê wek xwe dimîne. Ev destûrê dide ku lîste di ravekirinên parametreyan de bên dayîn. ]===] local function generate_params(ty) return { {"Parametreyên nivîsa jêgirtî", [=[Parametreyên jêrîn nivîsa jêgirtî bixwe rave dikin. Ev kom digel koma jêrîn (ji bo nivîsa jêgirtî ya orîjînal) nivîsa jêgirtinê rave dikin, dema hemû komên din ên parametreyan rêza jêderê kontrol dikin. Parametreyên vê koma dikarin neyên dayîn heke nivîsa jêgirtî cuda were nîşandan (wek nimûne di hin zimanên rojhilata Asyayê de, ku şablonên xwe hene ji bo nîşandana nivîsa jêgirtî, wek {{şx|ja-x}} ji bo japonî, {{şx|zh-x}} ji bo çînî, {{şx|ko-x}} ji bo koreyî, {{şx|th-x}} ji bo tayî û {{şx|km-x}} ji bo khmerî). Tevî wê jî, {{para|1}} divê were dayîn da ku zimanê jêgirtinê diyar bike.]=], {{"1", required = true}, [=[Lîsteyeke kodên zimên ên bi kome ji hev cuda, ku zimanê/zimanên nivîsa jêgirtî diyar dike; ji bo lîsteya kodan, li [[Wiktionary:List of languages]] binêre. Heke ziman ne îngilîzî be, şablon vê rastiyê bi nîşandana {(bi ``ziman``)} (ji bo yek zimanî), an {(bi ``ziman`` û ``ziman``)} (ji bo du zimanan), an {(bi ``ziman``, ``ziman`` ... û ``ziman``)} (ji bo sê an zêdetir zimanan) diyar dike. Rûpela madeyê dê herwiha li kategoriyeke bi forma {Kategorî:Jêgirtinên bi ``ziman``} were zêdekirin, ji bo zimanê yekem ê lîsteyê (ji bilî ku {{para|zimanê-termê}} hatibe dayîn, di wê rewşê de ew ziman ji bo kategoriyê tê bikaranîn, an {{para|nekat|1}} hatibe dayîn, di wê rewşê de rûpel nakeve tu kategoriyekê). Zimanê yekem ê lîsteyê herwiha fonta tê bikaranîn û latînîzekirina munasib jî diyar dike, heke nivîs ne bi herfên latînî be. {{para|zimanê-eserê}} bikar bîne ji bo diyarkirina zimanê/zimanên ku <<collection>> bixwe pê hatiye nivîsandin: li jêr binêre. <small>Parametreya {{para|lang}} bernaveke kevin e ji bo vê parametreyê; ji kerema xwe bikar neyîne. Heke ev were bikaranîn, hemû parametreyên hejmarî yek ji dor tên xwarê.</small>]=]}, {{"jêgirtin", "jg"}, [=[Nivîsa ku tê jêgirtin. Tîpên qalind bikar bîne ji bo diyarkirina termê ku tê îzahkirin, wiha: {{code||<nowiki>'''mirovnasî'''</nowiki>}}.]=]}, {"zimanê-eserê", [=[Lîsteyeke kodên zimên ên bi kome ji hev cuda, ku zimanê/zimanên ku kitêb pê hatiye nivîsandin diyar dike, heke ji nivîsa jêgirtî cuda be; ji bo lîsteya kodan, li [[Wiktionary:List of languages]] binêre.]=]}, {"zimanê-termê", [=[Kodeke zimên ku zimanê termê tê îzahkirin diyar dike, heke ji nivîsa jêgirtî cuda be; ji bo lîsteya kodan, li [[Wiktionary:List of languages]] binêre. Heke were dayîn, ev ziman ew e ku dema rûpel li kategoriyeke bi forma {Kategorî:Jêgirtinên bi ``ziman``} tê zêdekirin tê bikaranîn; wekî din, zimanê yekem ê bi {{para|1}} hatiye dayîn tê bikaranîn. Vê parametreyê tenê bide heke zimanê jêgirtinê ji zimanê termê cuda be, wek nimûne jêgirtineke îngilîziya navîn ku ji bo termeke îngilîziya nûjen tê bikaranîn, an tarîfeke îngilîzî ya termeke viyetnamî di ferhengeke viyetnamî-îngilîzî de.]=]}, {{"parantez", boolean = true}, [=[Jêgirtinekê bi [[bracket|kevanan]] dorpêç bike. Ev nîşan dide ku jêgirtin an behskirineke termekê ye (wek nimûne, "hin kes dibêjin kelîmeya '''''manoeuvre''''' zehmet e meriv rast binivîse") li şûna bikaranîneke rastîn a wê (wek nimûne, "divê em bi baldarî '''manoeuvre''' bikin da ku aloziyê çênekin"), an jî nimûneeke rastîn a termekê nade lê agahiyan li ser kelîmeyên eleqedar pêşkêş dike.]=]}, {{"tercime", "werger"}, [=[Heke nivîsa jêgirtî bi îngilîzî/kurmancî nebe, ev parametre dikare ji bo pêşkêşkirina [[wergêr|tercimeyek]]ê were bikaranîn.]=]}, {"hrf", [=[Heke nivîsa jêgirtî bi îngilîzî/kurmancî nebe û tercimeya bi {{para|tercime}} hatiye dayîn îdyomatîk be, ev parametre dikare ji bo pêşkêşkirina tercimeyeke [[herfî]] were bikaranîn.]=]}, {"footer", [=[Ev parametre dikare ji bo diyarkirina nivîseke serbixwe li binî, wek şirove an têbînî, were bikaranîn. (Bi zanebûn wek "footer" maye, kurmancîkirin nehatiye kirin.)]=]}, {"norm", [=[Heke nivîsa jêgirtî bi rastnivîsîna ne-standard hatibe nivîsandin, ev parametre guhertoya standardkirî ya nivîsê peyda dike. Ev bi taybetî ji bo jêgirtinên kevn e. Wek nimûne, ji bo poloniya kevn, ev parametre dikare guhertoyeke li gorî rastnivîsîna poloniya nûjen peyda bike, û ji bo nivîsa rûsî ya berî reforma rastnivîsînê ya 1917an, dikare rastnivîsîna reforma nû peyda bike.]=]}, {"tr", [=[Heke nivîsa jêgirtî {{w|pergaleke nivîsandinê}} ya cuda ji {{w|alfabeya latînî}} (alfabeya normal a bi îngilîzî tê bikaranîn) bikar tîne, ev parametre dikare ji bo pêşkêşkirina [[latînîzekirin]]eke wê were bikaranîn. Bala xwe bide ku gelek ziman latînîzekirineke otomatîk peyda dikin heke ev arguman neyê dayîn. Heke guhertoyeke standardkirî ya nivîsê bi {{para|norm}} hatibe dayîn, latînîzekirin dê li ser vê guhertoyê be, heke gengaz be (heke latînîzekirina guhertoya standardkirî têk biçe an standardkirin bi herfên latînî û orîjînal ne bi herfên latînî be, dê li ser nivîsa rastîn a jêgirtî be).]=]}, {"subst", [=[Cîguherînên fonetîk ku têne bikaranîn ji bo çareserkirina latînîzekirinên nerêbaz di hin zimanan de bi pergaleke nivîsandinê ya ne-latînî û latînîzekirina otomatîk (wek rûsî û yîdî). Fikra bingehîn ev e ku nivîsa jêgirtî berî latînîzekirinê bi awayekî fonetîk ji nû ve were nivîsandin, da ku latînîzekirin bi rastî telafuzê nîşan bide ne rastnivîsîna nerêbaz. Heke were dayîn, divê yek an çend rêzikên cîguherînê bin, bi kome ji hev cuda, her rêzika cîguherînê bi forma {JI//BO} ye ({JI/BO} jî tê qebûlkirin), ku {JI} nivîsa çavkaniyê ya bi xeta nivîsê ya çavkaniyê (wek kîrîlî an îbranî) diyar dike û {BO} jî nivîsa cîguherîner e, ew jî bi xeta nivîsê ya çavkaniyê. Cîguherîn bi rêzê tên bikaranîn û ne mecbûr in bi kelîmeyek tevayî re li hev bên. Bala xwe bide ku şêwazên Lua dikarin li şûna nivîsa rasterast di {JI} û {BO} de werin bikaranîn; li [[WT:LUA]] binêre. Ev tê wê wateyê ku bi taybetî, xêzikên di {JI} de divê wek {%-} bên nivîsandin da ku neyên şîrovekirin wekî hejmarkera şêwaza Lua ya ne-çavdar. Ji bo nimûneyên bikaranîna vê parametreyê li nimûneyên {{şx|jêder-kitêb}} binêre. Nimûneyên din di belgekirina {{şx|ux}} de têne dîtin; bikaranîn wek şablonê wekhev e. Heke {{para|norm}} ji bo peydakirina guhertoyeke standardkirî ya nivîsê tê bikaranîn, cîguherîn dê ji bo vê guhertoyê jî bên bikaranîn dema ew tê latînîzekirin.]=]}, {"ts", [=[Nivîsandina fonetîk a nivîsa jêgirtî, heke ne bi herfên latînî be di zimanekî de ku latînîzekirin ji telafuza rastîn pir cuda ye (wek akadî, misrî ya kevn û tîbetî). Ev nebe tenê ji bo dayîna telafuza IPA'yê were bikaranîn.]=]}, {"sc", [=[Koda xeta nivîsê ya nivîsa jêgirtî, heke ne bi xeta latînî be. Ji bo agahiyên zêdetir li [[Wiktionary:Scripts]] binêre. Kêm caran lazim e ev were diyarkirin çimkî xeta nivîsê ji nivîsa jêgirtî tê naskirin.]=]}, {"normsc", [=[Koda xeta nivîsê ya nivîsa standardkirî di {{para|norm}} de, heke ne bi xeta latînî be. Heke neyê dayîn, û nirxek di {{para|sc}} de hatibe dayîn, ev nirx dê ji bo diyarkirina xeta nivîsê ya nivîsa standardkirî were bikaranîn; wekî din (an heke {{para|normsc|auto}} hatibe dayîn), xeta nivîsê ya nivîsa standardkirî ji nivîsê bixwe tê naskirin.]=]}, {"e", [=[Etîket(ên) nivîsa jêgirtî. Etîket heman etîketên di {{şx|lb}}, {{şx|alt}}, {{şx|desc}} û {{şx|syn}}/{{şx|ant}}/hwd. de ne, û li gorî ziman cuda ne. Ji bo dîtina etîketên diyarkirî yên zimanekî, li belgekirina {{şx|lb}} binêre. Heke etîketek neyê naskirin, wek xwe tê nîşandan. Çend etîket dikarin werin dayîn, bi kome ji hev cuda bêyî valahî di navbera etîketan de (komeke bi valahiyeke li dûv wê nayê hesibandin wekî sînorker, lê wek perçeyeke etîketê tê hesibandin). Etîket wek etîketên rastê tên nîşandan, ango bi herfên xar, di kevanan de û li rastê nivîsa jêgirtî.]=]}, }, {"Parametreyên nivîsa jêgirtî ya orîjînal", [=[Parametreyên jêrîn nivîsa jêgirtî ya orîjînal rave dikin, dema nivîsa jêgirtî ya termê ku tê îzahkirin tercimeyek e.]=], {"zimanê-orîjînal", [=[Lîsteyeke kodên zimên ên bi kome ji hev cuda, ku zimanê/zimanên orîjînal ê ku nivîsa jêgirtî jê hatiye tercimekirin diyar dike; ji bo lîsteya kodan, li [[Wiktionary:List of languages]] binêre. Şablon vê rastiyê bi nîşandana {tercimeya orîjînala bi ``ziman``} (ji bo yek zimanî), an {tercimeya orîjînala bi ``ziman`` û ``ziman``} (ji bo du zimanan), an {tercimeya orîjînala bi ``ziman``, ``ziman`` ... û ``ziman``} (ji bo sê an zêdetir zimanan) diyar dike.]=]}, {"metna-orîjînal", [=[Guhertoya orîjînal a nivîsa jêgirtî, ku nivîsa di {{para|jêgirtin}} de jê hatiye tercimekirin. Ev nivîs divê bi koda zimên a zimanê nivîsê pêşgir bike, wek nimûne {<nowiki>gl:O teito é de '''pedra'''.</nowiki>} ji bo nivîsa orîjînal a bi galîsî. Dema nivîsa jêgirtî ya sereke ji îngilîzî hatibe tercimekirin, çêtir e nivîsa îngilîzî ya li hev were di {{para|metna-orîjînal}} de bête danîn, ne di {{para|tercime}} de; ya duyem ji bo tercimeyeke dubare bo îngilîzî ya nivîsa tercimekirî bikar bîne (ji bilî ku nivîsa jêgirtî tercimeyeke azad a orîjînal be, ne lazim e).]=]}, {"norm-orîjînal", [=[Heke nivîsa jêgirtî ya orîjînal bi rastnivîsîna ne-standard hatibe nivîsandin, ev parametre guhertoya standardkirî peyda dike. Ev dişibihe parametreya {{para|norm}} ji bo nivîsa jêgirtî ya sereke.]=]}, {"tr-orîjînal", [=[Heke nivîsa jêgirtî ya orîjînal {{w|pergaleke nivîsandinê}} ya cuda ji {{w|alfabeya latînî}} bikar tîne, ev parametre dikare ji bo pêşkêşkirina latînîzekirineke wê were bikaranîn. Ev dişibihe parametreya {{para|tr}} ji bo nivîsa jêgirtî ya sereke.]=]}, {"subst-orîjînal", [=[Cîguherînên fonetîk ku têne bikaranîn ji bo çareserkirina latînîzekirinên nerêbaz ên nivîsa jêgirtî ya orîjînal di hin zimanan de bi pergaleke nivîsandinê ya ne-latînî û latînîzekirina otomatîk (wek rûsî û yîdî). Ev dişibihe parametreya {{para|subst}} ji bo nivîsa jêgirtî ya sereke.]=]}, {"ts-orîjînal", [=[Nivîsandina fonetîk a nivîsa jêgirtî ya orîjînal, heke ne bi herfên latînî be di zimanekî de ku latînîzekirin ji telafuza rastîn pir cuda ye (wek akadî, misrî ya kevn û tîbetî). Ev dişibihe parametreya {{para|ts}} ji bo nivîsa jêgirtî ya sereke û nebe tenê ji bo dayîna telafuza IPA'yê were bikaranîn.]=]}, {"sc-orîjînal", [=[Koda xeta nivîsê ya nivîsa jêgirtî ya orîjînal, heke ne bi xeta latînî be. Ji bo agahiyên zêdetir li [[Wiktionary:Scripts]] binêre. Kêm caran lazim e ev were diyarkirin çimkî xeta nivîsê ji nivîsa jêgirtî tê naskirin.]=]}, {"normsc-orîjînal", [=[Koda xeta nivîsê ya nivîsa standardkirî di {{para|norm-orîjînal}} de, heke ne bi xeta latînî be. Heke neyê dayîn, û nirxek di {{para|sc-orîjînal}} de hatibe dayîn, ev nirx dê were bikaranîn; wekî din (an heke {{para|normsc-orîjînal|auto}} hatibe dayîn), xeta nivîsê ji nivîsê bixwe tê naskirin.]=]}, {"e-orîjînal", [=[Etîket(ên) nivîsa jêgirtî ya orîjînal. Ev dişibihe parametreya {{para|e}} ji bo nivîsa jêgirtî ya sereke.]=]}, }, {"Parametreyên li gorî tarîxê", {"tarîx", [=[Tarîxa ku <<work>> hatiye weşandin. An {{para|sal}} (û bi îxtiyarî {{para|meh}}), an {{para|tarîx}} bikar bîne, ne herduyan. Nirxa {{para|tarîx}} divê tarîxeke rastîn be, bi an bêyî roj, ne nivîseke azad. Çend format tên qebûlkirin; tê tewsiyekirin ku an bi forma ISO 8601 (''SAL''-''MEH''-''ROJ'') binivîse, wek nimûne {2023-08-11}, an jî mehê bi tevahî binivîse, wek nimûne {2023 tebax 11} (guhertoyên vê jî tên qebûlkirin, wek {tebax 11 2023} an {11 tebax 2023}). Tu dikarî rojê derxî û koda dê hewl bide tarîxê tenê bi meh û salê nîşan bide. Bêyî girêdana bi forma têketinê, derana wê dê bi forma {'''''SAL''''' ''Meh'' ''ROJ''} (an tenê {'''''SAL''''' ''Meh''}) were nîşandan, wek {'''2023''' tebax 11} (an {'''2023''' tebax} heke roj nehatibe dayîn).]=]}, {{"sal", "meh", annotated = true, useand = true}, [=[Sal û (bi îxtiyarî) meha ku <<work>> hatiye weşandin. Nirxên van parametreyan neyên şîrovekirin, û heke lazim be nivîseke azad dikare were dayîn. Heke berî salê {c.} hebe, wek nimûne {c. 1665}, ev nîşan dide ku sala weşandinê {{lg|c.|nêzîkî}} sala diyarkirî ye; bi heman rengî {a.} nîşan dide sala weşandinê {{lg|a.|berî}} sala diyarkirî ye, û {p.} nîşan dide sala weşandinê {{lg|p.|piştî}} sala diyarkirî ye. Sal bi herfên qalind tê nîşandan ji bilî ku nirxa parametreya {{para|sal}} bixwe jixwe herfên qalind tê de hebin, û meh (heke were dayîn) li dû wê tê. Heke ne tarîx û ne jî sal/meh hatibe dayîn, şablon peyama "(Tu dikarî [[:Category:Requests for date|tarîxa]] vê jêgirtinê binivîsî?)" nîşan dide û rûpelê li kategoriya [[:Category:Requests for date in LANG entries]] zêde dike, bi zimanê di {{para|1}} de hatiye dayîn. Peyam û zêdekirina kategoriyê dikarin bi {{para|bêtarîx|1}} werin vemirandin, lê tê tewsiyekirin ku tu hewl bidî tarîxek an tarîxeke texmînî bidî li şûna vê. Zêdekirina kategoriyê bi tenê dikare bi {{para|nekat|1}} were vemirandin, lê bi giştî ev nayê tewsiyekirin.]=]}, {"tarîxa-destpêkê", [=[Heke weşandin di nava rêzeyeke tarîxan de bûbe, tarîxa destpêkê bixe {{para|tarîxa-destpêkê}} (an {{para|sala-destpêkê}}/{{para|meha-destpêkê}}) û tarîxa dawî jî bixe {{para|tarîx}} (an {{para|sal}}/{{para|meh}}). Forma {{para|tarîxa-destpêkê}} wek ya {{para|tarîx}} e. Heke tarîx heman salê hebin lê meh û roja wan cuda be, sal tenê carekê tê nîşandan, bi heman rengî heke tenê roj cuda be. Tenê yekê ji {{para|tarîxa-destpêkê}} an {{para|sala-destpêkê}}/{{para|meha-destpêkê}} bikar bîne, ne herduyan.]=]}, {{"sala-destpêkê", "meha-destpêkê", annotated = true, useand = true}, [=[Wekî din, rêzeyekê bi bicîhkirina sal û meha destpêkê di {{para|sala-destpêkê}} û (bi îxtiyarî) {{para|meha-destpêkê}} de diyar bike. Ev dikarin nivîseke azad hebin, wek {{para|sal}} û {{para|meh}}. Ji bo diyarkirina ku weşandin nêzîkî, berî an piştî rêzeyeke diyarkirî ye, nîşanera munasib ({c.}, {a.} an {p.}) berî nirxa {{para|sal}} bicîh bike, ne berî nirxa {{para|sala-destpêkê}}.]=]}, {{"bêtarîx", boolean = true}, [=[Heke <<work>> bêtarîx be û tu tarîx (heta ya texmînî) bi awayekî maqûl neyê destnîşankirin, {{para|bêtarîx|1}} diyar bike. Ev rêza lênêrînê ya ku bi giştî tê nîşandan heke tarîx neyê dayîn, vedimirîne. Vê tenê ji ber ku tu tarîxê nizanî bikar neyîne; li şûna wê, tarîxê derxe û bihêle rêza lênêrînê were nîşandan û rûpel li kategoriya munasib a lênêrînê were zêdekirin, da ku kesekî din bikaribe alîkariyê bike.]=],}, }, {"Parametreyên li gorî nivîskar", {{"nivîskar", list = true, multientity = true}, [=[Nav(ên) nivîskar(an) ê/ên <<work>> ya jêgirtî. Çend nivîskaran bi niqteya bi virgul ji hev cuda bike, an parametreyên zêde {{para|nivîskar2}}, {{para|nivîskar3}}, hwd. bikar bîne. Wekî din, {{para|paşnav}} û {{para|pêşnav}} bikar bîne (ji bo pêşnav, û navên navîn an herfên pêşî), digel {{para|paşnav2}}/{{para|pêşnav2}} ji bo nivîskarên zêde. Herduyan bi hev re bikar neyîne.]=]}, {{"paşnav", "pêşnav", useand = true, list = true}, [=[Pêşnav (digel navên navîn an herfên pêşî) û paşnav(ên) nivîskar(an) ê/ên <<work>> ya jêgirtî. Ji bo nivîskarên zêde {{para|paşnav2}}/{{para|pêşnav2}}, {{para|paşnav3}}/{{para|pêşnav3}}, hwd. bikar bîne. Tê tercihkirin ku {{para|nivîskar}} li şûna {{para|paşnav}}/{{para|pêşnav}} were bikaranîn, bi taybetî ji bo navên axaftvanên zimanên biyanî, ku dibe hêsan nebe ew bikevin pêşnav û paşnavan. Bala xwe bide ku van parametreyan guherkerên paşiyê an guherkerên pêşiyê piştgirî nakin, û naskirina xeta nivîsê ya otomatîk nakin; ji ber vê yekê ew tenê dikarin ji bo navên bi herfên latînî werin bikaranîn.]=]}, {{"lînka-nivîskar", list = true}, [=[Navê meqaleyeke [https://en.wikipedia.org Wîkîpediyaya îngilîzî] li ser nivîskar, ku dê bi nav(ên) di {{para|nivîskar}} an {{para|paşnav}}/{{para|pêşnav}} de hatine dayîn ve were girêdan. Meqaleyên zêde dikarin bi navên nivîskarên din ve bi parametreyên {{para|lînka-nivîskar2}}, {{para|lînka-nivîskar3}}, hwd. werin girêdan. Pêşgira {:en:} an {w:} zêde neke. Wekî din, navê her kesî rasterast girêbide, wiha: {{para|nivîskar|<nowiki>[[w:Kathleen Taylor (biologist)|Kathleen Taylor]]</nowiki>}} an {{para|nivîskar|<nowiki>{{w|Samuel Johnson}}</nowiki>}}.]=]}, {{"hevnivîskar", multientity = true}, "Nav(ên) hevnivîskar(ên) <<work>>. Çend navan bi niqteya bi virgul ji hev cuda bike."}, {{"nivîskarê-sereke", multientity = true}, [=[Heke tu dixwazî diyar bikî ku perçeyek ji <<work:a>>, wek pêşgotin an destpêk, ji hêla kê ve hatiye nivîsandin, {{para|nivîskar}} bikar bîne, û {{para|nivîskarê-sereke}} jî bikar bîne ji bo diyarkirina nivîskar(ên) perçeya sereke ya <<work>>. Çend nivîskaran bi niqteya bi virgul ji hev cuda bike.]=]}, {{"terciman", multientity = true}, [=[Nav(ên) terciman(ên) <<collection>>. Çend navan bi niqteya bi virgul ji hev cuda bike. Xuyabûna rastîn girêdayî ye ka nivîskar an hevnivîskar berî wê hatine nîşandan an na. Heke ne, forma {John Doe, Mary Bloggs, wergêr} an {John Doe, Mary Bloggs, Richard Roe, wergêr} tê bikaranîn, bi navan pêşî. Wekî din, forma {tercimekirina John Doe û Mary Bloggs} an {tercimekirina John Doe, Mary Bloggs û Richard Roe} tê bikaranîn, da ku nivîskar(an) ji terciman(an) baştir cuda bike. Bala xwe bide ku di her du rewşan de jî niqteya bi virgul di derana wê de nayên bikaranîn wek sînorker.]=]}, {{"edîtor", multientity = true}, [=[Nav(ên) edîtor(ên) <<collection>>. Çend navan bi niqteya bi virgul ji hev cuda bike. Ev bi prensîbên dişibihin ên tercimanan, wek li jor: bêyî nivîskar, hevnivîskar an terciman berî wê, forma {John Doe, edîtor} an {John Doe, Mary Bloggs, Richard Roe, edîtor} (heke ji edîtorekî zêdetir hebe) tê bikaranîn. Wekî din, forma {bi edîtoriya John Doe û Mary Bloggs} an {bi edîtoriya John Doe, Mary Bloggs û Richard Roe} tê bikaranîn.]=],}, {{"editors", multientity = true}, [=[Nav(ên) edîtorên <<collection>>. Çend navan bi niqteya bi virgul ji hev cuda bike. Ferqa vê ya digel {{para|edîtor}} ev e ku dema nivîskar, hevnivîskar an terciman berî wê tune, ev parametre her tim "edîtor" nîşan dide, dema {{para|edîtor}} li gorî hejmara hebûnên diyarkirî "edîtor" an "edîtor" nîşan dide. (Hîna bernavek kurmancî ji bo dîtina vê cudatiyê bi taybetî nehatiye çêkirin; "editors" bikar bîne.)]=]}, {{"berhevkar", multientity = true}, [=[Nav(ên) berhevkar(ên) <<collection>>. Çend navan bi niqteya bi virgul ji hev cuda bike. Berhevkar dişibihin edîtoran lê bi taybetî ji bo berhevokên ji materyalên çavkaniyê (wek çîrokên devkî, stranên gelêrî, nameyên kesekî navdar, hwd.) têne bikaranîn. Ev qad wek {{para|edîtor}} dixebite lê "berhevkirin" li şûna "edîtorî" û "berhevkar(an)" li şûna "edîtor(an)" nîşan dide.]=]}, {{"compilers", multientity = true}, [=[Nav(ên) berhevkarên <<collection>>. Çend navan bi niqteya bi virgul ji hev cuda bike. Ji bo kengî ev bête bikaranîn li {{para|berhevkar}} binêre. (Hîna bernavek kurmancî ji bo vê cudatiyê nehatiye çêkirin; "compilers" bikar bîne.)]=]}, {{"jê-tê-girtin", multientity = true}, [=[Navê kesê tê jêgirtin, heke hemû nivîsa jêgirtî jêgirtina kesekî din e ne ya nivîskar bixwe.]=]}, }, {"Parametreyên li gorî sernav", {{"sernav", annotated = true, required = true}, [=[Sernavê <<collection>>.]=]}, {"tercimeya-sernav", [=[Heke sernavê <<collection>> bi îngilîzî/kurmancî nebe, ev parametre dikare ji bo pêşkêşkirina tercimeyeke sernav were bikaranîn, wekî alternatîfek ji bo diyarkirina tercimeyê bi guherkereke paşiyê (li jor binêre).]=]}, {{"serî", annotated = true}, [=[{{w|Rêzefirotina kitêban|Serî}}ya ku <<collection>> endamê wê ye.]=]}, {{"cildê-seriyê", annotated = true}, [=[Hejmara cildê <<collection>> di nava seriyê de ku endamê wê ye.]=]}, {"url", [=[URL'ya an navnîşana webê ya malperekê derveyî ku nivîsa tam a <<work>> tê de heye. ''Bi hîç malperekê ku muhtewaya wê mafê telîfê xera dike ve negire''.]=]}, {"urls", [=[Nivîseke azad, ji bo çend URL'yan. Berevajî {{para|url}}, edîtor divê bixwe kevanên URL'ê {[]} zêde bike.]=]}, }, {"Parametreyên li gorî beşê", {{"beş", annotated = true}, [=[Beşa <<collection>> ya jêgirtî. Tu dikarî an hejmareke beşê bi hejmarên erebî an romayî diyar bikî (wek nimûne, {{para|beş|7}} an {{para|beş|VII}}), an jî sernavekî beşê (wek nimûne, {{para|beş|Destpêk}}). Beşeke bi hejmarên erebî an romayî ya diyarkirî bi kelîmeya "beş" tê pêşgirtin, dema sernavekî beşê di "gîrçikên nîşandanê" de tê girtin.]=]}, {{"hejmara-beşê", annotated = true}, [=[Heke navê beşê di {{para|beş}} de hatibe dayîn, {{para|hejmara-beşê}} bikar bîne ji bo dayîna hejmara beşê ya li hev, ku dê di kevanan de li dû kelîmeya "beş" were nîşandan, wek nimûne {"Ceribandin" (beş 4)}.]=]}, {{"beş-sade", annotated = true}, [=[Nirxa tam a beşê, ku wek xwe tê nîşandan. Peyva "beş" û her gîrçikên xwestî zêde bike. Heke hem {{para|beş}} hem jî {{para|beş-sade}} hatibin dayîn, nirxa {{para|beş-sade}} li dû beşê, di kevanan de, tê nîşandan. Ev kêrhatî ye heke beşên vê <<collection>>ê bi kelîmeyek din a ji "beş" cuda werin binavkirin.]=]}, {"urlya-beşê", [=[[[w:Universal Resource Locator|URL]]'ya an navnîşana webê ya rûpeleke derveyî ku beş pê ve tê girêdan. Bala xwe bide ku bi giştî çêtir e {{para|urlya-rûpelê}} bikar bînî ji bo girêdana rasterast bi rûpela nivîsa jêgirtî, heke gengaz be. ''Bi hîç malperekê ku muhtewaya wê mafê [[w:copyright|telîfê]] xera dike ve negire''.]=]}, {"tercimeya-beş", [=[Heke beşa <<collection>> bi îngilîzî/kurmancî nebe, ev parametre dikare ji bo pêşkêşkirina tercimeyeke navê beşê were bikaranîn, wekî alternatîfek ji bo diyarkirina tercimeyê bi guherkereke paşiyê (li jor binêre).]=]}, {{"tercimanê-beşê", multientity = true}, [=[Tercimanê beşê, heke ji tercimanê giştî yê <<collection>> cuda be (bi {{para|terciman}} hatiye diyarkirin).]=]}, {{"seriya-beşê", "cildê-seriya-beşê", useand = true, annotated = true}, [=[Heke ev beş perçeyek e ji seriyeke beşên dişibihin, {{para|seriya-beşê}} dikare ji bo diyarkirina navê seriyê were bikaranîn, û {{para|cildê-seriya-beşê}} jî ji bo diyarkirina jimareya seriyê, heke hebe. Parametreyên {{para|serî}} û {{para|cildê-seriyê}} yên ji bo <<collection>> bi tevahî bide ber hev. Ev parametre bi taybetî ji bo stûnên dubareyî yên di rojnameyekê an tiştekî bi vî rengî de têne bikaranîn. Di {{şx|jêder-kovar}} de, parametreya {{para|beş}} wek {{para|sernav}} an {{para|meqale}} tê binavkirin û ji bo navê meqaleyeke kovarê, kovarê an rojnameyê tê bikaranîn, û parametreya {{para|seriya-beşê}} jî wek {{para|seriya-meqaleyê}} tê binavkirin û ji bo navê stûn an seriya meqaleyan a ku meqale perçeyek ji wê ye tê bikaranîn.]=]}, }, {"Parametreyên li gorî qismê", {{"qisim", annotated = true}, [=[Vê parametreyê bikar bîne ji bo diyarkirina perçeyeke (bi giştî bi hejmar) ji <<work:a>>, wekî alternatîf an temamkerê diyarkirina beşekê. Wek nimûne, di lîstikeke şanoyê de, {{para|qisim|perde II, dîmen iv}} bikar bîne, û di meqaleyeke kovareke teknîkî de, {{para|qisim|4}} bikar bîne. Heke nirxa vê parametreyê wek hejmareke romayî an erebî xuya bike, ew bi kelîmeya "qisim" tê pêşgirtin, wekî din wek xwe tê nîşandan (bide ber hev bi awayê wekhev ê {{para|beş}}).]=]}, {{"hejmara-qismê", annotated = true}, [=[Heke navê qismekê di {{para|qisim}} de hatibe dayîn, {{para|hejmara-qismê}} bikar bîne ji bo dayîna hejmara qismê ya li hev, ku dê di kevanan de li dû kelîmeya "qisim" were nîşandan, wek nimûne {Ceribandin (qisim 4)}.]=]}, {{"qisim-sade", annotated = true}, [=[Nirxa tam a qismê, ku wek xwe tê nîşandan; bide ber {{para|beş-sade}}. (Ev tenê ji bo temambûnê hatiye dayîn û bi giştî ne kêrhatî ye, çimkî nirxa {{para|qisim}} jî wek xwe tê nîşandan heke wek hejmarekê xuya nake.)]=]}, {"urlya-qismê", [=[[[w:Universal Resource Locator|URL]]'ya an navnîşana webê ya rûpeleke derveyî ku qisim pê ve tê girêdan. ''Bi hîç malperekê ku muhtewaya wê mafê [[w:copyright|telîfê]] xera dike ve negire''.]=]}, {"tercimeya-qism", [=[Heke qisma <<work>> bi îngilîzî/kurmancî nebe, ev parametre dikare ji bo pêşkêşkirina tercimeyeke qismê were bikaranîn, wekî alternatîfek ji bo diyarkirina tercimeyê bi guherkereke paşiyê (li jor binêre).]=]}, {{"rêzeya-qismê", "cildê-seriya-qismê", useand = true, annotated = true}, [=[Heke ev qisim perçeyek e ji seriyeke qismên dişibihin, {{para|rêzeya-qismê}} dikare ji bo diyarkirina navê seriyê were bikaranîn, û {{para|cildê-seriya-qismê}} jî ji bo diyarkirina jimareya seriyê, heke hebe. Parametreyên {{para|serî}} û {{para|cildê-seriyê}} yên ji bo <<collection>> bi tevahî, û {{para|seriya-beşê}} û {{para|cildê-seriya-beşê}} yên ji bo beşekê bide ber hev.]=]}, }, {"Parametreyên li gorî rûpel û rêzê", {{"rûpel", "rûpelên", annotated = true}, [=[Hejmara rûpel(an) an rêzeya rûpelan a <<work>>. Xeta dirêj (–) bikar bîne ji bo cudakirina hejmarên rûpelan a rêzeyê. Bi normal, {{para|rûpel}} û {{para|rûpelên}} bernavên hev in, û koda bixwe naskirin dike ka "rûpel" a yekjimar an "rûpelên" a pirjimar were nîşandan. Koda naskirinê "rûpelên" nîşan dide heke xeta dirêj (–), xeteke dirêjtir (—), xêzikek di navbera hejmaran de, an komek li dû valahiyekê û di navbera hejmaran de bibîne (valahî lazim e, da ku hejmar wek {1,478} bi cudakera hezaran neyên hesibandin wekî çend rûpel). Ji bo vemirandina vê naskirinê (wek nimûne, hin kitêb rûpelên xêzikî hene wek {3-16}), berî nirxê nîşana devnîgaşê ({!}) bicîh bike; heke ev were dayîn, navê parametreyê diyar dike ka "rûpel" an "rûpelên" were nîşandan. Wekî din, {{para|rûpel-sade}} bikar bîne. Wekî rewşeke taybet, nirxa {bêhejmar} dibe sedem {rûpela bêhejmar} were nîşandan.]=]}, {{"rûpel-sade", annotated = true}, [=[Nivîseke azad ku rûpel an rûpelên nivîsa jêgirtî diyar dike, wek nimûne {rûpela 8an} an {berga paşîn}. Tenê yekê ji {{para|rûpel}}, {{para|rûpelên}} û {{para|rûpel-sade}} bikar bîne.]=]}, {"urlya-rûpelê", [=[URL'ya an navnîşana webê ya rûpela ku rûpel(ên) <<work>> ê behskirî tê de ne. Hejmara rûpel(an) dê pê ve bê girêdan.]=]}, {{"rêz", "rêzên", annotated = true}, [=[Hejmara rêz(an) a nivîsa jêgirtî, wek nimûne {47} an {151–154}. Ev parametre wek {{para|rûpel}} û {{para|rûpelên}} dixebitin. Hejmara rêzan bi gelemperî di lîstikên şanoyê, helbestan û hin berhemên teknîkî de tên bikaranîn.]=]}, {{"rêz-sade", annotated = true}, [=[Nivîseke azad ku hejmara rêz(an) a nivîsa jêgirtî diyar dike, wek nimûne {beytên 44–45} an {jêrenot 3}. Tenê yekê ji {{para|rêz}}, {{para|rêzên}} û {{para|rêz-sade}} bikar bîne.]=]}, {"urlya-rêzê", [=[URL'ya an navnîşana webê ya rûpela ku rêz(ên) <<work>> ê behskirî tê de ne. Hejmara rêz(an) dê pê ve bê girêdan.]=]}, {{"stûn", "stûnên", "stûn-sade", useand = true, annotated = true}, [=[Hejmara stûn(an) a nivîsa jêgirtî. Ev parametre wek {{para|rûpel}}, {{para|rûpelên}} û {{para|rûpel-sade}} dixebitin.]=]}, {"urlya-stûnê", [=[URL'ya hejmara stûn(an) a nivîsa jêgirtî. Ev parametre wek {{para|urlya-rûpelê}} dixebite.]=]}, }, {"Parametreyên li gorî weşandinê", {{"weşanxane", multientity = true}, [=[Navê yek an çend weşanxaneyên <<collection>>. Heke ji weşanxaneyekê zêdetir hebe, navan bi niqteya bi virgul ji hev cuda bike.]=]}, {{"cih", multientity = true}, [=[Cihê ku <<collection>> lê hatiye weşandin. Heke ji cihekî zêdetir hebe, ciyan bi niqteya bi virgul ji hev cuda bike, wiha: {London; New York, N.Y.}.]=]}, {{"çap", annotated = true}, [=[Çapa <<collection>> ya jêgirtî, wek nimûne, {2an} an <code>3an a rastkirî û nûvekirî</code>. Li dû vê nivîsê kelîmeya "çap" tê zêdekirin (ji bo vemirandina vê {{para|çap-sade}} bikar bîne). Heke ji çapa yekem a <<collection>> tê jêgirtin, bi giştî ne lazim e ev rastî were diyarkirin.]=]}, {{"çap-sade", annotated = true}, [=[Nivîseke azad ku çapa <<collection>> ya jêgirtî diyar dike, wek nimûne {çapa 3an} an {çapa 5an, dîjîtalîzekirî} an {guhertoya 3.72}.]=]}, {{"sala-weşandinê", "meha-weşandinê", annotated = true, useand = true}, [=[Heke {{para|sal}} ji bo diyarkirina sala guhertoya orîjînal a <<issue>> tê bikaranîn, {{para|sala-weşandinê}} dikare ji bo diyarkirina sala guhertoya ku jê hatiye jêgirtin were bikaranîn, wek nimûne {|sal=1665|sala-weşandinê=2005}. {{para|meha-weşandinê}} dikare bi îxtiyarî ji bo diyarkirina meha weşandinê were bikaranîn. Sala weşandinê bi kelîmeya "weşandî" tê pêşgirtin. Ev parametre wek {{para|sal}} û {{para|meh}} têne xebitandin (ji bilî ku sal bi awayekî standard bi herfên qalind nayê nîşandan). Ev tê wê wateyê, wek nimûne, ku pêşgirên {c.}, {a.} û {p.} têne naskirin ji bo diyarkirina ku weşandin nêzîkî/berî/piştî tarîxeke diyarkirî bûye.]=]}, {"tarîxa-weşandinê", [=[Tarîxa ku guhertoya <<issue>> ya jêgirtî pê hatiye weşandin. An {{para|sala-weşandinê}} (û bi îxtiyarî {{para|meha-weşandinê}}), an {{para|tarîxa-weşandinê}} bikar bîne, ne herduyan. Wek {{para|tarîx}}, nirxa {{para|tarîxa-weşandinê}} divê tarîxeke rastîn be, bi an bêyî roj, ne nivîseke azad. Heman format wek yên {{para|tarîx}} tên naskirin.]=]}, {{"sala_destpêkê-weşandin", "meha-destpêkê-weşandin", annotated = true, useand = true}, [=[Heke weşandina guhertoya jêgirtî di nava rêzeyeke tarîxan de bûbe, sala destpêkê (û bi îxtiyarî meh) bi van parametreyan diyar bike û tarîxa dawî jî bixe {{para|sala-weşandinê}}/{{para|meha-weşandinê}} (an {{para|tarîxa-weşandinê}}). Ev bi awayekî wekhev bi {{para|sala-destpêkê}}/{{para|meha-destpêkê}} dixebite. Kêm caran lazim e van parametreyan bikar bînî.]=]}, {"tarîxa-destpêkê-weşandin", [=[Tarîxa destpêkê ya weşandina guhertoya jêgirtî, wekî alternatîfek ji bo diyarkirina {{para|sala_destpêkê-weşandin}}/{{para|meha-destpêkê-weşandin}}. Ev wek {{para|tarîxa-destpêkê}} dixebite. Kêm caran lazim e ev parametre were diyarkirin.]=]}, {{"sala-orîjînal", "meha-orîjînal", annotated = true, useand = true}, [=[Sala ku <<work>> cara pêşî hatiye weşandin, heke <<work>> ya jêgirtî guhertoyeke nû ya <<work:a>> ye (ne tenê çapeke nû). Wek nimûne, heke ji çapeke nûjen a Shakespeare an Milton tê jêgirtin, tarîxa çapa nûjen bixe {{para|sal}}/{{para|meh}} an {{para|tarîx}} û tarîxa çapa orîjînal jî bixe {{para|sala-orîjînal}}/{{para|meha-orîjînal}} an {{para|tarîxa-orîjînal}}. {{para|meha-orîjînal}} dikare bi îxtiyarî ji bo dayîna meha weşandina orîjînal were bikaranîn, an tarîxeke tam bi {{para|tarîxa-orîjînal}} were dayîn. An {{para|sala-orîjînal}}/{{para|meha-orîjînal}}, an {{para|tarîxa-orîjînal}} bikar bîne, ne herduyan. Ev parametre wek {{para|sal}} û {{para|meh}} têne xebitandin (ji bilî ku sal bi awayekî standard bi herfên qalind nayê nîşandan). Ev tê wê wateyê, wek nimûne, ku pêşgirên {c.}, {a.} û {p.} têne naskirin ji bo diyarkirina ku weşandina orîjînal nêzîkî/berî/piştî tarîxeke diyarkirî bûye.]=]}, {"tarîxa-orîjînal", [=[Tarîxa ku guhertoya orîjînal a <<work>> ya jêgirtî pê hatiye weşandin. An {{para|sala-orîjînal}} (û bi îxtiyarî {{para|meha-orîjînal}}), an {{para|tarîxa-orîjînal}} bikar bîne, ne herduyan. Wek {{para|tarîx}}, nirxa {{para|tarîxa-orîjînal}} divê tarîxeke rastîn be, bi an bêyî roj, ne nivîseke azad. Heman format wek yên {{para|tarîx}} tên naskirin.]=]}, {{"sala-destpêkê-orîjînal", "meha-destpêkê-orîjînal", annotated = true, useand = true}, [=[Sal/meha destpêkê ya guhertoya orîjînal a weşandinê, heke weşandin di nava rêzeyeke tarîxan de bûbe. An {{para|sala-destpêkê-orîjînal}} (û bi îxtiyarî {{para|meha-destpêkê-orîjînal}}), an {{para|tarîxa-destpêkê-orîjînal}} bikar bîne, ne herduyan. Ev bi awayekî wekhev bi {{para|sala-destpêkê}} û {{para|meha-destpêkê}} dixebite, û pir kêm caran lazim e were diyarkirin.]=]}, {"tarîxa-destpêkê-orîjînal", [=[Tarîxa destpêkê ya guhertoya orîjînal a weşandinê, heke weşandin di nava rêzeyeke tarîxan de bûbe. Ev wek {{para|tarîxa-destpêkê}} dixebite, û pir kêm caran lazim e were diyarkirin.]=]}, {{"platform", multientity = true}, [=[Platforma ku <<work>> lê hatiye weşandin. Ev ji bo platformên berhevkirina muhtewayê ne wek {{w|YouTube}}, {{w|Issuu}} û {{w|Magzter}}. (Hîna bernavek kurmancî ji bo vê parametreyê nehatiye çêkirin.) Ev wek "bi rêya PLATFORM" tê nîşandan.]=]}, {{"çavkanî", multientity = true}, [=[Çavkaniya muhtewaya <<work>>. Ev bi taybetî ji bo ajansên nûçeyan e wek {{w|Associated Press}}, {{w|Reuters}} û {{w|Agence France-Presse}} (AFP) (û ji ber vê yekê di {{şx|jêder-kovar}} de wek {{para|ajans}} tê binavkirin). Ev wek "ji ÇAVKANÎ hatiye wergirtin" tê nîşandan.]=]}, }, {"Parametreyên li gorî cildê", {{"cild", "cildên", annotated = true}, [=[Hejmara cild(an) a <<collection>>. Ev wek "cild CILD" tê nîşandan, an "cildên CILDÊN" heke rêzeyeke hejmaran were dayîn. Ka "cild" an "cildên" were nîşandan bi awayekî wekhev ê {{para|rûpel}} û {{para|rûpelên}} tê naskirin; {!} li destpêka nirxê bicîh bike ji bo vemirandina vê û rêzgirtina navê parametreyê. {{para|cild-sade}} bikar bîne heke tu nexwazî kelîmeya "cild" berî hejmara cildê xuya bibe.]=]}, {{"cild-sade", annotated = true}, [=[Nivîseke azad ku hejmara cild(an) a <<collection>> diyar dike, wek nimûne {kitêba II}. Tenê yekê ji {{para|cild}}, {{para|cildên}} û {{para|cild-sade}} bikar bîne.]=]}, {"urlya-cild", [=[URL'ya an navnîşana webê ya rûpela li hev a cildê ku nivîsa jêgirtî tê de ye, heke <<collection>> çend cild hebin bi URL'yên cuda. Hejmara cild(an) dê pê ve bê girêdan.]=]}, {{{"hejmar", "nimare"}, {"hejmarên", "nimareyên"}, {"hejmar-sade", "nimare-sade"}, useand = true, annotated = true}, [=[Hejmara/hejmarên nivîsa jêgirtî. Ev parametre wek {{para|rûpel}}, {{para|rûpelên}} û {{para|rûpel-sade}} dixebitin, ji bilî ku nivîsa xuyayî kelîmeya "hejmar" an "nimare" dihewîne (bêyî ferqa ka koma parametreyên {{para|hejmar}} an {{para|nimare}} têne bikaranîn; ew bernavên hev in). Nimûneyên bikaranîna {{para|hejmar-sade}} {kitêb 2} in (heke <<collection>> bi cildan hatibe dabeşkirin û cild jî bi kitêban) an {Hejmara Taybet 1} (ku têgeh ji almanî hatiye wergirtin, wateya "hejmareke taybet" dide).]=]}, {{{"urlya-hejmarê", "urlya-nimareyê"}, useand = true}, [=[URL'ya hejmara/hejmarên nivîsa jêgirtî. Ev parametre wek {{para|urlya-cild}} dixebite.]=]}, }, {"Parametreyên li gorî nasnameyê", {{"doi", "DOI"}, [=[[[w:Digital object identifier|Nasnameya berhema dîjîtal]] (DOI) ya <<work>>.]=]}, {{"isbn", "ISBN"}, [=[[[w:International Standard Book Number|Hejmara Standard a Navneteweyî ya Kitêbê]] (ISBN) ya <<collection>>. ISBN'ên 13-reqem tên tercihkirin li ser yên 10-reqem.]=]}, {{"issn", "ISSN"}, [=[[[w:International Standard Serial Number|Hejmara Rêzimalî ya Standard a Navneteweyî]] (ISSN) ya <<collection>>.]=]}, {{"jstor", "JSTOR"}, [=[Hejmara [[w:JSTOR|JSTOR]] ya <<work>>.]=]}, {{"lccn", "LCCN"}, [=[[[w:Library of Congress Control Number|Hejmara Kontrolê ya Pirtûkxaneya Kongreyê]] (LCCN) ya <<work>>.]=]}, {{"oclc", "OCLC"}, [=[Hejmara [[w:OCLC|Online Computer Library Center]] (OCLC) ya <<work>> (ku dikare li malpera [http://www.worldcat.org WorldCat] were lêgerandin).]=]}, {{"ol", "OL"}, [=[Hejmara [[w:Open Library|Open Library]] (bêyî "OL") ya <<work>>.]=]}, {{"pmid", "PMID"}, [=[Nasnameya [[w:PubMed#PubMed identifier|PubMed]] (PMID) ya <<work>>.]=]}, {{"pmcid", "PMCID"}, [=[Nasnameya [[w:PubMed Central#PMCID|PubMed Central]] (PMCID) ya <<work>>.]=]}, {{"ssrn", "SSRN"}, [=[Nasnameya [[w:Social Science Research Network|Social Science Research Network]] (SSRN) ya <<work>>.]=]}, {"bibcode", [=[{{w|Bibcode}}ya (koda bîbliyografîk, di pergalên daneyên stêrnasî de tê bikaranîn) <<work>>.]=]}, {"id", [=[Her nasnameyeke din a <<work>>.]=]}, }, {"Parametreyên li gorî arşîv û gihiştinê", {{"urlya-arşîvê", "tarîxa-arşîvê", useand = true}, [=[{{para|urlya-arşîvê}} û {{para|tarîxa-arşîvê}} (ku divê digel hev werin dayîn) bikar bîne ji bo diyarkirina URL'ya an navnîşana webê ya rûpeleke malperekê wek [https://archive.org Internet Archive] an [https://perma.cc Perma.cc] ku rûpel lê hatiye arşîvkirin, û tarîxa ku rûpel lê hatiye arşîvkirin.]=]}, {"tarîxa-gihiştinê", [=[Heke rûpel neyê arşîvkirin, {{para|tarîxa-gihiştinê}} bikar bîne ji bo diyarkirina tarîxa dawî ya ku rûpel hatiye gihiştin. Berevajî parametreyên din ên tarîxê, ev parametre nivîseke azad e. (Heke rûpel hatibe arşîvkirin, ne lazim e ev parametre were bikaranîn.)]=]}, }, {"Parametreyên cihêreng ên rêza jêderê", {"format", [=[Formata ku <<work>> lê ye, wek nimûne, {hardcover} an {paperback} ji bo kitêbekê an {blog} ji bo rûpeleke webê. (Hîna bernavek kurmancî ji bo vê parametreyê nehatiye çêkirin.)]=]}, {"janr", [=[{{w|Janra edebî}} ya <<work>>, wek nimûne {fiction} an {non-fiction}.]=]}, {"medium", [=[Medyaya qeydkirina <<work>>, wek nimûne, {Blu-ray}, {CD}, {DVD}, {fîlim}, {podcast}, {berhema televizyonê}, {qeyda dengî} an {kaseta vîdyoyê}. (Hîna bernavek kurmancî ji bo vê parametreyê nehatiye çêkirin.)]=]}, {{"nekat", boolean = true}, [=[{{para|nekat|1}} diyar bike ji bo vemirandina zêdekirina rûpelê li kategoriyeke bi forma {Kategorî:Jêgirtinên bi ``ziman``}. Ev bi normal nabe were kirin.]=]}, {{"nocolon", boolean = true}, [=[{{para|nocolon|1}} diyar bike ji bo vemirandina zêdekirina niqteya bi virgul li dawiya rêza jêderê. (Hîna bernavek kurmancî ji bo vê parametreyê nehatiye çêkirin.) Ev dikare were bikaranîn heke sernav bixwe (an kêm caran, nirxeke din a rêza jêderê) termê behskirî nîşan bide. Bawer bike ku tu herfên qalind ên sêalî bikar tînî di termê behskirî de, wek nimûne <code><nowiki>'''term'''</nowiki></code>, da ku diyar bike ka nivîsa jêgirtî kîjan e.]=]}, {{"wekçavkanî", boolean = true}, [=[{{para|wekçavkanî|1}} diyar bike ji bo zorkirina formata "çavkaniyê" (nivîskar pêşî).]=]}, {{"wekjêgirtin", boolean = true}, [=[{{para|wekjêgirtin|1}} diyar bike ji bo zorkirina formata "jêgirtinê" (sal pêşî).]=]}, }, {"Guhertoya nû ya <<work:a>> (parametreyên <code>*2</code>)", [=[Parametreyên jêrîn dikarin werin bikaranîn ji bo diyarkirina guhertoyeke nû ya <<work>>, wek çapeke nû, çapeke din, an guhertoyeke din a ji nû ve hatî weşandin. Awayê giştî yê vê ev e: # {{para|versiyona-nû|ji nû ve hatiye weşandin wekî}}, {{para|versiyona-nû|hate tercimekirin wekî}}, {{para|versiyona-nû|hate jêgirtin di}} an tiştên bi vî rengî diyar bike ji bo nîşandana ka guhertoya nû çi ye. (Di hin rewşan de, ev parametre dikare neyê dayîn; li jêr binêre.) # Nivîskar(ên) guhertoya nû bi {{para|2nivîskar}} diyar bike (çend nivîskaran bi niqteya bi virgul ji hev cuda bike) an {{para|2paşnav}}/{{para|2pêşnav}}. # Taybetmendiyên mayî yên guhertoya nû bi zêdekirina {2} li dû parametreyên li jor hatine diyarkirin bide, wek nimûne {{para|sernav2}} ji bo sernavê guhertoya nû, {{para|rûpel2}} ji bo hejmara rûpelê ya guhertoya nû, hwd. Hin parametreyên taybet wekî alternatîfek ji bo diyarkirina guhertoyeke nû bi vî rengî têne peyakirin. Wek nimûne, parametreyên {{para|orîjînal}} û {{para|ji-aliyê}} dikarin werin bikaranîn dema guhertoyeke tercimekirî ya <<work:a>> tê jêgirtin; li jêr binêre.]=], {"versiyona-nû", [=[Şablon dihesibîne ku guhertoyeke nû ya <<work>> tê behskirin heke {{para|versiyona-nû}} an {{para|cih2}} hatibin dayîn, an heke parametreyên nivîskarê guhertoya nû hatibin dayîn ({{para|2nivîskar}} an {{para|2paşnav}}), an heke parametreyeke din a sernav an nivîskarê guhertoya nû hatibe dayîn (her yek ji {{para|beş2}}, {{para|sernav2}}, {{para|terciman2}}, {{para|edîtor2}}). Paşê wiha tevdigere: * Heke nivîskar, edîtor û/an sernav hatibin dayîn, "ji nû ve hatiye weşandin wekî" nîşan dide. * Heke tenê cih, weşanxane û tarîxa weşandinê hatibin dayîn, "ji nû ve hatiye weşandin" nîşan dide. * Heke çapek hatibe dayîn, tu nivîs nayê nîşandan. {{para|versiyona-nû}} bikar bîne ji bo betalkirina vê tevgerê, wek nimûne, bi nîşandana "hate jêgirtin di" an "ji nû ve hatiye çapkirin wekî".]=]}, {{"2nivîskar", multientity = true}, [=[Nivîskarê guhertoya nû. Çend nivîskaran bi niqteya bi virgul ji hev cuda bike. Wekî din, {{para|2paşnav}} û {{para|2pêşnav}} bikar bîne.]=]}, {{"2paşnav", "2pêşnav", useand = true}, [=[Pêşnav (digel navên navîn an herfên pêşî) û paşnavê nivîskarê guhertoya nû. Tê tercihkirin ku {{para|2nivîskar}} li şûna {{para|2paşnav}}/{{para|2pêşnav}} were bikaranîn, ji ber çend sedeman: # Navên axaftvanên zimanên biyanî dibe hêsan nebe ew bikevin pêşnav û paşnavan. # Tenê yek nivîskar dikare bi {{para|2paşnav}}/{{para|2pêşnav}} were diyarkirin, dema çend nivîskarên bi niqteya bi virgul ji hev cuda dikarin bi {{para|2nivîskar}} werin dayîn. # Guherkerên paşiyê ji bo {{para|2paşnav}} û {{para|2pêşnav}} nayên piştgirîkirin û naskirina xeta nivîsê nayê kirin, tê wê wateyê ku tenê navên bi herfên latînî têne piştgirîkirin.]=]}, {"2lînka-nivîskar", [=[Navê meqaleyeke [https://en.wikipedia.org Wîkîpediyaya îngilîzî] li ser nivîskar, ku dê bi nav(ên) di {{para|2nivîskar}} an {{para|2paşnav}}/{{para|2pêşnav}} de hatine dayîn ve were girêdan. Pêşgira {:en:} an {w:} zêde neke. Wekî din, navê her kesî rasterast girêbide, wiha: {{para|2nivîskar|<nowiki>[[w:Kathleen Taylor (biologist)|Kathleen Taylor]]</nowiki>}}.]=]}, {{"{{para|sernav2}}, {{para|edîtor2}}, {{para|cih2}}, ''hwd.''", literal = true, multientity = true}, [=[Piraniya parametreyên li jor hatine navborîn dikarin li guhertoyeke nû ya <<work>> werin sepandin bi zêdekirina {2} li dû navê parametreyê. Tê tewsiyekirin ku bi kêmanî agahiyên çapkirinê yên guhertoya nû ya <<work>> bi {{para|cih2}}, {{para|weşanxane2}}, û {{para|tarîx2}} an {{para|sal2}} bêne dayîn.]=]}, }, {"Awayên taybet ên alternatîf ên diyarkirina guhertoyeke nû ya <<work:a>>", [=[Parametreyên jêrîn awayên alternatîf peyda dikin ji bo diyarkirina guhertoyeke nû ya <<work:a>>, wek çapeke nû an tercimeyek, an rewşeke ku perçeyek ji <<work:a>> di ya din de tê jêgirtin. Heke tu bibînî ku ev parametre têrê nakin ji bo diyarkirina hemû agahiyên li ser her du berheman, hewl nede agahiyên zêde bi zorê tê xin. Li şûna wê, awayê li jor hatiye rave kirin bikar bîne, bi {{para|versiyona-nû}} û {{para|2nivîskar}}, {{para|sernav2}}, hwd.]=], {{"orîjînal", annotated = true}, [=[Heke tu {{w|berhemeke derekî}} wek tercimeyekê jêgirî dikî, {{para|orîjînal}} bikar bîne ji bo diyarkirina sernavê berhema orîjînal, {{para|ji-aliyê}} ji bo diyarkirina nivîskarê berhema orîjînal û {{para|deriv}} ji bo diyarkirina cureyê berhema derekî. An {{para|orîjînal}}, an {{para|ji-aliyê}} divê were dayîn da ku ev awa kêrhatî be. Heke her sê hatibin dayîn, koda {``deriv`` ya ``orîjînal`` ji hêla ``ji-aliyê`` ve} nîşan dide. Heke {{para|orîjînal}} neyê dayîn, nivîsa xwerû {orîjînal} tê bikaranîn. Heke {{para|deriv}} neyê dayîn, nivîsa xwerû {tercime} tê bikaranîn. Heke {{para|ji-aliyê}} neyê dayîn, perçeya "ji hêla {``ji-aliyê``} ve" nayê nîşandan.]=]}, {{"ji-aliyê", multientity = true}, [=[Heke tu {{w|berhemeke derekî}} wek tercimeyekê jêgirî dikî, {{para|ji-aliyê}} bikar bîne ji bo diyarkirina nivîskar(ên) berhema orîjînal. Li {{para|orîjînal}} ya li jor binêre.]=]}, {"deriv", [=[Heke tu {{w|berhemeke derekî}} wek tercimeyekê jêgirî dikî, {{para|deriv}} bikar bîne ji bo diyarkirina cureyê berhema derekî. (Hîna bernavek kurmancî ji bo vê parametreyê nehatiye çêkirin.) Li {{para|orîjînal}} ya li jor binêre.]=]}, {{"cihê-jêgirtinê", annotated = true}, [=[Heke nivîsa jêgirtî ji kitêba A ye ku dibêje ev nivîs ji kitêbeke din a B hatiye wergirtin, van bike: * {{para|sernav}}, {{para|çap}}, û {{para|kesên-din}} bikar bîne ji bo dayîna agahiyan li ser kitêba B. (Wek nimûne, {{para|kesên-din}} dikare wiha were bikaranîn: {{para|kesên-din=1893, rûpel 72}}.) * {{para|cihê-jêgirtinê}} (ji bo sernavê kitêba A), {{para|cih}}, {{para|weşanxane}}, {{para|sal}}, {{para|rûpel}}, {{para|oclc}}, û parametreyên din ên standard bikar bîne ji bo dayîna agahiyan li ser kitêba A.]=]}, }, } end local quote_mods = { ["jêder-kitêb"] = { {"#substitute", work = "kitêb", collection = "kitêb", issue = "kitêb"}, {"sal", addalias = "2"}, {"nivîskar", addalias = "3"}, {"sernav", addalias = "4"}, {"url", addalias = "5"}, {"rûpel", addalias = "6"}, {"jêgirtin", addalias = "7"}, {"tercime", addalias = "8"}, {"beş", addalias = "made", append_desc = [=[Parametreya {{para|made}} dikare were bikaranîn heke ji ferhengekê tê jêgirtin.]=]}, {"tercimeya-beş", addalias = "tercimeya-made", replace_desc = [=[Heke beşa, an madeya, kitêbê bi îngilîzî/kurmancî nebe, ev parametre dikare ji bo pêşkêşkirina tercimeyeke navê beş an madeyê were bikaranîn, wekî alternatîfek ji bo diyarkirina tercimeyê bi guherkereke paşiyê (li jor binêre).]=]}, {"urlya-beşê", addalias = "urlya-madeyê", replace_desc = [=[[[w:Universal Resource Locator|URL]]'ya an navnîşana webê ya rûpeleke derveyî ku beş an made pê ve tê girêdan. Wek nimûne, heke kitêb hejmara rûpelan tune, rûpel dikare bi navê beş an madeyê ve, bi vê parametreyê, were girêdan. ''Bi hîç malperekê ku muhtewaya wê mafê [[w:copyright|telîfê]] xera dike ve negire''.]=]}, }, ["jêder-kovar"] = { {"#substitute", work = "meqale", collection = "kovar", issue = "hejmara kovarê"}, {"sal", addalias = "2"}, {"nivîskar", addalias = "3"}, {"sernav", replace_params = {"kovar", "kovar", "xezete", "xebat", "5", annotated = true}}, {"tercimeya-sernav", replace_params = {"tercimeya-kovar", "tercimeya-kovar", "tercimeya-xezete", "tercimeya-xebat"}}, {"url", addalias = "6"}, {"rûpel", addalias = "7"}, {"jêgirtin", addalias = "8"}, {"tercime", addalias = "9"}, {"çavkanî", addalias = "ajans"}, {"#replace_group", "Parametreyên li gorî beşê", {"Parametreyên li gorî meqaleyê", {{"sernav", "meqale", "4", annotated = true, semi_required = true}, [=[Sernavê meqaleya kovarê ya jêgirtî, ku dê di "gîrçikên nîşandanê yên xemilandî" de were girtin.]=]}, {{"sernav-sade", "meqale-sade", annotated = true}, [=[Sernavê meqaleyê, ku wek xwe tê nîşandan. Her gîrçikên xwestî û kelîmeyên din zêde bike. Heke hem {{para|sernav}} hem jî {{para|sernav-sade}} hatibin dayîn, nirxa {{para|sernav-sade}} li dû sernavî, di kevanan de, tê nîşandan. Ev kêrhatî ye wek nimûne ji bo diyarkirina hejmara meqaleyê an nasnameyeke din.]=]}, {{"urlya-sernav", "urlya-meqaleyê"}, [=[[[w:Universal Resource Locator|URL]]'ya an navnîşana webê ya rûpeleke derveyî ku meqale pê ve tê girêdan. Bala xwe bide ku bi giştî çêtir e {{para|urlya-rûpelê}} bikar bînî ji bo girêdana rasterast bi rûpela nivîsa jêgirtî, heke gengaz be. ''Bi hîç malperekê ku muhtewaya wê mafê [[w:copyright|telîfê]] xera dike ve negire''.]=]}, {{"tercimeya-sernav", "tercimeya-meqale"}, [=[Heke meqaleya kovarê bi îngilîzî/kurmancî nebe, ev parametre dikare ji bo pêşkêşkirina tercimeyeke sernav were bikaranîn, wekî alternatîfek ji bo diyarkirina tercimeyê bi guherkereke paşiyê (li jor binêre).]=]}, {{"tercimanê-meqaleyê", multientity = true}, [=[Tercimanê meqaleyê, heke ji tercimanê giştî yê kovarê cuda be (bi {{para|terciman}} hatiye diyarkirin).]=]}, {{"seriya-meqaleyê", "cildê-seriya-meqaleyê", annotated = true, useand = true}, [=[Heke ev meqale perçeyek e ji seriyeke meqaleyên dişibihin, {{para|seriya-meqaleyê}} dikare ji bo diyarkirina navê seriyê were bikaranîn, û {{para|cildê-seriya-meqaleyê}} jî ji bo diyarkirina jimareya seriyê, heke hebe. Parametreyên {{para|serî}} û {{para|cildê-seriyê}} yên ji bo kovarê bi tevahî bide ber hev. Ev parametre dikarin werin bikaranîn, wek nimûne, ji bo stûnên dubareyî yên di rojnameyekê de.]=]}, } }, }, } local function canonicalize_paramspec(paramspec, add_non_generic) -- Canonicalize a top-level string param to a list. if type(paramspec) == "string" then paramspec = {paramspec} end for j, paramset in ipairs(paramspec) do -- Canonicalize a second-level string param to a list. if type(paramset) ~= "table" or paramset.param then paramset = {paramset} paramspec[j] = paramset end for k, param in ipairs(paramset) do -- Canonicalize a single param to object form. if type(param) == "string" then param = {param = param} if add_non_generic and param.non_generic == nil then param.non_generic = true end paramset[k] = param end end end return paramspec end local function canonicalize_param_group(group, add_non_generic) local ind = 2 if type(group[2]) == "string" then ind = ind + 1 end for i = ind, #group do -- Canonicalize the parameter spec to the maximally-expressed form for easier processing. local paramspec, desc = unpack(group[i]) group[i][1] = canonicalize_paramspec(paramspec, add_non_generic) end end local function canonicalize_param_list(params, add_non_generic) -- Canonicalize an addalias= spec to a list for easier processing. if type(params) ~= "table" or params.param then params = {params} end for i, p in ipairs(params) do -- Canonicalize. if type(p) == "string" then p = {param = p} params[i] = p end if add_non_generic and p.non_generic == nil then p.non_generic = true end end return params end -- Apply the modifications specified in `mods` to the parameters in `params`. local function apply_mods(params, mods) local mod_table = {} local subvals -- First, convert the modifications to a dictionary for easy lookup as we traverse the existing parameters. for _, mod in ipairs(mods) do local param = mod[1] if param == "#substitute" then mod[1] = nil subvals = mod elseif param ~= "#replace_group" then -- Need to do replace_group after aliases because replace_group might introduce new params that we don't want aliases -- to touch (e.g. |title= in {{quote-journal}}). mod_table[param] = mod end end -- Process each group in turn. for _, group in ipairs(params) do canonicalize_param_group(group) local ind = 2 if type(group[2]) == "string" then ind = ind + 1 end for i = ind, #group do -- Go through each parameter group looking for modifications, and make them. To avoid problems -- side-effecting lists as we process them, we first clone the group and iterate over the clone, which -- remains unmodified. local paramspec, desc = unpack(group[i]) local specclone = m_table.deepCopy(paramspec) for j, paramset in ipairs(specclone) do for k, param in ipairs(paramset) do local mod = mod_table[param.param] if mod then if mod.addalias then -- Canonicalize an addalias= spec to a list for easier processing. local to_add = canonicalize_param_list(mod.addalias, "add non-generic") for _, ta in ipairs(to_add) do if paramspec.useand then -- Top level refers to logically-related params so alias goes at second level. table.insert(paramspec[j], ta) else table.insert(paramspec, {ta}) end end end if mod.replace_params then group[i][1] = canonicalize_paramspec(mod.replace_params, "add non-generic") end if mod.append_desc then group[i][2] = group[i][2] .. " " .. mod.append_desc end if mod.replace_desc then group[i][2] = mod.replace_desc end end end end end end for _, mod in ipairs(mods) do local param = mod[1] if param == "#replace_group" then local _, existing_group_name, new_group = unpack(mod) canonicalize_param_group(new_group) local ind = 2 if type(new_group[2]) == "string" then ind = ind + 1 end for i = ind, #new_group do local paramspec, desc = unpack(new_group[i]) for j, paramset in ipairs(paramspec) do for k, param in ipairs(paramset) do if param.non_generic == nil then param.non_generic = true end end end end local replaced = false for i, group in ipairs(params) do if group[1] == existing_group_name then params[i] = new_group replaced = true break end end if not replaced then error(("Internal error: Unable to locate existing group '%s'"):format(existing_group_name)) end end end return subvals end -- Format a param spec as found in the first element of a param description. local function format_param_spec(paramspec) if type(paramspec) ~= "table" or paramspec.param then paramspec = {paramspec} end local function format_one_param(param, non_generic) if non_generic then param = "<b>" .. param .. "</b>" end if paramspec.boolean then return ("<code>|%s=1</code>"):format(param) else return ("<code>|%s=</code>"):format(param) end end local function format_all_params_no_list(suffix) local formatted = {} for _, paramset in ipairs(paramspec) do if type(paramset) ~= "table" or paramset.param then paramset = {paramset} end local formatted_paramset = {} for _, p in ipairs(paramset) do if type(p) == "string" then p = {param = p} end -- Skip ...2 and ...3 versions of numeric params. if suffix == "" or not rfind(p.param, "^[0-9]+") then table.insert(formatted_paramset, format_one_param(p.param .. suffix, p.non_generic)) end end local to_insert = table.concat(formatted_paramset, "/") if to_insert ~= "" then table.insert(formatted, to_insert) end end return m_table.serialCommaJoin(formatted, {conj = paramspec.useand and "and" or "or"}) end local function format_all_params() if paramspec.list then local formatted = {} table.insert(formatted, format_all_params_no_list("")) table.insert(formatted, format_all_params_no_list("2")) table.insert(formatted, format_all_params_no_list("3")) table.insert(formatted, "hwd.") return table.concat(formatted, "; ") else return format_all_params_no_list("") end end local formatted_params if paramspec.literal then formatted_params = preprocess(paramspec[1][1].param) else formatted_params = format_all_params() end local reqtext = paramspec.required and " '''(lazim)'''" or "" return formatted_params .. reqtext end local function process_continued_string(desc, subvals) desc = rsub(desc, "{{", TEMP_DOUBLE_LBRACE) desc = rsub(desc, "}}", TEMP_DOUBLE_RBRACE) -- Join continuation lines. Do it twice in case of a single-character line (admittedly rare). desc = rsub(desc, "([^\n])\n[ \t]*([^ \t\n#*])", "%1 %2") desc = rsub(desc, "([^\n])\n[ \t]*([^ \t\n#*])", "%1 %2") -- Remove whitespace before list elements. desc = rsub(desc, "\n[ \t]*([#*])", "\n%1") desc = rsub(desc, "^[ \t]*([#*])", "%1") -- placeholder variable names between double backquotes desc = rsub(desc, "``([A-Za-z0-9_%-]+)``", "<var>%1</var>") -- variable/parameter names between backquotes desc = rsub(desc, "`([A-Za-z0-9_%-]+)`", '<code class="n">%1</code>') desc = rsub(desc, "%b{}", function(m0) -- {} blocks return "<code>" .. m0:sub(2, -2) .. "</code>" end) desc = rsub(desc, "<<([^><]+)>>", function(item) local parts = rsplit(item, ":") item = parts[1] if subvals[item] then if type(subvals[item]) == "string" then item = subvals[item] elseif type(subvals[item]) == "number" then item = "" .. subvals[item] else error("The item '<<" .. item .. ">>' is a " .. type(items[item]) .. " and can't be concatenated.") end else error("The item '" .. item .. "' was not found in the 'subvals' table.") end for i, part in ipairs(parts) do if i > 1 then if part == "a" then item = ku_add_indefinite(item) elseif part == "cap" then item = mw.getContentLanguage():ucfirst(item) end end end return item end) desc = rsub(desc, TEMP_DOUBLE_LBRACE, "{{") desc = rsub(desc, TEMP_DOUBLE_RBRACE, "}}") desc = preprocess(desc) return desc end local function format_parameter_group(group, subvals, level) local parts = {} local function ins(txt) table.insert(parts, txt) end local prefsuf = ("="):rep(level) ins(prefsuf .. process_continued_string(group[1], subvals) .. prefsuf) local ind = 2 if type(group[2]) == "string" then ins(process_continued_string(group[2], subvals)) ind = ind + 1 end ins('{| class="wikitable"') ins("! Parametre") ins("! Dikare bê etîketkirin") ins("! Dikare çend hebûnên bi niqteya bi virgul ji hev cuda bihewîne") ins("! Têbînî") for i = ind, #group do local paramspec, desc = unpack(group[i]) ins('|- style="vertical-align: top"') ins('| style="text-align: center" | ' .. format_param_spec(paramspec)) ins('| style="text-align: center" | ' .. ((paramspec.annotated or paramspec.multientity) and "'''Erê'''" or "Na")) ins('| style="text-align: center" | ' .. (paramspec.multientity and "'''Erê'''" or "Na")) ins("| " .. process_continued_string(desc, subvals)) end ins("|}") return table.concat(parts, "\n") end local function format_inline_modifiers(mods) local parts = {} local function ins(txt) table.insert(parts, txt) end ins('{| class="wikitable"') ins("! Guherker") ins("! Têbînî") for _, modspec in ipairs(mods) do local modifier, desc = unpack(modspec) ins('|- style="vertical-align: top"') ins('| style="text-align: center" | <code>' .. modifier .. "</code>") ins("| " .. process_continued_string(desc, {})) end ins("|}") return table.concat(parts, "\n") end local function format_introduction(template) local parts = {} local function ins(txt) table.insert(parts, txt) end ins("===Destpêk===") ins(process_continued_string(generate_param_intro_text(template), {})) ins("") ins('{| class="wikitable"') ins("! Guherker") ins("! Têbînî") for _, modspec in ipairs(generate_inline_modifiers(template)) do local modifier, desc = unpack(modspec) ins('|- style="vertical-align: top"') ins('| style="text-align: center" | <code>' .. modifier .. "</code>") ins("| " .. process_continued_string(desc, {})) end ins("|}") return table.concat(parts, "\n") end function export.show_doc(template) if type(template) == "table" then template = template.args[1] end local params = generate_params(template) local mods = quote_mods[template] if not mods then error(("No modifications found for template '%s'"):format(template)) end local subvals = apply_mods(params, mods) local parts = { format_introduction(template) } for _, group in ipairs(params) do table.insert(parts, format_parameter_group(group, subvals, 3)) end return table.concat(parts, "\n\n") end return export hw1bao7dmysrbo27713x7tjei684aba Bikarhêner:Wikihez/Gadget-test/util.js 2 1358591 6333825 6333779 2026-08-15T15:04:11Z Wikihez 7344 6333825 javascript text/javascript /** * Generic text and UI helpers for the entry-creation wizard; no wizard-specific * state, so any gadget can require("./start/util.js"). */ //<nowiki> function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function splitTercimeIzah(mane) { var m = /^([\s\S]*?)\s*\{\{îzah\|([\s\S]*)\}\}\s*$/.exec(mane || ""); return m ? { tercime: m[1], izah: m[2] } : null; } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var FOLD_EXTRA ={ "ı":"i", "ø":"o","đ":"d","ð":"d","ə":"e","ħ":"h","ł":"l","ŋ":"n","ʉ":"u", "ɨ":"i","ʒ":"z","ɛ":"e","ɔ":"o","æ":"ae", "œ":"oe","ß":"ss","þ":"th" }; function foldDiacritics(str) { if (str === null || str === undefined) return ""; var s = String(str).toLowerCase(); if (typeof s.normalize === "function") { // Split "î" into "i" + combining circumflex, then drop the accent. s = s.normalize("NFD").replace(/[\u0300-\u036f]/g, ""); } return s.replace(/[^\u0000-\u007f]/g, function (ch) { return Object.prototype.hasOwnProperty.call(FOLD_EXTRA, ch) ? FOLD_EXTRA[ch] : ch; }); } var WIKTKU_RESIZE_STORAGE_PREFIX = "wiktku_resize_height_"; function wiktkuResizeStorageKey(textarea) { var cls = (textarea.attr("class") || "").trim().replace(/\s+/g, "_"); return WIKTKU_RESIZE_STORAGE_PREFIX + cls; } function wiktkuSaveResizeHeight(textarea, height) { if (!(window.mw && mw.storage)) return; try { mw.storage.set(wiktkuResizeStorageKey(textarea), String(Math.round(height))); } catch (e) { /* localStorage unavailable (private mode, quota, …) — skip caching */ } } function wiktkuLoadResizeHeight(textarea) { if (!(window.mw && mw.storage)) return null; try { var v = mw.storage.get(wiktkuResizeStorageKey(textarea)); return v ? parseFloat(v) : null; } catch (e) { return null; } } function wiktkuMakeManualResizable(textarea) { textarea = $(textarea); if (!textarea.is("textarea") || textarea.hasClass("wiktku-start-narrow")) return; if (textarea.data("wiktkuResizableDone")) return; textarea.data("wiktkuResizableDone", true); textarea.wrap("<div class='wiktku-resize-wrap'></div>"); var grip = $("<div class='wiktku-resize-grip'></div>"); textarea.after(grip); // Restore this field's last saved height, if any. var cachedHeight = wiktkuLoadResizeHeight(textarea); if (cachedHeight) { var minHeightInit = parseFloat(textarea.css("min-height")) || 0; textarea.css("height", Math.max(cachedHeight, minHeightInit) + "px"); } var dragging = false, startY = 0, startHeight = 0; function onPointerMove(e) { if (!dragging) return; var oe = e.originalEvent || e; var minHeight = parseFloat(textarea.css("min-height")) || 0; var newHeight = startHeight + (oe.clientY - startY); textarea.css("height", Math.max(newHeight, minHeight) + "px"); } function onPointerUp(e) { if (!dragging) return; dragging = false; var oe = e.originalEvent || e; try { grip[0].releasePointerCapture(oe.pointerId); } catch (err) { /* ignore */ } $(document).off("pointermove", onPointerMove); $(document).off("pointerup pointercancel", onPointerUp); wiktkuSaveResizeHeight(textarea, textarea.outerHeight()); } grip.on("pointerdown", function (e) { var oe = e.originalEvent || e; if (oe.button !== undefined && oe.button !== 0) return; // primary contact only e.preventDefault(); dragging = true; startY = oe.clientY; startHeight = textarea.outerHeight(); try { grip[0].setPointerCapture(oe.pointerId); } catch (err) { /* ignore */ } $(document).on("pointermove", onPointerMove); $(document).on("pointerup pointercancel", onPointerUp); }); } /** Applies wiktkuMakeManualResizable to every eligible textarea in `context` (itself or its descendants). */ function wiktkuInitManualResize(context) { var $context = $(context); var $textareas = $context.is("textarea") ? $context : $context.find("textarea"); $textareas.each(function () { wiktkuMakeManualResizable(this); }); } /** URL of a template's own wiki page, via mw.util when available. */ function tplPageUrl(name) { var title = "Şablon:" + name; if (window.mw && mw.util && typeof mw.util.getUrl === "function") { return mw.util.getUrl(title); } return "/wiki/" + encodeURIComponent(title); } function wrapNativeSelect(select) { var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); if (select.prop("multiple")) { return wrapper.append(select); } var placeholder = select.attr("data-placeholder") || "Lê bigere..."; select.hide(); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .attr("role", "combobox") .attr("aria-autocomplete", "list") .attr("aria-expanded", "false") .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results' role='listbox'></ul>").hide(); var allOptions = []; var shown = []; var activeIndex = -1; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); var text = $(this).text(); // Skip a blank value with no label; a blank value WITH a label // (e.g. "clear the selection") is still a real, selectable option. if (!v && !text) return; // Language options read "Name (code)" -- score the name alone so // the trailing code doesn't also count as a name match. var name = text.replace(/\s*\([^()]*\)\s*$/, ""); allOptions.push({ value: v, text: text, disabled: $(this).prop("disabled"), // data-tpl options render as a template row (name, page link, info icon). tpl: $(this).attr("data-tpl") || "", tplStatus: $(this).attr("data-tpl-status") || "", foldCode: foldDiacritics(v), foldName: foldDiacritics(name), foldText: foldDiacritics(text) }); }); } cacheOptions(); // True if `q` starts a word inside `name` ("kevn" in "ingiliziya kevn"). function startsWord(name, q) { var from = 0, at; while ((at = name.indexOf(q, from)) !== -1) { if (at === 0 || /[\s\-\u2013\u2014(/,.]/.test(name.charAt(at - 1))) return true; from = at + 1; } return false; } // Lower rank = better match; a code match always outranks a name match. var RANK_NONE = 99; function rankOption(o, q) { var code = o.foldCode, name = o.foldName; if (code === q) return 0; // exact code if (code.indexOf(q) === 0) return 1; // code prefix if (name === q) return 2; // exact name if (name.indexOf(q) === 0) return 3; // name prefix if (startsWord(name, q)) return 4; // starts a word in the name if (name.indexOf(q) !== -1) return 5; // name substring if (code.indexOf(q) !== -1) return 6; // code substring if (o.foldText.indexOf(q) !== -1) return 7; // anywhere else in the label return RANK_NONE; } function positionList() { // Position the list above or below depending on viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px = 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); } function closeList() { resultsList.hide(); textInput.attr("aria-expanded", "false"); activeIndex = -1; } function showResults(query) { var q = foldDiacritics($.trim(query || "")); resultsList.empty(); activeIndex = -1; var matched = []; if (q) { $.each(allOptions, function (i, o) { if (o.disabled) return; var rank = rankOption(o, q); if (rank !== RANK_NONE) matched.push({ opt: o, rank: rank, i: i }); }); if (!matched.length && q.indexOf(" ") !== -1) { var tokens = q.split(/\s+/); $.each(allOptions, function (i, o) { if (o.disabled) return; var all = true; $.each(tokens, function (_, t) { if (o.foldText.indexOf(t) === -1) { all = false; return false; } }); if (all) matched.push({ opt: o, rank: 8, i: i }); }); } matched.sort(function (a, b) { if (a.rank !== b.rank) return a.rank - b.rank; // Inside the code tiers the shorter code is the better hit: // "an" -> "an" before "ang" before "ang-x-...". if (a.rank <= 1 && a.opt.foldCode.length !== b.opt.foldCode.length) { return a.opt.foldCode.length - b.opt.foldCode.length; } // Otherwise keep the menu's own order (pinned languages first). return a.i - b.i; }); } else { $.each(allOptions, function (i, o) { if (!o.disabled) matched.push({ opt: o, rank: 0, i: i }); }); } shown = $.map(matched.slice(0, 50), function (m) { return m.opt; }); if (!shown.length) { closeList(); return; } $.each(shown, function (idx, opt) { var li = $("<li role='option'></li>") .attr("data-value", opt.value) .attr("aria-selected", "false"); if (opt.tpl) { // Template row: status dot, name, then two icons that stopPropagation // so clicking them doesn't also select the option. li.addClass("wiktku-ac-tplrow"); li.append($("<span class='wiktku-tpl-dot'></span>") .addClass(opt.tplStatus === "yellow" ? "wiktku-tpl-dot-special" : "wiktku-tpl-dot-ok") .attr("title", opt.tplStatus === "yellow" ? "Tenê ji bo rewşên taybet" : "Tê pêşniyar kirin")); li.append($("<span class='wiktku-ac-tpltext'></span>").text(opt.text)); var icons = $("<span class='wiktku-tpl-icons'></span>"); // touchend must be stopped here too, or a tap on either icon // selects the template row instead of activating the icon. var STOP = "mousedown touchstart touchend touchmove"; var link = $("<a class='wiktku-tpl-icon wiktku-tpl-icon-link' target='_blank' rel='noopener'>🔗</a>") .attr("title", "Rûpela şablonê veke") .attr("href", tplPageUrl(opt.tpl)); // stopPropagation only -- preventDefault would stop the link from navigating. link.on("click", function (e) { e.stopPropagation(); }); link.on(STOP, function (e) { e.stopPropagation(); }); var info = $("<button type='button' class='wiktku-tpl-icon wiktku-tpl-icon-info'>i</button>") .attr("title", "Ev şablon çi dike?"); info.on(STOP, function (e) { e.stopPropagation(); }); info.on("click", function (e) { e.preventDefault(); e.stopPropagation(); var handler = select.data("wiktkuTplInfo"); if (typeof handler === "function") handler(opt.tpl, wrapper); }); icons.append(link).append(info); li.append(icons); } else { li.text(opt.text); } // touchend (not touchstart) so a scroll doesn't trigger a select. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // mousedown (not click) so it beats the input's blur handler. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); li.on("mouseenter", function () { // Don't scroll on hover -- it would shift the list under the pointer and cascade. setActive(idx, /* scrollIntoView */ false); }); resultsList.append(li); }); positionList(); resultsList.show(); resultsList[0].scrollTop = 0; textInput.attr("aria-expanded", "true"); } function setActive(idx, scrollIntoView) { var items = resultsList.children("li"); if (!items.length) return; if (idx < 0) idx = items.length - 1; if (idx >= items.length) idx = 0; activeIndex = idx; items.removeClass("wiktku-ac-active").attr("aria-selected", "false"); var li = items.eq(idx).addClass("wiktku-ac-active").attr("aria-selected", "true"); if (scrollIntoView === false) return; // Keep the active item visible for keyboard navigation. var ul = resultsList[0], el = li[0]; if (el.offsetTop < ul.scrollTop) { ul.scrollTop = el.offsetTop; } else if (el.offsetTop + el.offsetHeight > ul.scrollTop + ul.clientHeight) { ul.scrollTop = el.offsetTop + el.offsetHeight - ul.clientHeight; } } /** Puts the currently selected option's label back in the text box. */ function syncInputToSelect() { var cur = select.val(); var match = null; if (cur) { $.each(allOptions, function (_, o) { if (o.value === cur) { match = o; return false; } }); } textInput.val(match ? match.text : ""); } function selectOption(value, text) { textInput.val(text); select.val(value); closeList(); select.trigger("change"); } textInput.on("input", function () { showResults($(this).val()); }); textInput.on("focus", function () { // Select the current label so typing replaces it, and open the full list this.select(); showResults(""); }); textInput.on("click", function () { if (!resultsList.is(":visible")) showResults($(this).val()); }); textInput.on("keydown", function (e) { var open = resultsList.is(":visible"); switch (e.which) { case 40: // Down e.preventDefault(); if (!open) { showResults($(this).val()); setActive(0); } else setActive(activeIndex + 1); break; case 38: // Up e.preventDefault(); if (!open) { showResults($(this).val()); setActive(-1); } else setActive(activeIndex - 1); break; case 13: // Enter -- must never submit the form while the list is open if (open) { e.preventDefault(); if (activeIndex >= 0 && shown[activeIndex]) { selectOption(shown[activeIndex].value, shown[activeIndex].text); } else if (shown.length === 1) { selectOption(shown[0].value, shown[0].text); } } break; case 27: // Esc -- abandon the search, restore the real value if (open) { e.preventDefault(); closeList(); syncInputToSelect(); } break; case 9: // Tab -- commit the highlighted row on the way out if (open && activeIndex >= 0 && shown[activeIndex]) { selectOption(shown[activeIndex].value, shown[activeIndex].text); } closeList(); break; } }); textInput.on("blur", function () { // Short delay so a touchstart/mousedown on a result fires first. setTimeout(function () { closeList(); // Half-typed text that never became a selection would otherwise sit // in the box looking like a choice -- put the real value back. syncInputToSelect(); }, 200); }); // Re-caches the option list. Fired after the full language list loads, after // options are enabled/disabled, and after programmatic .val() changes. select.on("wiktku:refresh", function () { cacheOptions(); syncInputToSelect(); if (resultsList.is(":visible")) showResults(textInput.val()); }); wrapper.append(textInput).append(resultsList).append(select); return wrapper; } /** Gives every plain <select> under `root` the searchable picker; idempotent, and .wiktku-plain-select opts out. */ function initSelects(root) { $(root).find("select").addBack("select").not(".wiktku-plain-select").each(function () { var sel = $(this); if (sel.prop("multiple")) return; if (sel.closest(".wiktku-native-select-wrap").length) return; // already wrapped var marker = $("<span></span>").insertBefore(sel); marker.replaceWith(wrapNativeSelect(sel)); }); } module.exports = { capitalize: capitalize, decapitalize: decapitalize, escapeRegExp: escapeRegExp, stripWikilinks: stripWikilinks, splitTercimeIzah: splitTercimeIzah, insertAtCursor: insertAtCursor, foldDiacritics: foldDiacritics, wrapNativeSelect: wrapNativeSelect, initSelects: initSelects, tplPageUrl: tplPageUrl, makeManualResizable: wiktkuMakeManualResizable, initManualResize: wiktkuInitManualResize }; //</nowiki> ba8ada2wyl252f1tji10sarsjbzdqy0 öngörülebilir 0 1358593 6333788 2026-08-15T12:10:42Z Rewiye tine 7120 Rewiye tineî/ê navê [[öngörülebilir]] weke [[öngörülür]] guhart 6333788 wikitext text/x-wiki #BERALÎKIRIN [[öngörülür]] g421g3fx6jyfucln60w8cj7ti6mq1q8 6333792 6333788 2026-08-15T12:17:57Z Wikihez 7344 ([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +tr:rengdêr:{{guharto|tr|öngörülür}} 6333792 wikitext text/x-wiki == {{ziman|tr}} == === Rengdêr === {{rengdêr|tr}} # {{guharto|tr|öngörülür}} #* {{nimûne?|tr}} c780fzixhnsiacglwwqmmruue45yxhy unpredictable 0 1358594 6333796 2026-08-15T12:30:51Z Rewiye tine 7120 ([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +en:rengdêr: 6333796 wikitext text/x-wiki == {{ziman|en}} == === Rengdêr === {{rengdêr|en}} # [[nepêşbînbar]] #* {{nimûne?|en}} ==== Dijmane ==== * [[predictable]] eoa2ct9sibfc96bzqjp827zhm761ccn 6333810 6333796 2026-08-15T13:56:24Z Wikihez 7344 /* Îngilîzî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333810 wikitext text/x-wiki == {{ziman|en}} == === Rengdêr === {{rengdêr|en}} # [[nepêşbînbar]] #: {{dijmane|en|predictable}} #* {{nimûne?|en}} 3ef1airzolfyuww3kpiqn3e2oz3a1rw nepêşbînbar 0 1358595 6333799 2026-08-15T12:40:09Z Rewiye tine 7120 ([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +ku:rengdêr:dijmaneya pêşbînbar e. 6333799 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} === Rengdêr === {{rengdêr|ku}} # [[dijmane|Dijmaneya]] [[pêşbînbar|pêşbînbar]] e. #* {{nimûne?|ku}} ==== Etîmolojî ==== {{qertaf|ku|ne|pêş|bîn|bar}} ==== Werger ==== {{werger-ser|dijmaneya pêşbînbar e|1}} * {{Z|en}}: {{W|en|unpredictable}} * {{Z|tr}}: {{W|tr|öngörülemez}} {{werger-bin}} fdo0chbw4qui94kbaa21es5ioknl7gf 6333800 6333799 2026-08-15T12:42:09Z Rewiye tine 7120 6333800 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} === Rengdêr === {{rengdêr|ku}} # [[dijmane|Dijmaneya]] [[pêşbînbar|pêşbînbar]] e. #* {{nimûne?|ku}} ==== Dijmane ==== *[[pêşbînbar]] ==== Etîmolojî ==== {{qertaf|ku|ne|pêş|bîn|bar}} ==== Werger ==== {{werger-ser|dijmaneya pêşbînbar e|1}} * {{Z|en}}: {{W|en|unpredictable}} * {{Z|tr}}: {{W|tr|öngörülemez}} {{werger-bin}} mfphiiejc4jrt62ncg90oyso4khqyoi 6333801 6333800 2026-08-15T13:42:36Z Wikihez 7344 +nimûneya bikaranînê bi amûra « [[Mediawiki:Gadget-wikt.add-examples|Nimûne zêde bike]] » (v1.7). 6333801 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} === Rengdêr === {{rengdêr|ku}} # [[dijmane|Dijmaneya]] [[pêşbînbar|pêşbînbar]] e. #* {{jêder-kovar|ku|nivîskar=Denis Duclos|sernav=Sê krîzên sîstemê|kovar=Le Monde diplomatique kurdî|terciman=Yaqûb Karademîr|hejmar=21|sal=2011|rûpel=22|jêgirtin=Li pey hev rêzkirina van felaketên xirab qet ne tiştekî baş e, ji ber ku yek dê bibe sedemê "biserketina çav birçîtîyê" (1) û ya din dê bibe encama malwêranîyeke xwezayî ya '''nepêşbînbar''' û ya dawî jî bi êşên ku dibin xwedîya maneya –hêvîya me jî ew e– "bihareke gelan". Bi rastî sê xalên hevbeş ên van krîzan hene.}} ==== Dijmane ==== *[[pêşbînbar]] ==== Etîmolojî ==== {{qertaf|ku|ne|pêş|bîn|bar}} ==== Werger ==== {{werger-ser|dijmaneya pêşbînbar e|1}} * {{Z|en}}: {{W|en|unpredictable}} * {{Z|tr}}: {{W|tr|öngörülemez}} {{werger-bin}} qyatokogz00jnxbm7qiil2hs3zraue9 6333802 6333801 2026-08-15T13:46:02Z Wikihez 7344 +nimûneya bikaranînê bi amûra « [[Mediawiki:Gadget-wikt.add-examples|Nimûne zêde bike]] » (v1.7). 6333802 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} === Rengdêr === {{rengdêr|ku}} # [[dijmane|Dijmaneya]] [[pêşbînbar|pêşbînbar]] e. #* {{jêder-kovar|ku|nivîskar=Denis Duclos|sernav=Sê krîzên sîstemê|kovar=Le Monde diplomatique kurdî|terciman=Yaqûb Karademîr|hejmar=21|sal=2011|rûpel=22|jêgirtin=Li pey hev rêzkirina van felaketên xirab qet ne tiştekî baş e, ji ber ku yek dê bibe sedemê "biserketina çav birçîtîyê" (1) û ya din dê bibe encama malwêranîyeke xwezayî ya '''nepêşbînbar''' û ya dawî jî bi êşên ku dibin xwedîya maneya –hêvîya me jî ew e– "bihareke gelan". Bi rastî sê xalên hevbeş ên van krîzan hene.}} #* {{jêder-kitêb|ku|sernav=Digel Bêmilkkirinê. Kitêbeke Çalakîyan|terciman=Kawa Nemir|sal=2021|rûpel=59|jêgirtin=Bêyî deqên nivîskî yan jî tretmanan, bi awayekî binavbirrî em fi lîmê dikişînin û pêdeçûnê li ser dikin, lê wekî xerîkî peywendîyên pûtepêdanê û xwedangiringîyê, di rewşeke boş a neagehdarîyê û mereqdarîyê de û çaverê bo ya nepêşbînbar, weku Bresson em fêr kirin.}} ==== Dijmane ==== *[[pêşbînbar]] ==== Etîmolojî ==== {{qertaf|ku|ne|pêş|bîn|bar}} ==== Werger ==== {{werger-ser|dijmaneya pêşbînbar e|1}} * {{Z|en}}: {{W|en|unpredictable}} * {{Z|tr}}: {{W|tr|öngörülemez}} {{werger-bin}} 9bqj3f3gob5lpgwvyrkf7sepskmvffm 6333803 6333802 2026-08-15T13:46:30Z Wikihez 7344 /* Rengdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333803 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} === Rengdêr === {{rengdêr|ku}} # [[dijmane|Dijmaneya]] [[pêşbînbar|pêşbînbar]] e. #* {{jêder-kovar|ku|nivîskar=Denis Duclos|sernav=Sê krîzên sîstemê|kovar=Le Monde diplomatique kurdî|terciman=Yaqûb Karademîr|hejmar=21|sal=2011|rûpel=22|jêgirtin=Li pey hev rêzkirina van felaketên xirab qet ne tiştekî baş e, ji ber ku yek dê bibe sedemê "biserketina çav birçîtîyê" (1) û ya din dê bibe encama malwêranîyeke xwezayî ya '''nepêşbînbar''' û ya dawî jî bi êşên ku dibin xwedîya maneya –hêvîya me jî ew e– "bihareke gelan". Bi rastî sê xalên hevbeş ên van krîzan hene.}} #* {{jêder-kitêb|ku|sernav=Digel Bêmilkkirinê. Kitêbeke Çalakîyan|terciman=Kawa Nemir|sal=2021|rûpel=59|jêgirtin=Bêyî deqên nivîskî yan jî tretmanan, bi awayekî binavbirrî em fi lîmê dikişînin û pêdeçûnê li ser dikin, lê wekî xerîkî peywendîyên pûtepêdanê û xwedangiringîyê, di rewşeke boş a neagehdarîyê û mereqdarîyê de û çaverê bo ya '''nepêşbînbar''', weku Bresson em fêr kirin.}} ==== Dijmane ==== *[[pêşbînbar]] ==== Etîmolojî ==== {{qertaf|ku|ne|pêş|bîn|bar}} ==== Werger ==== {{werger-ser|dijmaneya pêşbînbar e|1}} * {{Z|en}}: {{W|en|unpredictable}} * {{Z|tr}}: {{W|tr|öngörülemez}} {{werger-bin}} 5ksliofdxa6l7c4ck3qp2a0lvj69uhq 6333804 6333803 2026-08-15T13:50:10Z Wikihez 7344 +nimûneya bikaranînê bi amûra « [[Mediawiki:Gadget-wikt.add-examples|Nimûne zêde bike]] » (v1.7). 6333804 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} === Rengdêr === {{rengdêr|ku}} # [[dijmane|Dijmaneya]] [[pêşbînbar|pêşbînbar]] e. #* {{jêder-kovar|ku|nivîskar=Denis Duclos|sernav=Sê krîzên sîstemê|kovar=Le Monde diplomatique kurdî|terciman=Yaqûb Karademîr|hejmar=21|sal=2011|rûpel=22|jêgirtin=Li pey hev rêzkirina van felaketên xirab qet ne tiştekî baş e, ji ber ku yek dê bibe sedemê "biserketina çav birçîtîyê" (1) û ya din dê bibe encama malwêranîyeke xwezayî ya '''nepêşbînbar''' û ya dawî jî bi êşên ku dibin xwedîya maneya –hêvîya me jî ew e– "bihareke gelan". Bi rastî sê xalên hevbeş ên van krîzan hene.}} #* {{jêder-kitêb|ku|sernav=Digel Bêmilkkirinê. Kitêbeke Çalakîyan|terciman=Kawa Nemir|sal=2021|rûpel=59|jêgirtin=Bêyî deqên nivîskî yan jî tretmanan, bi awayekî binavbirrî em fi lîmê dikişînin û pêdeçûnê li ser dikin, lê wekî xerîkî peywendîyên pûtepêdanê û xwedangiringîyê, di rewşeke boş a neagehdarîyê û mereqdarîyê de û çaverê bo ya '''nepêşbînbar''', weku Bresson em fêr kirin.}} #* {{jêder-websîte|ku|nivîskar=Ehmad Aseed|sernav=Li bajarê Faşîr ê li Sûdanê zêdetirî 81 hezar kes koçber bûn|websîte=ronahi.tv|url=https://ronahi.tv/archives/363693|tarîx=2025-11-06|jêgirtin=Rewşa giştî jî wekî “teng û '''nepêşbînbar”''' hate binxêzkirin.}} ==== Dijmane ==== *[[pêşbînbar]] ==== Etîmolojî ==== {{qertaf|ku|ne|pêş|bîn|bar}} ==== Werger ==== {{werger-ser|dijmaneya pêşbînbar e|1}} * {{Z|en}}: {{W|en|unpredictable}} * {{Z|tr}}: {{W|tr|öngörülemez}} {{werger-bin}} 8ykcecw87mcf55nc5gka9216mwnyb0x 6333805 6333804 2026-08-15T13:54:06Z Wikihez 7344 /* Rengdêr */ 6333805 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} === Rengdêr === {{rengdêr|ku}} # [[dijmane|Dijmaneya]] [[pêşbînbar|pêşbînbar]] e. #* {{jêder-kovar|ku|nivîskar=Denis Duclos|sernav=Sê krîzên sîstemê|kovar=Le Monde diplomatique kurdî|terciman=Yaqûb Karademîr|hejmar=21|sal=2011|rûpel=22|jêgirtin=Li pey hev rêzkirina van felaketên xirab qet ne tiştekî baş e, ji ber ku yek dê bibe sedemê "biserketina çav birçîtîyê" (1) û ya din dê bibe encama malwêranîyeke xwezayî ya '''nepêşbînbar''' û ya dawî jî bi êşên ku dibin xwedîya maneya –hêvîya me jî ew e– "bihareke gelan". Bi rastî sê xalên hevbeş ên van krîzan hene.}} #* {{jêder-kitêb|ku|sernav=Digel Bêmilkkirinê. Kitêbeke Çalakîyan|terciman=Kawa Nemir|sal=2021|rûpel=59|jêgirtin=Bêyî deqên nivîskî yan jî tretmanan, bi awayekî binavbirrî em fi lîmê dikişînin û pêdeçûnê li ser dikin, lê wekî xerîkî peywendîyên pûtepêdanê û xwedangiringîyê, di rewşeke boş a neagehdarîyê û mereqdarîyê de û çaverê bo ya '''nepêşbînbar''', weku Bresson em fêr kirin.}} #* {{jêder-websîte|ku|nivîskar=<!--Zotero otomatîk vî navî dide: Ehmad Aseed bnr. https://ku.wiktionary.org/api/rest_v1/data/citation/mediawiki/https%3A%2F%2Fronahi.tv%2Farchives%2F363693-->|sernav=Li bajarê Faşîr ê li Sûdanê zêdetirî 81 hezar kes koçber bûn|websîte=ronahi.tv|url=https://ronahi.tv/archives/363693|tarîx=2025-11-06|jêgirtin=Rewşa giştî jî wekî “teng û '''nepêşbînbar”''' hate binxêzkirin.}} ==== Dijmane ==== *[[pêşbînbar]] ==== Etîmolojî ==== {{qertaf|ku|ne|pêş|bîn|bar}} ==== Werger ==== {{werger-ser|dijmaneya pêşbînbar e|1}} * {{Z|en}}: {{W|en|unpredictable}} * {{Z|tr}}: {{W|tr|öngörülemez}} {{werger-bin}} laavi9hbpwlzep5e8qiz5gj1ro4vljg 6333806 6333805 2026-08-15T13:54:23Z Wikihez 7344 /* Etîmolojî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333806 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} === Rengdêr === {{rengdêr|ku}} # [[dijmane|Dijmaneya]] [[pêşbînbar|pêşbînbar]] e. #* {{jêder-kovar|ku|nivîskar=Denis Duclos|sernav=Sê krîzên sîstemê|kovar=Le Monde diplomatique kurdî|terciman=Yaqûb Karademîr|hejmar=21|sal=2011|rûpel=22|jêgirtin=Li pey hev rêzkirina van felaketên xirab qet ne tiştekî baş e, ji ber ku yek dê bibe sedemê "biserketina çav birçîtîyê" (1) û ya din dê bibe encama malwêranîyeke xwezayî ya '''nepêşbînbar''' û ya dawî jî bi êşên ku dibin xwedîya maneya –hêvîya me jî ew e– "bihareke gelan". Bi rastî sê xalên hevbeş ên van krîzan hene.}} #* {{jêder-kitêb|ku|sernav=Digel Bêmilkkirinê. Kitêbeke Çalakîyan|terciman=Kawa Nemir|sal=2021|rûpel=59|jêgirtin=Bêyî deqên nivîskî yan jî tretmanan, bi awayekî binavbirrî em fi lîmê dikişînin û pêdeçûnê li ser dikin, lê wekî xerîkî peywendîyên pûtepêdanê û xwedangiringîyê, di rewşeke boş a neagehdarîyê û mereqdarîyê de û çaverê bo ya '''nepêşbînbar''', weku Bresson em fêr kirin.}} #* {{jêder-websîte|ku|nivîskar=<!--Zotero otomatîk vî navî dide: Ehmad Aseed bnr. https://ku.wiktionary.org/api/rest_v1/data/citation/mediawiki/https%3A%2F%2Fronahi.tv%2Farchives%2F363693-->|sernav=Li bajarê Faşîr ê li Sûdanê zêdetirî 81 hezar kes koçber bûn|websîte=ronahi.tv|url=https://ronahi.tv/archives/363693|tarîx=2025-11-06|jêgirtin=Rewşa giştî jî wekî “teng û '''nepêşbînbar”''' hate binxêzkirin.}} ==== Dijmane ==== *[[pêşbînbar]] ==== Etîmolojî ==== {{qertaf|ku|ne-|pêşbînbar}} ==== Werger ==== {{werger-ser|dijmaneya pêşbînbar e|1}} * {{Z|en}}: {{W|en|unpredictable}} * {{Z|tr}}: {{W|tr|öngörülemez}} {{werger-bin}} iqanczjbv06a2qayz842gqoav2kuiej 6333807 6333806 2026-08-15T13:54:30Z Wikihez 7344 /* Etîmolojî */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333807 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} === Rengdêr === {{rengdêr|ku}} # [[dijmane|Dijmaneya]] [[pêşbînbar|pêşbînbar]] e. #* {{jêder-kovar|ku|nivîskar=Denis Duclos|sernav=Sê krîzên sîstemê|kovar=Le Monde diplomatique kurdî|terciman=Yaqûb Karademîr|hejmar=21|sal=2011|rûpel=22|jêgirtin=Li pey hev rêzkirina van felaketên xirab qet ne tiştekî baş e, ji ber ku yek dê bibe sedemê "biserketina çav birçîtîyê" (1) û ya din dê bibe encama malwêranîyeke xwezayî ya '''nepêşbînbar''' û ya dawî jî bi êşên ku dibin xwedîya maneya –hêvîya me jî ew e– "bihareke gelan". Bi rastî sê xalên hevbeş ên van krîzan hene.}} #* {{jêder-kitêb|ku|sernav=Digel Bêmilkkirinê. Kitêbeke Çalakîyan|terciman=Kawa Nemir|sal=2021|rûpel=59|jêgirtin=Bêyî deqên nivîskî yan jî tretmanan, bi awayekî binavbirrî em fi lîmê dikişînin û pêdeçûnê li ser dikin, lê wekî xerîkî peywendîyên pûtepêdanê û xwedangiringîyê, di rewşeke boş a neagehdarîyê û mereqdarîyê de û çaverê bo ya '''nepêşbînbar''', weku Bresson em fêr kirin.}} #* {{jêder-websîte|ku|nivîskar=<!--Zotero otomatîk vî navî dide: Ehmad Aseed bnr. https://ku.wiktionary.org/api/rest_v1/data/citation/mediawiki/https%3A%2F%2Fronahi.tv%2Farchives%2F363693-->|sernav=Li bajarê Faşîr ê li Sûdanê zêdetirî 81 hezar kes koçber bûn|websîte=ronahi.tv|url=https://ronahi.tv/archives/363693|tarîx=2025-11-06|jêgirtin=Rewşa giştî jî wekî “teng û '''nepêşbînbar”''' hate binxêzkirin.}} ==== Dijmane ==== *[[pêşbînbar]] ==== Etîmolojî ==== {{qertaf|ku|ne-|pêşbînbar}}. ==== Werger ==== {{werger-ser|dijmaneya pêşbînbar e|1}} * {{Z|en}}: {{W|en|unpredictable}} * {{Z|tr}}: {{W|tr|öngörülemez}} {{werger-bin}} ixrfnmeapwkvmppdimeytb3f1uhl2yq 6333808 6333807 2026-08-15T13:55:10Z Wikihez 7344 /* Rengdêr */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333808 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} === Rengdêr === {{rengdêr|ku}} # Ya/yê ku ne [[pêşbînbar|pêşbînbar]] e. #* {{jêder-kovar|ku|nivîskar=Denis Duclos|sernav=Sê krîzên sîstemê|kovar=Le Monde diplomatique kurdî|terciman=Yaqûb Karademîr|hejmar=21|sal=2011|rûpel=22|jêgirtin=Li pey hev rêzkirina van felaketên xirab qet ne tiştekî baş e, ji ber ku yek dê bibe sedemê "biserketina çav birçîtîyê" (1) û ya din dê bibe encama malwêranîyeke xwezayî ya '''nepêşbînbar''' û ya dawî jî bi êşên ku dibin xwedîya maneya –hêvîya me jî ew e– "bihareke gelan". Bi rastî sê xalên hevbeş ên van krîzan hene.}} #* {{jêder-kitêb|ku|sernav=Digel Bêmilkkirinê. Kitêbeke Çalakîyan|terciman=Kawa Nemir|sal=2021|rûpel=59|jêgirtin=Bêyî deqên nivîskî yan jî tretmanan, bi awayekî binavbirrî em fi lîmê dikişînin û pêdeçûnê li ser dikin, lê wekî xerîkî peywendîyên pûtepêdanê û xwedangiringîyê, di rewşeke boş a neagehdarîyê û mereqdarîyê de û çaverê bo ya '''nepêşbînbar''', weku Bresson em fêr kirin.}} #* {{jêder-websîte|ku|nivîskar=<!--Zotero otomatîk vî navî dide: Ehmad Aseed bnr. https://ku.wiktionary.org/api/rest_v1/data/citation/mediawiki/https%3A%2F%2Fronahi.tv%2Farchives%2F363693-->|sernav=Li bajarê Faşîr ê li Sûdanê zêdetirî 81 hezar kes koçber bûn|websîte=ronahi.tv|url=https://ronahi.tv/archives/363693|tarîx=2025-11-06|jêgirtin=Rewşa giştî jî wekî “teng û '''nepêşbînbar”''' hate binxêzkirin.}} ==== Dijmane ==== *[[pêşbînbar]] ==== Etîmolojî ==== {{qertaf|ku|ne-|pêşbînbar}}. ==== Werger ==== {{werger-ser|dijmaneya pêşbînbar e|1}} * {{Z|en}}: {{W|en|unpredictable}} * {{Z|tr}}: {{W|tr|öngörülemez}} {{werger-bin}} 3l4c3j8bu7wosldznm493d81fwqg2ze 6333809 6333808 2026-08-15T13:55:35Z Wikihez 7344 /* Werger */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333809 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} === Rengdêr === {{rengdêr|ku}} # Ya/yê ku ne [[pêşbînbar|pêşbînbar]] e. #* {{jêder-kovar|ku|nivîskar=Denis Duclos|sernav=Sê krîzên sîstemê|kovar=Le Monde diplomatique kurdî|terciman=Yaqûb Karademîr|hejmar=21|sal=2011|rûpel=22|jêgirtin=Li pey hev rêzkirina van felaketên xirab qet ne tiştekî baş e, ji ber ku yek dê bibe sedemê "biserketina çav birçîtîyê" (1) û ya din dê bibe encama malwêranîyeke xwezayî ya '''nepêşbînbar''' û ya dawî jî bi êşên ku dibin xwedîya maneya –hêvîya me jî ew e– "bihareke gelan". Bi rastî sê xalên hevbeş ên van krîzan hene.}} #* {{jêder-kitêb|ku|sernav=Digel Bêmilkkirinê. Kitêbeke Çalakîyan|terciman=Kawa Nemir|sal=2021|rûpel=59|jêgirtin=Bêyî deqên nivîskî yan jî tretmanan, bi awayekî binavbirrî em fi lîmê dikişînin û pêdeçûnê li ser dikin, lê wekî xerîkî peywendîyên pûtepêdanê û xwedangiringîyê, di rewşeke boş a neagehdarîyê û mereqdarîyê de û çaverê bo ya '''nepêşbînbar''', weku Bresson em fêr kirin.}} #* {{jêder-websîte|ku|nivîskar=<!--Zotero otomatîk vî navî dide: Ehmad Aseed bnr. https://ku.wiktionary.org/api/rest_v1/data/citation/mediawiki/https%3A%2F%2Fronahi.tv%2Farchives%2F363693-->|sernav=Li bajarê Faşîr ê li Sûdanê zêdetirî 81 hezar kes koçber bûn|websîte=ronahi.tv|url=https://ronahi.tv/archives/363693|tarîx=2025-11-06|jêgirtin=Rewşa giştî jî wekî “teng û '''nepêşbînbar”''' hate binxêzkirin.}} ==== Dijmane ==== *[[pêşbînbar]] ==== Etîmolojî ==== {{qertaf|ku|ne-|pêşbînbar}}. ==== Werger ==== {{werger-ser|ya/yê ne pêşbînbar|1}} * {{Z|en}}: {{W|en|unpredictable}} * {{Z|tr}}: {{W|tr|öngörülemez}} {{werger-bin}} ox76x9em7si51esvyx6lbqzuuuiot2e 6333812 6333809 2026-08-15T14:12:07Z Balyozbot 7867 Bot: Paqijiyên kozmetîk (Lînk paqij kir, +Valahiya lîsteyan.) 6333812 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} === Rengdêr === {{rengdêr|ku}} # Ya/yê ku ne [[pêşbînbar]] e. #* {{jêder-kovar|ku|nivîskar=Denis Duclos|sernav=Sê krîzên sîstemê|kovar=Le Monde diplomatique kurdî|terciman=Yaqûb Karademîr|hejmar=21|sal=2011|rûpel=22|jêgirtin=Li pey hev rêzkirina van felaketên xirab qet ne tiştekî baş e, ji ber ku yek dê bibe sedemê "biserketina çav birçîtîyê" (1) û ya din dê bibe encama malwêranîyeke xwezayî ya '''nepêşbînbar''' û ya dawî jî bi êşên ku dibin xwedîya maneya –hêvîya me jî ew e– "bihareke gelan". Bi rastî sê xalên hevbeş ên van krîzan hene.}} #* {{jêder-kitêb|ku|sernav=Digel Bêmilkkirinê. Kitêbeke Çalakîyan|terciman=Kawa Nemir|sal=2021|rûpel=59|jêgirtin=Bêyî deqên nivîskî yan jî tretmanan, bi awayekî binavbirrî em fi lîmê dikişînin û pêdeçûnê li ser dikin, lê wekî xerîkî peywendîyên pûtepêdanê û xwedangiringîyê, di rewşeke boş a neagehdarîyê û mereqdarîyê de û çaverê bo ya '''nepêşbînbar''', weku Bresson em fêr kirin.}} #* {{jêder-websîte|ku|nivîskar=<!--Zotero otomatîk vî navî dide: Ehmad Aseed bnr. https://ku.wiktionary.org/api/rest_v1/data/citation/mediawiki/https%3A%2F%2Fronahi.tv%2Farchives%2F363693-->|sernav=Li bajarê Faşîr ê li Sûdanê zêdetirî 81 hezar kes koçber bûn|websîte=ronahi.tv|url=https://ronahi.tv/archives/363693|tarîx=2025-11-06|jêgirtin=Rewşa giştî jî wekî “teng û '''nepêşbînbar”''' hate binxêzkirin.}} ==== Dijmane ==== * [[pêşbînbar]] ==== Etîmolojî ==== {{qertaf|ku|ne-|pêşbînbar}}. ==== Werger ==== {{werger-ser|ya/yê ne pêşbînbar|1}} * {{Z|en}}: {{W|en|unpredictable}} * {{Z|tr}}: {{W|tr|öngörülemez}} {{werger-bin}} k18u2spd0g1ee1t1p1q9wyjoumt1lcr 6333813 6333812 2026-08-15T14:17:38Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6333813 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} === Rengdêr === {{rengdêr|ku}} # Ya/yê ku ne [[mimkûn|mimkûn]] e ji [[ber|berê]] de [[hatin|were]] [[texmîn kirin|texmînkirin]]. #* {{jêder-kovar|ku|nivîskar=Denis Duclos|sernav=Sê krîzên sîstemê|kovar=Le Monde diplomatique kurdî|terciman=Yaqûb Karademîr|hejmar=21|sal=2011|rûpel=22|jêgirtin=Li pey hev rêzkirina van felaketên xirab qet ne tiştekî baş e, ji ber ku yek dê bibe sedemê "biserketina çav birçîtîyê" (1) û ya din dê bibe encama malwêranîyeke xwezayî ya '''nepêşbînbar''' û ya dawî jî bi êşên ku dibin xwedîya maneya –hêvîya me jî ew e– "bihareke gelan". Bi rastî sê xalên hevbeş ên van krîzan hene.}} #* {{jêder-kitêb|ku|sernav=Digel Bêmilkkirinê. Kitêbeke Çalakîyan|terciman=Kawa Nemir|sal=2021|rûpel=59|jêgirtin=Bêyî deqên nivîskî yan jî tretmanan, bi awayekî binavbirrî em fi lîmê dikişînin û pêdeçûnê li ser dikin, lê wekî xerîkî peywendîyên pûtepêdanê û xwedangiringîyê, di rewşeke boş a neagehdarîyê û mereqdarîyê de û çaverê bo ya '''nepêşbînbar''', weku Bresson em fêr kirin.}} #* {{jêder-websîte|ku|nivîskar=<!--Zotero otomatîk vî navî dide: Ehmad Aseed bnr. https://ku.wiktionary.org/api/rest_v1/data/citation/mediawiki/https%3A%2F%2Fronahi.tv%2Farchives%2F363693-->|sernav=Li bajarê Faşîr ê li Sûdanê zêdetirî 81 hezar kes koçber bûn|websîte=ronahi.tv|url=https://ronahi.tv/archives/363693|tarîx=2025-11-06|jêgirtin=Rewşa giştî jî wekî “teng û '''nepêşbînbar”''' hate binxêzkirin.}} ==== Dijmane ==== * {{g|ku|pêşbînbar}} ==== Etîmolojî ==== {{qertaf|ku|ne-|pêşbînbar}}. ==== Werger ==== {{werger-ser|ya/yê ne pêşbînbar|1}} * {{Z|en}}: {{W|en|unpredictable}} * {{Z|tr}}: {{W|tr|öngörülemez}} {{werger-bin}} t3xyqfa2yi4jos2sh2wajrinufwamkx 6333814 6333813 2026-08-15T14:17:55Z Wikihez 7344 /* Werger */ (bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re) 6333814 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} === Rengdêr === {{rengdêr|ku}} # Ya/yê ku ne [[mimkûn|mimkûn]] e ji [[ber|berê]] de [[hatin|were]] [[texmîn kirin|texmînkirin]]. #* {{jêder-kovar|ku|nivîskar=Denis Duclos|sernav=Sê krîzên sîstemê|kovar=Le Monde diplomatique kurdî|terciman=Yaqûb Karademîr|hejmar=21|sal=2011|rûpel=22|jêgirtin=Li pey hev rêzkirina van felaketên xirab qet ne tiştekî baş e, ji ber ku yek dê bibe sedemê "biserketina çav birçîtîyê" (1) û ya din dê bibe encama malwêranîyeke xwezayî ya '''nepêşbînbar''' û ya dawî jî bi êşên ku dibin xwedîya maneya –hêvîya me jî ew e– "bihareke gelan". Bi rastî sê xalên hevbeş ên van krîzan hene.}} #* {{jêder-kitêb|ku|sernav=Digel Bêmilkkirinê. Kitêbeke Çalakîyan|terciman=Kawa Nemir|sal=2021|rûpel=59|jêgirtin=Bêyî deqên nivîskî yan jî tretmanan, bi awayekî binavbirrî em fi lîmê dikişînin û pêdeçûnê li ser dikin, lê wekî xerîkî peywendîyên pûtepêdanê û xwedangiringîyê, di rewşeke boş a neagehdarîyê û mereqdarîyê de û çaverê bo ya '''nepêşbînbar''', weku Bresson em fêr kirin.}} #* {{jêder-websîte|ku|nivîskar=<!--Zotero otomatîk vî navî dide: Ehmad Aseed bnr. https://ku.wiktionary.org/api/rest_v1/data/citation/mediawiki/https%3A%2F%2Fronahi.tv%2Farchives%2F363693-->|sernav=Li bajarê Faşîr ê li Sûdanê zêdetirî 81 hezar kes koçber bûn|websîte=ronahi.tv|url=https://ronahi.tv/archives/363693|tarîx=2025-11-06|jêgirtin=Rewşa giştî jî wekî “teng û '''nepêşbînbar”''' hate binxêzkirin.}} ==== Dijmane ==== * {{g|ku|pêşbînbar}} ==== Etîmolojî ==== {{qertaf|ku|ne-|pêşbînbar}}. ==== Werger ==== {{werger-ser|ya/yê ne mimkûn e ji berê de were texmînkirin|1}} * {{Z|en}}: {{W|en|unpredictable}} * {{Z|tr}}: {{W|tr|öngörülemez}} {{werger-bin}} cadx7baaec98xtesipjjgoyj7a7mhr4 6333830 6333814 2026-08-15T15:12:07Z Balyozbot 7867 Bot: Paqijiyên kozmetîk (Lînk paqij kir.) 6333830 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} === Rengdêr === {{rengdêr|ku}} # Ya/yê ku ne [[mimkûn]] e ji [[ber]]ê de [[hatin|were]] [[texmîn kirin|texmînkirin]]. #* {{jêder-kovar|ku|nivîskar=Denis Duclos|sernav=Sê krîzên sîstemê|kovar=Le Monde diplomatique kurdî|terciman=Yaqûb Karademîr|hejmar=21|sal=2011|rûpel=22|jêgirtin=Li pey hev rêzkirina van felaketên xirab qet ne tiştekî baş e, ji ber ku yek dê bibe sedemê "biserketina çav birçîtîyê" (1) û ya din dê bibe encama malwêranîyeke xwezayî ya '''nepêşbînbar''' û ya dawî jî bi êşên ku dibin xwedîya maneya –hêvîya me jî ew e– "bihareke gelan". Bi rastî sê xalên hevbeş ên van krîzan hene.}} #* {{jêder-kitêb|ku|sernav=Digel Bêmilkkirinê. Kitêbeke Çalakîyan|terciman=Kawa Nemir|sal=2021|rûpel=59|jêgirtin=Bêyî deqên nivîskî yan jî tretmanan, bi awayekî binavbirrî em fi lîmê dikişînin û pêdeçûnê li ser dikin, lê wekî xerîkî peywendîyên pûtepêdanê û xwedangiringîyê, di rewşeke boş a neagehdarîyê û mereqdarîyê de û çaverê bo ya '''nepêşbînbar''', weku Bresson em fêr kirin.}} #* {{jêder-websîte|ku|nivîskar=<!--Zotero otomatîk vî navî dide: Ehmad Aseed bnr. https://ku.wiktionary.org/api/rest_v1/data/citation/mediawiki/https%3A%2F%2Fronahi.tv%2Farchives%2F363693-->|sernav=Li bajarê Faşîr ê li Sûdanê zêdetirî 81 hezar kes koçber bûn|websîte=ronahi.tv|url=https://ronahi.tv/archives/363693|tarîx=2025-11-06|jêgirtin=Rewşa giştî jî wekî “teng û '''nepêşbînbar”''' hate binxêzkirin.}} ==== Dijmane ==== * {{g|ku|pêşbînbar}} ==== Etîmolojî ==== {{qertaf|ku|ne-|pêşbînbar}}. ==== Werger ==== {{werger-ser|ya/yê ne mimkûn e ji berê de were texmînkirin|1}} * {{Z|en}}: {{W|en|unpredictable}} * {{Z|tr}}: {{W|tr|öngörülemez}} {{werger-bin}} suedl21d0sicxav6uf482v4nd6aorxh Şablon:Ç:ota:Abikean:1888 10 1358596 6333868 2026-08-15T19:01:40Z Wikihez 7344 [[:en:Template:R:ota:Abikean:1888]] hat kopîkirin ([[Bikarhêner:Wikihez/skrîpt/js/kopi-enWikt.js|kopi-enWikt.js]]) 6333868 wikitext text/x-wiki {{#invoke:quote|call_template |template=cite-book |last={{xlit|hy|Աբիկեան}} |first={{xlit|hy|Միհրան}} |authorlink=Mihran Apikyan |title={{xlit|hy|Երեքլեզուեան ընդարձակ բառարան տաճկերէն հայերէն գաղղիերէն}} |trans-title=A Comprehensive Trilingual Ottoman–Armenian–French Dictionary |entry={{lang|ota|{{{1|{{pagename}}}}}}} |location=Constantinople |publisher={{xlit|hy|Ն. Կ. Պէրպէրեան}} Press |year=1888 |pageparam=page |url=https://books.google.com/books?id=5j8zAAAAMAAJ&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages}}}}}}|[0-9]+}}}} |pageurl=https://books.google.com/books?id=5j8zAAAAMAAJ&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages}}}}}}|[0-9]+}}}} |allowparams=1 }}<noinclude>{{reference template cat|ota|hy}}</noinclude> gahgjqmbh9urrn7c6v4o53r1eekral8 6333869 6333868 2026-08-15T19:01:48Z Wikihez 7344 Wikihezî/ê navê [[Şablon:R:ota:Abikean:1888]] weke [[Şablon:Ç:ota:Abikean:1888]] guhart 6333868 wikitext text/x-wiki {{#invoke:quote|call_template |template=cite-book |last={{xlit|hy|Աբիկեան}} |first={{xlit|hy|Միհրան}} |authorlink=Mihran Apikyan |title={{xlit|hy|Երեքլեզուեան ընդարձակ բառարան տաճկերէն հայերէն գաղղիերէն}} |trans-title=A Comprehensive Trilingual Ottoman–Armenian–French Dictionary |entry={{lang|ota|{{{1|{{pagename}}}}}}} |location=Constantinople |publisher={{xlit|hy|Ն. Կ. Պէրպէրեան}} Press |year=1888 |pageparam=page |url=https://books.google.com/books?id=5j8zAAAAMAAJ&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages}}}}}}|[0-9]+}}}} |pageurl=https://books.google.com/books?id=5j8zAAAAMAAJ&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages}}}}}}|[0-9]+}}}} |allowparams=1 }}<noinclude>{{reference template cat|ota|hy}}</noinclude> gahgjqmbh9urrn7c6v4o53r1eekral8 6333871 6333869 2026-08-15T19:04:11Z Wikihez 7344 6333871 wikitext text/x-wiki {{#invoke:quote|call_template |template=cite-book |last={{xlit|hy|Աբիկեան}} |first={{xlit|hy|Միհրան}} |authorlink=Mihran Apikyan |title={{xlit|hy|Երեքլեզուեան ընդարձակ բառարան տաճկերէն հայերէն գաղղիերէն}} |trans-title=Ferhengeke Sê-zimanî ya Berfireh bi Osmanî-Ermenî-Fransî |entry={{lang|ota|{{{1|{{pagename}}}}}}} |location=Constantinople |publisher={{xlit|hy|Ն. Կ. Պէրպէրեան}} Press |year=1888 |pageparam=page,r,rûpel |url=https://books.google.com/books?id=5j8zAAAAMAAJ&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages|{{{r|{{{rûpel}}}}}}}}}}}}|[0-9]+}}}} |pageurl=https://books.google.com/books?id=5j8zAAAAMAAJ&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages|{{{r|{{{rûpel}}}}}}}}}}}}|[0-9]+}}}} |allowparams=1,r,rûpel }}<noinclude>{{reference template cat|ota|hy}}</noinclude> o20ypk1qy1dv1cfz9gwfozut6ek5ogl Şablon:R:ota:Abikean:1888 10 1358597 6333870 2026-08-15T19:01:49Z Wikihez 7344 Wikihezî/ê navê [[Şablon:R:ota:Abikean:1888]] weke [[Şablon:Ç:ota:Abikean:1888]] guhart 6333870 wikitext text/x-wiki #BERALÎKIRIN [[Şablon:Ç:ota:Abikean:1888]] ncz0mpz0j2caz7a79zqlflnb7mjq1vc Şablon:R:ota:BdM 10 1358598 6333872 2026-08-15T19:04:28Z Wikihez 7344 Ji bo [[Şablon:R:ota:BarbierDeMeynard]] hat beralîkirin ([[Bikarhêner:Wikihez/skrîpt/js/kopi-enWikt.js|kopi-enWikt.js]]) 6333872 wikitext text/x-wiki #BERALÎKIRIN [[Şablon:R:ota:BarbierDeMeynard]] ehfdr50asce5kuhfsxdtwzgbqztvtzd Şablon:Ç:ota:BarbierDeMeynard 10 1358599 6333873 2026-08-15T19:04:28Z Wikihez 7344 [[:en:Template:R:ota:BarbierDeMeynard]] hat kopîkirin ([[Bikarhêner:Wikihez/skrîpt/js/kopi-enWikt.js|kopi-enWikt.js]]) 6333873 wikitext text/x-wiki {{#invoke:quote|call_template |template=cite-book |last=Barbier de Meynard |first=Charles |authorlink=Charles Barbier de Meynard |entry={{lang|ota|{{{1|{{pagename}}}}}}} |title=Dictionnaire turc-français |location=Paris |publisher=E. Leroux |year={{#switch:{{{volume|{{{vol}}}}}}|I|1=1881|II|2=1886|#default=1881–1886}} |volume={{{volume|{{{vol|}}}}}} |pageparam=page |pageurl={{#switch:{{{volume|{{{vol}}}}}}|I|1=https://books.google.com/books?id=oFbmAAAAMAAJ&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages}}}}}}|[0-9]+}}}}|II|2=https://books.google.com/books?id=qVfmAAAAMAAJ&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages}}}}}}|[0-9]+}}}}}} |allowparams=1,volume,vol }}<noinclude>{{refcat}}</noinclude> 9sya1nf42z1mpds186icx43e3uso03j 6333874 6333873 2026-08-15T19:05:56Z Wikihez 7344 6333874 wikitext text/x-wiki {{#invoke:quote|call_template |template=cite-book |last=Barbier de Meynard |first=Charles |authorlink=Charles Barbier de Meynard |entry={{lang|ota|{{{1|{{pagename}}}}}}} |title=Dictionnaire turc-français<t:Ferhenga tirkî-fransî> |location=Paris |publisher=E. Leroux |year={{#switch:{{{volume|{{{vol|{{{cild|}}}}}}}}}|I|1=1881|II|2=1886|#default=1881–1886}} |volume={{{volume|{{{vol|{{{cild|}}}}}}}}} |pageparam=pager,r,rûpel |pageurl={{#switch:{{{volume|{{{vol|{{{cild|}}}}}}}}}|I|1=https://books.google.com/books?id=oFbmAAAAMAAJ&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages}}}}}}|[0-9]+}}}}|II|2=https://books.google.com/books?id=qVfmAAAAMAAJ&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages|{{{r|{{{rûpel|}}}}}}}}}}}}|[0-9]+}}}}}} |allowparams=1,volume,vol,cild,r,rûpel }}<noinclude>{{refcat}}</noinclude> qqgfyqnoyubufr3wfc05oq7hf3xsrz5 6333875 6333874 2026-08-15T19:06:04Z Wikihez 7344 Wikihezî/ê navê [[Şablon:R:ota:BarbierDeMeynard]] weke [[Şablon:Ç:ota:BarbierDeMeynard]] guhart 6333874 wikitext text/x-wiki {{#invoke:quote|call_template |template=cite-book |last=Barbier de Meynard |first=Charles |authorlink=Charles Barbier de Meynard |entry={{lang|ota|{{{1|{{pagename}}}}}}} |title=Dictionnaire turc-français<t:Ferhenga tirkî-fransî> |location=Paris |publisher=E. Leroux |year={{#switch:{{{volume|{{{vol|{{{cild|}}}}}}}}}|I|1=1881|II|2=1886|#default=1881–1886}} |volume={{{volume|{{{vol|{{{cild|}}}}}}}}} |pageparam=pager,r,rûpel |pageurl={{#switch:{{{volume|{{{vol|{{{cild|}}}}}}}}}|I|1=https://books.google.com/books?id=oFbmAAAAMAAJ&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages}}}}}}|[0-9]+}}}}|II|2=https://books.google.com/books?id=qVfmAAAAMAAJ&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages|{{{r|{{{rûpel|}}}}}}}}}}}}|[0-9]+}}}}}} |allowparams=1,volume,vol,cild,r,rûpel }}<noinclude>{{refcat}}</noinclude> qqgfyqnoyubufr3wfc05oq7hf3xsrz5 Şablon:R:ota:BarbierDeMeynard 10 1358600 6333876 2026-08-15T19:06:04Z Wikihez 7344 Wikihezî/ê navê [[Şablon:R:ota:BarbierDeMeynard]] weke [[Şablon:Ç:ota:BarbierDeMeynard]] guhart 6333876 wikitext text/x-wiki #BERALÎKIRIN [[Şablon:Ç:ota:BarbierDeMeynard]] kzc5pcofjdkemjr3iyewqrdn41e7a4i Şablon:Ç:ota:Hindoglu 10 1358601 6333877 2026-08-15T19:06:41Z Wikihez 7344 [[:en:Template:R:ota:Hindoglu]] hat kopîkirin ([[Bikarhêner:Wikihez/skrîpt/js/kopi-enWikt.js|kopi-enWikt.js]]) 6333877 wikitext text/x-wiki {{#invoke:quote|call_template |template=cite-book |last=Hindoglu |first=Artin |authorlink=Artin Hindoğlu |title=Hazine-i lûgat ou dictionnaire abrégé turc-français |entry={{lang|ota|{{{1|{{pagename}}}}}}} |url=https://books.google.com/books?id=NiMmVc-1op0C&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages}}}}}}|[0-9]+}}}} |location=Vienna |publisher=F. Beck |year=1838 |pageparam=page |pageurl=https://books.google.com/books?id=NiMmVc-1op0C&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages}}}}}}|[0-9]+}}}} |allowparams=1 }}<noinclude>{{reference template cat}}</noinclude> 9xwh8xjnetzpaum1yv2bwumwxce5v5i 6333878 6333877 2026-08-15T19:07:42Z Wikihez 7344 6333878 wikitext text/x-wiki {{#invoke:quote|call_template |template=cite-book |last=Hindoglu |first=Artin |authorlink=Artin Hindoğlu |title=Hazine-i lûgat ou dictionnaire abrégé turc-français |entry={{lang|ota|{{{1|{{pagename}}}}}}} |url=https://books.google.com/books?id=NiMmVc-1op0C&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages|{{{r|{{{rûpel|}}}}}}}}}}}}|[0-9]+}}}} |location=Vienna |publisher=F. Beck |year=1838 |pageparam=page,r,rûpel |pageurl=https://books.google.com/books?id=NiMmVc-1op0C&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages|{{{r|{{{rûpel|}}}}}}}}}}}}|[0-9]+}}}} |allowparams=1,r,rûpel }}<noinclude>{{reference template cat}}</noinclude> 9lw74cyphr4lo9mvs990ud6o9chb7b5 6333879 6333878 2026-08-15T19:07:52Z Wikihez 7344 Wikihezî/ê navê [[Şablon:R:ota:Hindoglu]] weke [[Şablon:Ç:ota:Hindoglu]] guhart 6333878 wikitext text/x-wiki {{#invoke:quote|call_template |template=cite-book |last=Hindoglu |first=Artin |authorlink=Artin Hindoğlu |title=Hazine-i lûgat ou dictionnaire abrégé turc-français |entry={{lang|ota|{{{1|{{pagename}}}}}}} |url=https://books.google.com/books?id=NiMmVc-1op0C&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages|{{{r|{{{rûpel|}}}}}}}}}}}}|[0-9]+}}}} |location=Vienna |publisher=F. Beck |year=1838 |pageparam=page,r,rûpel |pageurl=https://books.google.com/books?id=NiMmVc-1op0C&pg=PA{{#expr:{{#invoke:string/templates|match|{{{page|{{{pages|{{{r|{{{rûpel|}}}}}}}}}}}}|[0-9]+}}}} |allowparams=1,r,rûpel }}<noinclude>{{reference template cat}}</noinclude> 9lw74cyphr4lo9mvs990ud6o9chb7b5 Şablon:R:ota:Hindoglu 10 1358602 6333880 2026-08-15T19:07:52Z Wikihez 7344 Wikihezî/ê navê [[Şablon:R:ota:Hindoglu]] weke [[Şablon:Ç:ota:Hindoglu]] guhart 6333880 wikitext text/x-wiki #BERALÎKIRIN [[Şablon:Ç:ota:Hindoglu]] qis3qgxlx5opx144k8kmtkobszkv4oh Şablon:Ç:trk:Clauson 10 1358603 6333881 2026-08-15T19:08:28Z Wikihez 7344 [[:en:Template:R:trk:Clauson]] hat kopîkirin ([[Bikarhêner:Wikihez/skrîpt/js/kopi-enWikt.js|kopi-enWikt.js]]) 6333881 wikitext text/x-wiki {{#invoke:quote|call_template |template=cite-book |last=Clauson |first=Gerard |authorlink=Gerard Clauson |title=An Etymological Dictionary of pre-thirteenth-century Turkish |entry={{#if:{{{entry|{{{1|}}}}}}|trk-pro:{{{entry|{{{1|}}}}}} }} |location=Oxford |publisher=Clarendon Press |year=1972 |isbn=0198641125 |oclc = 655135958 |pageparam = page |pageurl=https://archive.org/details/etymologicaldict0000clau/page/{{#invoke:string/templates|match|{{{page|{{{pages|{{{1}}}}}}}}}|[0-9]+|}} |allowparams = entry,1 }}<noinclude>{{refcat|trk-pro|otk|oui|tr|ota}}</noinclude> hna49o27rnxw7vnwm1mar62gag57936 6333882 6333881 2026-08-15T19:09:48Z Wikihez 7344 6333882 wikitext text/x-wiki {{#invoke:quote|call_template |template=cite-book |last=Clauson |first=Gerard |authorlink=Gerard Clauson |title=An Etymological Dictionary of pre-thirteenth-century Turkish |entry={{#if:{{{entry|{{{1|}}}}}}|trk-pro:{{{entry|{{{1|}}}}}} }} |location=Oxford |publisher=Clarendon Press |year=1972 |isbn=0198641125 |oclc = 655135958 |pageparam = page,r,rûpel |pageurl=https://archive.org/details/etymologicaldict0000clau/page/{{#invoke:string/templates|match|{{{page|{{{pages|{{{1|{{{r|{{{rûpel}}}}}}}}}}}}}}}|[0-9]+|}} |allowparams = entry,1,r,rûpel }}<noinclude>{{refcat|trk-pro|otk|oui|tr|ota}}</noinclude> hye94m0buhbg7ra0y57g6e58j2i159g 6333883 6333882 2026-08-15T19:10:30Z Wikihez 7344 6333883 wikitext text/x-wiki {{#invoke:quote|call_template |template=cite-book |last=Clauson |first=Gerard |authorlink=Gerard Clauson |title=An Etymological Dictionary of pre-thirteenth-century Turkish<t:Ferhenga Etîmolojîk a Tirkiya Beriya Sedsala Sêzdehan> |entry={{#if:{{{entry|{{{1|}}}}}}|trk-pro:{{{entry|{{{1|}}}}}} }} |location=Oxford |publisher=Clarendon Press |year=1972 |isbn=0198641125 |oclc = 655135958 |pageparam = page,r,rûpel |pageurl=https://archive.org/details/etymologicaldict0000clau/page/{{#invoke:string/templates|match|{{{page|{{{pages|{{{1|{{{r|{{{rûpel}}}}}}}}}}}}}}}|[0-9]+|}} |allowparams = entry,1,r,rûpel }}<noinclude>{{refcat|trk-pro|otk|oui|tr|ota}}</noinclude> movaprny5kz27uz03laimpfnryebnxu 6333890 6333883 2026-08-15T19:32:25Z Wikihez 7344 Wikihezî/ê navê [[Şablon:R:trk:Clauson]] weke [[Şablon:Ç:trk:Clauson]] guhart 6333883 wikitext text/x-wiki {{#invoke:quote|call_template |template=cite-book |last=Clauson |first=Gerard |authorlink=Gerard Clauson |title=An Etymological Dictionary of pre-thirteenth-century Turkish<t:Ferhenga Etîmolojîk a Tirkiya Beriya Sedsala Sêzdehan> |entry={{#if:{{{entry|{{{1|}}}}}}|trk-pro:{{{entry|{{{1|}}}}}} }} |location=Oxford |publisher=Clarendon Press |year=1972 |isbn=0198641125 |oclc = 655135958 |pageparam = page,r,rûpel |pageurl=https://archive.org/details/etymologicaldict0000clau/page/{{#invoke:string/templates|match|{{{page|{{{pages|{{{1|{{{r|{{{rûpel}}}}}}}}}}}}}}}|[0-9]+|}} |allowparams = entry,1,r,rûpel }}<noinclude>{{refcat|trk-pro|otk|oui|tr|ota}}</noinclude> movaprny5kz27uz03laimpfnryebnxu 6333897 6333890 2026-08-15T20:08:58Z Wikihez 7344 6333897 wikitext text/x-wiki {{#invoke:quote|call_template |template=cite-book |last=Clauson |first=Gerard |authorlink=Gerard Clauson |title=en:An Etymological Dictionary of pre-thirteenth-century Turkish<t:Ferhenga Etîmolojîk a Tirkiya Beriya Sedsala Sêzdehan> |entry={{#if:{{{entry|{{{1|}}}}}}|trk-pro:{{{entry|{{{1|}}}}}} }} |location=Oxford |publisher=Clarendon Press |year=1972 |isbn=0198641125 |oclc = 655135958 |pageparam = page,r,rûpel |pageurl=https://archive.org/details/etymologicaldict0000clau/page/{{#invoke:string/templates|match|{{{page|{{{pages|{{{1|{{{r|{{{rûpel}}}}}}}}}}}}}}}|[0-9]+|}} |allowparams = entry,1,r,rûpel }}<noinclude>{{refcat|trk-pro|otk|oui|tr|ota}}</noinclude> 24fkmk5cgn3x8q5turven3be41dn9d1 6333912 6333897 2026-08-15T22:04:47Z Wikihez 7344 6333912 wikitext text/x-wiki {{#invoke:quote|call_template |template=cite-book |last=Clauson |first=Gerard |authorlink=en:Gerard Clauson |title=en:An Etymological Dictionary of pre-thirteenth-century Turkish<t:Ferhenga Etîmolojîk a Tirkiya Beriya Sedsala Sêzdehan> |entry={{#if:{{{entry|{{{1|}}}}}}|trk-pro:{{{entry|{{{1|}}}}}} }} |location=Oxford |publisher=en:Clarendon Press |year=1972 |isbn=0198641125 |oclc = 655135958 |pageparam = page,r,rûpel |pageurl=https://archive.org/details/etymologicaldict0000clau/page/{{#invoke:string/templates|match|{{{page|{{{pages|{{{1|{{{r|{{{rûpel}}}}}}}}}}}}}}}|[0-9]+|}} |allowparams = entry,1,r,rûpel }}<noinclude>{{refcat|trk-pro|otk|oui|tr|ota}}</noinclude> 4ysn86y48qvmtr81k97ijh8furv7i9f 6333913 6333912 2026-08-15T22:07:15Z Wikihez 7344 6333913 wikitext text/x-wiki {{#invoke:quote|call_template |template=cite-book |author=en:Clauson, Gerard |authorlink=en:Gerard Clauson |title=en:An Etymological Dictionary of pre-thirteenth-century Turkish<t:Ferhenga Etîmolojîk a Tirkiya Beriya Sedsala Sêzdehan> |entry={{#if:{{{entry|{{{1|}}}}}}|trk-pro:{{{entry|{{{1|}}}}}} }} |location=Oxford |publisher=en:Clarendon Press |year=1972 |isbn=0198641125 |oclc = 655135958 |pageparam = page,r,rûpel |pageurl=https://archive.org/details/etymologicaldict0000clau/page/{{#invoke:string/templates|match|{{{page|{{{pages|{{{1|{{{r|{{{rûpel}}}}}}}}}}}}}}}|[0-9]+|}} |allowparams = entry,1,r,rûpel }}<noinclude>{{refcat|trk-pro|otk|oui|tr|ota}}</noinclude> afu5we8iwpatfx33jkbrjjgvsyxcpuc ككلك 0 1358604 6333884 2026-08-15T19:12:12Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: Ji [[en:ككلك|en.wikt]] 6333884 wikitext text/x-wiki == {{ziman|ota}} == === Navdêr === {{navdêr|ota|tr=keklik}} # {{awayekî din|ota|ككلیك|tr=keklik|w=kew}} ==== Bêhtir bixwîne ==== * {{R:ota:Hindoglu|page=393a}} * {{R:ota:Meninski|L|column=3987}} * {{R:ota:Redhouse|page=1560}} t51a9ao1bp2vv9jy3munvhtuslr8rq9 Şablon:R:trk:Clauson 10 1358605 6333891 2026-08-15T19:32:26Z Wikihez 7344 Wikihezî/ê navê [[Şablon:R:trk:Clauson]] weke [[Şablon:Ç:trk:Clauson]] guhart 6333891 wikitext text/x-wiki #BERALÎKIRIN [[Şablon:Ç:trk:Clauson]] 8zk2x76o7lafwkq6vck05qnsfojj92p Kategorî:Teyr bi osmanî 14 1358606 6333895 2026-08-15T19:54:48Z Wikihez 7344 Bi riya [[Bikarhêner:Wikihez/skrîpt/js/addAutoCat.js/belge|JS]]: {{katbike}} û înterwîkî 6333895 wikitext text/x-wiki {{katbike}} 1dpx16ue3vl1l6c1hkqu0q6ftpl2ezh آبلوقه 0 1358607 6333918 2026-08-15T22:43:31Z Wikihez 7344 ([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +ota:navdêr:abloqe 6333918 wikitext text/x-wiki == {{ziman|ota}} == === Navdêr === {{navdêr|ota|tr=abluka|p=abluka|ptr=ablukalar}} # [[abloqe|abloqe]] #* {{nimûne?|ota}} ==== Etîmolojî ==== Ji {{deyn|it|ota|blocco}}. ==== Dûnde ==== * {{dû|tr|abluka}} * {{dû|hy|ապլուքա|deyn=1}} * {{dû|ku|abloqe|deyn=1}} ==== Çavkanî ==== * {{R:ota:Kelekian|page=3}} * {{R:tr:Nishanyan|abluka}} 3vpv0qzso1c8e94b64h3704w9m4o8f1 6333984 6333918 2026-08-16T00:12:12Z Balyozbot 7867 Bot: Paqijiyên kozmetîk (Lînk paqij kir.) 6333984 wikitext text/x-wiki == {{ziman|ota}} == === Navdêr === {{navdêr|ota|tr=abluka|p=abluka|ptr=ablukalar}} # [[abloqe]] #* {{nimûne?|ota}} ==== Etîmolojî ==== Ji {{deyn|it|ota|blocco}}. ==== Dûnde ==== * {{dû|tr|abluka}} * {{dû|hy|ապլուքա|deyn=1}} * {{dû|ku|abloqe|deyn=1}} ==== Çavkanî ==== * {{R:ota:Kelekian|page=3}} * {{R:tr:Nishanyan|abluka}} s4ytxpr2mnskkeg849puz5rayzs8a9x Modul:ckb-tewîn-nav 828 1358608 6334071 2026-08-16T04:29:46Z Ghybu 1393 ckb-tewîn-nav 6334071 Scribunto text/plain -- Binêre [[Şablon:ckb-tewîn-nav]] local export = {} --[[ local vowels = { -- short vowels ["ە"] = true, -- e ["و"] = true, -- u -- long vowels ["ا"] = true, -- a ["وو"] = true, -- û ["ۆ"] = true, -- o ["ێ"] = true, -- ê ["ی"] = true, -- î -- half-vowels ["و"] = true, -- w ["ی"] = true -- y } --]] local gsub = mw.ustring.gsub local match = mw.ustring.match function export.declination(noun) local decl = {} if not noun or noun == "" then return decl end local lastLetter = mw.ustring.sub(noun, -1) -- 1. NAVKÎ (Nominal) decl.nomSg = noun decl.nomPl = "" -- 2. NEBINAVKIRÎ (Indefinite) -- Yekjimar if match(lastLetter, "[اەێیۆوو]") then decl.indefSg = noun .. "یەک" else decl.indefSg = noun .. "ێک" end -- Pirjimar if match(lastLetter, "[اێۆوو]") then decl.indefPl = noun .. "یان" elseif lastLetter == "ە" then -- Remove the 'ە' and append 'ان' local stem = gsub(noun, "ە$", "") decl.indefPl = stem .. "ان" else decl.indefPl = noun .. "ان" end -- 3. BINAVKIRÎ (Definite) -- Yekjimar if match(lastLetter, "[ەاۆ]") then decl.defSg = noun .. "کە" --elseif match(lastLetter, "[وێی]") then -- decl.defPl = noun .. "ەکە" else decl.defSg = noun .. "ەکە" end -- Pirjimar if match(lastLetter, "[ەاۆ]") then decl.defPl = noun .. "کان" --elseif match(lastLetter, "[وێی]") then -- decl.defPl = noun .. "ەکان" else decl.defPl = noun .. "ەکان" end -- 4. NÎŞANDER (Demonstrative) -- Yekjimar if match(lastLetter, "[اەێۆ]") then decl.demonsSg = "ئەم " .. noun .. "یە" else decl.demonsSg = "ئەم " .. noun .. "ە" end -- Pirjimar if lastLetter == "ا" then decl.demonsPl = "ئەم " .. noun .. "یانە" elseif lastLetter == "ە" then -- Remove the 'ە' and append 'انە' local stem = gsub(noun, "ە$", "") decl.demonsPl = "ئەم " .. stem .. "انە" else decl.demonsPl = "ئەم " .. noun .. "انە" end return decl end return export gtnxh965dhjiwy5wysg8zyx7fjtgl6f 6334072 6334071 2026-08-16T04:43:04Z Ghybu 1393 6334072 Scribunto text/plain -- Binêre [[Şablon:ckb-tewîn-nav]] local export = {} --[[ local vowels = { -- short vowels ["ە"] = true, -- e ["و"] = true, -- u -- long vowels ["ا"] = true, -- a ["وو"] = true, -- û ["ۆ"] = true, -- o ["ێ"] = true, -- ê ["ی"] = true, -- î -- half-vowels ["و"] = true, -- w ["ی"] = true -- y } --]] local gsub = mw.ustring.gsub local match = mw.ustring.match function export.declination(noun) local decl = {} if not noun or noun == "" then return decl end local lastLetter = mw.ustring.sub(noun, -1) local lastTwo = mw.ustring.sub(noun, -2) -- 1. NAVKÎ (Nominal) decl.nomSg = noun decl.nomPl = "" -- 2. NEBINAVKIRÎ (Indefinite) -- Yekjimar if lastTwo == "وو" or match(lastLetter, "[اەێیۆ]") then decl.indefSg = noun .. "یەک" else decl.indefSg = noun .. "ێک" end -- Pirjimar if lastTwo == "وو" or match(lastLetter, "[اێۆ]") then decl.indefPl = noun .. "یان" elseif lastLetter == "ە" then -- Remove the 'ە' and append 'ان' local stem = gsub(noun, "ە$", "") decl.indefPl = stem .. "ان" else decl.indefPl = noun .. "ان" end -- 3. BINAVKIRÎ (Definite) -- Yekjimar if match(lastLetter, "[ەاۆ]") then decl.defSg = noun .. "کە" --elseif match(lastLetter, "[وێی]") then -- decl.defPl = noun .. "ەکە" else decl.defSg = noun .. "ەکە" end -- Pirjimar if match(lastLetter, "[ەاۆ]") then decl.defPl = noun .. "کان" --elseif match(lastLetter, "[وێی]") then -- decl.defPl = noun .. "ەکان" else decl.defPl = noun .. "ەکان" end -- 4. NÎŞANDER (Demonstrative) -- Yekjimar if match(lastLetter, "[اەێۆ]") then decl.demonsSg = "ئەم " .. noun .. "یە" else decl.demonsSg = "ئەم " .. noun .. "ە" end -- Pirjimar if lastLetter == "ا" then decl.demonsPl = "ئەم " .. noun .. "یانە" elseif lastLetter == "ە" then -- Remove the 'ە' and append 'انە' local stem = gsub(noun, "ە$", "") decl.demonsPl = "ئەم " .. stem .. "انە" else decl.demonsPl = "ئەم " .. noun .. "انە" end return decl end return export qcszy6drua2vef2mpf9e87lyocgwjwx heristin 0 1358609 6334078 2026-08-16T07:34:18Z Keyomerd 8814 Rûpel bi "== {{ziman|ku}} == === Lêker 1 === {{lêker|ku|c=x-ngh}} # [[alîn]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} {{werger-bin}} === Lêker 2 === {{lêker|ku|c=x-gh}} # [[pelçiqandin]], [[pelixandin]], [[eciqandin]] #* {{Memozîn 2007|jêgirtin=Sermest bi dest têk '''heristin'''</br>Bû gelte û gelc û daheristin|r=137}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} {{werger-bin}}" hat çêkirin 6334078 wikitext text/x-wiki == {{ziman|ku}} == === Lêker 1 === {{lêker|ku|c=x-ngh}} # [[alîn]] ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} {{werger-bin}} === Lêker 2 === {{lêker|ku|c=x-gh}} # [[pelçiqandin]], [[pelixandin]], [[eciqandin]] #* {{Memozîn 2007|jêgirtin=Sermest bi dest têk '''heristin'''</br>Bû gelte û gelc û daheristin|r=137}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} {{werger-bin}} pyawzritucd07t3ywbjjt5ygiufd4hd 6334079 6334078 2026-08-16T07:38:16Z Keyomerd 8814 /* Lêker 1 */ 6334079 wikitext text/x-wiki == {{ziman|ku}} == === Lêker 1 === {{lêker|ku|c=x-ngh}} # [[alîn]] ==== Jê ==== * {{g|ku|daheristin}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} {{werger-bin}} === Lêker 2 === {{lêker|ku|c=x-gh}} # [[pelçiqandin]], [[pelixandin]], [[eciqandin]] #* {{Memozîn 2007|jêgirtin=Sermest bi dest têk '''heristin'''</br>Bû gelte û gelc û daheristin|r=137}} ==== Etîmolojî ==== {{bêetîmolojî|ku}} ==== Werger ==== {{werger-ser}} {{werger-bin}} ft84k3bszr0kvzdlzrohp811fga228w kînewer 0 1358610 6334082 2026-08-16T08:04:32Z Keyomerd 8814 Rûpel bi "== {{ziman|ku}} == === Rengdêr === {{rengdêr|ku}} # [[kîndar]], [[bikîn]] #* {{Memozîn 2007|jêgirtin=Ew '''kînewer-i''' xebîs-i mudbir</br>Yenî Bekirê bi dil muzewwir|r=143}} ==== Etîmolojî ==== Ji {{paş|ku|kîn|ewer}}. ==== Werger ==== {{werger-ser}} {{werger-bin}}" hat çêkirin 6334082 wikitext text/x-wiki == {{ziman|ku}} == === Rengdêr === {{rengdêr|ku}} # [[kîndar]], [[bikîn]] #* {{Memozîn 2007|jêgirtin=Ew '''kînewer-i''' xebîs-i mudbir</br>Yenî Bekirê bi dil muzewwir|r=143}} ==== Etîmolojî ==== Ji {{paş|ku|kîn|ewer}}. ==== Werger ==== {{werger-ser}} {{werger-bin}} e9y3rvzabp4qgfay2m122x92pp9dy2n Bikarhêner:Mîr Yüce 2 1358611 6334085 2026-08-16T11:45:30Z Mîr Yüce 15259 /* */ Ekecik Kürtleri ve Yöresel Ağız Özellikleri. 6334085 wikitext text/x-wiki Ekecik Kürtleri ve Yöresel Ağız Özellikleri (Vikipedi Taslağı) Ekecik Kürtleri (Kürtçe: Kurdên Ekecikê), Aksaray ili sınırları içinde yer alan Ekecik Dağı ve çevresindeki köylerde yaşayan, Orta Anadolu Kürtleri (Kurdên Anatolya Navîn) topluluğunun önemli bir kolunu oluşturan etnokültürel bir gruptur. Osmanlı arşiv belgelerinde 16. yüzyıldan itibaren "Ekecik", "Ekeli" veya "Eke" adlarıyla anılan bu topluluk, tarihsel süreç içerisinde konar-göçer yaşam tarzından Aksaray Sancağı'na bağlı köylerde yerleşik hayata geçmiştir. 1. Tarihçe ve Yerleşim Ekecik Aşireti'ne ilişkin ilk yazılı arşiv belgeleri 16. yüzyıl başlarına dayanmaktadır. Arşiv kaynaklarında "Ekrad" (Kürtler) kategorisinde kaydedilen aşiret mensupları, Tuz Gölü'nün doğusu ile Ekecik Dağı (2.133 m) eteklerinde yoğunlaşmıştır. Tarihsel süreçte Eyübeli (günümüzde Ortaköy) ve Aksaray Merkez kazalarına bağlı çok sayıda köyde iskan edilmişlerdir. Tarihsel İskan Köyleri Osmanlı nüfus ve tahrir defterlerinde (örneğin 1837 Nüfus Defteri) Ekecik Aşireti'nin yerleştiği tespit edilen başlıca yerleşim yerleri şunlardır: Ahmetli, Ahmet Fakihler, Alayuntlu, Borucu, Cemalbağı Çat, Çatkilise, Çayağıl, Ekecik (Ekeciktol), Göçen, Gürgeni Hamza Fakih, Hüsrev, Kabakulak, Karaköy, Kızılçubuk, Kızılcık Koymaz, Köşklü, Kumağıl, Saka, Salman, Saraycık, Tepeköy, Yağdı, Yarımca 2. Dilbilimsel Özellikler ve Yöresel Terminoloji Ekecik bölgesinde konuşulan Kürtçe (Kurmancî), Orta Anadolu ağız grubuna girmekte olup, özgün işlevsel ve fonetik nitelikler barındırır. Yöredeki günlük yaşam, hayvancılık ve geleneksel hijyen uygulamaları, dilde son derece ince kavramsallaştırmaların oluşmasını sağlamıştır. Örnek Etnografik ve Dilbilimsel Terim Karşılaştırması Kavram / Kelime Tanım ve İşlevi Kültürel ve Hijyenik Arka Plan Sergo Sadece hayvan dışkısının (gübrenin) biriktirildiği ve döküldüğü alan. Tarımsal gübreleme ve tezek üretimi amacıyla ayrıştırılmış alan. Silgo İnsan dışkısı ile soba/ocak külünün karıştırılarak döküldüğü özel alan. Külün dezenfektan, koku giderici ve kurutucu özelliğinden faydalanılan geleneksel hijyen pratiği. 3. Vikipedi / Wîkîferheng Katkı Metni (MediaWiki Biçimi) Aşağıdaki kod bloğunda, doğrudan Vikipedi veya Wîkîferheng (Kürtçe Wiktionary) üzerinde kopyalayıp düzenle butonuna bastıktan sonra yapıştırabileceğiniz MediaWiki kaynak kodu verilmiştir: == Ekecik Ağzı ve Etnografik Terimler == === Sergo ve Silgo Ayrımı === Aksaray Ekecik Kürtlerinin dilsel dağarcığında eski köy yaşamının hijyen ve tarım pratiklerine dayalı özel kavramsallaştırmalar bulunur: * '''Sergo''': Sadece hayvan dışkısının (gübrenin) döküldüğü ve biriktirildiği alan. * '''Silgo''': İnsan dışkısı ile soba/ocak külünün karıştırılarak döküldüğü alan. Eski köy yaşamında soba külünün dezenfektan, koku giderici ve atık kurutucu işlevinden yararlanılmış; bu iki ayrı alan dilbilimsel olarak iki farklı terimle ifade edilmiştir. == Kaynakça == * Aksaray Tarih Araştırmaları Merkezi, "Ekecik Aşireti Kayıtları". * T.C. Başbakanlık Osmanlı Arşivi (BOA), Aksaray Sancağı Nüfus Defterleri. 4. Katkı Yapma Rehberi Wîkîferheng (Kürtçe Vikipedi Sözlük): "Sergo" ve "Silgo" başlıklarını ayrı ayrı açarak kelime türünü (nav/isim), kökenini ve anlamını ekleyebilirsiniz. Vikipedi (Türkçe / Kürtçe): Aksaray / Ekecik veya Orta Anadolu Kürtleri maddelerinde "Kültür" ya da "Dil" alt başlığı altına bu nitelikli bilgileri ekleyebilirsiniz. 5lmo92n78w9ajvt7a5wl6v0fsnrpqtx