ويكاموس arwiktionary https://ar.wiktionary.org/wiki/%D9%88%D9%8A%D9%83%D8%A7%D9%85%D9%88%D8%B3:%D8%A7%D9%84%D8%B5%D9%81%D8%AD%D8%A9_%D8%A7%D9%84%D8%B1%D8%A6%D9%8A%D8%B3%D9%8A%D8%A9 MediaWiki 1.47.0-wmf.12 case-sensitive ميديا خاص نقاش مستخدم نقاش المستخدم ويكاموس نقاش ويكاموس ملف نقاش الملف ميدياويكي نقاش ميدياويكي قالب نقاش القالب مساعدة نقاش المساعدة تصنيف نقاش التصنيف ملحق نقاش الملحق مكنز نقاش المكنز نص زمني نقاش النص الزمني وحدة نقاش الوحدة فعالية نقاش فعالية وحدة:ar-verb 828 188226 1096874 1072305 2026-07-20T13:32:10Z ForzaGreen 28665 تصحيح تصريف «أفعل» الأجوف اليائي إلى أجوف (أَفَالَ)، مع استثناء 7 جذور مسموعة 1096874 Scribunto text/plain local export = {} --[=[ This module implements {{ar-conj}} and provides the underlying conjugation functions for {{ar-verb}} (whose actual formatting is done in [[Module:ar-headword]]). Author: User:Benwing, from an early version (2013-2014) by User:Atitarev, User:ZxxZxxZ. ]=] --[=[ TERMINOLOGY: -- "slot" = A particular combination of tense/mood/person/number/etc. Example slot names for verbs are "past_1s" (past tense first-person singular), "juss_pass_3fp" (non-past jussive passive third-person feminine plural) "ap" (active participle). Each slot is filled with zero or more forms. -- "form" = The conjugated Arabic form representing the value of a given slot. -- "lemma" = The dictionary form of a given Arabic term. For Arabic, normally the third person masculine singular past, although other forms may be used if this form is missing (e.g. in passive-only verbs or verbs lacking the past). ]=] --[=[ FIXME: 1. Finish unimplemented conjugation types. Only IX-final-weak left (extremely rare, possibly only one verb اِعْمَايَ (according to Haywood and Nahmad p. 244, who are very specific about the irregular occurrence of alif + yā instead of expected اِعْمَيَّ with doubled yā). Not in Hans Wehr. NOTE: Not true about this, cf. form IX اِرْعَوَى "to desist, to repent, to see the light". Also note form XII اِخْضَوْضَرَ = form IX اِخْضَرَّ "to be or become green". [DONE except for اِعْمَايَ] 2. Implement irregular verbs as special cases and recognize them, e.g. -- laysa "to not be"; only exists in the past tense, no non-past, no imperative, no participles, no passive, no verbal noun. Irregular alternation las-/lays-. [IMPLEMENTABLE USING OVERRIDES] -- istaḥā yastaḥī "be ashamed of" -- this is complex according to Hans Wehr because there are two verbs, regular istaḥyā yastaḥyī "to spare (someone)'s life" and irregular istaḥyā yastaḥyī "to be ashamed to face (someone)", which is irregular because it has the alternate irregular form istaḥā yastaḥī which only applies to this meaning. Currently we follow Haywood and Nahmad in saying that both varieties can be spelled istaḥyā/istaḥā/istaḥḥā, but we should instead use a variant= param similar to حَيَّ to distinguish the two possibilities, and maybe not include istaḥḥā. -- ʿayya/ʿayiya yaʿayyu/yaʿyā "to not find the right way, be incapable of, stammer, falter, fall ill". This appears to be a mixture of a geminate and final-weak verb. Unclear what the whole paradigm looks like. Do the consonant-ending parts in the past follow the final-weak paradigm? Is it the same in the non-past? Or can you conjugate the non-past fully as either geminate or final-weak? -- اِنْمَحَى inmaḥā or يمَّحَى immaḥā "to be effaced, obliterated; to disappear, vanish" has irregular assimilation of inm- to imm- as an alternative. inmalasa "to become smooth; to glide; to slip away; to escape" also has immalasa as an alternative. The only other form VII verbs in Hans Wehr beginning with -m- are inmalaḵa "to be pulled out, torn out, wrenched" and inmāʿa "to be melted, to melt, to dissolve", which are not listed with imm- alternatives, but might have them; if so, we should handle this generally. [DONE] -- يَرَعَ yaraʕa yariʕu "to be a coward, to be chickenhearted" as an alternative form of يَرِعَ yariʕa yayraʕu (as given in Wehr). [IMPLEMENTABLE USING OVERRIDES] 3. Implement individual override parameters for each paradigm part. See Module:fro-verb for an example of how to do this generally. Note that {{temp|ar-conj-I}} and other of the older templates already had such individual override params. [DONE] Irregular verbs already implemented: -- [ḥayya/ḥayiya yaḥyā "live" -- behaves like a normal final-weak verb (e.g. past first singular ḥayītu) except in the past-tense parts with vowel-initial endings (all the third person except for the third feminine plural). The normal singular and dual endings have -yiya- in them, which compresses to -yya-, with the normal endings the less preferred ones. In masculine third plural, expected ḥayū is replaced by ḥayyū by analogy to the -yy- parts, and the regular form is not given as an alternant in John Mace. Barron's 201 verbs appears to have the regular ḥayū as the part, however. Note also that final -yā appears with tall alif. This appears to be a spelling convention of Arabic, also applying in ḥayyā (form II, "to keep (someone) alive") and 'aḥyā (form IV, "to animate, revive, give birth to, give new life to").] -- implemented -- [ittaxadha yattaxidhu "take"] -- implemented -- [sa'ala yas'alu "ask" with alternative jussive/imperative yasal/sal] -- implemented -- [ra'ā yarā "see"] -- implemented -- ['arā yurī "show"] -- implemented -- ['akala ya'kulu "eat" with imperative kul] -- implemented -- ['axadha ya'xudhu "take" with imperative xudh] -- implemented -- ['amara ya'muru "order" with imperative mur] -- implemented --]=] local force_cat = false -- set to true for debugging -- if true, always maintain manual translit during processing, and compare against full translit at the end local debug_translit = false local lang = require("وحدة:languages/ملعب").getByCode("ar") --W local m_links = require("وحدة:links/ملعب2") --W local m_string_utilities = require("Module:string utilities") local m_table = require("Module:table") local ar_utilities = require("Module:ar-utilities/en") --W local ar_nominals = require("Module:ar-nominals") local iut = require("Module:inflection utilities") local put = require("Module:parse utilities") local pron_qualifier_module = "Module:pron qualifier" local list_to_text = mw.text.listToText local rfind = m_string_utilities.find local rsubn = m_string_utilities.gsub local rmatch = m_string_utilities.match local rsplit = m_string_utilities.split local usub = m_string_utilities.sub local ulen = m_string_utilities.len local u = m_string_utilities.char local unpack = unpack or table.unpack -- Lua 5.2 compatibility local dump = mw.dumpObject -- Within this module, conjugations are the functions that do the actual -- conjugating by creating the parts of a basic verb. -- They are defined further down. local conjugations = {} -- hamza variants local HAMZA = u(0x0621) -- hamza on the line (stand-alone hamza) = ء local HAMZA_ON_ALIF = u(0x0623) local HAMZA_ON_W = u(0x0624) local HAMZA_UNDER_ALIF = u(0x0625) local HAMZA_ON_Y = u(0x0626) local HAMZA_ANY = "[" .. HAMZA .. HAMZA_ON_ALIF .. HAMZA_UNDER_ALIF .. HAMZA_ON_W .. HAMZA_ON_Y .. "]" local HAMZA_PH = u(0xFFF0) -- hamza placeholder local BAD = u(0xFFF1) local BORDER = u(0xFFF2) -- diacritics local A = u(0x064E) -- fatḥa local AN = u(0x064B) -- fatḥatān (fatḥa tanwīn) local U = u(0x064F) -- ḍamma local UN = u(0x064C) -- ḍammatān (ḍamma tanwīn) local I = u(0x0650) -- kasra local IN = u(0x064D) -- kasratān (kasra tanwīn) local SK = u(0x0652) -- sukūn = no vowel local SH = u(0x0651) -- šadda = gemination of consonants local DAGGER_ALIF = u(0x0670) local DIACRITIC_ANY_BUT_SH = "[" .. A .. I .. U .. AN .. IN .. UN .. SK .. DAGGER_ALIF .. "]" -- Pattern matching short vowels local AIU = "[" .. A .. I .. U .. "]" -- Pattern matching short vowels or sukūn local AIUSK = "[" .. A .. I .. U .. SK .. "]" -- Pattern matching any diacritics that may be on a consonant local DIACRITIC = SH .. "?" .. DIACRITIC_ANY_BUT_SH -- translit_patterns local vowels = "aeiouāēīōū" local NV = "[^" .. vowels .. "]" local dia = {a = A, i = I, u = U} local undia = {[A] = "a", [I] = "i", [U] = "u", ["-"] = "-"} -- various letters and signs local ALIF = u(0x0627) -- ʾalif = ا local AMAQ = u(0x0649) -- ʾalif maqṣūra = ى local AMAD = u(0x0622) -- ʾalif madda = آ local TAM = u(0x0629) -- tāʾ marbūṭa = ة local T = u(0x062A) -- tāʾ = ت local HYPHEN = u(0x0640) local N = u(0x0646) -- nūn = ن local W = u(0x0648) -- wāw = و local Y = u(0x064A) -- yāʾ = ي local S = "س" local M = "م" local LRM = u(0x200e) -- left-to-right mark -- common combinations local AH = A .. TAM local AT = A .. T local AA = A .. ALIF local AAMAQ = A .. AMAQ local AAH = AA .. TAM local AAT = AA .. T local II = I .. Y local UU = U .. W local AY = A .. Y local AW = A .. W local AYSK = AY .. SK local AWSK = AW .. SK local NA = N .. A local NI = N .. I local AAN = AA .. N local AANI = AA .. NI local AYNI = AYSK .. NI local AWNA = AWSK .. NA local AYNA = AYSK .. NA local AYAAT = AY .. AAT local UNU = "[" .. UN .. U .. "]" local MA = M .. A local MU = M .. U local TA = T .. A local TU = T .. U local _I = ALIF .. I local _U = ALIF .. U --W: Morphological pattern (الوزن الصرفي) to verb form mapping local MORPHOLOGICAL_PATTERN_TO_FORM = { ["فعَل يفعُل"] = "I/a~u", ["فعَل يفعِل"] = "I/a~i", ["فعَل يفعَل"] = "I/a~a", ["فعُل يفعُل"] = "I/u~u", ["فعِل يفعَل"] = "I/i~a", ["فعِل يفعِل"] = "I/i~i", ["فعّل"] = "II", ["فاعل"] = "III", ["أفعل"] = "IV", ["تفعّل"] = "V", ["تفاعل"] = "VI", ["انفعل"] = "VII", ["افتعل"] = "VIII", ["افعلّ"] = "IX", ["استفعل"] = "X", ["افعالّ"] = "XI", ["افعوعل"] = "XII", ["افعوّل"] = "XIII", ["فعلل"] = "Iq", ["تفعلل"] = "IIq", ["افعنلل"] = "IIIq", -- "XIV" should not be used ["افعللّ"] = "IVq", } --W: Create reverse mapping from form to morphological pattern local FORM_TO_MORPHOLOGICAL_PATTERN = {} for pattern, form in pairs(MORPHOLOGICAL_PATTERN_TO_FORM) do FORM_TO_MORPHOLOGICAL_PATTERN[form] = pattern end --W: local MORPHOLOGICAL_PATTERN_TO_BASIC_DERIV = { ["فعَل يفعُل"] = "مُجرَّد", ["فعَل يفعِل"] = "مُجرَّد", ["فعَل يفعَل"] = "مُجرَّد", ["فعُل يفعُل"] = "مُجرَّد", ["فعِل يفعَل"] = "مُجرَّد", ["فعِل يفعِل"] = "مُجرَّد", ["فعّل"] = "مزيد بحرف", ["فاعل"] = "مزيد بحرف", ["أفعل"] = "مزيد بحرف", ["تفعّل"] = "مزيد بحرفين", ["تفاعل"] = "مزيد بحرفين", ["انفعل"] = "مزيد بحرفين", ["افتعل"] = "مزيد بحرفين", ["افعلّ"] = "مزيد بحرفين", ["استفعل"] = "مزيد بثلاثة أحرف", ["افعالّ"] = "مزيد بثلاثة أحرف", ["افعوعل"] = "مزيد بثلاثة أحرف", ["افعوّل"] = "مزيد بثلاثة أحرف", ["فعلل"] = "مُجرَّد", ["تفعلل"] = "مزيد بحرف", ["افعنلل"] = "مزيد بحرفين", ["افعللّ"] = "مزيد بحرفين", } local translit_cache = { -- hamza variants [HAMZA] = "ʔ", [HAMZA_ON_ALIF] = "ʔ", [HAMZA_ON_W] = "ʔ", [HAMZA_UNDER_ALIF] = "ʔ", [HAMZA_ON_Y] = "ʔ", [HAMZA_PH] = "ʔ", -- diacritics [A] = "a", [AN] = "an", [U] = "u", [UN] = "un", [I] = "i", [IN] = "in", [SK] = "", [SH] = "*", -- handled specially [DAGGER_ALIF] = "ā", -- various letters and signs [""] = "", [ALIF] = BAD, -- we should never be transliterating ALIF by itself, as its translit in isolation is ambiguous [AMAQ] = BAD, [AMAD] = "ʔā", [TAM] = "", [T] = "t", [N] = "n", [W] = "w", [Y] = "y", [S] = "s", [M] = "m", [LRM] = "", -- common combinations [AH] = "a", [AT] = "at", [AA] = "ā", [AAMAQ] = "ā", [AAH] = "āh", [AAT] = "āt", [II] = "ī", [UU] = "ū", [AY] = "ay", [AW] = "aw", [AYSK] = "ay", [AWSK] = "aw", [NA] = "na", [NI] = "ni", [AAN] = "ān", [AANI] = "āni", [AYNI] = "ayni", [AWNA] = "awna", [AYNA] = "ayna", [AYAAT] = "ayāt", [MA] = "ma", [MU] = "mu", [TA] = "ta", [TU] = "tu", [_I] = "i", [_U] = "u", } local function transliterate(text) local cached = translit_cache[text] if cached then if cached == BAD then error(("Internal error: Unable to transliterate %s because explicitly marked as BAD"):format(text)) end return cached end local tr = (lang:transliterate(text)) if not tr then error(("Internal error: Unable to transliterate: %s"):format(text)) end translit_cache[text] = tr return tr end local all_person_number_list = { "1s", "2ms", "2fs", "3ms", "3fs", "2d", "3md", "3fd", "1p", "2mp", "2fp", "3mp", "3fp" } local function make_person_number_slot_accel_list(list) local slot_accel_list = {} return slot_accel_list end local imp_person_number_list = {} for _, pn in ipairs(all_person_number_list) do if pn:find("^2") then table.insert(imp_person_number_list, pn) end end local passive_types = m_table.listToSet { "pass", -- verb has both active and passive "ipass", -- verb is active with impersonal passive "nopass", -- verb is active-only "onlypass", -- verb is passive-only "onlypass-impers", -- verb itself is impersonal, meaning passive-only with impersonal passive } local indicator_flags = m_table.listToSet { "nopast", "no_nonpast", "noimp", "nocat", -- don't categorize or include annotations about this; useful in suppletive parts of verbs "reduced", -- verb has assimilation/reduction of initial coronals "altgem", -- form X with alternative past geminate forms with final-weak endings } export.potential_lemma_slots = {"past_3ms", "past_pass_3ms", "ind_3ms", "ind_pass_3ms", "imp_2ms"} export.unsettable_slots = {} for _, potential_lemma_slot in ipairs(export.potential_lemma_slots) do table.insert(export.unsettable_slots, potential_lemma_slot .. "_linked") end -- We don't set the active participle directly for form I because we don't want stative verbs (with past vowel i or u) -- to default to فَاعِل. Instead we set the special slot 'ap1' and later copy it to 'ap' for non-stative verbs. The user -- meanwhile can explicitly request the فَاعِل form for active participles for stative verbs using `ap:+`. table.insert(export.unsettable_slots, "ap1") -- primary default فَاعِل for form I active participles table.insert(export.unsettable_slots, "ap2") -- secondary default فَعِيل for form I active participles (stative I) table.insert(export.unsettable_slots, "ap3") -- secondary default فَعِل for form I active participles (stative II) table.insert(export.unsettable_slots, "apcd") -- secondary default أَفْعَل for form I active participles (color/defect) table.insert(export.unsettable_slots, "apan") -- secondary default فَعْلَان for form I active participles (in -ān) table.insert(export.unsettable_slots, "pp2") -- secondary default فَعِيل for form I passive participles (same as ap2) table.insert(export.unsettable_slots, "vn2") -- secondary default فِعَال for form III verbal nouns export.unsettable_slots_set = m_table.listToSet(export.unsettable_slots) local default_indicator_to_active_participle_slot = { ["+"] = "ap1", ["++"] = "ap2", ["+++"] = "ap3", ["+cd"] = "apcd", ["+an"] = "apan", } local slots_that_may_be_uncertain = { vn = "verbal noun", ap = "active participle", } -- Initialize all the slots for which we generate forms. local function add_slots(alternant_multiword_spec) alternant_multiword_spec.verb_slots = { {"ap", "act|part"}, {"pp", "pass|part"}, {"vn", "vnoun"}, } for _, unsettable_slot in ipairs(export.unsettable_slots) do table.insert(alternant_multiword_spec.verb_slots, {unsettable_slot, "-"}) end -- Add entries for a slot with person/number variants. -- `slot_prefix` is the prefix of the slot, typically specifying the tense/aspect. -- `tag_suffix` is a string listing the set of inflection tags to add after the person/number tags. -- `person_number_list` is a list of the person/number slot suffixes to add to `slot_prefix`. local function add_personal_slot(slot_prefix, tag_suffix, person_number_list) for _, persnum in ipairs(person_number_list) do local slot = slot_prefix .. "_" .. persnum local accel = persnum:gsub("(.)", "%1|") .. tag_suffix table.insert(alternant_multiword_spec.verb_slots, {slot, accel}) end end local tenses = { {"past", "past|%s"}, {"ind", "non-past|%s|ind"}, {"sub", "non-past|%s|sub"}, {"juss", "non-past|%s|juss"}, } for _, slot_accel in ipairs(tenses) do local slot, accel = unpack(slot_accel) for _, voice in ipairs {"act", "pass"} do add_personal_slot(voice == "act" and slot or slot .. "_pass", accel:format(voice), all_person_number_list) end end add_personal_slot("imp", "imp", imp_person_number_list) alternant_multiword_spec.verb_slots_map = {} for _, slot_accel in ipairs(alternant_multiword_spec.verb_slots) do local slot, accel = unpack(slot_accel) alternant_multiword_spec.verb_slots_map[slot] = accel end end local overridable_stems = {} local slot_override_param_mods = { footnote = { item_dest = "footnotes", store = "insert", }, alt = {}, t = { -- [[Module:links]] expects the gloss in "gloss". item_dest = "gloss", }, gloss = {}, g = { -- [[Module:links]] expects the genders in "g". `sublist = true` automatically splits on comma (optionally -- with surrounding whitespace). item_dest = "genders", sublist = true, }, pos = {}, lit = {}, id = {}, -- Qualifiers and labels q = { type = "qualifier", }, qq = { type = "qualifier", }, l = { type = "labels", }, ll = { type = "labels", }, } local function generate_obj(formval, parse_err, prefix, is_slot_override) local val, uncertain = formval:match("^(.*)(%?)$") val = val or formval uncertain = not not uncertain local ar, translit = val:match("^(.*)//(.*)$") if not ar then ar = val end if ar == "" then if uncertain then ar = "?" else error(("Can't specify blank value for override for %s override '%s'"):format( is_slot_override and "slot" or "stem", prefix)) end end return {form = ar, translit = translit, uncertain = uncertain} end local function parse_inline_modifiers(comma_separated_group, parse_err, prefix, is_slot_override) local function this_generate_obj(formval, parse_err) return generate_obj(formval, parse_err, prefix, is_slot_override) end return put.parse_inline_modifiers_from_segments { group = comma_separated_group, props = { param_mods = slot_override_param_mods, parse_err = parse_err, generate_obj = this_generate_obj, pre_normalize_modifiers = function(data) local modtext = data.modtext modtext = modtext:match("^(%[.*%])$") if modtext then return ("<footnote:%s>"):format(modtext) end return data.modtext end, }, } end local function allow_multiple_values_for_override(comma_separated_groups, data, is_slot_override) local retvals = {} for _, comma_separated_group in ipairs(comma_separated_groups) do local retval if is_slot_override then retval = parse_inline_modifiers(comma_separated_group, data.parse_err) else retval = generate_obj(comma_separated_group[1], data.parse_err, data.prefix, is_slot_override) retval.footnotes = data.fetch_footnotes(comma_separated_group) end table.insert(retvals, retval) end for _, form in ipairs(retvals) do if form.form == "+" or default_indicator_to_active_participle_slot[form.form] then if form.form ~= "+" and default_indicator_to_active_participle_slot[form.form] and not is_slot_override then error(("Stem override '%s' cannot use %s to request a secondary default"):format( data.prefix, form.form)) end data.base.slot_override_uses_default[data.prefix] = true end end for _, form in ipairs(retvals) do if form.form == "-" then data.base.slot_explicitly_missing[data.prefix] = true break end end if data.base.slot_explicitly_missing[data.prefix] then for _, form in ipairs(retvals) do if form.form ~= "-" then data.parse_err(("For slot or stem '%s', saw both - and a value other than -, which isn't allowed"): format(data.prefix)) end end return nil end return retvals end local function simple_choice(choices) return function(separated_groups, data) if #separated_groups > 1 then data.parse_err("For spec '" .. data.prefix .. ":', only one value currently allowed") end if #separated_groups[1] > 1 then data.parse_err("For spec '" .. data.prefix .. ":', no footnotes currently allowed") end local choice = separated_groups[1][1] if not m_table.contains(choices, choice) then data.parse_err("For spec '" .. data.prefix .. ":', saw value '" .. choice .. "' but expected one of '" .. table.concat(choices, "،") .. "'") end return choice end end for _, overridable_stem in ipairs { "past", "past_v", "past_c", "past_pass", "past_pass_v", "past_pass_c", "nonpast", "nonpast_v", "nonpast_c", "nonpast_pass", "nonpast_pass_v", "nonpast_pass_c", "imp", "imp_v", "imp_c", } do overridable_stems[overridable_stem] = allow_multiple_values_for_override end overridable_stems.past_final_weak_vowel = simple_choice { "ay", "aw", "ī", "ū" } overridable_stems.past_pass_final_weak_vowel = simple_choice { "ay", "aw", "ī", "ū" } overridable_stems.nonpast_final_weak_vowel = simple_choice { "ā", "ī", "ū" } overridable_stems.nonpast_pass_final_weak_vowel = simple_choice { "ā", "ī", "ū" } ------------------------------------------------------------------------------- -- Utility functions -- ------------------------------------------------------------------------------- -- version of rsubn() that discards all but the first return value local function rsub(term, foo, bar) return (rsubn(term, foo, bar)) end -- version of rsubn() that returns a 2nd argument boolean indicating whether a substitution was made. local function rsubb(term, foo, bar) local retval, nsubs = rsubn(term, foo, bar) return retval, nsubs > 0 end -- Concatenate one or more strings or form objects. local function q(...) local not_all_strings = debug_translit local has_manual_translit = debug_translit for i = 1, select("#", ...) do local argt = select(i, ...) if not argt then error(("Internal error: Saw nil at index %s: %s"):format(i, dump({...}))) end if type(argt) ~= "string" then not_all_strings = true if argt.translit then has_manual_translit = true break end end end if not not_all_strings then -- just strings, concatenate directly return table.concat({...}) end local formvals = {} local translit = has_manual_translit and {} or nil local footnotes for i = 1, select("#", ...) do local argt = select(i, ...) if type(argt) == "string" then formvals[i] = argt if has_manual_translit then translit[i] = transliterate(argt) end else formvals[i] = argt.form if has_manual_translit then translit[i] = argt.translit or transliterate(argt.form) end footnotes = iut.combine_footnotes(footnotes, argt.footnotes) end end -- FIXME: Do we want to support other properties? return { form = table.concat(formvals), translit = has_manual_translit and table.concat(translit) or nil, footnotes = footnotes, } end -- Return the formval associated with `rad` (a radical or past/non-past vowel, either a string or form object). local function rget(rad) if type(rad) == "string" then return rad elseif type(rad) == "table" then return rad.form else error(("Internal error: Unexpected type for radical or past/non-past vowel: %s"):format(dump(rad))) end end export.rget = rget -- for use in [[Module:ar-headword]] -- Return the footnotes associated with `rad` (a radical or past/non-past vowel, either a string or form object). local function rget_footnotes(rad) if type(rad) == "string" then return nil elseif type(rad) == "table" then return rad.footnotes else error(("Internal error: Unexpected type for radical or past/non-past vowel: %s"):format(dump(rad))) end end -- Return true if the formval associated with `rad` (a radical or past/non-past vowel, either a string or form object) -- is `val`. local function req(rad, val) return rget(rad) == val end -- Map `vow` (a past/non-past vowel, either a string or form object without translit) by passing the formval through -- `fn`. Don't call this on radicals because they may have manual translit and it isn't clear how to handle that. local function map_vowel(vow, fn) if type(vow) == "string" then return fn(vow) elseif type(vow) == "table" then return {form = fn(vow.form), footnotes = vow.footnotes} else error(("Internal error: Unexpected type for past/non-past vowel: %s"):format(dump(vow))) end end local function get_radicals_3(vowel_spec) return vowel_spec.rad1, vowel_spec.rad2, vowel_spec.rad3, vowel_spec.past, vowel_spec.nonpast end local function get_radicals_4(vowel_spec) return vowel_spec.rad1, vowel_spec.rad2, vowel_spec.rad3, vowel_spec.rad4 end local function is_final_weak(base, vowel_spec) return vowel_spec.weakness == "final-weak" or base.form == "XV" end --W: Create a simple link local function link_term_simple(text) return "[[" .. text .. "]]" end local function link_term(text, face, id) return m_links.full_link({lang = lang, term = text, tr = "-", id = id}, face) end local function tag_text(text, tag, class) return m_links.full_link({lang = lang, alt = text, tr = "-"}) end local function track(page) require("Module:debug/track")("ar-verb/" .. page) return true end local function track_if_ar_conj(base, page) if base.alternant_multiword_spec.source_template == "ar-conj" then require("Module:debug/track")("ar-verb/" .. page) end return true end local function reorder_shadda(word) -- shadda+short-vowel (including tanwīn vowels, i.e. -an -in -un) gets -- replaced with short-vowel+shadda during NFC normalisation, which -- MediaWiki does for all Unicode strings; however, it makes various -- processes inconvenient, so undo it. word = rsub(word, "(" .. DIACRITIC_ANY_BUT_SH .. ")" .. SH, SH .. "%1") return word end local function apply_nfc_shadda(word) -- Apply NFC-style normalization: reorder shadda+vowel to vowel+shadda -- to match MediaWiki's automatic NFC normalization. This reverses the -- internal shadda+vowel format used during processing. word = rsub(word, SH .. "(" .. DIACRITIC_ANY_BUT_SH .. ")", "%1" .. SH) return word end ------------------------------------------------------------------------------- -- Basic functions to inflect tenses -- ------------------------------------------------------------------------------- local function skip_slot(base, slot, allow_overrides) if base.slot_explicitly_missing[slot] then return true end if not allow_overrides and base.slot_overrides[slot] and not base.slot_override_uses_default[slot] then -- Skip any slots for which there are overrides, except those that request the default value using +, ++, etc. return true end if base.passive == "nopass" and (slot == "pp" or slot:find("_pass")) then return true elseif base.passive == "onlypass" and slot ~= "pp" and slot ~= "vn" and not slot:find("_pass") then return true elseif base.passive == "ipass" and slot:find("_pass") and not slot:find("3ms") then return true elseif base.passive == "onlypass-impers" and slot ~= "pp" and slot ~= "vn" and (not slot:find("_pass") or slot:find("_pass") and not slot:find("3ms")) then return true end if base.nopast and slot:find("^past_") then return true end if base.noimp and slot:find("^imp_") then return true end if base.no_nonpast and (slot:find("^ind_") or slot:find("^sub_") or slot:find("^juss")) then return true end return false end local function basic_combine_stem_ending(stem, ending) return stem .. ending end local function basic_combine_stem_ending_tr(stem, ending) return stem .. ending end -- Concatenate `prefixes`, `stems` and `endings` (any of which may be an abbreviate form list, i.e. strings, form -- objects or lists of strings or form objects) and store into `slot`. If a user-supplied override exists for the slot, -- nothing will happen unless `allow_overrides` is provided. local function add3(base, slot, prefixes, stems, endings, allow_overrides) if skip_slot(base, slot, allow_overrides) then return end -- Optimization since the prefixes are almost always single strings. if type(prefixes) == "string" then local function do_combine_stem_ending(stem, ending) return prefixes .. stem .. ending end local function do_combine_stem_ending_tr(stem, ending) return transliterate(prefixes) .. stem .. ending end iut.add_forms(base.forms, slot, stems, endings, do_combine_stem_ending, transliterate, do_combine_stem_ending_tr, base.form_footnotes) else iut.add_multiple_forms(base.forms, slot, {prefixes, stems, endings}, basic_combine_stem_ending, transliterate, basic_combine_stem_ending_tr, base.form_footnotes) end end -- Insert one or more forms in `form_or_forms` into `slot`. `form_or_forms` is an abbreviated form list (see comment at -- top of [[Module:inflection utilities]]). If a user-supplied override exists for the slot, nothing will happen unless -- `allow_overrides` is provided. BEWARE: One form object should never occur in two different slots, or twice in a given -- slot; if taking a form object from an existing slot, make sure to shallowCopy() it. local function insert_form_or_forms(base, slot, form_or_forms, allow_overrides, uncertain) if not skip_slot(base, slot, allow_overrides) then -- Some optimizations of the most common case of inserting a single string. if type(form_or_forms) == "string" and not base.form_footnotes then form_or_forms = {form = form_or_forms, uncertain = uncertain} iut.insert_form(base.forms, slot, form_or_forms) else local list = iut.convert_to_general_list_form(form_or_forms, base.form_footnotes) if uncertain then for _, formobj in ipairs(list) do formobj.uncertain = true end end iut.insert_forms(base.forms, slot, list) end end end -- Insert `string_or_form` into both the ap2 and pp2 slots, shallowCopying a form object to make sure no form objects -- occur in two slots. local function insert_ap2_pp2(base, string_or_form) insert_form_or_forms(base, "ap2", string_or_form) if type(string_or_form) == "table" then string_or_form = m_table.shallowCopy(string_or_form) end insert_form_or_forms(base, "pp2", string_or_form) end -- Convert `stemforms` (a string, a form object, or a list of strings and/or form objects) into "general form" (a list -- of form objects) and map `fn` over the list of objects. `fn` is passed two arguments (form value and translit) and -- should likewise return the new form value and translit. Footnotes will be preserved. FIXME: Preserve other metadata. local function map_general(stemforms, fn) return iut.map_forms(iut.convert_to_general_list_form(stemforms), fn) end -- Similar to map_general() except that `fn` should return a single value (one or more strings or form objects), instead -- of two values (form value and translit), and the resulting value(s) from all calls to `fn` will be flattened to -- construct the overall return value. Footnotes will be preserved. FIXME: Preserve other metadata. local function flatmap_general(stemforms, fn) return iut.flatmap_forms(iut.convert_to_general_list_form(stemforms), fn) end -- Given user-supplied stem overrides in `base`, construct any derived stem overrides (e.g. vowel-specific or -- consonant-specific variants), and truncate initial y-/ي- in any non-past overrides. local function construct_stems(base) local stems = base.stem_overrides stems.past_v = stems.past_v or stems.past stems.past_c = stems.past_c or stems.past stems.past_pass_v = stems.past_pass_v or stems.past_pass stems.past_pass_c = stems.past_pass_c or stems.past_pass stems.nonpast_v = stems.nonpast_v or stems.nonpast stems.nonpast_c = stems.nonpast_c or stems.nonpast stems.nonpast_pass_v = stems.nonpast_pass_v or stems.nonpast_pass stems.nonpast_pass_c = stems.nonpast_pass_c or stems.nonpast_pass stems.imp_v = stems.imp_v or stems.imp stems.imp_c = stems.imp_c or stems.imp local function truncate_nonpast_initial_cons(stem_type, form, translit) if form == "+" then return form, translit end if not form:find("^" .. Y) then error(("Form value %s for stem type '%s' should begin with ي"):format(form, stem_type)) end form = form:gsub("^" .. Y, "") if translit then if not translit:find("^y") then error(("Translit value %s for stem type '%s' should begin with y"):format(translit, stem_type)) end translit = translit:gsub("^y", "") end return form, translit end for _, nonpast_stem_type in ipairs { "nonpast_v", "nonpast_c", "nonpast_pass_v", "nonpast_pass_c" } do if stems[nonpast_stem_type] then stems[nonpast_stem_type] = map_general(stems[nonpast_stem_type], function(form, translit) return truncate_nonpast_initial_cons(nonpast_stem_type, form, translit) end) end end end -- Given user-specified overrides for stem `stemname`, return overrides with occurrences of + replaced by -- `default_stem`. If no overrides, return `default_stem`, or {} if no default. local function override_stem_if_needed(base, stemname, default_stem) local overrides = base.stem_overrides[stemname] if not overrides then return default_stem or {} end return map_general(overrides, function(form, translit) if form ~= "+" and default_indicator_to_active_participle_slot[form] then error(("Stem overrides cannot use secondary default indicators but saw %s in stem override '%s'"):format( form, stemname)) end if form == "+" then if translit then error(("Cannot supply manual translit along with + for stem override '%s'"):format(stemname)) end if not default_stem then error(("Cannot use + for stem override '%s' because no default is available"):format(stemname)) end if type(default_stem) ~= "string" then error(("Internal error: Default stem for '%s' is not a string: %s"):format(stemname, dump(default_stem))) end return default_stem end return form, translit end) end ------------------------------------------------------------------------------- -- Properties of different verbal forms -- ------------------------------------------------------------------------------- local allowed_vforms = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII", "XIII", "XIV", "XV", "Iq", "IIq", "IIIq", "IVq"} local allowed_vforms_set = m_table.listToSet(allowed_vforms) local allowed_vforms_with_weakness = m_table.shallowCopy(allowed_vforms) -- The user needs to be able to explicitly specify that a form-I verb (specifically one whose initial radical is و) is -- sound. Cf. wajiʕa yawjaʕu (not #yajaʕu) "to ache, to hurt". In general, i~a and u~u verbs whose initial radical is و -- seem to not assimilate the first radical; cf. وقح "to be shameless", variously waqaḥa~yaqiḥu, waquḥa~yawquḥu and -- waqiḥa~yawqaḥu, whereas a~i verbs (wafaḍa~yafiḍu "to rush"), i~i verbs (wafiqa~yafiqu "to be proper, to be suitable") -- and a~a verbs (waḍaʕa~yaḍaʕu "to set down, to place") do assimilate. But there are naturally exceptions, e.g. -- waṭiʔa~yaṭaʔu "to tread, to trample"; wasiʕa~yasaʕu "to be spacious; to be well-off"; waṯiʔa~yaṯaʔu "to get bruised, -- to be sprained". Also beware of waniya~yawnā "to be faint; to languish", which is sound in the first radical and -- final-weak in the last radical. Nonetheless, the regularity of the patterns mentioned above suggest we should provide -- them as defaults. -- Note that there are other cases of unexpectedly sound verbs, e.g. izdawaja~yazdawiju "to be in pairs", layisa~yalyasu -- "to be valiant, to be brave", ʔaḥwaja~yuḥwiju "to need", istahwana~yastahwinu "to consider easy", sawisa~yaswasu "to -- be or become moth-eaten or worm-eaten" (vs. sāsa~yasūsu "to govern, to rule" from the same radicals), ʕawira~yaʕwaru -- "to be one-eyed", istajwaba~yastajwibu "to interrogate", etc. But in these cases there is no need for explicit user -- specification as the lemma itself specifies the unexpected soundness. for _, form_with_weakness in ipairs { "I-sound", "I-assimilated", "none-sound", "none-hollow", "none-geminate", "none-final-weak" } do table.insert(allowed_vforms_with_weakness, form_with_weakness) end local allowed_vforms_with_weakness_set = m_table.listToSet(allowed_vforms_with_weakness) local function vform_supports_final_weak(vform) return vform ~= "XI" and vform ~= "XV" and vform ~= "IVq" end local function vform_supports_geminate(vform) return vform == "I" or vform == "III" or vform == "IV" or vform == "VI" or vform == "VII" or vform == "VIII" or vform == "X" end local function vform_supports_hollow(vform) return vform == "I" or vform == "IV" or vform == "VII" or vform == "VIII" or vform == "X" end local function vform_probably_impersonal_passive(vform, weakness, past_vowel, nonpast_vowel) return vform == "I" and req(past_vowel, I) or vform == "V" or vform == "VI" or vform == "X" or vform == "IIq" end local function vform_probably_full_passive(vform) return vform == "II" or vform == "III" or vform == "IV" or vform == "Iq" end local function vform_probably_no_passive(vform, weakness, past_vowel, nonpast_vowel) return vform == "I" and req(past_vowel, U) or vform == "VII" or vform == "IX" or vform == "XI" or vform == "XII" or vform == "XIII" or vform == "XIV" or vform == "XV" or vform == "IIIq" or vform == "IVq" end -- Active vforms II, III, IV, Iq use non-past prefixes in -u- instead of -a-. local function prefix_vowel_from_vform(vform) if vform == "II" or vform == "III" or vform == "IV" or vform == "Iq" then return "u" else return "a" end end -- True if the active non-past takes a-vocalization rather than i-vocalization in its last syllable. local function vform_nonpast_a_vowel(vform) return vform == "V" or vform == "VI" or vform == "XV" or vform == "IIq" end -- True if the `passive` spec indicates a passive-only verb. local function is_passive_only(passive) return passive == "onlypass" or passive == "onlypass-impers" end export.is_passive_only = is_passive_only -- for use in [[Module:ar-headword]] ------------------------------------------------------------------------------- -- Properties of specific sounds -- ------------------------------------------------------------------------------- -- Is radical wāw (و) or yāʾ (ي)? local function is_waw_ya(rad) return req(rad, W) or req(rad, Y) end -- Check that radical is wāw (و) or yāʾ (ي), error if not local function check_waw_ya(rad) if not is_waw_ya(rad) then error("Expecting weak radical: '" .. rget(rad) .. "' should be " .. W .. " or " .. Y) end end -- Form-I verb حيّ or حيي and form-X verb استحيا or استحى local function hayy_radicals(rad1, rad2, rad3) return req(rad1, "ح") and req(rad2, Y) and is_waw_ya(rad3) end -- FUCK ME HARD. "Lua error at line 1514: main function has more than 200 local variables". local function create_conjugations() ------------------------------------------------------------------------------- -- Radicals associated with various irregular verbs -- ------------------------------------------------------------------------------- -- Form-I verb أخذ or form-VIII verb اتخذ local function axadh_radicals(rad1, rad2, rad3) return req(rad1, HAMZA) and req(rad2, "خ") and req(rad3, "ذ") end -- Form-I verb whose imperative has a reduced form: أكل and أخذ and أمر. Return "shortonly" if only -- short-form imperatives exist (أكل and أخذ) or "shortlong" if long-form imperatives also exist (أمر); -- they are used after a clitic like فَ and وَ. local function reduced_imperative_verb(rad1, rad2, rad3) return axadh_radicals(rad1, rad2, rad3) and "shortonly" or req(rad1, HAMZA) and req(rad2, "ك") and req(rad3, "ل") and "shortonly" or req(rad1, HAMZA) and req(rad2, "م") and req(rad3, "ر") and "shortlong" end -- Form-I verb رأى and form-IV verb أرى local function raa_radicals(rad1, rad2, rad3) return req(rad1, "ر") and req(rad2, HAMZA) and is_waw_ya(rad3) end -- Form-I verb سأل local function saal_radicals(rad1, rad2, rad3) return req(rad1, "س") and req(rad2, HAMZA) and req(rad3, "ل") end -- Form-I verb كان local function kaan_radicals(rad1, rad2, rad3) return req(rad1, "ك") and req(rad2, W) and req(rad3, N) end ------------------------------------------------------------------------------- -- Sets of past endings -- ------------------------------------------------------------------------------- -- The 13 endings of the sound/hollow/geminate past tense. local past_endings = { -- singular SK .. TU, SK .. TA, SK .. "تِ", A, A .. "تْ", --dual SK .. "تُمَا", AA, A .. "تَا", -- plural SK .. "نَا", SK .. "تُمْ", -- shadda + vowel diacritic ends up in the wrong order due to Unicode -- bug, so keep them separate to avoid this SK .. "تُن" .. SH .. A, UU .. ALIF, SK .. "نَ" } -- Make endings for final-weak past in -aytu or -awtu. AYAW is AY or AW as appropriate. Note that AA and AW are -- global variables. local function make_past_endings_ay_aw(ayaw, third_sg_masc) return { -- singular ayaw .. SK .. TU, ayaw .. SK .. TA, ayaw .. SK .. "تِ", third_sg_masc, A .. "تْ", --dual ayaw .. SK .. "تُمَا", ayaw .. AA, A .. "تَا", -- plural ayaw .. SK .. "نَا", ayaw .. SK .. "تُمْ", -- shadda + vowel diacritic ends up in the wrong order due to Unicode -- bug, so keep them separate to avoid this ayaw .. SK .. "تُن" .. SH .. A, AW .. SK .. ALIF, ayaw .. SK .. "نَ" } end -- past final-weak -aytu endings local past_endings_ay = make_past_endings_ay_aw(AY, AAMAQ) -- past final-weak -awtu endings local past_endings_aw = make_past_endings_ay_aw(AW, AA) -- used for alternative endings for form-X geminate verbs like اِسْتَمَرَّ local past_endings_ay_12_person_only = { -- singular AY .. SK .. TU, AY .. SK .. TA, AY .. SK .. "تِ", {}, {}, --dual AY .. SK .. "تُمَا", {}, {}, -- plural AY .. SK .. "نَا", AY .. SK .. "تُمْ", -- shadda + vowel diacritic ends up in the wrong order due to Unicode -- bug, so keep them separate to avoid this AY .. SK .. "تُن" .. SH .. A, {}, {}, } -- Make endings for final-weak past in -ītu or -ūtu. IIUU is ī or ū as appropriate. Note that AA and UU are global -- variables. local function make_past_endings_ii_uu(iiuu) return { -- singular iiuu .. TU, iiuu .. TA, iiuu .. "تِ", iiuu .. A, iiuu .. A .. "تْ", --dual iiuu .. "تُمَا", iiuu .. AA, iiuu .. A .. "تَا", -- plural iiuu .. "نَا", iiuu .. "تُمْ", -- shadda + vowel diacritic ends up in the wrong order due to Unicode -- bug, so keep them separate to avoid this iiuu .. "تُن" .. SH .. A, UU .. ALIF, iiuu .. "نَ" } end -- past final-weak -ītu endings local past_endings_ii = make_past_endings_ii_uu(II) -- past final-weak -ūtu endings local past_endings_uu = make_past_endings_ii_uu(UU) ------------------------------------------------------------------------------- -- Sets of non-past prefixes and endings -- ------------------------------------------------------------------------------- local nonpast_prefix_consonants = { -- singular HAMZA, T, T, Y, T, -- dual T, Y, T, -- plural N, T, T, Y, Y } -- There are only five distinct endings in all non-past verbs. Make any set of non-past endings given these five -- distinct endings. local function make_nonpast_endings(null, fem, dual, pl, fempl) return { -- singular null, null, fem, null, null, -- dual dual, dual, dual, -- plural null, pl, fempl, pl, fempl } end -- endings for non-past indicative local ind_endings = make_nonpast_endings( U, II .. NA, AANI, UU .. NA, SK .. NA ) -- Make the endings for non-past subjunctive/jussive, given the vowel diacritic used in "null" endings -- (1s/2ms/3ms/3fs/1p). local function make_sub_juss_endings(dia_null) return make_nonpast_endings( dia_null, II, AA, UU .. ALIF, SK .. NA ) end -- endings for non-past subjunctive local sub_endings = make_sub_juss_endings(A) -- endings for non-past jussive local juss_endings = make_sub_juss_endings(SK) -- endings for alternative geminate non-past jussive in -a; same as subjunctive local juss_endings_alt_a = sub_endings -- endings for alternative geminate non-past jussive in -i local juss_endings_alt_i = make_sub_juss_endings(I) -- Endings for final-weak non-past indicative in -ā. Note that AY, AW and AAMAQ are global variables. local ind_endings_aa = make_nonpast_endings( AAMAQ, AYSK .. NA, AY .. AANI, AWSK .. NA, AYSK .. NA ) -- Make endings for final-weak non-past indicative in -ī or -ū; IIUU is ī or ū as appropriate. Note that II and UU -- are global variables. local function make_ind_endings_ii_uu(iiuu) return make_nonpast_endings( iiuu, II .. NA, iiuu .. AANI, UU .. NA, iiuu .. NA ) end -- endings for final-weak non-past indicative in -ī local ind_endings_ii = make_ind_endings_ii_uu(II) -- endings for final-weak non-past indicative in -ū local ind_endings_uu = make_ind_endings_ii_uu(UU) -- Endings for final-weak non-past subjunctive in -ā. Note that AY, AW, ALIF, AAMAQ are global variables. local sub_endings_aa = make_nonpast_endings( AAMAQ, AYSK, AY .. AA, AWSK .. ALIF, AYSK .. NA ) -- Make endings for final-weak non-past subjunctive in -ī or -ū. IIUU is ī or ū as appropriate. Note that AA, II, -- UU, ALIF are global variables. local function make_sub_endings_ii_uu(iiuu) return make_nonpast_endings( iiuu .. A, II, iiuu .. AA, UU .. ALIF, iiuu .. NA ) end -- endings for final-weak non-past subjunctive in -ī local sub_endings_ii = make_sub_endings_ii_uu(II) -- endings for final-weak non-past subjunctive in -ū local sub_endings_uu = make_sub_endings_ii_uu(UU) -- endings for final-weak non-past jussive in -ā local juss_endings_aa = make_nonpast_endings( A, AYSK, AY .. AA, AWSK .. ALIF, AYSK .. NA ) -- Make endings for final-weak non-past jussive in -ī or -ū. IU is short i or u, IIUU is long ī or ū as appropriate. -- Note that AA, II, UU, ALIF are global variables. local function make_juss_endings_ii_uu(iu, iiuu) return make_nonpast_endings( iu, II, iiuu .. AA, UU .. ALIF, iiuu .. NA ) end -- endings for final-weak non-past jussive in -ī local juss_endings_ii = make_juss_endings_ii_uu(I, II) -- endings for final-weak non-past jussive in -ū local juss_endings_uu = make_juss_endings_ii_uu(U, UU) ------------------------------------------------------------------------------- -- Sets of imperative endings -- ------------------------------------------------------------------------------- -- Extract the second person jussive endings to get corresponding imperative endings. local function imperative_endings_from_jussive(endings) return {endings[2], endings[3], endings[6], endings[10], endings[11]} end -- normal imperative endings local imp_endings = imperative_endings_from_jussive(juss_endings) -- alternative geminate imperative endings in -a local imp_endings_alt_a = imperative_endings_from_jussive(juss_endings_alt_a) -- alternative geminate imperative endings in -i local imp_endings_alt_i = imperative_endings_from_jussive(juss_endings_alt_i) -- final-weak imperative endings in -ā local imp_endings_aa = imperative_endings_from_jussive(juss_endings_aa) -- final-weak imperative endings in -ī local imp_endings_ii = imperative_endings_from_jussive(juss_endings_ii) -- final-weak imperative endings in -ū local imp_endings_uu = imperative_endings_from_jussive(juss_endings_uu) ------------------------------------------------------------------------------- -- Basic functions to inflect tenses -- ------------------------------------------------------------------------------- -- Add to `base` the inflections for the tense indicated by `tense` (the prefix in the slot names, e.g. 'past' -- or 'juss_pass'), formed by combining the `prefixes`, `stems` and `endings`. Each of `prefixes`, `stems` and -- `endings` is either a sequence of 5 (for the imperative) or 13 (for other tenses) abbreviated form lists (each of -- which is either a string, a form object, or a list of strings and/or form objects; see -- [[Module:inflection utilities]] for more info). Alternatively, any of `prefixes`, `stems` or `endings` can be a -- single-element list containing an abbreviated form list, with an additional key `all_same` set to true, or (as a -- special case) a single string; in the latter cases, the same value is used for all 5 or 13 slots. If existing -- inflections already exist, they will be added to, not overridden. `pnums` is the list of person/number slot name -- suffixes, which must match up with the elements in `prefixes`, `stems` and `endings` (i.e. 5 for imperative, 13 -- otherwise). local function inflect_tense_1(base, tense, prefixes, stems, endings, pnums) if not prefixes or not stems or not endings then return end local function verify_affixes(affixname, affixes) local function interr(msg) error(("Internal error: For tense '%s', '%s' %s: %s"):format(tense, affixname, msg, dump(affixes))) end if type(affixes) == "string" then -- do nothing elseif type(affixes) ~= "table" then interr("is not a table or string") elseif affixes.all_same then if #affixes ~= 1 then interr(("with all_same = true should have length 1 but has length %s"):format(#affixes)) end else if #affixes ~= #pnums then interr(("should have length %s but has length %s"):format(#pnums, #affixes)) end end end verify_affixes("prefixes", prefixes) verify_affixes("stems", stems) verify_affixes("endings", endings) local function get_affix(affixes, i) if type(affixes) == "string" then return affixes elseif affixes.all_same then return affixes[1] else return affixes[i] end end for i, pnum in ipairs(pnums) do local prefix = get_affix(prefixes, i) local stem = get_affix(stems, i) local ending = get_affix(endings, i) local slot = tense .. "_" .. pnum add3(base, slot, prefix, stem, ending) end end -- Add to `base` the inflections for the tense indicated by `tense` (the prefix in the slot names, e.g. 'past' -- or 'juss_pass'), formed by combining the `prefixes`, `stems` and `endings`. This is a simple wrapper around -- inflect_tense_1() that applies to all tenses other than the imperative; see inflect_tense_1() for more -- information about the parameters. local function inflect_tense(base, tense, prefixes, stems, endings) inflect_tense_1(base, tense, prefixes, stems, endings, all_person_number_list) end -- Like inflect_tense() but for the imperative, which has only five parts instead of 13 and no prefixes. local function inflect_tense_imp(base, stems, endings) inflect_tense_1(base, "imp", "", stems, endings, imp_person_number_list) end ------------------------------------------------------------------------------- -- Functions to inflect the past tense -- ------------------------------------------------------------------------------- -- Generate past verbs using specified vowel and consonant stems; works for sound, assimilated, hollow, and geminate -- verbs, active and passive. local function past_2stem_conj(base, tense, v_stem, c_stem, footnote_12) local passive = tense:find("_pass") and "_pass" or "" -- Override stems with user-specified stems if available. v_stem = override_stem_if_needed(base, "past" .. passive .. "_v", v_stem) local c_stem_12 = c_stem if footnote_12 then c_stem_12 = iut.combine_form_and_footnotes(c_stem_12, footnote_12) end c_stem_12 = override_stem_if_needed(base, "past" .. passive .. "_c", c_stem_12) local c_stem_3 = override_stem_if_needed(base, "past" .. passive .. "_c", c_stem) inflect_tense(base, tense, "", { -- singular c_stem_12, c_stem_12, c_stem_12, v_stem, v_stem, --dual c_stem_12, v_stem, v_stem, -- plural c_stem_12, c_stem_12, c_stem_12, v_stem, c_stem_3 }, past_endings) end -- Generate past verbs using single specified stem; works for sound and assimilated verbs, active and passive. local function past_1stem_conj(base, tense, stem) past_2stem_conj(base, tense, stem, stem) end ------------------------------------------------------------------------------- -- Functions to inflect non-past tenses -- ------------------------------------------------------------------------------- -- Generate non-past conjugation, with two stems, for vowel-initial and consonant-initial endings, respectively. -- Useful for active and passive; for all forms; for all weaknesses (sound, assimilated, hollow, final-weak and -- geminate) and for all types of non-past (indicative, subjunctive, jussive) except for the imperative. (There is a -- separate wrapper function below for geminate jussives because they have three alternants.) Both stems may be the -- same, e.g. for sound verbs. -- `prefix_vowel` will be either "a" or "u". `endings` should be an array of 13 items. If `endings` is nil or -- omitted, infer the endings from the tense. If `jussive` is true, or `endings` is nil and `tense` indicatives -- jussive, use the jussive pattern of vowel/consonant stems (different from the normal ones). local function nonpast_2stem_conj(base, tense, prefix_vowel, v_stem, c_stem, endings, jussive) local passive = tense:find("_pass") and "_pass" or "" -- Override stems with user-specified stems if available. v_stem = override_stem_if_needed(base, "nonpast" .. passive .. "_v", v_stem and q(dia[prefix_vowel], v_stem) or nil) c_stem = override_stem_if_needed(base, "nonpast" .. passive .. "_c", c_stem and q(dia[prefix_vowel], c_stem) or nil) if not endings then if tense:find("^ind") then endings = ind_endings elseif tense:find("^sub") then endings = sub_endings elseif tense:find("^juss") then jussive = true endings = juss_endings else error("Internal error: Unrecognized tense '" .. tense .."'") end end if not jussive then inflect_tense(base, tense, nonpast_prefix_consonants, { -- singular v_stem, v_stem, v_stem, v_stem, v_stem, --dual v_stem, v_stem, v_stem, -- plural v_stem, v_stem, c_stem, v_stem, c_stem }, endings) else inflect_tense(base, tense, nonpast_prefix_consonants, { -- singular -- 'adlul, tadlul, tadullī, yadlul, tadlul c_stem, c_stem, v_stem, c_stem, c_stem, --dual -- tadullā, yadullā, tadullā v_stem, v_stem, v_stem, -- plural -- nadlul, tadullū, tadlulna, yadullū, yadlulna c_stem, v_stem, c_stem, v_stem, c_stem }, endings) end end -- Generate non-past conjugation with one stem (no distinct stems for vowel-initial and consonant-initial endings). -- See nonpast_2stem_conj(). local function nonpast_1stem_conj(base, tense, prefix_vowel, stem, endings, jussive) nonpast_2stem_conj(base, tense, prefix_vowel, stem, stem, endings, jussive) end -- Generate active/passive jussive geminative. There are three alternants, two with terminations -a and -i and one -- in a null termination with a distinct pattern of vowel/consonant stem usage. See nonpast_2stem_conj() for a -- description of the arguments. local function jussive_gem_conj(base, tense, prefix_vowel, v_stem, c_stem) -- alternative in -a nonpast_2stem_conj(base, tense, prefix_vowel, v_stem, c_stem, juss_endings_alt_a) -- alternative in -i nonpast_2stem_conj(base, tense, prefix_vowel, v_stem, c_stem, juss_endings_alt_i) -- alternative in -null; requires different combination of v_stem and -- c_stem since the null endings require the c_stem (e.g. "tadlul" here) -- whereas the corresponding endings above in -a or -i require the v_stem -- (e.g. "tadulla, tadulli" above) nonpast_2stem_conj(base, tense, prefix_vowel, v_stem, c_stem, juss_endings, "jussive") end ------------------------------------------------------------------------------- -- Functions to inflect the imperative -- ------------------------------------------------------------------------------- -- Generate imperative conjugation, with two stems, for vowel-initial and consonant-initial endings, respectively. -- Useful for all forms, and for all weaknesses other than final-weak. Note that the two stems may be the same -- (specifically for sound and assimilated verbs). If `endings` is nil or omitted, use `imp_endings`. If `alt_gem` -- is specified, use the pattern of vowel and consonant stems appropriate for the alternative geminate imperatives -- that use a null ending of -a or -i instead of an empty ending. local function make_2stem_imperative(base, v_stem, c_stem, endings, alt_gem) endings = endings or imp_endings -- Override stems with user-specified stems if available. v_stem = override_stem_if_needed(base, "imp_v", v_stem) c_stem = override_stem_if_needed(base, "imp_c", c_stem) if alt_gem then inflect_tense_imp(base, {v_stem, v_stem, v_stem, v_stem, c_stem}, endings) else inflect_tense_imp(base, {c_stem, v_stem, v_stem, v_stem, c_stem}, endings) end end -- Generate imperative parts for sound or assimilated verbs. local function make_1stem_imperative(base, stem) make_2stem_imperative(base, stem, stem) end -- Generate imperative parts for geminate verbs form I (also IV, VII, VIII, X). local function make_gem_imperative(base, v_stem, c_stem) make_2stem_imperative(base, v_stem, c_stem, imp_endings_alt_a, "alt gem") make_2stem_imperative(base, v_stem, c_stem, imp_endings_alt_i, "alt gem") make_2stem_imperative(base, v_stem, c_stem) end ------------------------------------------------------------------------------- -- Functions to inflect entire verbs -- ------------------------------------------------------------------------------- -- Generate finite parts of a sound verb (also works for assimilated verbs) from five stems (past and non-past, -- active and passive, plus imperative) plus the prefix vowel in the active non-past ("a" or "u"). local function make_sound_verb(base, past_stem, past_pass_stem, nonpast_stem, nonpast_pass_stem, imp_stem, prefix_vowel) past_1stem_conj(base, "past", past_stem) past_1stem_conj(base, "past_pass", past_pass_stem) nonpast_1stem_conj(base, "ind", prefix_vowel, nonpast_stem) nonpast_1stem_conj(base, "sub", prefix_vowel, nonpast_stem) nonpast_1stem_conj(base, "juss", prefix_vowel, nonpast_stem) nonpast_1stem_conj(base, "ind_pass", "u", nonpast_pass_stem) nonpast_1stem_conj(base, "sub_pass", "u", nonpast_pass_stem) nonpast_1stem_conj(base, "juss_pass", "u", nonpast_pass_stem) make_1stem_imperative(base, imp_stem) end local function past_final_weak_endings_from_vowel(vowel) if vowel == "ay" then return past_endings_ay elseif vowel == "aw" then return past_endings_aw elseif vowel == "ī" then return past_endings_ii elseif vowel == "ū" then return past_endings_uu elseif not vowel then return nil else error(("Internal error: Unrecognized past final-weak vowel spec '%s'"):format(vowel)) end end local function nonpast_final_weak_endings_from_vowel(vowel) if vowel == "ā" then return ind_endings_aa, sub_endings_aa, juss_endings_aa, imp_endings_aa elseif vowel == "ī" then return ind_endings_ii, sub_endings_ii, juss_endings_ii, imp_endings_ii elseif vowel == "ū" then return ind_endings_uu, sub_endings_uu, juss_endings_uu, imp_endings_uu elseif not vowel then return nil else error(("Internal error: Unrecognized non-past final-weak vowel spec '%s'"):format(vowel)) end end -- Generate finite parts of a final-weak verb from five stems (past and non-past, active and passive, plus -- imperative), the past active ending vowel (ay, aw, ī or ū), the non-past active ending vowel (ā, ī or ū) and the -- prefix vowel in the active non-past (a or u). local function make_final_weak_verb(base, past_stem, past_pass_stem, nonpast_stem, nonpast_pass_stem, imp_stem, past_ending_vowel, nonpast_ending_vowel, prefix_vowel) past_stem = override_stem_if_needed(base, "past", past_stem) past_pass_stem = override_stem_if_needed(base, "past_pass", past_pass_stem) -- Don't call override_stem_if_needed() here for non-past stems; it's called in nonpast_2stem_conj(). imp_stem = override_stem_if_needed(base, "imp", imp_stem) -- + not supported for ending vowel overrides past_ending_vowel = base.stem_overrides.past_final_weak_vowel or past_ending_vowel local past_pass_ending_vowel = base.stem_overrides.past_pass_final_weak_vowel or "ī" nonpast_ending_vowel = base.stem_overrides.nonpast_final_weak_vowel or nonpast_ending_vowel local nonpast_pass_ending_vowel = base.stem_overrides.nonpast_pass_final_weak_vowel or "ā" local past_endings = past_final_weak_endings_from_vowel(past_ending_vowel) local past_pass_endings = past_final_weak_endings_from_vowel(past_pass_ending_vowel) local ind_endings, sub_endings, juss_endings, imp_endings = nonpast_final_weak_endings_from_vowel(nonpast_ending_vowel) local ind_pass_endings, sub_pass_endings, juss_pass_endings = nonpast_final_weak_endings_from_vowel(nonpast_pass_ending_vowel) inflect_tense(base, "past", "", {past_stem, all_same = 1}, past_endings) inflect_tense(base, "past_pass", "", {past_pass_stem, all_same = 1}, past_pass_endings) nonpast_1stem_conj(base, "ind", prefix_vowel, nonpast_stem, ind_endings) nonpast_1stem_conj(base, "sub", prefix_vowel, nonpast_stem, sub_endings) nonpast_1stem_conj(base, "juss", prefix_vowel, nonpast_stem, juss_endings) nonpast_1stem_conj(base, "ind_pass", "u", nonpast_pass_stem, ind_pass_endings) nonpast_1stem_conj(base, "sub_pass", "u", nonpast_pass_stem, sub_pass_endings) nonpast_1stem_conj(base, "juss_pass", "u", nonpast_pass_stem, juss_pass_endings) inflect_tense_imp(base, {imp_stem, all_same = 1}, imp_endings) end -- Generate finite parts of an augmented (form II+) final-weak verb from five stems (past and non-past, active and -- passive, plus imperative) plus the prefix vowel in the active non-past ("a" or "u") and a flag indicating if it -- behaves like a form V/VI verb in taking non-past endings in -ā instead of -ī. local function make_augmented_final_weak_verb(base, past_stem, past_pass_stem, nonpast_stem, nonpast_pass_stem, imp_stem, prefix_vowel, form56) make_final_weak_verb(base, past_stem, past_pass_stem, nonpast_stem, nonpast_pass_stem, imp_stem, "ay", form56 and "ā" or "ī", prefix_vowel) end -- Generate finite parts of an augmented (form II+) sound or final-weak verb, given: -- * `base` (conjugation data structure); -- * `vowel_spec` (radicals, weakness); -- * `past_stem_base` (active past stem minus last syllable (= -al or -ā)); -- * `nonpast_stem_base` (non-past stem minus last syllable (= -al/-il or -ā/-ī); -- * `past_pass_stem_base` (passive past stem minus last syllable (= -il or -ī)); -- * `vn` (verbal noun). local function make_augmented_sound_final_weak_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) insert_form_or_forms(base, "vn", vn) local lastrad = base.quadlit and vowel_spec.rad4 or vowel_spec.rad3 local final_weak = is_final_weak(base, vowel_spec) local prefix_vowel = prefix_vowel_from_vform(base.verb_form) local form56 = vform_nonpast_a_vowel(base.verb_form) local a_base_suffix = final_weak and "" or q(A, lastrad) local i_base_suffix = final_weak and "" or q(I, lastrad) -- past and non-past stems, active and passive local past_stem = q(past_stem_base, a_base_suffix) -- In forms 5 and 6, non-past has /a/ as last stem vowel in the non-past -- in both active and passive, but /i/ in the active participle and /a/ -- in the passive participle. Elsewhere, consistent /i/ in active non-past -- and participle, consistent /a/ in passive non-past and participle. -- Hence, forms 5 and 6 differ only in the non-past active (but not -- active participle), so we have to split the finite non-past stem and -- active participle stem. local nonpast_stem = q(nonpast_stem_base, form56 and a_base_suffix or i_base_suffix) local ap_stem = q(nonpast_stem_base, i_base_suffix) local past_pass_stem = q(past_pass_stem_base, i_base_suffix) local nonpast_pass_stem = q(nonpast_stem_base, a_base_suffix) -- imperative stem local imp_stem = q(past_stem_base, form56 and a_base_suffix or i_base_suffix) -- make parts if final_weak then make_augmented_final_weak_verb(base, past_stem, past_pass_stem, nonpast_stem, nonpast_pass_stem, imp_stem, prefix_vowel, form56) else make_sound_verb(base, past_stem, past_pass_stem, nonpast_stem, nonpast_pass_stem, imp_stem, prefix_vowel) end -- active and passive participle if final_weak then insert_form_or_forms(base, "ap", q(MU, ap_stem, IN)) insert_form_or_forms(base, "pp", q(MU, nonpast_pass_stem, AN, AMAQ)) else insert_form_or_forms(base, "ap", q(MU, ap_stem)) insert_form_or_forms(base, "pp", q(MU, nonpast_pass_stem)) end end -- Generate finite parts of a hollow or geminate verb from ten stems (vowel and consonant stems for each of past and -- non-past, active and passive, plus imperative) plus the prefix vowel in the active non-past ("a" or "u"), plus a -- flag indicating if we are a geminate verb. local function make_hollow_geminate_verb(base, geminate, past_v_stem, past_c_stem, past_pass_v_stem, past_pass_c_stem, nonpast_v_stem, nonpast_c_stem, nonpast_pass_v_stem, nonpast_pass_c_stem, imp_v_stem, imp_c_stem, prefix_vowel, altgem_note) past_2stem_conj(base, "past", past_v_stem, past_c_stem, altgem_note) past_2stem_conj(base, "past_pass", past_pass_v_stem, past_pass_c_stem) nonpast_2stem_conj(base, "ind", prefix_vowel, nonpast_v_stem, nonpast_c_stem) nonpast_2stem_conj(base, "sub", prefix_vowel, nonpast_v_stem, nonpast_c_stem) nonpast_2stem_conj(base, "ind_pass", "u", nonpast_pass_v_stem, nonpast_pass_c_stem) nonpast_2stem_conj(base, "sub_pass", "u", nonpast_pass_v_stem, nonpast_pass_c_stem) if geminate then jussive_gem_conj(base, "juss", prefix_vowel, nonpast_v_stem, nonpast_c_stem) jussive_gem_conj(base, "juss_pass", "u", nonpast_pass_v_stem, nonpast_pass_c_stem) make_gem_imperative(base, imp_v_stem, imp_c_stem) else nonpast_2stem_conj(base, "juss", prefix_vowel, nonpast_v_stem, nonpast_c_stem) nonpast_2stem_conj(base, "juss_pass", "u", nonpast_pass_v_stem, nonpast_pass_c_stem) make_2stem_imperative(base, imp_v_stem, imp_c_stem) end end -- Generate finite parts of an augmented (form II+) hollow verb, given: -- * `base` (conjugation data structure); -- * `vowel_spec` (radicals, weakness); -- * `past_stem_base` (invariable part of active past stem); -- * `nonpast_stem_base` (invariable part of nonpast stem); -- * `past_pass_stem_base` (invariable part of passive past stem); -- * `vn` (verbal noun). local function make_augmented_hollow_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) insert_form_or_forms(base, "vn", vn) local lastrad = base.quadlit and vowel_spec.rad4 or vowel_spec.rad3 local form410 = base.verb_form == "IV" or base.verb_form == "X" local prefix_vowel = prefix_vowel_from_vform(base.verb_form) local a_base_suffix_v, a_base_suffix_c local i_base_suffix_v, i_base_suffix_c a_base_suffix_v = q(AA, lastrad) -- 'af-āl-a, inf-āl-a a_base_suffix_c = q(A, lastrad) -- 'af-al-tu, inf-al-tu i_base_suffix_v = q(II, lastrad) -- 'uf-īl-a, unf-īl-a i_base_suffix_c = q(I, lastrad) -- 'uf-il-tu, unf-il-tu -- past and non-past stems, active and passive, for vowel-initial and -- consonant-initial endings local past_v_stem = q(past_stem_base, a_base_suffix_v) local past_c_stem = q(past_stem_base, a_base_suffix_c) -- yu-f-īl-u, ya-staf-īl-u but yanf-āl-u, yaft-āl-u local nonpast_v_stem = q(nonpast_stem_base, form410 and i_base_suffix_v or a_base_suffix_v) local nonpast_c_stem = q(nonpast_stem_base, form410 and i_base_suffix_c or a_base_suffix_c) local past_pass_v_stem = q(past_pass_stem_base, i_base_suffix_v) local past_pass_c_stem = q(past_pass_stem_base, i_base_suffix_c) local nonpast_pass_v_stem = q(nonpast_stem_base, a_base_suffix_v) local nonpast_pass_c_stem = q(nonpast_stem_base, a_base_suffix_c) -- imperative stem local imp_v_stem = q(past_stem_base, form410 and i_base_suffix_v or a_base_suffix_v) local imp_c_stem = q(past_stem_base, form410 and i_base_suffix_c or a_base_suffix_c) -- make parts make_hollow_geminate_verb(base, false, past_v_stem, past_c_stem, past_pass_v_stem, past_pass_c_stem, nonpast_v_stem, nonpast_c_stem, nonpast_pass_v_stem, nonpast_pass_c_stem, imp_v_stem, imp_c_stem, prefix_vowel) -- active participle insert_form_or_forms(base, "ap", q(MU, nonpast_v_stem)) -- passive participle insert_form_or_forms(base, "pp", q(MU, nonpast_pass_v_stem)) end -- Generate finite parts of an augmented (form II+) geminate verb, given: -- * `base` (conjugation data structure); -- * `vowel_spec` (radicals, weakness); -- * `past_stem_base` (invariable part of active past stem; this and the stem bases below will end with a consonant -- for forms IV, X, IVq, and a short vowel for the others); -- * `nonpast_stem_base` (invariable part of nonpast stem); -- * `past_pass_stem_base` (invariable part of passive past stem); -- * `vn` (verbal noun); -- * `altgem_note` (footnote to add to active past 1/2-person forms, when alternative forms are supplied [form X]). local function make_augmented_geminate_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn, altgem_note) insert_form_or_forms(base, "vn", vn) local vform = base.verb_form local lastrad = base.quadlit and vowel_spec.rad4 or vowel_spec.rad3 local prefix_vowel = prefix_vowel_from_vform(vform) local a_base_suffix_v, a_base_suffix_c local i_base_suffix_v, i_base_suffix_c if vform == "IV" or vform == "X" or vform == "IVq" then a_base_suffix_v = q(A, lastrad, SH) -- 'af-all a_base_suffix_c = q(SK, lastrad, A, lastrad) -- 'af-lal i_base_suffix_v = q(I, lastrad, SH) -- yuf-ill i_base_suffix_c = q(SK, lastrad, I, lastrad) -- yuf-lil else a_base_suffix_v = q(lastrad, SH) -- fā-ll, infa-ll a_base_suffix_c = q(lastrad, A, lastrad) -- fā-lal, infa-lal i_base_suffix_v = q(lastrad, SH) -- yufā-ll, yanfa-ll i_base_suffix_c = q(lastrad, I, lastrad) -- yufā-lil, yanfa-lil end -- past and non-past stems, active and passive, for vowel-initial and -- consonant-initial endings local past_v_stem = q(past_stem_base, a_base_suffix_v) local past_c_stem = q(past_stem_base, a_base_suffix_c) local nonpast_v_stem = q(nonpast_stem_base, vform_nonpast_a_vowel(vform) and a_base_suffix_v or i_base_suffix_v) local nonpast_c_stem = q(nonpast_stem_base, vform_nonpast_a_vowel(vform) and a_base_suffix_c or i_base_suffix_c) -- NOTE: Formerly had a comment that "vform III and VI passive past do not have contracted parts, only -- uncontracted parts, which are added separately by those functions". This is based on Mace -- "Arabic Verbs and Essential Grammar" (1999) entry 63 (continued), which shows passive ḥūjija but no ḥūjja; -- but that is apparently a mistake, as (1) verb tables in other books do show contracted passive parts for -- these forms; (2) there is no mention of such an exception on p. 99, which explains how geminate ("doubled") -- verbs work (on the contrary, it says "The contracted and uncontracted pairs (see above) are found all -- over Forms III and VI of the doubled verbs"). local past_pass_v_stem = q(past_pass_stem_base, i_base_suffix_v) local past_pass_c_stem = q(past_pass_stem_base, i_base_suffix_c) local nonpast_pass_v_stem = q(nonpast_stem_base, a_base_suffix_v) local nonpast_pass_c_stem = q(nonpast_stem_base, a_base_suffix_c) -- imperative stem local imp_v_stem = q(past_stem_base, vform_nonpast_a_vowel(vform) and a_base_suffix_v or i_base_suffix_v) local imp_c_stem = q(past_stem_base, vform_nonpast_a_vowel(vform) and a_base_suffix_c or i_base_suffix_c) -- make parts make_hollow_geminate_verb(base, "geminate", past_v_stem, past_c_stem, past_pass_v_stem, past_pass_c_stem, nonpast_v_stem, nonpast_c_stem, nonpast_pass_v_stem, nonpast_pass_c_stem, imp_v_stem, imp_c_stem, prefix_vowel, altgem_note) -- active participle insert_form_or_forms(base, "ap", q(MU, nonpast_v_stem)) -- passive participle insert_form_or_forms(base, "pp", q(MU, nonpast_pass_v_stem)) end ------------------------------------------------------------------------------- -- Conjugation functions for specific conjugation types -- ------------------------------------------------------------------------------- local function form_i_imp_stem_through_rad1(base, nonpast_vowel, rad1) local imp_vowel = map_vowel(nonpast_vowel, function(vow) if vow == A or vow == I then return I elseif vow == U then return U elseif not skip_slot(base, "imp_2ms") then error(("Internal error: Non-past vowel %s isn't a, i, or u, should have been caught earlier"):format( dump(nonpast_vowel))) else -- Passive-only; imperative won't ever be displayed so it doesn't matter. return I end end) -- Mace ("Arabic Verbs and Essentials of Grammar" p. 63: [https://archive.org/details/arabicverbsessen00john/page/62/mode/2up]) -- claims that initial hamza is assimilated/elided into a long vowel in the form-I imperative, but apparently -- this isn't corrrect. local vowel_on_alif = map_vowel(imp_vowel, function(vow) return ALIF .. vow end) return q(vowel_on_alif, rad1, SK) end -- Implement form-I sound or assimilated verb. ASSIMILATED is true for assimilated verbs. local function make_form_i_sound_assimilated_verb(base, vowel_spec, assimilated) local rad1, rad2, rad3, past_vowel, nonpast_vowel = get_radicals_3(vowel_spec) -- Verbal nouns (maṣādir) for form I are unpredictable and have to be supplied -- past and non-past stems, active and passive local past_stem = q(rad1, A, rad2, past_vowel, rad3) local nonpast_stem = assimilated and q(rad2, nonpast_vowel, rad3) or q(rad1, SK, rad2, nonpast_vowel, rad3) local past_pass_stem = q(rad1, U, rad2, I, rad3) local nonpast_pass_stem = q(rad1, SK, rad2, A, rad3) -- imperative stem -- check for irregular verb with reduced imperative (أَخَذَ or أَكَلَ or أَمَرَ) local reducedimp = reduced_imperative_verb(rad1, rad2, rad3) if reducedimp then base.irregular = true end local imp_stem_suffix = q(rad2, nonpast_vowel, rad3) local long_imp_stem_base = form_i_imp_stem_through_rad1(base, nonpast_vowel, rad1) local short_imp_stem_base = "" local imp_stem = q((assimilated or reducedimp) and "" or long_imp_stem_base, imp_stem_suffix) -- make parts make_sound_verb(base, past_stem, past_pass_stem, nonpast_stem, nonpast_pass_stem, imp_stem, "a") if reducedimp == "shortlong" then make_1stem_imperative(base, iut.combine_form_and_footnotes(q(long_imp_stem_base, imp_stem_suffix), mw.getCurrentFrame():preprocess("[used especially with a clitic such as {{m|ar|فَ}} or {{m|ar|وَ}}]"))) end -- Check for irregular verb سَأَلَ with alternative jussive and imperative. Calling this after make_sound_verb() -- adds additional entries to the paradigm parts. if saal_radicals(rad1, rad2, rad3) then base.irregular = true nonpast_1stem_conj(base, "juss", "a", "سَل") nonpast_1stem_conj(base, "juss_pass", "u", "سَل") make_1stem_imperative(base, "سَل") end -- Active participle. insert_form_or_forms(base, "ap1", q(rad1, AA, rad2, I, rad3)) -- Insert alternative active participle (stative type I) فَعِيل. Since not all verbs have this, we require that -- verbs that do have it specify it explicitly; a shortcut ++ is provided to make this easier (e.g. <ap:++> to -- indicate that the alternative form should be used for the active participle, <ap:+,++> to indicate that both -- forms can be used, and <ap:-> to indicate that there is no active participle). The same form is used for -- secondary default passive participle. insert_ap2_pp2(base, q(rad1, A, rad2, II, rad3)) -- Active participle, stative type II فَعِل (+++). insert_form_or_forms(base, "ap3", q(rad1, A, rad2, I, rad3)) -- Active participle, color/defect أَفْعَل (+cd). insert_form_or_forms(base, "apcd", q(HAMZA, A, rad1, SK, rad2, A, rad3)) -- Active participle, -ān فَعْلَان (+an). insert_form_or_forms(base, "apan", q(rad1, A, rad2, SK, rad3, AAN)) -- Passive participle. insert_form_or_forms(base, "pp", q(MA, rad1, SK, rad2, UU, rad3)) end conjugations["I-sound"] = function(base, vowel_spec) make_form_i_sound_assimilated_verb(base, vowel_spec, false) end conjugations["none-sound"] = function(base, vowel_spec) -- All default stems are nil. make_sound_verb(base) end conjugations["none-hollow"] = function(base, vowel_spec) -- All default stems are nil. make_hollow_geminate_verb(base, false) end conjugations["none-geminate"] = function(base, vowel_spec) -- All default stems are nil. make_hollow_geminate_verb(base, "geminate") end conjugations["none-final-weak"] = function(base, vowel_spec) -- All default stems are nil. make_final_weak_verb(base) end conjugations["I-assimilated"] = function(base, vowel_spec) make_form_i_sound_assimilated_verb(base, vowel_spec, "assimilated") end local function make_form_i_hayy_verb(base, vowel_spec) -- Verbal nouns (maṣādir) for form I are unpredictable and have to be supplied base.irregular = true -- past and non-past stems, active and passive, and imperative stem local past_c_stem = "حَيِي" local past_v_stem_long = past_c_stem local past_v_stem_short = "حَيّ" local past_pass_c_stem = "حُيِي" local past_pass_v_stem_long = past_pass_c_stem local past_pass_v_stem_short = "حُيّ" local nonpast_stem = "حْي" local nonpast_pass_stem = nonpast_stem local imp_stem = _I .. nonpast_stem -- make parts past_2stem_conj(base, "past", {}, past_c_stem) past_2stem_conj(base, "past_pass", {}, past_pass_c_stem) local variant = vowel_spec.variant or "both" if variant == "short" or variant == "both" then past_2stem_conj(base, "past", past_v_stem_short, {}) past_2stem_conj(base, "past_pass", past_pass_v_stem_short, {}) end function inflect_long_variant(tense, long_stem, short_stem) inflect_tense_1(base, tense, "", {long_stem, long_stem, long_stem, long_stem, short_stem}, {past_endings[4], past_endings[5], past_endings[7], past_endings[8], past_endings[12]}, {"3ms", "3fs", "3md", "3fd", "3mp"}) end if variant == "long" or variant == "both" then inflect_long_variant("past", past_v_stem_long, past_v_stem_short) inflect_long_variant("past_pass", past_pass_v_stem_long, past_pass_v_stem_short) end nonpast_1stem_conj(base, "ind", "a", nonpast_stem, ind_endings_aa) nonpast_1stem_conj(base, "sub", "a", nonpast_stem, sub_endings_aa) nonpast_1stem_conj(base, "juss", "a", nonpast_stem, juss_endings_aa) nonpast_1stem_conj(base, "ind_pass", "u", nonpast_pass_stem, ind_endings_aa) nonpast_1stem_conj(base, "sub_pass", "u", nonpast_pass_stem, sub_endings_aa) nonpast_1stem_conj(base, "juss_pass", "u", nonpast_pass_stem, juss_endings_aa) inflect_tense_imp(base, {imp_stem, all_same = 1}, imp_endings_aa) -- active and passive participles apparently do not exist for this verb end -- Implement form-I final-weak assimilated+final-weak verb. ASSIMILATED is true for assimilated verbs. local function make_form_i_final_weak_verb(base, vowel_spec, assimilated) local rad1, rad2, rad3, past_vowel, nonpast_vowel = get_radicals_3(vowel_spec) -- حَيَّ or حَيِيَ is weird enough that we handle it as a separate function. if hayy_radicals(rad1, rad2, rad3) then make_form_i_hayy_verb(base, vowel_spec) return end -- Verbal nouns (maṣādir) for form I are unpredictable and have to be supplied. -- Past and non-past stems, active and passive, and imperative stem. local past_stem = q(rad1, A, rad2) local past_pass_stem = q(rad1, U, rad2) local nonpast_stem, nonpast_pass_stem, imp_stem if raa_radicals(rad1, rad2, rad3) then base.irregular = true nonpast_stem = rad1 nonpast_pass_stem = rad1 imp_stem = rad1 else nonpast_pass_stem = q(rad1, SK, rad2) if assimilated then nonpast_stem = rad2 imp_stem = rad2 else nonpast_stem = nonpast_pass_stem imp_stem = q(form_i_imp_stem_through_rad1(base, nonpast_vowel, rad1), rad2) end end -- Make parts. local past_ending_vowel = req(rad3, Y) and req(past_vowel, A) and "ay" or req(rad3, W) and req(past_vowel, A) and "aw" or req(past_vowel, I) and "ī" or "ū" -- Try to preserve footnotes attached to the third radical and/or past and/or non-past vowels. local past_footnotes = iut.combine_footnotes(rget_footnotes(rad3), rget_footnotes(past_vowel)) local nonpast_ending_vowel = req(nonpast_vowel, A) and "ā" or req(nonpast_vowel, I) and "ī" or "ū" local nonpast_footnotes = iut.combine_footnotes(rget_footnotes(rad3), rget_footnotes(nonpast_vowel)) make_final_weak_verb(base, iut.combine_form_and_footnotes(past_stem, past_footnotes), iut.combine_form_and_footnotes(past_pass_stem, past_footnotes), iut.combine_form_and_footnotes(nonpast_stem, nonpast_footnotes), iut.combine_form_and_footnotes(nonpast_pass_stem, nonpast_footnotes), iut.combine_form_and_footnotes(imp_stem, nonpast_footnotes), past_ending_vowel, nonpast_ending_vowel, "a") -- Active participle. insert_form_or_forms(base, "ap1", q(rad1, AA, rad2, IN)) -- Active participle, stative type I فَعِيّ (++). FIXME: Is this correct when rad3 is W? insert_ap2_pp2(base, q(rad1, A, rad2, II, SH)) -- Active participle, stative type II فَعٍ (+++). FIXME: Any examples of this to verify it's correct? insert_form_or_forms(base, "ap3", q(rad1, A, rad2, IN)) -- Active participle, color/defect أَفْعَى (+cd). insert_form_or_forms(base, "apcd", q(HAMZA, A, rad1, SK, rad2, AAMAQ)) -- Active participle, -ān فَعْيَان or فَعْوَان (+an). -- FIXME: Any examples of this for both rad3 = W and y to verify it's correct? insert_form_or_forms(base, "apan", q(rad1, A, rad2, SK, rad3, AAN)) -- Passive participle. insert_form_or_forms(base, "pp", q(MA, rad1, SK, rad2, req(rad3, Y) and II or UU, SH)) end conjugations["I-final-weak"] = function(base, vowel_spec) make_form_i_final_weak_verb(base, vowel_spec, false) end conjugations["I-assimilated+final-weak"] = function(base, vowel_spec) make_form_i_final_weak_verb(base, vowel_spec, "assimilated") end conjugations["I-hollow"] = function(base, vowel_spec) local rad1, rad2, rad3, past_vowel, nonpast_vowel = get_radicals_3(vowel_spec) -- In some sense, hollow vowels i~i and u~u are more "correct" than a~i and a~u, but the latter follow the -- pattern of other form-I verbs, so we map i~i to a~i and u~u to a~u in infer_radicals(). Now however we have -- to undo this to get the actual past vowel based on the non-past vowel. if req(past_vowel, A) then past_vowel = map_vowel(past_vowel, function(vow) return req(nonpast_vowel, A) and I or rget(nonpast_vowel) end) end local lengthened_nonpast = map_vowel(nonpast_vowel, function(vow) return vow == U and UU or vow == I and II or AA end) -- Verbal nouns (maṣādir) for form I are unpredictable and have to be supplied. -- active past stems - vowel (v) and consonant (c) local past_v_stem = q(rad1, AA, rad3) local past_c_stem = q(rad1, past_vowel, rad3) -- active non-past stems - vowel (v) and consonant (c) local nonpast_v_stem = q(rad1, lengthened_nonpast, rad3) local nonpast_c_stem = q(rad1, nonpast_vowel, rad3) -- passive past stems - vowel (v) and consonant (c) -- 'ufīla, 'ufiltu local past_pass_v_stem = q(rad1, II, rad3) local past_pass_c_stem = q(rad1, I, rad3) -- passive non-past stems - vowel (v) and consonant (c) -- yufāla/yufalna -- stem is built differently but conjugation is identical to sound verbs local nonpast_pass_v_stem = q(rad1, AA, rad3) local nonpast_pass_c_stem = q(rad1, A, rad3) -- imperative stem local imp_v_stem = nonpast_v_stem local imp_c_stem = nonpast_c_stem -- make parts make_hollow_geminate_verb(base, false, past_v_stem, past_c_stem, past_pass_v_stem, past_pass_c_stem, nonpast_v_stem, nonpast_c_stem, nonpast_pass_v_stem, nonpast_pass_c_stem, imp_v_stem, imp_c_stem, "a") if kaan_radicals(rad1, rad2, rad3) then local endings = make_nonpast_endings(U, {}, {}, {}, {}) inflect_tense(base, "juss", nonpast_prefix_consonants, q(A, rad1), endings) base.irregular = true end -- Active participle. insert_form_or_forms(base, "ap1", req(rad3, HAMZA) and q(rad1, AA, HAMZA, IN) or q(rad1, AA, HAMZA, I, rad3)) -- Active participle, stative type I فَيِّد (++). FIXME: Any examples of this to verify it's correct? insert_ap2_pp2(base, q(rad1, A, Y, SH, I, rad3)) -- Active participle, stative type II فَيِد (+++). FIXME: Any examples of this to verify it's correct? insert_form_or_forms(base, "ap3", q(rad1, A, Y, I, rad3)) -- Active participle, color/defect أَفّيَد or أَفّوَد (+cd). FIXME: Any examples of this to verify it's correct? insert_form_or_forms(base, "apcd", q(HAMZA, A, rad1, SK, rad2, A, rad3)) -- Active participle, -ān فَيْدَان or فَوْدَان (+an). Example: جَاعَ "to be hungry", act part جَوْعَان insert_form_or_forms(base, "apan", q(rad1, A, rad2, SK, rad3, AAN)) -- Passive participle. insert_form_or_forms(base, "pp", q(MA, rad1, req(rad2, Y) and II or UU, rad3)) end conjugations["I-geminate"] = function(base, vowel_spec) local rad1, rad2, rad3, past_vowel, nonpast_vowel = get_radicals_3(vowel_spec) -- Verbal nouns (maṣādir) for form I are unpredictable and have to be supplied. -- active past stems - vowel (v) and consonant (c) local past_v_stem = q(rad1, A, rad2, SH) local past_c_stem = q(rad1, A, rad2, past_vowel, rad2) -- active non-past stems - vowel (v) and consonant (c) local nonpast_v_stem = q(rad1, nonpast_vowel, rad2, SH) local nonpast_c_stem = q(rad1, SK, rad2, nonpast_vowel, rad2) -- passive past stems - vowel (v) and consonant (c) -- dulla/dulilta local past_pass_v_stem = q(rad1, U, rad2, SH) local past_pass_c_stem = q(rad1, U, rad2, I, rad2) -- passive non-past stems - vowel (v) and consonant (c) --yudallu/yudlalna -- stem is built differently but conjugation is identical to sound verbs local nonpast_pass_v_stem = q(rad1, A, rad2, SH) local nonpast_pass_c_stem = q(rad1, SK, rad2, A, rad2) -- imperative stem local imp_v_stem = q(rad1, nonpast_vowel, rad2, SH) local imp_c_stem = q(form_i_imp_stem_through_rad1(base, nonpast_vowel, rad1), rad2, nonpast_vowel, rad2) -- make parts make_hollow_geminate_verb(base, "geminate", past_v_stem, past_c_stem, past_pass_v_stem, past_pass_c_stem, nonpast_v_stem, nonpast_c_stem, nonpast_pass_v_stem, nonpast_pass_c_stem, imp_v_stem, imp_c_stem, "a") -- Active participle. insert_form_or_forms(base, "ap1", q(rad1, AA, rad2, SH)) -- Active participle, stative type I فَعِيع (++). FIXME: Any examples of this to verify it's correct? insert_ap2_pp2(base, q(rad1, A, rad2, II, rad2)) -- Active participle, stative type II فَعّ (+++). Example: بَرَّ "to be pious", active participle بَرّ insert_form_or_forms(base, "ap3", q(rad1, A, rad2, SH)) -- Active participle, color/defect أَفَعّ (+cd). -- Example: لَصَّ "to be thievish, to steal repeatedly", active participle أَلَصّ. insert_form_or_forms(base, "apcd", q(HAMZA, A, rad1, A, rad2, SH)) -- Active participle, -ān فَعَّان (+an). FIXME: Any examples of this to verify it's correct? insert_form_or_forms(base, "apan", q(rad1, A, rad2, SH, AAN)) -- Passive participle. insert_form_or_forms(base, "pp", q(MA, rad1, SK, rad2, UU, rad2)) end -- Return the ta- (active, past and non-past) and tu- (passive past) prefixes for a form II/III/V/VI verb. -- Form V and VI verbs normally use ta- and tu-, but reduced (base.reduced) verbs use different prefixes. Form II -- and III verbs have no prefix. local function form_ii_iii_v_vi_ta_tu_prefix(base, rad1) local vform = base.verb_form if vform == "V" or vform == "VI" then if base.reduced then -- To simplify the code, we generate two rad1's with a sukūn between them, which is cleaned up in -- postprocessing. return q(_I, rad1, SK), q(rad1, SK), q(_U, rad1, SK) else return TA, TA, TU end else return "", "", "" end end -- Make form II or V sound or final-weak verb. local function make_form_ii_v_sound_final_weak_verb(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) local final_weak = is_final_weak(base, vowel_spec) local vform = base.verb_form local ta_past_prefix, ta_nonpast_prefix, tu_past_prefix = form_ii_iii_v_vi_ta_tu_prefix(base, rad1) local vn = vform == "V" and q(ta_past_prefix, rad1, A, rad2, SH, final_weak and IN or q(U, rad3)) or q(TA, rad1, SK, rad2, II, final_weak and AH or rad3) -- various stem bases local past_stem_base = q(ta_past_prefix, rad1, A, rad2, SH) local nonpast_stem_base = q(ta_nonpast_prefix, rad1, A, rad2, SH) local past_pass_stem_base = q(tu_past_prefix, rad1, U, rad2, SH) -- make parts make_augmented_sound_final_weak_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) end conjugations["II-sound"] = function(base, vowel_spec) make_form_ii_v_sound_final_weak_verb(base, vowel_spec) end conjugations["II-final-weak"] = function(base, vowel_spec) make_form_ii_v_sound_final_weak_verb(base, vowel_spec) end local function make_form_iii_alt_vn(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) local final_weak = is_final_weak(base, vowel_spec) -- Insert alternative verbal noun فِعَال. Since not all verbs have this, we require that verbs that do have it -- specify it explicitly; a shortcut ++ is provided to make this easier (e.g. <vn:+,++> to indicate that -- both the normal verbal noun مُفَاعَلَة and secondary verbal noun فِعَال are available). insert_form_or_forms(base, "vn2", q(rad1, I, rad2, AA, final_weak and HAMZA or rad3)) end -- Make form III or VI sound or final-weak verb. local function make_form_iii_vi_sound_final_weak_verb(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) local final_weak = is_final_weak(base, vowel_spec) local vform = base.verb_form local ta_past_prefix, ta_nonpast_prefix, tu_past_prefix = form_ii_iii_v_vi_ta_tu_prefix(base, rad1) local vn = vform == "VI" and q(ta_past_prefix, rad1, AA, rad2, final_weak and IN or q(U, rad3)) or q(MU, rad1, AA, rad2, final_weak and AAH or q(A, rad3, AH)) -- various stem bases local past_stem_base = q(ta_past_prefix, rad1, AA, rad2) local nonpast_stem_base = q(ta_nonpast_prefix, rad1, AA, rad2) local past_pass_stem_base = q(tu_past_prefix, rad1, UU, rad2) -- make parts make_augmented_sound_final_weak_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) if vform == "III" then make_form_iii_alt_vn(base, vowel_spec) end end conjugations["III-sound"] = function(base, vowel_spec) make_form_iii_vi_sound_final_weak_verb(base, vowel_spec) end conjugations["III-final-weak"] = function(base, vowel_spec) make_form_iii_vi_sound_final_weak_verb(base, vowel_spec) end -- Make form III or VI geminate verb. local function make_form_iii_vi_geminate_verb(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) local vform = base.verb_form local ta_past_prefix, ta_nonpast_prefix, tu_past_prefix = form_ii_iii_v_vi_ta_tu_prefix(base, rad1) -- Alternative verbal noun فِعَال will be inserted when we add sound parts below. local vn = vform == "VI" and q(ta_past_prefix, rad1, AA, rad2, SH) or q(MU, rad1, AA, rad2, SH, AH) -- Various stem bases. local past_stem_base = q(ta_past_prefix, rad1, AA) local nonpast_stem_base = q(ta_nonpast_prefix, rad1, AA) local past_pass_stem_base = q(tu_past_prefix, rad1, UU) -- Make parts. local variant = vowel_spec.variant or "short" if variant == "short" or variant == "both" then make_augmented_geminate_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) end -- Also add alternative sound (non-compressed) parts. This will lead to some duplicate entries, but they are -- removed during addition. if variant == "long" or variant == "both" then make_form_iii_vi_sound_final_weak_verb(base, vowel_spec) elseif vform == "III" then -- Still need to add the alternative form-III verbal noun. make_form_iii_alt_vn(base, vowel_spec) end end conjugations["III-geminate"] = function(base, vowel_spec) make_form_iii_vi_geminate_verb(base, vowel_spec) end -- Make form IV sound or final-weak verb. local function make_form_iv_sound_final_weak_verb(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) local final_weak = is_final_weak(base, vowel_spec) -- core of stem base, minus stem prefixes local stem_core -- check for irregular verb أَرَى local is_raa = raa_radicals(rad1, rad2, rad3) if is_raa then base.irregular = true stem_core = rad1 else stem_core = q(rad1, SK, rad2) end -- verbal noun local vn = is_raa and q(HAMZA, I, stem_core, AA, HAMZA, AH) or q(HAMZA, I, stem_core, AA, final_weak and HAMZA or rad3) -- various stem bases local past_stem_base = q(HAMZA, A, stem_core) local nonpast_stem_base = stem_core local past_pass_stem_base = q(HAMZA, U, stem_core) -- make parts make_augmented_sound_final_weak_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) end conjugations["IV-sound"] = function(base, vowel_spec) make_form_iv_sound_final_weak_verb(base, vowel_spec) end conjugations["IV-final-weak"] = function(base, vowel_spec) make_form_iv_sound_final_weak_verb(base, vowel_spec) end conjugations["IV-hollow"] = function(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) -- verbal noun local vn = q(HAMZA, I, rad1, AA, rad3, AH) -- various stem bases local past_stem_base = q(HAMZA, A, rad1) local nonpast_stem_base = rad1 local past_pass_stem_base = q(HAMZA, U, rad1) -- make parts make_augmented_hollow_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) end conjugations["IV-geminate"] = function(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) local vn = q(HAMZA, I, rad1, SK, rad2, AA, rad2) -- various stem bases local past_stem_base = q(HAMZA, A, rad1) local nonpast_stem_base = rad1 local past_pass_stem_base = q(HAMZA, U, rad1) -- make parts make_augmented_geminate_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) end conjugations["V-sound"] = function(base, vowel_spec) make_form_ii_v_sound_final_weak_verb(base, vowel_spec) end conjugations["V-final-weak"] = function(base, vowel_spec) make_form_ii_v_sound_final_weak_verb(base, vowel_spec) end conjugations["VI-sound"] = function(base, vowel_spec) make_form_iii_vi_sound_final_weak_verb(base, vowel_spec) end conjugations["VI-final-weak"] = function(base, vowel_spec) make_form_iii_vi_sound_final_weak_verb(base, vowel_spec) end conjugations["VI-geminate"] = function(base, vowel_spec) make_form_iii_vi_geminate_verb(base, vowel_spec) end -- Make a verbal noun of the general form that applies to forms VII and above. RAD12 is the first consonant cluster -- (after initial اِ) and RAD34 is the second consonant cluster. RAD5 is the final consonant. local function high_form_verbal_noun(rad12, rad34, rad5) return q(_I, rad12, I, rad34, AA, rad5) end -- Populate a sound or final-weak verb for any of the various high-numbered augmented forms (form VII and up) that -- have up to 5 consonants in two clusters in the stem and the same pattern of vowels between. Some of these -- consonants in certain verb parts are w's, which leads to apparent anomalies in certain stems of these parts, but -- these anomalies are handled automatically in postprocessing, where we resolve sequences of iwC -> īC, uwC -> ūC, -- w + sukūn + w -> w + shadda. -- RAD12 is the first consonant cluster (after initial اِ) and RAD34 is the second consonant cluster. RAD5 is the -- final consonant. local function make_high_form_sound_final_weak_verb(base, vowel_spec, rad12, rad34, rad5) local final_weak = is_final_weak(base, vowel_spec) local vn = high_form_verbal_noun(rad12, rad34, final_weak and HAMZA or rad5) -- various stem bases local nonpast_stem_base = q(rad12, A, rad34) local past_stem_base = q(_I, nonpast_stem_base) local past_pass_stem_base = q(_U, rad12, U, rad34) -- make parts make_augmented_sound_final_weak_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) end local function form_vii_nrad1(base, rad1) if base.reduced then if not req(rad1, M) then error(("Internal error: Form VII first radical %s is not م but .reduced specified; should have been caught earlier"): format(rget(rad1))) end return M .. SH else return q("نْ", rad1) end end -- Make form VII sound or final-weak verb. local function make_form_vii_sound_final_weak_verb(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) make_high_form_sound_final_weak_verb(base, vowel_spec, form_vii_nrad1(base, rad1), rad2, rad3) end conjugations["VII-sound"] = function(base, vowel_spec) make_form_vii_sound_final_weak_verb(base, vowel_spec) end conjugations["VII-final-weak"] = function(base, vowel_spec) make_form_vii_sound_final_weak_verb(base, vowel_spec) end conjugations["VII-hollow"] = function(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) local nrad1 = form_vii_nrad1(base, rad1) local vn = high_form_verbal_noun(nrad1, Y, rad3) -- various stem bases local nonpast_stem_base = nrad1 local past_stem_base = q(_I, nonpast_stem_base) local past_pass_stem_base = q(_U, nrad1) -- make parts make_augmented_hollow_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) end conjugations["VII-geminate"] = function(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) local nrad1 = form_vii_nrad1(base, rad1) local vn = high_form_verbal_noun(nrad1, rad2, rad2) -- various stem bases local nonpast_stem_base = q(nrad1, A) local past_stem_base = q(_I, nonpast_stem_base) local past_pass_stem_base = q(_U, nrad1, U) -- make parts make_augmented_geminate_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) end -- Return Form VIII verbal noun. local function form_viii_verbal_noun(base, vowel_spec, rad1, rad2, rad3) local final_weak = is_final_weak(base, vowel_spec) rad3 = final_weak and HAMZA or rad3 return {high_form_verbal_noun(vowel_spec.form_viii_assim, rad2, rad3)} end -- Make form VIII sound or final-weak verb. local function make_form_viii_sound_final_weak_verb(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) -- check for irregular verb اِتَّخَذَ if axadh_radicals(rad1, rad2, rad3) then base.irregular = true rad1 = T end make_high_form_sound_final_weak_verb(base, vowel_spec, vowel_spec.form_viii_assim, rad2, rad3) end conjugations["VIII-sound"] = function(base, vowel_spec) make_form_viii_sound_final_weak_verb(base, vowel_spec) end conjugations["VIII-final-weak"] = function(base, vowel_spec) make_form_viii_sound_final_weak_verb(base, vowel_spec) end conjugations["VIII-hollow"] = function(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) local vn = form_viii_verbal_noun(base, vowel_spec, rad1, Y, rad3) -- various stem bases local nonpast_stem_base = vowel_spec.form_viii_assim local past_stem_base = q(_I, nonpast_stem_base) local past_pass_stem_base = q(_U, nonpast_stem_base) -- make parts make_augmented_hollow_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) end conjugations["VIII-geminate"] = function(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) local vn = form_viii_verbal_noun(base, vowel_spec, rad1, rad2, rad2) -- various stem bases local nonpast_stem_base = q(vowel_spec.form_viii_assim, A) local past_stem_base = q(_I, nonpast_stem_base) local past_pass_stem_base = q(_U, vowel_spec.form_viii_assim, U) -- make parts make_augmented_geminate_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) end conjugations["IX-sound"] = function(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) local vn = q(_I, rad1, SK, rad2, I, rad3, AA, rad3) -- various stem bases local nonpast_stem_base = q(rad1, SK, rad2, A) local past_stem_base = q(_I, nonpast_stem_base) local past_pass_stem_base = q(_U, rad1, SK, rad2, U) -- make parts make_augmented_geminate_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) end conjugations["IX-final-weak"] = function(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) make_high_form_sound_final_weak_verb(base, vowel_spec, q(rad1, SK, rad2), rad3, rad3) end -- Populate a sound or final-weak verb for any of the various high-numbered -- augmented forms that have 5 consonants in the stem and the same pattern of -- vowels. Some of these consonants in certain verb parts are w's, which leads to -- apparent anomalies in certain stems of these parts, but these anomalies -- are handled automatically in postprocessing, where we resolve sequences of -- iwC -> īC, uwC -> ūC, w + sukūn + w -> w + shadda. local function make_high5_form_sound_final_weak_verb(base, vowel_spec, rad1, rad2, rad3, rad4, rad5) make_high_form_sound_final_weak_verb(base, vowel_spec, q(rad1, SK, rad2), q(rad3, SK, rad4), rad5) end -- Make form X sound or final-weak verb. local function make_form_x_sound_final_weak_verb(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) -- check for irregular verb اِسْتَحْيَا (also اِسْتَحَى) local is_hayy = hayy_radicals(rad1, rad2, rad3) local variant = vowel_spec.variant or "both" if not is_hayy or variant == "long" or variant == "both" then make_high5_form_sound_final_weak_verb(base, vowel_spec, S, T, rad1, rad2, rad3) end if is_hayy and (variant == "short" or variant == "both") then base.irregular = true -- Add alternative entries to the verbal paradigms. Any duplicates are removed during addition. make_high_form_sound_final_weak_verb(base, vowel_spec, S .. SK .. T, rad1, rad3) end end conjugations["X-sound"] = function(base, vowel_spec) make_form_x_sound_final_weak_verb(base, vowel_spec) end conjugations["X-final-weak"] = function(base, vowel_spec) make_form_x_sound_final_weak_verb(base, vowel_spec) end conjugations["X-hollow"] = function(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) local vn = q(base.reduced and "اِسْ" or "اِسْتِ", rad1, AA, rad3, AH) -- various stem bases local past_stem_base = q(base.reduced and "اِسْ" or "اِسْتَ", rad1) local nonpast_stem_base = q(base.reduced and "سْ" or "سْتَ", rad1) local past_pass_stem_base = q(base.reduced and "اُسْ" or "اُسْتُ", rad1) -- make parts make_augmented_hollow_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) end conjugations["X-geminate"] = function(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) local vn = q("اِسْتِ", rad1, SK, rad2, AA, rad2) -- various stem bases local past_stem_base = q("اِسْتَ", rad1) local nonpast_stem_base = q("سْتَ", rad1) local past_pass_stem_base = q("اُسْتُ", rad1) -- make parts if base.altgem then inflect_tense(base, "past", "", {q(past_stem_base, A, rad2, SH), all_same = 1}, past_endings_ay_12_person_only) end make_augmented_geminate_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn, base.altgem and "[uncommon]" or nil) end conjugations["XI-sound"] = function(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) local vn = q(_I, rad1, SK, rad2, II, rad3, AA, rad3) -- various stem bases local nonpast_stem_base = q(rad1, SK, rad2, AA) local past_stem_base = q(_I, nonpast_stem_base) local past_pass_stem_base = q(_U, rad1, SK, rad2, UU) -- make parts make_augmented_geminate_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) end -- Probably no form XI final-weak, since already geminate in form; would behave as XI-sound. -- Make form XII sound or final-weak verb. local function make_form_xii_sound_final_weak_verb(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) make_high5_form_sound_final_weak_verb(base, vowel_spec, rad1, rad2, W, rad2, rad3) end conjugations["XII-sound"] = function(base, vowel_spec) make_form_xii_sound_final_weak_verb(base, vowel_spec) end conjugations["XII-final-weak"] = function(base, vowel_spec) make_form_xii_sound_final_weak_verb(base, vowel_spec) end -- Make form XIII sound or final-weak verb. local function make_form_xiii_sound_final_weak_verb(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) make_high5_form_sound_final_weak_verb(base, vowel_spec, rad1, rad2, W, W, rad3) end conjugations["XIII-sound"] = function(base, vowel_spec) make_form_xiii_sound_final_weak_verb(base, vowel_spec) end conjugations["XIII-final-weak"] = function(base, vowel_spec) make_form_xiii_sound_final_weak_verb(base, vowel_spec) end -- Make a form XIV or XV sound or final-weak verb. Last radical appears twice (if`anlala / yaf`anlilu) so if it were -- w or y you'd get if`anwā / yaf`anwī or if`anyā / yaf`anyī, i.e. unlike for most augmented verbs, the identity of -- the radical matters. local function make_form_xiv_xv_sound_final_weak_verb(base, vowel_spec) local rad1, rad2, rad3 = get_radicals_3(vowel_spec) local lastrad = base.verb_form == "XV" and Y or rad3 make_high5_form_sound_final_weak_verb(base, vowel_spec, rad1, rad2, N, rad3, lastrad) end conjugations["XIV-sound"] = function(base, vowel_spec) make_form_xiv_xv_sound_final_weak_verb(base, vowel_spec) end conjugations["XIV-final-weak"] = function(base, vowel_spec) make_form_xiv_xv_sound_final_weak_verb(base, vowel_spec) end conjugations["XV-sound"] = function(base, vowel_spec) make_form_xiv_xv_sound_final_weak_verb(base, vowel_spec) end -- Probably no form XV final-weak, since already final-weak in form; would behave as XV-sound. -- Make form Iq or IIq sound or final-weak verb. local function make_form_iq_iiq_sound_final_weak_verb(base, vowel_spec) local rad1, rad2, rad3, rad4 = get_radicals_4(vowel_spec) local final_weak = is_final_weak(base, vowel_spec) local vform = base.verb_form local vn = vform == "IIq" and q(TA, rad1, A, rad2, SK, rad3, (final_weak and IN or q(U, rad4))) or q(rad1, A, rad2, SK, rad3, (final_weak and AAH or q(A, rad4, AH))) local ta_pref = vform == "IIq" and TA or "" local tu_pref = vform == "IIq" and TU or "" -- various stem bases local past_stem_base = q(ta_pref, rad1, A, rad2, SK, rad3) local nonpast_stem_base = past_stem_base local past_pass_stem_base = q(tu_pref, rad1, U, rad2, SK, rad3) -- make parts make_augmented_sound_final_weak_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) end conjugations["Iq-sound"] = function(base, vowel_spec) make_form_iq_iiq_sound_final_weak_verb(base, vowel_spec) end conjugations["Iq-final-weak"] = function(base, vowel_spec) make_form_iq_iiq_sound_final_weak_verb(base, vowel_spec) end conjugations["IIq-sound"] = function(base, vowel_spec) make_form_iq_iiq_sound_final_weak_verb(base, vowel_spec) end conjugations["IIq-final-weak"] = function(base, vowel_spec) make_form_iq_iiq_sound_final_weak_verb(base, vowel_spec) end -- Make form IIIq sound or final-weak verb. local function make_form_iiiq_sound_final_weak_verb(base, vowel_spec) local rad1, rad2, rad3, rad4 = get_radicals_4(vowel_spec) make_high5_form_sound_final_weak_verb(base, vowel_spec, rad1, rad2, N, rad3, rad4) end conjugations["IIIq-sound"] = function(base, vowel_spec) make_form_iiiq_sound_final_weak_verb(base, vowel_spec) end conjugations["IIIq-final-weak"] = function(base, vowel_spec) make_form_iiiq_sound_final_weak_verb(base, vowel_spec) end conjugations["IVq-sound"] = function(base, vowel_spec) local rad1, rad2, rad3, rad4 = get_radicals_4(vowel_spec) local vn = q(_I, rad1, SK, rad2, I, rad3, SK, rad4, AA, rad4) -- various stem bases local past_stem_base = q(_I, rad1, SK, rad2, A, rad3) local nonpast_stem_base = q(rad1, SK, rad2, A, rad3) local past_pass_stem_base = q(_U, rad1, SK, rad2, U, rad3) -- make parts make_augmented_geminate_verb(base, vowel_spec, past_stem_base, nonpast_stem_base, past_pass_stem_base, vn) end -- Probably no form IVq final-weak, since already geminate in form; would behave as IVq-sound. end create_conjugations() ------------------------------------------------------------------------------- -- Guts of main conjugation function -- ------------------------------------------------------------------------------- -- Given form, weakness and radicals, check to make sure the radicals present are allowable for the weakness. Hamzas on -- alif/wāw/yāʾ seats are never allowed (should always appear as hamza-on-the-line), and various weaknesses have various -- strictures on allowable consonants. local function check_radicals(form, weakness, rad1, rad2, rad3, rad4) local function hamza_check(index, rad) if rad == HAMZA_ON_ALIF or rad == HAMZA_UNDER_ALIF or rad == HAMZA_ON_W or rad == HAMZA_ON_Y then error("Radical " .. index .. " is " .. rad .. " but should be ء (hamza on the line)") end end local function check_waw_ya(index, rad) if not is_waw_ya(rad) then error("Radical " .. index .. " is " .. rad .. " but should be و or ي") end end local function check_not_waw_ya(index, rad) if is_waw_ya(rad) then error("In a sound verb, radical " .. index .. " should not be و or ي") end end hamza_check(rad1) hamza_check(rad2) hamza_check(rad3) hamza_check(rad4) if weakness == "assimilated" or weakness == "assimilated+final-weak" then if rad1 ~= W then error("Radical 1 is " .. rad1 .. " but should be و") end -- don't check that non-assimilated form I verbs don't have wāw as their -- first radical because some form-I verbs exist where a first-radical wāw -- behaves as sound, e.g. wajuha yawjuhu "to be distinguished". end if weakness == "final-weak" or weakness == "assimilated+final-weak" then if rad4 then check_waw_ya(4, rad4) else check_waw_ya(3, rad3) end elseif vform_supports_final_weak(form) then -- non-final-weak verbs cannot have weak final radical if there's a corresponding -- final-weak verb category. I think this is safe. We may have problems with -- ḥayya/ḥayiya yaḥyā if we treat it as a geminate verb. if rad4 then check_not_waw_ya(4, rad4) else check_not_waw_ya(3, rad3) end end if weakness == "hollow" then check_waw_ya(2, rad2) -- don't check that non-hollow verbs in forms that support hollow verbs -- don't have wāw or yāʾ as their second radical because some verbs exist -- where a middle-radical wāw/yāʾ behaves as sound, e.g. form-VIII izdawaja -- "to be in pairs". end if weakness == "geminate" then if rad4 then error("Internal error: No geminate quadrilaterals, should not be seen") end if rad2 ~= rad3 then error("Weakness is geminate; radical 3 is " .. rad3 .. " but should be same as radical 2 " .. rad2) end elseif vform_supports_geminate(form) then -- non-geminate verbs cannot have second and third radical same if there's -- a corresponding geminate verb category. I think this is safe. We -- don't fuss over double wāw or double yāʾ because this could legitimately -- be a final-weak verb with middle wāw/yāʾ, treated as sound. if rad4 then error("Internal error: No quadrilaterals should support geminate verbs") end if rad2 == rad3 and not is_waw_ya(rad2) then error("Weakness is '" .. weakness .. "'; radical 2 and 3 are same at " .. rad2 .. " but should not be; consider making weakness 'geminate'") end end end -- array of substitutions; each element is a 2-entry array FROM, TO; do it -- this way so the concatenations only get evaluated once local postprocess_subs = { -- reorder short-vowel + shadda -> shadda + short-vowel for easier processing {"(" .. AIU .. ")" .. SH, SH .. "%1"}, ----------same letter separated by sukūn should instead use shadda--------- ------------happens e.g. in kun-nā "we were".----------------- {"(.)" .. SK .. "%1", "%1" .. SH}, ---------------------------- assimilated verbs ---------------------------- -- iw, iy -> ī (assimilated verbs) {I .. W .. SK, II}, {I .. Y .. SK, II}, -- uw, uy -> ū (assimilated verbs) {U .. W .. SK, UU}, {U .. Y .. SK, UU}, -------------- final -yā uses tall alif not alif maqṣūra ------------------ {"(" .. Y .. SH .. "?" .. A .. ")" .. AMAQ, "%1" .. ALIF}, ----------------------- handle hamza assimilation ------------------------- -- initial hamza + short-vowel + hamza + sukūn -> hamza + long vowel {HAMZA .. A .. HAMZA .. SK, HAMZA .. A .. ALIF}, {HAMZA .. I .. HAMZA .. SK, HAMZA .. I .. Y}, {HAMZA .. U .. HAMZA .. SK, HAMZA .. U .. W} } local postprocess_tr_subs = { {"ī([" .. vowels .. "y*])", "iy%1"}, {"ū([" .. vowels .. "w*])", "uw%1"}, {"(.)%*", "%1%1"}, -- implement shadda ---------------------------- assimilated verbs ---------------------------- -- iw, iy -> ī (assimilated verbs) {"iw([^" .. vowels .. "w])", "ī%1"}, {"iy([^" .. vowels .. "y])", "ī%1"}, -- uw, uy -> ū (assimilated verbs) {"uw([^" .. vowels .. "w])", "ū%1"}, {"uy([^" .. vowels .. "y])", "ū%1"}, ----------------------- handle hamza assimilation ------------------------- -- initial hamza + short-vowel + hamza + sukūn -> hamza + long vowel {"ʔaʔ(" .. NV .. ")", "ʔā%1"}, {"ʔiʔ(" .. NV .. ")", "ʔī%1"}, {"ʔuʔ(" .. NV .. ")", "ʔū%1"}, } -- Post-process verb parts to eliminate phonological anomalies. Many of the changes, particularly the tricky ones, -- involve converting hamza to have the proper seat. The rules for this are complicated and are documented on the -- [[w:Hamza]] Wikipedia page. In some cases there are alternatives allowed, and we handle them below by returning -- multiple possibilities. local function postprocess_term(term) if term == "?" then return "?" end -- Add BORDER at text boundaries. term = BORDER .. term .. BORDER -- Do the main post-processing, based on the pattern substitutions in postprocess_subs. for _, sub in ipairs(postprocess_subs) do term = rsub(term, sub[1], sub[2]) end term = term:gsub(BORDER, "") if not rfind(term, HAMZA) then return term end term = term:gsub(HAMZA, HAMZA_PH) term = ar_utilities.process_hamza(term) if #term == 1 then term = term[1] end return term end local function postprocess_translit(translit) if translit == "?" then return "?" end -- Add BORDER at text boundaries. translit = BORDER .. translit .. BORDER -- Do the main post-processing, based on the pattern substitutions in postprocess_tr_subs. for _, sub in ipairs(postprocess_tr_subs) do translit = rsub(translit, sub[1], sub[2]) end translit = translit:gsub(BORDER, "") return translit end local function postprocess_forms(base) local converted_values = {} for slot, forms in pairs(base.forms) do local need_dedup = false for i, form in ipairs(forms) do local term = postprocess_term(form.form) local translit = form.translit and postprocess_translit(form.translit) or nil if term ~= form.form or translit ~= form.translit then need_dedup = true end converted_values[i] = {term, translit} end if need_dedup then local temp_dedup = {} for i = 1, #forms do local new_term, new_translit = unpack(converted_values[i]) if type(new_term) == "table" then for _, nt in ipairs(new_term) do local new_formobj = { form = nt, translit = new_translit, footnotes = forms[i].footnotes, } iut.insert_form(temp_dedup, "temp", new_formobj) end else local new_formobj = { form = new_term, translit = new_translit, footnotes = forms[i].footnotes, } iut.insert_form(temp_dedup, "temp", new_formobj) end end base.forms[slot] = temp_dedup.temp end end end local function process_slot_overrides(base) for slot, forms in pairs(base.slot_overrides) do local existing_values = base.forms[slot] base.forms[slot] = nil for _, form in ipairs(forms) do -- + in active participle for form I requests slot ap1 if form.form == "+" and (base.verb_form ~= "I" or slot ~= "ap") then if not existing_values then error(("Slot '%s' requested the default value but no such value available"):format(slot)) end -- We maintain an invariant that no two slots share a form object (although they may share the footnote -- lists inside the form objects). However, there is no need to copy the form objects here because there -- is a one-to-one correspondence between slots and slot overrides, i.e. you can't have a default value -- go into two slots. insert_form_or_forms(base, slot, existing_values, "allow overrides", form.uncertain) elseif default_indicator_to_active_participle_slot[form.form] then if form.form == "++" then if slot ~= "vn" and slot ~= "ap" and slot ~= "pp" then error(("Secondary default value request '++' only applicable to verbal nouns and pariciples, but found in slot '%s'"): format(slot)) end else if slot ~= "ap" then error(("Secondary default value request '%s' only applicable to active pariciples, but found in slot '%s'"): format(form.form, slot)) end end local secondary_default_slot = slot == "vn" and "vn2" or slot == "pp" and "pp2" or default_indicator_to_active_participle_slot[form.form] local existing_values = base.forms[secondary_default_slot] if not existing_values then error(("Slot '%s' requested a secondary default value using '%s' but no such value available"): format(slot, form.form)) end -- See comment above about the lack of need to copy the form objects. insert_form_or_forms(base, slot, existing_values, "allow overrides", form.uncertain) -- To make sure there aren't shared form objects. base.forms[secondary_default_slot] = nil else insert_form_or_forms(base, slot, form, "allow overrides", form.uncertain) end end end -- Now, for non-stative form-I verbs, fill the active participle slot from ap1 unless it should be missing (e.g. -- passive-only or user specified 'ap:-'). if base.verb_form == "I" and not base.forms.ap and base.forms.ap1 and not skip_slot(base, "ap") then local saw_non_stative = false for _, vowel_spec in ipairs(base.conj_vowels) do if req(vowel_spec.past, A) then saw_non_stative = true break end end if saw_non_stative then base.forms.ap = base.forms.ap1 -- To make sure there aren't shared form objects. base.forms.ap1 = nil end end end local function handle_lemma_linked(base) -- Compute linked versions of potential lemma slots, for use in {{ar-verb}}. We substitute the original lemma -- (before removing links) for forms that are the same as the lemma, if the original lemma has links. for _, slot in ipairs(export.potential_lemma_slots) do if base.forms[slot] then insert_form_or_forms(base, slot .. "_linked", iut.map_forms(base.forms[slot], function(form) if form == base.lemma and rfind(base.linked_lemma, "%[%[") then return base.linked_lemma else return form end end)) end end end -- Process specs given by the user using 'addnote[SLOTSPEC][FOOTNOTE][FOOTNOTE][...]'. local function process_addnote_specs(base) for _, spec in ipairs(base.addnote_specs) do for _, slot_spec in ipairs(spec.slot_specs) do slot_spec = "^" .. slot_spec .. "$" for slot, forms in pairs(base.forms) do if rfind(slot, slot_spec) then -- To save on memory, side-effect the existing forms. for _, form in ipairs(forms) do form.footnotes = iut.combine_footnotes(form.footnotes, spec.footnotes) end end end end end end local function add_missing_links_to_forms(base) -- Any forms without links should get them now. Redundant ones will be stripped later. for slot, forms in pairs(base.forms) do for _, form in ipairs(forms) do if not form.form:find("%[%[") then form.form = "[[" .. form.form .. "]]" end end end end local function conjugate_verb(base) construct_stems(base) for _, vowel_spec in ipairs(base.conj_vowels) do -- Reconstruct conjugation type from verb form and (possibly inferred) weakness. conj_type = base.verb_form .. "-" .. vowel_spec.weakness -- Check that the conjugation type is recognized. if not conjugations[conj_type] then error("Unknown conjugation type '" .. conj_type .. "'") end -- The way the conjugation functions work is they always add entries to the appropriate parts of the paradigm -- (each of which is an array), rather than setting the values. This makes it possible to call more than one -- conjugation function and essentially get a paradigm of the "either A or B" kind. Doing this may insert -- duplicate entries into a particular paradigm part, but this is not a problem because we check for duplicate -- entries when adding them, and don't insert in that case. conjugations[conj_type](base, vowel_spec) end postprocess_forms(base) process_slot_overrides(base) -- This should happen before add_missing_links_to_forms() so that the comparison `form == base.lemma` in -- handle_lemma_linked() works correctly and compares unlinked forms to unlinked forms. handle_lemma_linked(base) process_addnote_specs(base) if not base.alternant_multiword_spec.args.noautolinkverb then add_missing_links_to_forms(base) end end local function parse_indicator_spec(angle_bracket_spec) -- Store the original angle bracket spec so we can reconstruct the overall conj spec with the lemma(s) in them. local base = { angle_bracket_spec = angle_bracket_spec, conj_vowels = {}, root_consonants = {}, user_stem_overrides = {}, user_slot_overrides = {}, slot_explicitly_missing = {}, slot_uncertain = {}, slot_override_uses_default = {}, addnote_specs = {}, } local function parse_err(msg) error(msg .. ": " .. angle_bracket_spec) end local function fetch_footnotes(separated_group) local footnotes for j = 2, #separated_group - 1, 2 do if separated_group[j + 1] ~= "" then parse_err("Extraneous text after bracketed footnotes: '" .. table.concat(separated_group) .. "'") end if not footnotes then footnotes = {} end table.insert(footnotes, separated_group[j]) end return footnotes end local inside = angle_bracket_spec:match("^<(.*)>$") assert(inside) local segments = put.parse_multi_delimiter_balanced_segment_run(inside, {{"[", "]"}, {"<", ">"}}) local dot_separated_groups = put.split_alternating_runs_and_strip_spaces(segments, "%.") -- The first dot-separated element must specify the verb form, e.g. IV or IIq. If the form is I, it needs to include -- the the past and non-past vowels, e.g. I/a~u for kataba ~ yaktubu. More than one vowel can be given, -- comma-separated, and more than one past~non-past pair can be given, slash-separated, e.g. I/a,u~u/i~a for form I -- كمل, which can be conjugated as kamala/kamula ~ yakmulu or kamila ~ yakmalu. An individual vowel spec must be one -- of a, i or u and in general (a) at least one past~non-past pair most be given, and (b) both past and non-past -- vowels must be given even though sometimes the vowel can be determined from the unvocalized form. An exception is -- passive-only verbs, where the vowels can't in general be determined (except indirectly in some cases by looking -- at an associated non-passive verb); in that case, the vowel~vowel spec can left out. local slash_separated_groups = put.split_alternating_runs_and_strip_spaces(dot_separated_groups[1], "/") local form_spec = slash_separated_groups[1] base.form_footnotes = fetch_footnotes(form_spec) if form_spec[1] == "" then parse_err("Missing verb form") end if not allowed_vforms_with_weakness_set[form_spec[1]] then parse_err(("Unrecognized verb form '%s', should be one of %s"):format( form_spec[1], list_to_text(allowed_vforms, nil, " or "))) end if form_spec[1]:find("%-") then base.verb_form, base.explicit_weakness = form_spec[1]:match("^(.-)%-(.*)$") else base.verb_form = form_spec[1] end if #slash_separated_groups > 1 then if base.verb_form ~= "I" then parse_err(("Past~non-past vowels can only be specified when verb form is I, but saw form '%s'"):format( base.verb_form)) end for i = 2, #slash_separated_groups do local slash_separated_group = slash_separated_groups[i] local tilde_separated_groups = put.split_alternating_runs_and_strip_spaces(slash_separated_group, "~") if #tilde_separated_groups ~= 2 then parse_err(("Expected two tilde-separated vowel specs: %s"):format(table.concat(slash_separated_group))) end local function parse_conj_vowels(tilde_separated_group, vtype) local conj_vowel_objects = {} local comma_separated_groups = put.split_alternating_runs_and_strip_spaces(tilde_separated_group, ",") for _, comma_separated_group in ipairs(comma_separated_groups) do local conj_vowel = comma_separated_group[1] if conj_vowel ~= "a" and conj_vowel ~= "i" and conj_vowel ~= "u" then parse_err(("Expected %s conjugation vowel '%s' to be one of a, i or u in %s"):format( vtype, conj_vowel, table.concat(slash_separated_group))) end conj_vowel = dia[conj_vowel] local conj_vowel_footnotes = fetch_footnotes(comma_separated_group) -- Try to use strings when possible as it makes q() significantly more efficient. if conj_vowel_footnotes then table.insert(conj_vowel_objects, {form = conj_vowel, footnotes = conj_vowel_footnotes}) else table.insert(conj_vowel_objects, conj_vowel) end end return conj_vowel_objects end local conj_vowel_spec = { past = parse_conj_vowels(tilde_separated_groups[1], "past"), nonpast = parse_conj_vowels(tilde_separated_groups[2], "non-past"), } table.insert(base.conj_vowels, conj_vowel_spec) end end for i = 2, #dot_separated_groups do local dot_separated_group = dot_separated_groups[i] local first_element = dot_separated_group[1] if first_element == "addnote" then local spec_and_footnotes = fetch_footnotes(dot_separated_group) if #spec_and_footnotes < 2 then parse_err("Spec with 'addnote' should be of the form 'addnote[SLOTSPEC][FOOTNOTE][FOOTNOTE][...]'") end local slot_spec = table.remove(spec_and_footnotes, 1) local slot_spec_inside = rmatch(slot_spec, "^%[(.*)%]$") if not slot_spec_inside then parse_err("Internal error: slot_spec " .. slot_spec .. " should be surrounded with brackets") end local slot_specs = rsplit(slot_spec_inside, ",") -- FIXME: Here, [[Module:it-verb]] called strip_spaces(). Generally we don't do this. Should we? table.insert(base.addnote_specs, {slot_specs = slot_specs, footnotes = spec_and_footnotes}) elseif first_element:find("^var:") then if #dot_separated_group > 1 then parse_err(("Can't attach footnotes to 'var:' spec '%s'"):format(first_element)) end base.variant = first_element:match("^var:(.*)$") elseif first_element:find("^I+V?:") then local root_cons, root_cons_value = first_element:match("^(I+V?):(.*)$") local root_index if root_cons == "I" then root_index = 1 elseif root_cons == "II" then root_index = 2 elseif root_cons == "III" then root_index = 3 elseif root_cons == "IV" then root_index = 4 if not base.verb_form:find("q$") then parse_err(("Can't specify root consonant IV for non-quadriliteral verb form '%s': %s"):format( base.verb_form, first_element)) end end local cons, translit = root_cons_value:match("^(.*)//(.*)$") if not cons then cons = root_cons_value end local root_footnotes = fetch_footnotes(dot_separated_group) if not translit and not root_footnotes then base.root_consonants[root_index] = cons else base.root_consonants[root_index] = {form = cons, translit = translit, footnotes = root_footnotes} end elseif first_element:find("^[a-z][a-z0-9_]*:") then local slot_or_stem, remainder = first_element:match("^(.-):(.*)$") dot_separated_group[1] = remainder local comma_separated_groups = put.split_alternating_runs_and_strip_spaces(dot_separated_group, "[,،]") if overridable_stems[slot_or_stem] then if base.user_stem_overrides[slot_or_stem] then parse_err("Overridable stem '" .. slot_or_stem .. "' specified twice") end base.user_stem_overrides[slot_or_stem] = overridable_stems[slot_or_stem](comma_separated_groups, {prefix = slot_or_stem, base = base, parse_err = parse_err, fetch_footnotes = fetch_footnotes}) else -- assume a form override; we validate further later when the possible slots are available if base.user_slot_overrides[slot_or_stem] then parse_err("Form override '" .. slot_or_stem .. "' specified twice") end base.user_slot_overrides[slot_or_stem] = allow_multiple_values_for_override(comma_separated_groups, {prefix = slot_or_stem, base = base, parse_err = parse_err, fetch_footnotes = fetch_footnotes}, "is form override") end elseif indicator_flags[first_element] then if #dot_separated_group > 1 then parse_err("No footnotes allowed with '" .. first_element .. "' spec") end if base[first_element] then parse_err("Spec '" .. first_element .. "' specified twice") end base[first_element] = true else local passive, uncertain = first_element:match("^(.*)(%?)$") passive = passive or first_element uncertain = not not uncertain if passive_types[passive] then if #dot_separated_group > 1 then parse_err("No footnotes allowed with '" .. passive .. "' spec") end if base.passive then parse_err("Value for passive type specified twice") end base.passive = passive base.passive_uncertain = uncertain else parse_err("Unrecognized spec '" .. first_element .. "'") end end end return base end -- Normalize all lemmas, substituting the pagename for blank lemmas and adding links to multiword lemmas. local function normalize_all_lemmas(alternant_multiword_spec, head) -- (1) Add links to all before and after text. Remember the original text so we can reconstruct the verb spec later. if not alternant_multiword_spec.args.noautolinktext then iut.add_links_to_before_and_after_text(alternant_multiword_spec, "remember original") end -- (2) Remove any links from the lemma, but remember the original form so we can use it below in the 'lemma_linked' -- form. iut.map_word_specs(alternant_multiword_spec, function(base) if base.lemma == "" then base.lemma = head end base.user_specified_lemma = base.lemma base.lemma = m_links.remove_links(base.lemma) base.user_specified_verb = base.lemma base.verb = base.user_specified_verb local linked_lemma if alternant_multiword_spec.args.noautolinkverb or base.user_specified_lemma:find("%[%[") then linked_lemma = base.user_specified_lemma else -- Add links to the lemma so the user doesn't specifically need to, since we preserve -- links in multiword lemmas and include links in non-lemma forms rather than allowing -- the entire form to be a link. linked_lemma = iut.add_links(base.user_specified_lemma) end base.linked_lemma = linked_lemma end) end --W: Lexical exceptions — yāʾ-middle roots whose Form IV (أفعل) keeps the yāʾ SOUND -- instead of undergoing the regular إعلال to a hollow verb (أَفْيَلَ, not أَفَالَ). -- These are attested verbs (not the صفة مشبهة like أَخْيَف/خَيْفاء); each is sourced below. -- Only Form IV is affected; forms VII/VIII/X of these roots remain hollow. -- Keyed by rad1..rad2..rad3. local SOUND_FORM_IV_ROOTS = { ["خيل"] = true, -- أَخْيَلَ: أخيلت السماءُ تهيأت للمطر — المعجم الوسيط ج1 ص266 (وبه أَخالت أيضًا) ["غيل"] = true, -- أَغْيَلَ: أغيلته فهي مُغْيِل، سقته الغَيْل — لسان العرب ج11 ص111 (وبه أغالت أيضًا) ["حيج"] = true, -- أَحْيَجَ: أحيجت الأرضُ، على خلاف القياس — تاج العروس ج5 ص500 ["حين"] = true, -- أَحْيَنَ: أحين القومُ آن لهم أن يبلغوا ما أملوه — المعجم الوسيط ج1 ص212 ["خيف"] = true, -- أَخْيَفَ: أخيف الحاجُّ نزلوا خيف منى — كتاب الأفعال لابن القوطية ص35 ["ريف"] = true, -- أَرْيَفَ: أريفت الأرضُ إريافًا (خصبت) — المحيط في اللغة ج10 ص256 ["زين"] = true, -- أَزْيَنَ: أزينت الأرضُ، حسّنها عشبها — مقاييس اللغة ج3 ص41 } -- Determine weakness from radicals. Used when root given in place of lemma (e.g. for {{ar-verb forms}}). local function weakness_from_radicals(form, rad1, rad2, rad3, rad4) local weakness = nil local quadlit = form:find("q$") -- If weakness unspecified, derive from radicals. if not quadlit then if is_waw_ya(rad3) and rad1 == W and form == "I" then weakness = "assimilated+final-weak" elseif is_waw_ya(rad3) and vform_supports_final_weak(form) then weakness = "final-weak" elseif rad2 == rad3 and vform_supports_geminate(form) then weakness = "geminate" elseif is_waw_ya(rad2) and vform_supports_hollow(form) then --W: Both wāw (و) and yāʾ (ي) in the middle position create hollow verbs, in form I -- (قَالَ from ق-و-ل, بَاعَ from ب-ي-ع) and in the augmented forms IV, VII, VIII, X -- (أَتَاسَ from ت-ي-س, أَبَانَ from ب-ي-ن, أَطَاحَ from ط-ي-ح — معجم متن اللغة). if form == "IV" and rad2 == Y and SOUND_FORM_IV_ROOTS[rad1 .. rad2 .. rad3] then -- Lexical exceptions whose Form IV keeps the yāʾ sound (أَفْيَلَ); see SOUND_FORM_IV_ROOTS. weakness = "sound" else weakness = "hollow" end elseif rad1 == W and form == "I" then weakness = "assimilated" else weakness = "sound" end else if is_waw_ya(rad4) then weakness = "final-weak" else weakness = "sound" end end return weakness end -- Join the infixed tāʔ (ت) to the first radical in form VIII verbs. This may cause assimilation of the tāʔ to the -- radical or in some cases the radical to the tāʔ. Used when a root is supplied instead of a lemma (which already has -- the appropriate assimilation in it). local function form_viii_join_ta(rad) if rad == W or rad == Y or rad == "ت" then return "تّ" elseif rad == "د" then return "دّ" elseif rad == "ث" then return "ثّ" elseif rad == "ذ" then return "ذّ" elseif rad == "ز" then return "زْد" elseif rad == "ص" then return "صْط" elseif rad == "ض" then return "ضْط" elseif rad == "ط" then return "طّ" elseif rad == "ظ" then return "ظّ" else return rad .. SK .. "ت" end end local function detect_indicator_spec(base) base.forms = {} base.stem_overrides = {} base.slot_overrides = {} if not base.conj_vowels[1] then -- These may be converted to inferred vowels. If not, we throw an error if form I and not passive-only. base.conj_vowels = {{ past = "-", nonpast = "-", }} else -- If multiple vowels specified for a given vowel type (e.g. a,u~u), expand so that each spec in local expansion = {} for _, spec in ipairs(base.conj_vowels) do for _, past in ipairs(spec.past) do for _, nonpast in ipairs(spec.nonpast) do table.insert(expansion, {past = past, nonpast = nonpast}) end end end base.conj_vowels = expansion end local vform = base.verb_form -- check for quadriliteral form (Iq, IIq, IIIq, IVq) base.quadlit = not not vform:find("q$") -- Infer radicals as necessary. We infer a separate set of radicals for each past~non-past vowel combination because -- they may be different (particularly with form-I hollow verbs). for _, vowel_spec in ipairs(base.conj_vowels) do -- NOTE: rad1, rad2, etc. refer to user-specified radicals, which are formobj tables that optionally specify an -- explicit manual translit, whereas ir1, ir2, etc. refer to inferred radicals, which are either strings or -- lists of possible radicals. local rads = base.root_consonants local rad1, rad2, rad3, rad4 = rads[1], rads[2], rads[3], rads[4] -- Default any unspecified radicals to radicals determined from the headword. The returned radicals may be -- lists of possible radicals, where the first radical should be chosen if the user didn't explicitly specify a -- radical but all are allowed. If `ambig = true` is set in the table, the radical is considered ambiguous and -- categories won't be created for weak radicals. local weakness, ir1, ir2, ir3, ir4 if vform ~= "none" then ir1, ir2, ir3 = rmatch(base.lemma, "^([^_])_([^_])_([^_])$") if not ir1 then ir1, ir2, ir3, ir4 = rmatch(base.lemma, "^([^_])_([^_])_([^_])_([^_])$") end if ir1 then -- root given instead of lemma weakness = weakness_from_radicals(vform, ir1, ir2, ir3, ir4) if vform == "VIII" then vowel_spec.form_viii_assim = form_viii_join_ta(ir1) end else local ret = export.infer_radicals { headword = base.lemma, vform = vform, passive = base.passive, past_vowel = vowel_spec.past, nonpast_vowel = vowel_spec.nonpast, is_reduced = base.reduced, } weakness, ir1, ir2, ir3, ir4 = ret.weakness, ret.rad1, ret.rad2, ret.rad3, ret.rad4 vowel_spec.form_viii_assim = ret.form_viii_assim vowel_spec.past = ret.past_vowel vowel_spec.nonpast = ret.nonpast_vowel vowel_spec.variant = base.variant or ret.variant end end -- For most ambiguous radicals, the choice of radical doesn't matter because it doesn't affect the conjugation -- one way or another. For form I hollow verbs, however, it definitely does. In fact, the choice of radical is -- critical even beyond the past and non-past vowels because it affects the form of the passive participle. So, -- check for this and signal an error if the radical could not be inferred and is not given explicitly. if vform == "I" and type(ir2) == "table" and ir2.need_radical and not rad2 then error("Unable to guess middle radical of hollow form I verb; need to specify radical explicitly") end if vform == "I" and not is_passive_only(base.passive) and ( rget(vowel_spec.past) == "-" or rget(vowel_spec.nonpast) == "-") then error("Form I verb that isn't passive-only or final-weak must have past~non-past vowels specified") end -- Convert ambiguous radicals. local function regularize_inferred_radical(rad) if type(rad) == "table" then if rad.ambig then return {form = rad[1], ambig = true} else return rad[1] end else return rad end end -- Return the appropriate radical at index `index` (1 through 4), based either on the user-specified radical -- `user_radical` or (if unspecified) `inferred_radical`, inferred from the unvocalized lemma. Two values are -- returned, the "regularized" version of the radical (where ambiguous inferred radicals are converted to their -- most likely actual radical) and the non-regularized version. The returned values are form objects rather than -- strings. local function fetch_radical(user_radical, inferred_radical, index) if not user_radical then return regularize_inferred_radical(inferred_radical), inferred_radical else local rad_formval = rget(user_radical) if type(inferred_radical) == "table" then local allowed_radical_set = m_table.listToSet(inferred_radical) if not allowed_radical_set[rad_formval] then error(("For lemma %s, radical %s ambiguously inferred as %s but user radical incompatibly given as %s"): format(base.lemma, index, list_to_text(inferred_radical, nil, " or "), rad_formval)) end elseif rad_formval ~= inferred_radical then error(("For lemma %s, radical %s inferred as %s but user radical incompatibly given as %s"): format(base.lemma, index, inferred_radical, rad_formval)) end return user_radical, user_radical end end if vform ~= "none" then vowel_spec.rad1, vowel_spec.unreg_rad1 = fetch_radical(rad1, ir1, 1) vowel_spec.rad2, vowel_spec.unreg_rad2 = fetch_radical(rad2, ir2, 2) vowel_spec.rad3, vowel_spec.unreg_rad3 = fetch_radical(rad3, ir3, 3) if base.quadlit then vowel_spec.rad4, vowel_spec.unreg_rad4 = fetch_radical(rad4, ir4, 4) end end if vform == "I" then -- If explicit weakness given using 'I-sound' or 'I-assimilated', we may need to adjust the inferred weakness. if base.explicit_weakness == "sound" then if weakness == "assimilated" then weakness = "sound" elseif weakness == "assimilated+final-weak" then -- Verbs like waniya~yawnā "to be faint; to languish" (although the defaults should handle this -- correctly) weakness = "final-weak" else error(("Can't specify form 'I-sound' when inferred weakness is '%s' for lemma %s"):format( weakness, base.lemma)) end elseif base.explicit_weakness == "assimilated" then if weakness == "sound" then -- i~a verbs like waṭiʔa~yaṭaʔu "to tread, to trample"; wasiʕa~yasaʕu "to be spacious; to be well-off"; -- waṯiʔa~yaṯaʔu "to get bruised, to be sprained", which would default to sound. weakness = "assimilated" elseif weakness == "final-weak" then -- For completeness; not clear if any verbs occur where this is needed. (There are plenty of -- assimilated+final-weak verbs but the defaults should take care of them.) weakness = "assimilated+final-weak" else error(("Can't specify form 'I-assimilated' when inferred weakness is '%s' for lemma %s"):format( weakness, base.lemma)) end elseif base.explicit_weakness then error(("Internal error: Unrecognized value '%s' for base.explicit_weakness"):format(base.explicit_weakness)) end elseif vform == "none" then weakness = base.explicit_weakness elseif base.explicit_weakness then error(("Internal error: Explicit weakness should not be specifiable except with forms I and none, but saw explicit weakness '%s' with verb form '%s'"): format(base.explicit_weakness, vform)) end vowel_spec.weakness = weakness if vform ~= "none" then -- Error if radicals are wrong given the weakness. More likely to happen if the weakness is explicitly given -- rather than inferred. Will also happen if certain incorrect letters are included as radicals e.g. hamza on -- top of various letters, alif maqṣūra, tā' marbūṭa. check_radicals(vform, weakness, rget(vowel_spec.rad1), rget(vowel_spec.rad2), rget(vowel_spec.rad3), base.quadlit and rget(vowel_spec.rad4) or nil) end -- Check the variant value. local form_iii_vi_geminate = (vform == "III" or vform == "VI") and rget(vowel_spec.rad2) == rget(vowel_spec.rad3) and not req(vowel_spec.rad2, Y) local hayy_i_x = hayy_radicals(vowel_spec.rad1, vowel_spec.rad2, vowel_spec.rad3) and (vform == "I" or vform == "X") if form_iii_vi_geminate or hayy_i_x then if vowel_spec.variant and vowel_spec.variant ~= "long" and vowel_spec.variant ~= "short" and vowel_spec.variant ~= "both" then error(("For form-III/VI geminate verb or form-I/X verb with ح-ي-ي radicals, saw unrecognized 'var:%s' value; should be 'var:long', 'var:short' or 'var:both'"):format( vowel_spec.variant)) end elseif vowel_spec.variant then error(("Variant value 'var:%s' not allowed in this context"):format(vowel_spec.variant)) end end -- If form I, regroup expanded vowels for display purposes. if vform == "I" then local group_by_past = {} for _, vowel_spec in ipairs(base.conj_vowels) do m_table.insertIfNot(group_by_past, { past = undia[rget(vowel_spec.past)], nonpasts = {undia[rget(vowel_spec.nonpast)]}, }, { key = function(obj) return obj.past end, combine = function(obj1, obj2) for _, nonpast in ipairs(obj2.nonpasts) do m_table.insertIfNot(obj1.nonpasts, nonpast) end end, }) end local group_by_nonpast = {} for _, vowel_spec in ipairs(group_by_past) do m_table.insertIfNot(group_by_nonpast, { pasts = {vowel_spec.past}, nonpasts = vowel_spec.nonpasts, }, { key = function(obj) return obj.nonpasts end, combine = function(obj1, obj2) for _, past in ipairs(obj2.pasts) do m_table.insertIfNot(obj1.pasts, past) end end, }) end base.grouped_conj_vowels = group_by_nonpast end -- Set value of passive. If not specified, default is yes for forms II, III, IV and Iq; no but uncertainly for -- forms VII, IX, XI - XV and IIIq - IVq, as well as form I with past vowel u; impersonal but uncertainly for form -- V, VI, X and IIq, as well as form I with past vowel i; and yes but uncertainly for the remainder (form I with -- past vowel only a and form VIII). if not base.passive then base.passive_defaulted = true -- Temporary tracking for defaulted passives by verb form, weakness and (for form I) past/non-past vowels. track_if_ar_conj(base, "passive-defaulted/" .. vform) for _, vowel_spec in ipairs(base.conj_vowels) do track_if_ar_conj(base, "passive-defaulted/" .. vform.. "/" .. vowel_spec.weakness) if vform == "I" then local past_nonpast = ("%s~%s"):format(undia[vowel_spec.past], undia[vowel_spec.nonpast]) track_if_ar_conj(base, "passive-defaulted/I/" .. past_nonpast) track_if_ar_conj(base, "passive-defaulted/I/" .. vowel_spec.weakness .. "/" .. past_nonpast) end end if vform_probably_full_passive(vform) then base.passive = "pass" else base.passive_uncertain = true for _, vowel_spec in ipairs(base.conj_vowels) do if vform_probably_no_passive(vform, vowel_spec.weakness, vowel_spec.past, vowel_spec.nonpast) then base.passive = "nopass" break elseif vform_probably_impersonal_passive(vform, vowel_spec.weakness, vowel_spec.past, vowel_spec.nonpast) then base.passive = "ipass" break end end base.passive = base.passive or "pass" end end -- NOTE: Currently there are no built-in stems or form overrides for Arabic; this code is inherited from -- [[Module:ca-verb]], where such things do exist, and is kept for generality in case we decide in the future to -- implement such things. -- Override built-in verb stems and overrides with user-specified ones. for stem, values in pairs(base.user_stem_overrides) do base.stem_overrides[stem] = values end for slot, values in pairs(base.user_slot_overrides) do if not base.alternant_multiword_spec.verb_slots_map[slot] then error("Unrecognized override slot '" .. slot .. "': " .. base.angle_bracket_spec) end if export.unsettable_slots_set[slot] then error("Slot '" .. slot .. "' cannot be set using an override: " .. base.angle_bracket_spec) end if skip_slot(base, slot, "allow overrides") then error("Override slot '" .. slot .. "' would be skipped based on the passive, 'noimp' and/or 'no_nonpast' settings: " .. base.angle_bracket_spec) end base.slot_overrides[slot] = values end if base.verb_form == "none-final-weak" then for _, stem_type in ipairs { "past", "past_pass", "nonpast", "nonpast_pass" } do if base.stem_overrides[stem_type .. "_c"] or base.stem_overrides[stem_type .. "_v"] then error(("Specify past stem for verb type 'none-final-weak' using '%s:...' not '%s_c:...' or '%s_v:...'"): format(stem_type, stem_type, stem_type)) end end for _, stem_type in ipairs { "past", "nonpast" } do if base.stem_overrides[stem_type] or not base.stem_overrides[stem_type .. "_final_weak_vowel"] then error(("For verb type 'none-final-weak', if '%s:...' specified, so must '%s_final_weak_vowel:...'"): format(stem_type, stem_type)) end end end end local function detect_all_indicator_specs(alternant_multiword_spec) add_slots(alternant_multiword_spec) alternant_multiword_spec.verb_forms = {} -- This means at least one individual base had the slot marked as explicitly missing. Another base (e.g. when -- there are multiple alternants) might have a value for the slot. In practice, we only respect this when there are -- no overall values in the slot and `slot_uncertain` isn't set; in this case, we display "no ..." for the slot -- instead of simply not displaying anything for the slot. alternant_multiword_spec.slot_explicitly_missing = {} -- This means at least one individual base had no values for the slot and the slot marked as explicitly uncertain. -- Note that this is different from a value being present but marked as uncertain (e.g. if an override was given -- with a ? after it); this causes the form object for the value to have `uncertain = true` set. If there are no -- overall values in the slot and `slot_uncertain` is set, we display this in the headword. alternant_multiword_spec.slot_uncertain = {} iut.map_word_specs(alternant_multiword_spec, function(base) -- So arguments, etc. can be accessed. WARNING: Creates circular reference. base.alternant_multiword_spec = alternant_multiword_spec detect_indicator_spec(base) if not base.nocat then m_table.insertIfNot(alternant_multiword_spec.verb_forms, base.verb_form) end if base.passive then alternant_multiword_spec.passive = base.passive end if base.passive_uncertain then alternant_multiword_spec.passive_uncertain = true end for slot, _ in pairs(base.slot_explicitly_missing) do alternant_multiword_spec.slot_explicitly_missing[slot] = true end end) end local function determine_slot_uncertainty_from_forms(alternant_multiword_spec) iut.map_word_specs(alternant_multiword_spec, function(base) -- If no verbal noun and verb form is not 'none' (manually-specified stems) — which currently only happens for -- form I — and the verbal noun wasn't explicitly indicated as missing using <vn:->, we assume it's just -- unknown/unspecified rather than missing. Same with active participles. for uncertain_slot, _ in pairs(slots_that_may_be_uncertain) do if not base.forms[uncertain_slot] and vform ~= "none" and not skip_slot(base, uncertain_slot) then base.slot_uncertain[uncertain_slot] = true end end -- Propagate slot uncertainty up. Currently only the verbal noun can have this set but we write the code -- generally. for slot, _ in pairs(base.slot_uncertain) do alternant_multiword_spec.slot_uncertain[slot] = true end end) -- If slot is uncertain and has no value, explicitly set its value to "?". for uncertain_slot, _ in pairs(slots_that_may_be_uncertain) do if not alternant_multiword_spec.forms[uncertain_slot] and alternant_multiword_spec.slot_uncertain[uncertain_slot] then alternant_multiword_spec.forms[uncertain_slot] = {{form = "?"}} end end end -- Determine certain properties of the verb from the overall forms, such as whether the verb is active-only or -- passive-only, is impersonal, lacks an imperative, etc. local function determine_verb_properties_from_forms(alternant_multiword_spec) alternant_multiword_spec.has_active = false alternant_multiword_spec.has_passive = false alternant_multiword_spec.has_non_impers_active = false alternant_multiword_spec.has_non_impers_passive = false alternant_multiword_spec.has_imp = false alternant_multiword_spec.has_past = false alternant_multiword_spec.has_nonpast = false for slot, _ in pairs(alternant_multiword_spec.forms) do if slot == "ap" or slot:find("[123]") and not slot:find("_pass") then alternant_multiword_spec.has_active = true end if slot == "pp" or slot:find("[123]") and slot:find("_pass") then alternant_multiword_spec.has_passive = true end if slot:find("[123]") and not slot:find("pass_[123]") and not slot:find("3ms") then alternant_multiword_spec.has_non_impers_active = true end if slot:find("pass_[123]") and not slot:find("3ms") then alternant_multiword_spec.has_non_impers_passive = true end if slot:find("^imp_") then alternant_multiword_spec.has_imp = true end if slot:find("^past_") then alternant_multiword_spec.has_past = true end if slot:find("^ind_") or slot:find("^sub_") or slot:find("^juss_") then alternant_multiword_spec.has_nonpast = true end end end local function add_categories_and_annotation(alternant_multiword_spec, base, multiword_lemma, insert_ann, insert_cat) -- Useful e.g. in constructing suppletive verbs out of parts. For a verb like جاء or أتى whose imperative comes -- from the unrelated verb تعالى, we don't want the latter verb showing up in categories or annotations. if base.nocat then return end local vform = base.verb_form if vform ~= "none" then insert_ann("form", vform) insert_cat("form-" .. vform .. " verbs") --W: Add morphological pattern corresponding to the form local morph_pattern = FORM_TO_MORPHOLOGICAL_PATTERN[vform] if morph_pattern then insert_ann("morph_pattern", morph_pattern) end end if base.reduced then insert_ann("reduced", "reduced") if vform ~= "none" then insert_cat("form-" .. vform .. " reduced verbs") end end if base.quadlit then insert_cat("verbs with quadriliteral roots") end if base.passive_defaulted then insert_cat("verbs with defaulted passive") end for _, vowel_spec in ipairs(base.conj_vowels) do local rad1, rad2, rad3, rad4 = get_radicals_4(vowel_spec) local final_weak = is_final_weak(base, vowel_spec) local weakness = vowel_spec.weakness -- We have to distinguish weakness by form and weakness by conjugation. Weakness by form merely indicates the -- presence of weak letters in certain positions in the radicals. Weakness by conjugation is related to how the -- verbs are conjugated. For example, form-II verbs that are "hollow by form" (middle radical is wāw or yāʾ) are -- conjugated as sound verbs. Another example: form-I verbs with initial wāw are "assimilated by form" and most -- are assimilated by conjugation as well, but a few are sound by conjugation, e.g. wajuha yawjuhu "to be -- distinguished" (rather than wajuha yajuhu); similarly for some hollow-by-form verbs in various forms, e.g. -- form VIII izdawaja yazdawiju "to be in pairs" (rather than izdāja yazdāju). Categories referring to weakness -- always refer to weakness by conjugation; weakness by form is distinguished only by categories such as -- [[:Category:Arabic form-III verbs with و as second radical]]. insert_ann("weakness", weakness) if vform ~= "none" then insert_cat(("%s form-%s verbs"):format(weakness, vform)) end local function radical_is_ambiguous(rad) return type(rad) == "table" and rad.ambig end local function radical_is_unambiguous_weak(rad) return not radical_is_ambiguous(rad) and (is_waw_ya(rad) or req(rad, HAMZA)) end if vform ~= "none" then local ur1, ur2, ur3, ur4 = vowel_spec.unreg_rad1, vowel_spec.unreg_rad2, vowel_spec.unreg_rad3, vowel_spec.unreg_rad4 -- Create headword categories based on the radicals. Do the following before -- converting the Latin radicals into Arabic ones so we distinguish -- between ambiguous and non-ambiguous radicals. if radical_is_ambiguous(ur1) or radical_is_ambiguous(ur2) or radical_is_ambiguous(ur3) or ur4 and radical_is_ambiguous(ur4) then insert_cat("verbs with ambiguous radicals") end if radical_is_unambiguous_weak(ur1) then insert_cat("form-" .. vform .. " verbs with " .. rget(ur1) .. " as first radical") end if radical_is_unambiguous_weak(ur2) then insert_cat("form-" .. vform .. " verbs with " .. rget(ur2) .. " as second radical") end if radical_is_unambiguous_weak(ur3) then insert_cat("form-" .. vform .. " verbs with " .. rget(ur3) .. " as third radical") end if ur4 and radical_is_unambiguous_weak(ur4) then insert_cat("form-" .. vform .. " verbs with " .. rget(ur4) .. " as fourth radical") end end end if vform == "I" and not is_passive_only(base.passive) then for _, vowel_spec in ipairs(base.grouped_conj_vowels) do insert_ann("vowels", ("%s ~ %s"):format(table.concat(vowel_spec.pasts, "/"), table.concat(vowel_spec.nonpasts, "/"))) for _, past in ipairs(vowel_spec.pasts) do for _, nonpast in ipairs(vowel_spec.nonpasts) do if past == "-" or nonpast == "-" then error("Internal error: Saw form I past vowel %s and non-past vowel %s but - in place of vowel should have triggered an error earlier") end insert_cat(("form-I verbs with past vowel %s and non-past vowel %s"):format(past, nonpast)) --W: Add morphological pattern for form I based on vowels local form_i_with_vowels = ("I/%s~%s"):format(past, nonpast) local morph_pattern = FORM_TO_MORPHOLOGICAL_PATTERN[form_i_with_vowels] if morph_pattern then insert_ann("morph_pattern", morph_pattern) end end end end end for slot, name in pairs(slots_that_may_be_uncertain) do if base.slot_uncertain[slot] then -- An unspecified and non-defaulted verbal noun (form I) is considered uncertain rather than explicitly -- missing. Use <vn:-> to explicitly indicate the lack of verbal noun. Same for form-I stative active -- participles. insert_cat(("verbs with unknown or uncertain %ss"):format(name)) end end if base.irregular then insert_ann("irreg", "irregular") insert_cat("irregular verbs") end end -- Compute the categories to add the verb to, as well as the annotation to display in the conjugation title bar. We -- combine the code to do these functions as both categories and title bar contain similar information. local function compute_categories_and_annotation(alternant_multiword_spec) alternant_multiword_spec.categories = {} local ann = {} alternant_multiword_spec.annotation = ann ann.form = {} ann.morph_pattern = {} --W: arabic morphological pattern corresponding to the form ann.weakness = {} ann.vowels = {} ann.passive = nil ann.reduced = {} ann.irreg = {} ann.defective = {} local multiword_lemma = false for _, slot in ipairs(export.potential_lemma_slots) do if alternant_multiword_spec.forms[slot] then for _, formobj in ipairs(alternant_multiword_spec.forms[slot]) do if formobj.form:find(" ") then multiword_lemma = true break end end break end end local function insert_ann(anntype, value) m_table.insertIfNot(alternant_multiword_spec.annotation[anntype], value) end local function insert_cat(cat, also_when_multiword) -- Don't place multiword terms in categories like 'Arabic form-II verbs' to avoid spamming the categories with -- such terms. if also_when_multiword or not multiword_lemma then m_table.insertIfNot(alternant_multiword_spec.categories, "Arabic " .. cat) end end iut.map_word_specs(alternant_multiword_spec, function(base) add_categories_and_annotation(alternant_multiword_spec, base, multiword_lemma, insert_ann, insert_cat) end) for slot, name in pairs(slots_that_may_be_uncertain) do if alternant_multiword_spec.forms[slot] then for _, form in ipairs(alternant_multiword_spec.forms[slot]) do if form.uncertain then if form.form == "?" then insert_cat(("verbs with explicitly unknown %ss"):format(name)) else insert_cat(("verbs needing %s checked"):format(name)) end break end end end end if alternant_multiword_spec.has_active then if alternant_multiword_spec.has_passive and alternant_multiword_spec.has_non_impers_passive then insert_cat("verbs with full passive") ann.passive = "full passive" elseif alternant_multiword_spec.has_passive then insert_cat("verbs with impersonal passive") ann.passive = "impersonal passive" else insert_cat("verbs lacking passive forms") ann.passive = "no passive" end else if alternant_multiword_spec.has_non_impers_passive then insert_cat("passive verbs") insert_cat("verbs with full passive") ann.passive = "passive-only" else insert_cat("passive verbs") insert_cat("impersonal verbs") insert_cat("verbs with impersonal passive") ann.passive = "impersonal (passive-only)" end end if alternant_multiword_spec.passive_uncertain then insert_cat("verbs needing passive checked") ann.passive = ann.passive .. ' <abbr title="passive status uncertain">(?)</abbr>' end if alternant_multiword_spec.has_active and not alternant_multiword_spec.has_imp then insert_ann("defective", "no imperative") insert_cat("verbs lacking imperative forms") end if not alternant_multiword_spec.has_past then insert_ann("defective", "no past") insert_cat("verbs lacking past forms") end if not alternant_multiword_spec.has_nonpast then insert_ann("defective", "no non-past") insert_cat("verbs lacking non-past forms") end local ann_parts = {} local function insert_ann_part(part, conj) local val = table.concat(ann[part], conj or " or ") if val ~= "" and val ~= "regular" then table.insert(ann_parts, val) end end insert_ann_part("form") insert_ann_part("weakness") insert_ann_part("reduced") insert_ann_part("vowels") if ann.passive then table.insert(ann_parts, ann.passive) end insert_ann_part("irreg") insert_ann_part("defective", "، ") --W: Save morph_pattern before overwriting annotation with string alternant_multiword_spec.morph_pattern = ann.morph_pattern alternant_multiword_spec.annotation = table.concat(ann_parts, "، ") end local function show_forms(alternant_multiword_spec) local lemmas = {} for _, slot in ipairs(export.potential_lemma_slots) do if alternant_multiword_spec.forms[slot] then for _, formobj in ipairs(alternant_multiword_spec.forms[slot]) do table.insert(lemmas, formobj) end break end end alternant_multiword_spec.lemmas = lemmas -- save for later use in make_table() alternant_multiword_spec.vn = alternant_multiword_spec.forms.vn -- save for later use in make_table() -- Reconstruct the original verb spec without overrides for verbal nouns and participles, since those specific slots -- are ignored by {{ar-verb form}}. Compute this once beforehand; `transform_accel_obj` is called repeatedly on each -- form and we don't want to compute this repeatedly. local reconstructed_verb_spec = iut.reconstruct_original_spec(alternant_multiword_spec, { preprocess_angle_bracket_spec = function(spec) spec = spec:match("^<(.*)>$") assert(spec) local segments = put.parse_multi_delimiter_balanced_segment_run(spec, {{"[", "]"}, {"<", ">"}}) local dot_separated_groups = put.split_alternating_runs_and_strip_spaces(segments, "%.") -- Rejoin each dot-separated group into a single string, since we aren't actually going to do any parsing -- of bracket-bounded textual runs; then filter out overrides for verbal nouns and participles. local filtered_indicators = {} for _, dot_separated_group in ipairs(dot_separated_groups) do local indicator = table.concat(dot_separated_group) -- FIXME: Do we want to filter out any other indicators? if not (indicator:find("^vn:") or indicator:find("^[ap]p:")) then table.insert(filtered_indicators, indicator) end end return ("<%s>"):format(table.concat(filtered_indicators, ".")) end, }) -- If we're dealing with a single word, no alternants and a single verb form, use the auto-conjugation-fetching -- variant. local reconstructed_lemma, inside = reconstructed_verb_spec:match("^([^ <>()]+)(%b<>)$") if inside and alternant_multiword_spec.verb_forms[1] and not alternant_multiword_spec.verb_forms[2] then reconstructed_verb_spec = ("+%s<%s>"):format(reconstructed_lemma, alternant_multiword_spec.verb_forms[1]) end local function transform_accel_obj(slot, formobj, accel_obj) if not accel_obj then return accel_obj end if slot == "ap" or slot == "pp" or slot == "vn" then -- FIXME: [[Module:accel]] can't correctly handle more than one verb form for participles and verbal nouns accel_obj.form = slot .. "-" .. table.concat(alternant_multiword_spec.verb_forms, "،") else accel_obj.form = "verb-form-" .. reconstructed_verb_spec end return accel_obj end local function generate_link(data) local form = data.form local term = form.formval_for_link local alt = form.alt if term == "?" then term = nil alt = "?" end --W: Create simple link for verb forms without #Arabic anchor local display = alt or term local link if display then link = link_term_simple(display) else link = "" end link = link .. iut.get_footnote_text(form.footnotes, data.footnote_obj) if form.q and form.q[1] or form.qq and form.qq[1] or form.l and form.l[1] or form.ll and form.ll[1] then link = require(pron_qualifier_module).format_qualifiers { lang = lang, text = link, q = form.q, qq = form.qq, l = form.l, ll = form.ll, } end return link end local props = { lang = lang, lemmas = lemmas, transform_accel_obj = transform_accel_obj, generate_link = generate_link, slot_list = alternant_multiword_spec.verb_slots, include_translit = false, } iut.show_forms(alternant_multiword_spec.forms, props) end ------------------------------------------------------------------------------- -- Functions to create inflection tables -- ------------------------------------------------------------------------------- -- Make the conjugation table. Called from export.show(). local function make_table(alternant_multiword_spec) local text = mw.getCurrentFrame():expandTemplate{ title = 'inflection-table-top', args = { title = 'تصريف {title}', tall = 'yes', palette = 'green', category = 'conjugation', class = 'tr-alongside', -- temp hack to prevent extra line break } } text = text .. [=[ ! colspan="6" | <<الْمَصْدَر>> | colspan="7" | {vn} ]=] if alternant_multiword_spec.has_active then text = text .. [=[ |- ! colspan="6" | <<اِسْم الْفَاعِل>> | colspan="7" | {ap} ]=] end if alternant_multiword_spec.has_passive then text = text .. [=[ |- ! colspan="6" | <<اِسْم الْمَفْعُول>> | colspan="7" | {pp} ]=] end text = text .. [=[ |- ! colspan="999" class="separator" | ]=] if alternant_multiword_spec.has_active then text = text .. [=[ |- ! colspan="12" class="outer" | <<الْفِعْل الْمَعْلُوم>> |- ! colspan="2" | ! colspan="3" | <<الْمُفْرَد>> ! rowspan="12" class="separator" | ! colspan="2" | <<الْمُثَنَّى>> ! rowspan="12" class="separator" | ! colspan="3"| <<الْجَمْع>> |- ! colspan="2"| ! <<الْمُتَكَلِّم>> ! <<الْمُخَاطَب>> ! <<الْغَائِب>> ! <<الْمُخَاطَب>> ! <<الْغَائِب>> ! <<الْمُتَكَلِّم>> ! <<الْمُخَاطَب>> ! <<الْغَائِب>> |- ! rowspan="2" | <<الْمَاضِي>> ! class="secondary" | المذكر | rowspan="2" | {past_1s} | {past_2ms} | {past_3ms} | rowspan="2" | {past_2d} | {past_3md} | rowspan="2" | {past_1p} | {past_2mp} | {past_3mp} |- ! class="secondary" | المؤنث | {past_2fs} | {past_3fs} | {past_3fd} | {past_2fp} | {past_3fp} |- ! rowspan="2" | <<الْمُضَارِع الْمَرْفُوع>> ! class="secondary" | المذكر | rowspan="2" | {ind_1s} | {ind_2ms} | {ind_3ms} | rowspan="2" | {ind_2d} | {ind_3md} | rowspan="2" | {ind_1p} | {ind_2mp} | {ind_3mp} |- ! class="secondary" | المؤنث | {ind_2fs} | {ind_3fs} | {ind_3fd} | {ind_2fp} | {ind_3fp} |- ! rowspan="2" | <<الْمُضَارِع الْمَنْصُوب>> ! class="secondary" | المذكر | rowspan="2" | {sub_1s} | {sub_2ms} | {sub_3ms} | rowspan="2" | {sub_2d} | {sub_3md} | rowspan="2" | {sub_1p} | {sub_2mp} | {sub_3mp} |- ! class="secondary" | المؤنث | {sub_2fs} | {sub_3fs} | {sub_3fd} | {sub_2fp} | {sub_3fp} |- ! rowspan="2" | <<الْمُضَارِع الْمَجْزُوم>> ! class="secondary" | المذكر | rowspan="2" | {juss_1s} | {juss_2ms} | {juss_3ms} | rowspan="2" | {juss_2d} | {juss_3md} | rowspan="2" | {juss_1p} | {juss_2mp} | {juss_3mp} |- ! class="secondary" | المؤنث | {juss_2fs} | {juss_3fs} | {juss_3fd} | {juss_2fp} | {juss_3fp} |- ! rowspan="2" | <<الْأَمْر>> ! class="secondary" | المذكر | rowspan="2" | | {imp_2ms} | rowspan="2" | | rowspan="2" | {imp_2d} | rowspan="2" | | rowspan="2" | | {imp_2mp} | rowspan="2" | |- ! class="secondary" | المؤنث | {imp_2fs} | {imp_2fp} ]=] end if alternant_multiword_spec.has_passive then text = text .. [=[ |- ! colspan="999" class="separator" | |- ! colspan="12" class="outer" | <<الْفِعْل الْمَجْهُول>> |- ! colspan="2" | ! colspan="3" | <<الْمُفْرَد>> ! rowspan="10" class="separator" | ! colspan="2" | <<الْمُثَنَّى>> ! rowspan="10" class="separator" | ! colspan="3" | <<الْجَمْع>> |- ! colspan="2" | ! <<الْمُتَكَلِّم>> ! <<الْمُخَاطَب>> ! <<الْغَائِب>> ! <<الْمُخَاطَب>> ! <<الْغَائِب>> ! <<الْمُتَكَلِّم>> ! <<الْمُخَاطَب>> ! <<الْغَائِب>> |- ! rowspan="2" | <<الْمَاضِي>> ! class="secondary" | المذكر | rowspan="2" | {past_pass_1s} | {past_pass_2ms} | {past_pass_3ms} | rowspan="2" | {past_pass_2d} | {past_pass_3md} | rowspan="2" | {past_pass_1p} | {past_pass_2mp} | {past_pass_3mp} |- ! class="secondary" | المؤنث | {past_pass_2fs} | {past_pass_3fs} | {past_pass_3fd} | {past_pass_2fp} | {past_pass_3fp} |- ! rowspan="2" | <<الْمُضَارِع الْمَرْفُوع>> ! class="secondary" | المذكر | rowspan="2" | {ind_pass_1s} | {ind_pass_2ms} | {ind_pass_3ms} | rowspan="2" | {ind_pass_2d} | {ind_pass_3md} | rowspan="2" | {ind_pass_1p} | {ind_pass_2mp} | {ind_pass_3mp} |- ! class="secondary" | المؤنث | {ind_pass_2fs} | {ind_pass_3fs} | {ind_pass_3fd} | {ind_pass_2fp} | {ind_pass_3fp} |- ! rowspan="2" | <<الْمُضَارِع الْمَنْصُوب>> ! class="secondary" | المذكر | rowspan="2" | {sub_pass_1s} | {sub_pass_2ms} | {sub_pass_3ms} | rowspan="2" | {sub_pass_2d} | {sub_pass_3md} | rowspan="2" | {sub_pass_1p} | {sub_pass_2mp} | {sub_pass_3mp} |- ! class="secondary" | المؤنث | {sub_pass_2fs} | {sub_pass_3fs} | {sub_pass_3fd} | {sub_pass_2fp} | {sub_pass_3fp} |- ! rowspan="2" | <<الْمُضَارِع الْمَجْزُوم>> ! class="secondary" | المذكر | rowspan="2" | {juss_pass_1s} | {juss_pass_2ms} | {juss_pass_3ms} | rowspan="2" | {juss_pass_2d} | {juss_pass_3md} | rowspan="2" | {juss_pass_1p} | {juss_pass_2mp} | {juss_pass_3mp} |- ! class="secondary" | المؤنث | {juss_pass_2fs} | {juss_pass_3fs} | {juss_pass_3fd} | {juss_pass_2fp} | {juss_pass_3fp} ]=] end text = text .. mw.getCurrentFrame():expandTemplate{ title = 'inflection-table-bottom', args = { notes = '{footnote}', } } local forms = alternant_multiword_spec.forms if not alternant_multiword_spec.lemmas then forms.title = "—" else local linked_lemmas = {} for _, form in ipairs(alternant_multiword_spec.lemmas) do --W: Create simple link for lemmas without #Arabic anchor -- table.insert(linked_lemmas, link_term(form.form, "term")) table.insert(linked_lemmas, link_term_simple(form.form)) end forms.title = table.concat(linked_lemmas, "، ") end local ann_parts = {} if alternant_multiword_spec.annotation ~= "" then table.insert(ann_parts, alternant_multiword_spec.annotation) end if alternant_multiword_spec.vn then local linked_vns = {} for _, form in ipairs(alternant_multiword_spec.vn) do table.insert(linked_vns, link_term(form.form, "term")) end table.insert(ann_parts, (#linked_vns > 1 and "verbal nouns" or "verbal noun") .. " " .. table.concat(linked_vns, "، ")) end local annotation = table.concat(ann_parts, "، ") --W: use only arabic morphological pattern in title annotation local morph_patterns = alternant_multiword_spec.morph_pattern if morph_patterns and #morph_patterns > 0 then annotation = table.concat(morph_patterns, "، ") forms.title = forms.title .. " (" .. annotation .. ")" end -- Format the table. local tagged_table = rsub(text, "<<(.-)>>", tag_text) return m_string_utilities.format(tagged_table, forms) end -- Helper function to get root letters and verb classification for simplified table header -- Returns: root_display (e.g., "ح س ب"), verb_type (e.g., "فعل ثلاثي صحيح سالم") local function get_verb_info(alternant_multiword_spec) local root_display = "" local verb_type = "فعل" local rad1, rad2, rad3, rad4 -- Extract radicals from the base word spec using iut.map_word_specs -- This accesses the radicals directly from the parsed verb specification iut.map_word_specs(alternant_multiword_spec, function(base) -- Get radicals from the first conjugation vowel spec if base.conj_vowels and #base.conj_vowels > 0 then local vowel_spec = base.conj_vowels[1] -- Extract radicals, handling both table and string types local function extract_radical(rad) if type(rad) == "table" then -- If it's a table, get the first element or the string representation return rad[1] or rget(rad) else return rad end end rad1 = extract_radical(vowel_spec.rad1) rad2 = extract_radical(vowel_spec.rad2) rad3 = extract_radical(vowel_spec.rad3) rad4 = vowel_spec.rad4 and extract_radical(vowel_spec.rad4) end end) -- Get basic/derived classification from morphological pattern local basic_deriv if alternant_multiword_spec.morph_pattern and #alternant_multiword_spec.morph_pattern > 0 then local morph_pattern = alternant_multiword_spec.morph_pattern[1] basic_deriv = MORPHOLOGICAL_PATTERN_TO_BASIC_DERIV[morph_pattern] end -- Format root display with spaces between letters if rad1 and rad2 and rad3 then if rad4 then -- Quadrilateral root_display = rad1 .. " " .. rad2 .. " " .. rad3 .. " " .. rad4 verb_type = "فعل رباعي" if basic_deriv then verb_type = verb_type .. " " .. basic_deriv end else -- triliteral root_display = rad1 .. " " .. rad2 .. " " .. rad3 verb_type = "فعل ثلاثي" if basic_deriv then verb_type = verb_type .. " " .. basic_deriv if basic_deriv == "مُجرَّد" then --W: the classification concerns only triliteral basic verbs (الثلاثي المُجرَّد) local classification = export.classify_triliteral_verb(rad1, rad2, rad3) verb_type = verb_type .. " " .. classification end end end end return root_display, verb_type end -- Make simplified conjugation table for ar.wiktionary. Called from export.show(). -- This table shows only past, present indicative, and imperative forms. -- No passive voice, no participles, no verbal nouns. local function make_table_ar(alternant_multiword_spec) local text = mw.getCurrentFrame():expandTemplate{ title = 'inflection-table-top', args = { title = 'تصريف {title}', tall = 'yes', palette = 'green', category = 'conjugation', class = 'tr-alongside', -- temp hack to prevent extra line break } } -- Get verb root and classification local root_display, verb_type = get_verb_info(alternant_multiword_spec) -- First row: Root and verb type spanning all columns text = text .. "! colspan=\"2\" | <<الجذر>>: " .. root_display .. "\n" text = text .. "| colspan=\"3\" | <<'''" .. verb_type .. "'''>>\n" text = text .. [=[ |- ! colspan="2" | <<الضمائر>> ! <<الماضي>> ! <<المضارع>> ! <<الأمر>> |- ! rowspan="2" | <<المتكلّم>> | <<أنا>> | {past_1s} | {ind_1s} | |- | <<نحن>> | {past_1p} | {ind_1p} | |- ! rowspan="5" | <<المخاطب>> | <<أنتَ>> | {past_2ms} | {ind_2ms} | {imp_2ms} |- | <<أنتِ>> | {past_2fs} | {ind_2fs} | {imp_2fs} |- | <<أنتما>> | {past_2d} | {ind_2d} | {imp_2d} |- | <<أنتم>> | {past_2mp} | {ind_2mp} | {imp_2mp} |- | <<أنتنّ>> | {past_2fp} | {ind_2fp} | {imp_2fp} |- ! rowspan="6" | <<الغائب>> | <<هو>> | {past_3ms} | {ind_3ms} | |- | <<هي>> | {past_3fs} | {ind_3fs} | |- | <<هما>> | {past_3md} | {ind_3md} | |- | <<هما>> | {past_3fd} | {ind_3fd} | |- | <<هم>> | {past_3mp} | {ind_3mp} | |- | <<هنّ>> | {past_3fp} | {ind_3fp} | ]=] text = text .. mw.getCurrentFrame():expandTemplate{ title = 'inflection-table-bottom', args = { notes = '{footnote}', } } local forms = alternant_multiword_spec.forms if not alternant_multiword_spec.lemmas then forms.title = "—" else local linked_lemmas = {} for _, form in ipairs(alternant_multiword_spec.lemmas) do --W: Create simple link for lemmas without #Arabic anchor -- table.insert(linked_lemmas, link_term(form.form, "term")) table.insert(linked_lemmas, link_term_simple(form.form)) end forms.title = table.concat(linked_lemmas, "، ") end local ann_parts = {} if alternant_multiword_spec.annotation ~= "" then table.insert(ann_parts, alternant_multiword_spec.annotation) end local annotation = table.concat(ann_parts, "، ") --W: use only arabic morphological pattern in title annotation local morph_patterns = alternant_multiword_spec.morph_pattern if morph_patterns and #morph_patterns > 0 then annotation = table.concat(morph_patterns, "، ") forms.title = forms.title .. " (" .. annotation .. ")" end -- Format the table. local tagged_table = rsub(text, "<<(.-)>>", tag_text) return m_string_utilities.format(tagged_table, forms) end ------------------------------------------------------------------------------- -- Verb classification functions -- ------------------------------------------------------------------------------- --[=[ تصنيف الفعل الثلاثي المُجرَّد حسب نوعه Classify an Arabic triliteral basic verb root based on its three letters. @param r1 الحرف الأول (first root letter - الفاء) @param r2 الحرف الثاني (second root letter - العين) @param r3 الحرف الثالث (third root letter - اللام) @return str: نوع الفعل (verb type classification in Arabic) Examples: classify_triliteral_verb('ك', 'ت', 'ب') --> 'صحيح سالم' classify_triliteral_verb('أ', 'ت', 'ي') --> 'معتل ناقص يائي مهموز الفاء' classify_triliteral_verb('ق', 'ل', 'و') --> 'معتل ناقص واوي' ]=] function export.classify_triliteral_verb(r1, r2, r3) -- تعريف أحرف العلة والهمزة -- الحروف الضعيفة (أحرف العلة): واو وياء فقط local weak_letters = {[W] = true, [Y] = true} -- الهمزة: جميع أشكال الهمزة (ء، أ، إ، ؤ، ئ) local hamza_letters = { [HAMZA] = true, -- ء [HAMZA_ON_ALIF] = true, -- أ [HAMZA_UNDER_ALIF] = true, -- إ [HAMZA_ON_W] = true, -- ؤ [HAMZA_ON_Y] = true -- ئ } -- فحص كل حرف local is_hamza = {hamza_letters[r1] or false, hamza_letters[r2] or false, hamza_letters[r3] or false} local is_weak = {weak_letters[r1] or false, weak_letters[r2] or false, weak_letters[r3] or false} -- عدد أحرف العلة local weak_count = (is_weak[1] and 1 or 0) + (is_weak[2] and 1 or 0) + (is_weak[3] and 1 or 0) -- فحص التضعيف (الحرف الثاني = الثالث) local is_doubled = (r2 == r3) -- ═══════════════════════════════════════════════════════════ -- المُعتل: الفعل الذي يحتوي على حرف أو أكثر من أحرف العلة -- ═══════════════════════════════════════════════════════════ if weak_count > 0 then -- ───────────────────────────────────────────────────── -- لفيف: يحتوي على حرفين أو أكثر من أحرف العلة -- ───────────────────────────────────────────────────── if weak_count >= 2 then -- مقرون: حرفا العلة متجاوران if is_weak[2] and is_weak[3] then -- الثاني والثالث if is_hamza[1] then return "معتل لفيف مقرون مهموز الفاء" end return "معتل لفيف مقرون" elseif is_weak[1] and is_weak[2] then -- الأول والثاني return "معتل لفيف مقرون" -- مفروق: الأول والثالث حرفا علة elseif is_weak[1] and is_weak[3] then if is_hamza[2] then return "معتل لفيف مفروق مهموز العين" end return "معتل لفيف مفروق" end -- ───────────────────────────────────────────────────── -- مثال: الحرف الأول حرف علة -- ───────────────────────────────────────────────────── elseif is_weak[1] then if r1 == W then -- واوي if is_hamza[3] then return "معتل مثال واوي مهموز اللام" elseif is_doubled then return "معتل مثال واوي مُضعَّف" elseif is_hamza[2] then return "معتل مثال واوي مهموز العين" end return "معتل مثال واوي" else -- يائي (ي) if is_doubled then return "معتل مثال يائي مُضعَّف" elseif is_hamza[2] then return "معتل مثال يائي مهموز العين" end return "معتل مثال يائي" end -- ───────────────────────────────────────────────────── -- أجوف: الحرف الثاني حرف علة -- ───────────────────────────────────────────────────── elseif is_weak[2] then if r2 == W then -- واوي if is_hamza[3] then return "معتل أجوف واوي مهموز اللام" elseif is_hamza[1] then return "معتل أجوف واوي مهموز الفاء" end return "معتل أجوف واوي" else -- يائي (ي) if is_hamza[3] then return "معتل أجوف يائي مهموز اللام" elseif is_hamza[1] then return "معتل أجوف يائي مهموز الفاء" end return "معتل أجوف يائي" end -- ───────────────────────────────────────────────────── -- ناقص: الحرف الثالث حرف علة -- ───────────────────────────────────────────────────── elseif is_weak[3] then if r3 == W then -- واوي if is_hamza[1] then return "معتل ناقص واوي مهموز الفاء" elseif is_hamza[2] then return "معتل ناقص واوي مهموز العين" end return "معتل ناقص واوي" else -- يائي (ي) if is_hamza[1] then return "معتل ناقص يائي مهموز الفاء" elseif is_hamza[2] then return "معتل ناقص يائي مهموز العين" end return "معتل ناقص يائي" end end -- ═══════════════════════════════════════════════════════════ -- الصحيح: الفعل الذي لا يحتوي على أحرف العلة -- ═══════════════════════════════════════════════════════════ else -- ───────────────────────────────────────────────────── -- مهموز: يحتوي على همزة -- ───────────────────────────────────────────────────── if is_hamza[1] or is_hamza[2] or is_hamza[3] then -- مهموز الفاء واللام: الأول والثالث همزة if is_hamza[1] and is_hamza[3] then return "صحيح مهموز الفاء واللام" -- مهموز الفاء elseif is_hamza[1] then if is_doubled then return "صحيح مُضعَّف مهموز الفاء" end return "صحيح مهموز الفاء" -- مهموز العين elseif is_hamza[2] then return "صحيح مهموز العين" -- مهموز اللام elseif is_hamza[3] then return "صحيح مهموز اللام" end -- ───────────────────────────────────────────────────── -- مُضعَّف: الحرف الثاني = الثالث -- ───────────────────────────────────────────────────── elseif is_doubled then return "صحيح مُضعَّف" -- ───────────────────────────────────────────────────── -- سالم: لا همزة، لا حرف علة، لا تضعيف -- ───────────────────────────────────────────────────── else return "صحيح سالم" end end return "غير معروف" end ------------------------------------------------------------------------------- -- External entry points -- ------------------------------------------------------------------------------- --W: Normalize root to use underscores as separators -- Accepts: "كتب", "ك_ت_ب", or "ك ت ب" -- Returns: "ك_ت_ب" local function normalize_root(root) if not root then return nil end -- Helper function to normalize a single character/radical local function normalize_char(char) -- Convert all hamza variants to canonical bare hamza if char == HAMZA_ON_ALIF or char == HAMZA_UNDER_ALIF or char == HAMZA_ON_W or char == HAMZA_ON_Y then return HAMZA -- Convert alif maqṣūra to yaa (ى → ي) elseif char == AMAQ then return Y -- Reject alif - it's not a root radical elseif char == ALIF then error("Root contains alif (ا) which is not a valid root radical. For weak verbs, use و (waw) or ي (yaa) instead.") end return char end -- Convert alif madda to hamza + alif for processing (will be caught as error below) root = root:gsub(AMAD, HAMZA .. ALIF) -- Replace spaces with underscores root = root:gsub(" ", "_") -- If no underscores yet, insert them between each character if not root:find("_") then -- Extract only Arabic letters (excluding diacritics) -- Arabic letter range: U+0621 to U+064A (basic letters) local chars = {} for char in mw.ustring.gmatch(root, "[ء-ي]") do table.insert(chars, normalize_char(char)) end root = table.concat(chars, "_") else -- Root already has underscores (e.g., "أ_م_ن"), normalize each radical local parts = mw.text.split(root, "_") for i, part in ipairs(parts) do parts[i] = normalize_char(part) end root = table.concat(parts, "_") end return root end --W: Construct the [1] parameter from root (جذر) and morphological pattern (وزن) -- Example: -- input: root="كتب", pattern="فعَل يفعُل" -- output: "ك_ت_ب<I/a~u>" local function construct_verb_spec(root, pattern) if not root or not pattern then return nil end local normalized_root = normalize_root(root) local form_code = MORPHOLOGICAL_PATTERN_TO_FORM[pattern] if not form_code then error("Unknown morphological pattern (وزن صرفي): " .. pattern) end return normalized_root .. "<" .. form_code .. ">" end -- Wrapper function that accepts جذر (root) and وزن (pattern) as parameters -- Returns: verb_type (e.g., "فعل ثلاثي مُجرَّد صحيح سالم") -- Example: export.get_verb_type({["جذر"] = "كتب", ["وزن"] = "فعَل يفعُل"}) function export.get_verb_type(args) local verb_spec if args["جذر"] and args["وزن"] then verb_spec = construct_verb_spec(args["جذر"], args["وزن"]) elseif args[1] then verb_spec = args[1] else error("Must provide either جذر and وزن, or a verb specification in args[1]") end local alternant_multiword_spec = export.do_generate_forms({[1] = verb_spec}) local _, verb_type = get_verb_info(alternant_multiword_spec) return verb_type end -- Append two lists `l1` and `l2`, removing duplicates. If either is {nil}, just return the other. local function combine_lists(l1, l2) -- combine_footnotes() does exactly what we want. return iut.combine_footnotes(l1, l2) end local function combine_metadata(data) local src1 = data.form1 local src2 = data.form2 local dest = data.dest_form dest.uncertain = src1.uncertain or src2.uncertain if src1.genders and src2.genders and not m_table.deepEquals(src1.genders, src2.genders) then -- do nothing else dest.genders = src1.genders or src2.genders end if src1.pos and src2.pos and src1.pos ~= src2.pos then -- do nothing else dest.pos = src1.pos or src2.pos end -- Don't copy .alt, .gloss, .lit, .id, which describe a single term and don't extend to multiword terms. dest.q = combine_lists(src1.q, src2.q) dest.qq = combine_lists(src1.qq, src2.qq) dest.l = combine_lists(src1.l, src2.l) dest.ll = combine_lists(src1.ll, src2.ll) end -- Externally callable function to parse and conjugate a verb given user-specified arguments. -- Return value is WORD_SPEC, an object where the conjugated forms are in `WORD_SPEC.forms` -- for each slot. If there are no values for a slot, the slot key will be missing. The value -- for a given slot is a list of objects {form=FORM, footnotes=FOOTNOTES}. function export.do_generate_forms(args, source_template, headword_head) local PAGENAME = mw.loadData("Module:headword/data").pagename local function in_template_space() local nsText = mw.title.getCurrentTitle().nsText return nsText == "Template" or nsText == "قالب" end -- Determine the verb spec we're being asked to generate the conjugation of. This may be taken from the current page -- title or the value of |pagename=; but not when called from {{ar-verb form}}, where the page title is a -- non-lemma form. Note that the verb spec may omit the lemma; e.g. it may be "<II>". For this reason, we use the -- value of `pagename` computed here down below, when calling normalize_all_lemmas(). local pagename = source_template ~= "ar-verb form" and args.pagename or PAGENAME local head = headword_head or pagename --W: If both root (جذر) and morphological pattern (وزن) are provided, construct [1] if args["جذر"] and args["جذر"] ~= "" and args["وزن"] and args["وزن"] ~= "" then local constructed = construct_verb_spec(args["جذر"], args["وزن"]) if constructed and constructed ~= "" then args[1] = constructed end end local arg1 = args[1] if not arg1 then if (pagename == "ar-conj" or pagename == "ar-verb" or pagename == "ar-verb form" or pagename == "تصريف") and in_template_space() then arg1 = "كتب<I/a~u.pass>" else arg1 = "<>" end end -- When called from {{ar-verb form}}, determine the non-lemma form whose inflections we're being asked to -- determine. This normally comes from the page title or the value of |pagename=. local verb_form_of_form if source_template == "ar-verb form" then verb_form_of_form = args.pagename if not verb_form_of_form then if PAGENAME == "ar-verb form" and in_template_space() then verb_form_of_form = "كتبت" else verb_form_of_form = PAGENAME end end end local incorporated_headword_head_into_lemma = false if arg1:find("^<.*>$") then -- missing lemma if head:find(" ") then -- If multiword lemma, try to add arg spec after the first word. -- Try to preserve the brackets in the part after the verb, but don't do it -- if there aren't the same number of left and right brackets in the verb -- (which means the verb was linked as part of a larger expression). local first_word, post = rmatch(head, "^(.-)( .*)$") local left_brackets = rsub(first_word, "[^%[]", "") local right_brackets = rsub(first_word, "[^%]]", "") if #left_brackets == #right_brackets then arg1 = iut.remove_redundant_links(first_word) .. arg1 .. post incorporated_headword_head_into_lemma = true else -- Try again using the form without links. local linkless_head = m_links.remove_links(head) if linkless_head:find(" ") then first_word, post = rmatch(linkless_head, "^(.-)( .*)$") arg1 = first_word .. arg1 .. post else error("Unable to incorporate <...> spec into explicit head due to a multiword linked verb or " .. "unbalanced brackets; please include <> explicitly: " .. arg1) end end else -- Will be incorporated through `head` below in the call to normalize_all_lemmas(). incorporated_headword_head_into_lemma = true end end local parse_props = { parse_indicator_spec = parse_indicator_spec, angle_brackets_omittable = true, allow_blank_lemma = true, } local alternant_multiword_spec = iut.parse_inflected_text(arg1, parse_props) alternant_multiword_spec.pos = pos or "verbs" alternant_multiword_spec.args = args alternant_multiword_spec.source_template = source_template alternant_multiword_spec.verb_form_of_form = verb_form_of_form alternant_multiword_spec.incorporated_headword_head_into_lemma = incorporated_headword_head_into_lemma normalize_all_lemmas(alternant_multiword_spec, head) detect_all_indicator_specs(alternant_multiword_spec) local inflect_props = { lang = lang, slot_list = alternant_multiword_spec.verb_slots, inflect_word_spec = conjugate_verb, combine_metadata = combine_metadata, -- We add links around the generated verbal forms rather than allow the entire multiword -- expression to be a link, so ensure that user-specified links get included as well. include_user_specified_links = true, } iut.inflect_multiword_or_alternant_multiword_spec(alternant_multiword_spec, inflect_props) if debug_translit then for slot, forms in pairs(alternant_multiword_spec.forms) do for _, form in ipairs(forms) do if form.translit then local full_form_translit = (lang:transliterate(m_links.remove_links(form.form))) if full_form_translit ~= form.translit then error(("Internal error: For slot '%s', form '%s' incremental translit '%s' not same as full translit '%s'"): format(slot, form.form, form.translit, full_form_translit)) end end form.form = iut.remove_redundant_links(form.form) end end end -- Remove redundant brackets around entire forms. for slot, forms in pairs(alternant_multiword_spec.forms) do for _, form in ipairs(forms) do form.form = iut.remove_redundant_links(form.form) end end -- Apply NFC-style normalization: reorder shadda+vowel to vowel+shadda -- to match MediaWiki's automatic NFC normalization (which is applied on enwiktionary -- but not in local Lua environments). This reverses the postprocessing step. for slot, forms in pairs(alternant_multiword_spec.forms) do for _, form in ipairs(forms) do form.form = apply_nfc_shadda(form.form) end end determine_slot_uncertainty_from_forms(alternant_multiword_spec) determine_verb_properties_from_forms(alternant_multiword_spec) compute_categories_and_annotation(alternant_multiword_spec) if args.json and source_template == "ar-conj" then -- There is a circular reference in `base.alternant_multiword_spec`, which points back to top level. iut.map_word_specs(alternant_multiword_spec, function(base) base.alternant_multiword_spec = nil end) return require("Module:JSON").toJSON(alternant_multiword_spec) end return alternant_multiword_spec end -- Entry point for {{ar-conj}}. Template-callable function to parse and conjugate a verb given -- user-specified arguments and generate a displayable table of the conjugated forms. function export.show(frame) local parent_args = frame:getParent() and frame:getParent().args or frame.args --W local params = { [1] = {}, ["noautolinktext"] = {type = "boolean"}, ["noautolinkverb"] = {type = "boolean"}, ["t"] = {}, -- for use by {{ar-verb form}}; otherwise ignored ["id"] = {}, -- for use by {{ar-verb form}}; otherwise ignored ["pagename"] = {}, -- for testing/documentation pages ["json"] = {type = "boolean"}, -- for bot use --W: additional parameters for ar.wiktionary.org ["جذر"] = {type = "string"}, --W: الجذر اللغوي, root ["وزن"] = {type = "string"}, --W: الوزن الصرفي, morphological pattern ["كامل"] = {type = "boolean"}, --W: show full table (default is simplified table) } local args = require("Module:parameters").process(parent_args, params) --W: If both root (جذر) and morphological pattern (وزن) are provided, construct [1] if args["جذر"] and args["جذر"] ~= "" and args["وزن"] and args["وزن"] ~= "" then local constructed = construct_verb_spec(args["جذر"], args["وزن"]) if constructed and constructed ~= "" then args[1] = constructed end end local alternant_multiword_spec = export.do_generate_forms(args, "ar-conj") if type(alternant_multiword_spec) == "string" then -- JSON return value return alternant_multiword_spec end show_forms(alternant_multiword_spec) --W: Choose table type: simplified (default) or full (comprehensive) local table_html if args["كامل"] then table_html = make_table(alternant_multiword_spec) else table_html = make_table_ar(alternant_multiword_spec) end --W: don't add categories --W: TODO: all lines with insert_cat() are to be removed. -- return table_html .. -- require("Module:utilities").format_categories(alternant_multiword_spec.categories, lang, nil, nil, force_cat) return table_html end function export.verb_forms(frame) local parargs = frame:getParent().args local params = { [1] = {}, [2] = {}, [3] = {}, [4] = {}, [5] = {}, pagename = {}, } for _, form in ipairs(allowed_vforms) do -- FIXME: We go up to 5 here. The code supports unlimited variants but it's unlikely we will ever see more than -- 2. for index = 1, 5 do local prefix = index == 1 and form or form .. index params[prefix .. "-pv"] = {} for _, extn in ipairs { "", "-vn", "-ap", "-pp" } do params[prefix .. extn] = {} params[prefix .. extn .. "-head"] = {} -- FIXME: No -tr? params[prefix .. extn .. "-gloss"] = {} end end end local args = require("Module:parameters").process(parargs, params) local i = 1 local past_vowel_re = "^[aui,]*$" local combined_root = nil if not args[i] or rfind(args[i], past_vowel_re) then combined_root = args.pagename or mw.loadData("Module:headword/data").pagename if not rfind(combined_root, "^([^ ]) ([^ ]) ([^ ])$") and not rfind(combined_root, "^([^ ]) ([^ ]) ([^ ]) ([^ ])$") then error("When inferring roots from page title, need three or four space-separated radicals: " .. combined_root) end elseif rfind(args[i], " ") then combined_root = args[i] i = i + 1 else local separate_roots = {} while args[i] and not rfind(args[i], past_vowel_re) do table.insert(separate_roots, args[i]) i = i + 1 end combined_root = table.concat(separate_roots, " ") end local past_vowel = args[i] i = i + 1 if past_vowel and not rfind(past_vowel, past_vowel_re) then error("Unrecognized past vowel, should be 'a', 'i', 'u', 'a,u', etc. or empty: " .. past_vowel) end -- Spaces interfere with parsing as a unit in [[Module:inflection utilities]], so replace with underscore. combined_root = combined_root:gsub(" ", "_") local split_root = rsplit(combined_root, "_") -- Map from verb forms (I, II, etc.) to a table of verb properties, -- which has entries e.g. for "verb" (either true to autogenerate the verb -- head, or an explicitly specified verb head using e.g. argument "I-head"), -- and for "verb-gloss" (which comes from e.g. the argument "I" or "I-gloss"), -- and for "vn" and "vn-gloss", "ap" and "ap-gloss", "pp" and "pp-gloss". local verb_properties = {} for _, form in ipairs(allowed_vforms) do local formpropslist = {} local derivs = {{"verb", ""}, {"vn", "-vn"}, {"ap", "-ap"}, {"pp", "-pp"}} local index = 1 while true do local formprops = {} local prefix = index == 1 and form or form .. index if prefix == "I" then formprops.pv = past_vowel end if args[prefix .. "-pv"] then formprops.pv = args[prefix .. "-pv"] end for _, deriv in ipairs(derivs) do local prop = deriv[1] local extn = deriv[2] if args[prefix .. extn] == "+" then formprops[prop] = true elseif args[prefix .. extn] == "-" then formprops[prop] = false elseif args[prefix .. extn] then formprops[prop] = true formprops[prop .. "-gloss"] = args[prefix .. extn] end if args[prefix .. extn .. "-head"] then if formprops[prop] == nil then formprops[prop] = true end formprops[prop] = args[prefix .. extn .. "-head"] end if args[prefix .. extn .. "-gloss"] then if formprops[prop] == nil then formprops[prop] = true end formprops[prop .. "-gloss"] = args[prefix .. extn .. "-gloss"] end end if formprops.verb then -- If a verb form specified, also turn on vn (unless form I, with -- unpredictable vn) and ap, and maybe pp, according to form, -- weakness and past vowel. But don't turn these on if there's -- an explicit on/off specification for them (e.g. I-pp=-). if form ~= "I" and formprops.vn == nil then formprops.vn = true end if formprops.ap == nil then formprops.ap = true end local weakness = weakness_from_radicals(form, split_root[1], split_root[2], split_root[3], split_root[4]) if formprops.pp == nil and not vform_probably_no_passive(form, weakness, rsplit(formprops.pv or "", ","), {}) then formprops.pp = true end if formprops.verb == true or formprops.vn == true or formprops.ap == true or formprops.pp == true then formprops.need_autogen = true end table.insert(formpropslist, formprops) index = index + 1 else break end end table.insert(verb_properties, {form, formpropslist}) end -- Go through and create the verb form derivations as necessary, when they haven't been explicitly given. for _, vplist in ipairs(verb_properties) do local vform = vplist[1] for _, props in ipairs(vplist[2]) do if props.need_autogen then local form_with_vowels if vform == "I" then local pv = props.pv if not pv then -- Make up likely past vowels based on weakness and actual radical. if split_root[3] == W then -- final-weak form_with_vowels = "I/a~u" elseif split_root[3] == Y then form_with_vowels = "I/a~i" elseif split_root[2] == W then --hollow form_with_vowels = "I/u~u" elseif split_root[2] == Y then form_with_vowels = "I/i~i" else -- most common; doesn't matter so much since we're not displaying the non-past form_with_vowels = "I/a~u" end else local pvs = rsplit(pv, ",") local vowel_sufs = {} for _, pv in ipairs(pvs) do local vowel_spec if pv == "a" then -- Make up likely past vowels based on weakness and actual radical. if split_root[3] == W then -- final-weak vowel_spec = "a~u" elseif split_root[3] == Y then vowel_spec = "a~i" elseif split_root[2] == W then --hollow vowel_spec = "a~u" elseif split_root[2] == Y then vowel_spec = "a~i" else -- most common; doesn't matter so much since we're not displaying the non-past vowel_spec = "a~u" end elseif pv == "i" then -- most common; doesn't matter so much since we're not displaying the non-past vowel_spec = "i~a" elseif pv == "u" then -- most common; doesn't matter so much since we're not displaying the non-past vowel_spec = "u~u" else error(("Internal error: Bad past vowel '%s' in {{ar-verb forms}}"):format(pv)) end table.insert(vowel_sufs, vowel_spec) end form_with_vowels = "I/" .. table.concat(vowel_sufs, "/") end else form_with_vowels = vform end local angle_bracket_spec = ("%s<%s.pass>"):format(combined_root, form_with_vowels) local alternant_multiword_spec = export.do_generate_forms({angle_bracket_spec}, "ar-verb forms") local function format_forms(forms) if not forms then return "-" -- FIXME: Throw an error? end local formatted = {} for _, form in ipairs(forms) do if form.translit then table.insert(formatted, ("%s//%s"):format(form.form, form.translit)) else table.insert(formatted, form.form) end end return table.concat(formatted, "،") end if props.verb == true then props.verb = format_forms(alternant_multiword_spec.forms.past_3ms) end for _, deriv in ipairs({"vn", "ap", "pp"}) do if props[deriv] == true then props[deriv] = format_forms(alternant_multiword_spec.forms[deriv]) end end end end end -- Go through and output the result local formtextarr = {} for _, vplist in ipairs(verb_properties) do local form = vplist[1] for _, props in ipairs(vplist[2]) do local textarr = {} if props.verb then local text = "* '''[[Appendix:Arabic verbs#Form " .. form .. "|Form " .. form .. "]]''': " local linktext = {} local splitheads = rsplit(props.verb, "[,،]") for _, head in ipairs(splitheads) do table.insert(linktext, m_links.full_link({lang = lang, term = head, gloss = props["verb-gloss"]})) end text = text .. table.concat(linktext, "، ") table.insert(textarr, text) for _, derivengl in ipairs({{"vn", "Verbal noun"}, {"ap", "Active participle"}, {"pp", "Passive participle"}}) do local deriv = derivengl[1] local engl = derivengl[2] if props[deriv] then local text = "** " .. engl .. ": " local linktext = {} local splitheads = rsplit(props[deriv], "[,،]") for _, head in ipairs(splitheads) do local ar, translit = head:match("^(.*)//(.-)$") if not ar then ar = head end table.insert(linktext, m_links.full_link {lang = lang, term = ar, tr = translit, gloss = props[deriv .. "-gloss"]} ) end text = text .. table.concat(linktext, "، ") table.insert(textarr, text) end end table.insert(formtextarr, table.concat(textarr, "\n")) end end end return table.concat(formtextarr, "\n") end -- Infer radicals from lemma headword (i.e. 3rd masculine singular past) and verb form (I, II, etc.). Throw an error if -- headword is malformed. A given returned radical may be actually be a list of possible radicals, where the first one -- should be used if the user didn't explicitly give the radical. If the list contains a field `ambig = true`, the -- radical is considered ambiguous and should not be categorized. `is_reduced` indicates that the user specified -- `.reduced` to indicate that the verb form is reduced by assimilation and/or haplology (typically archaic Koranic -- forms such as اِدَّارَأَ instead of تَدَارَأَ; or اِسْطَاعَ instead of اِسْتِطَاعَ; etc. function export.infer_radicals(data) local headword, vform, passive, past_vowel, nonpast_vowel, is_reduced = data.headword, data.vform, data.passive, data.past_vowel, data.nonpast_vowel, data.is_reduced past_vowel = past_vowel or "-" nonpast_vowel = nonpast_vowel or "-" local function verify_vowel(vowel, param) if vowel ~= A and vowel ~= I and vowel ~= U and vowel ~= "-" then error(("Internal error: Bad value for %s: %s (should be Arabic diacritic vowel or '-')"):format( param, vowel)) end end verify_vowel(past_vowel, "past_vowel") verify_vowel(nonpast_vowel, "nonpast_vowel") local ch = {} local form_viii_assim, variant -- sub out alif-madda for easier processing headword = rsub(headword, AMAD, HAMZA .. ALIF) local function infer_err(msg, noann) local anns = {} local nohead, novform if noann == "nohead" then nohead = true elseif noann == "novform" then novform = true elseif noann == "nohead-vform" then nohead = true novform = true elseif noann then error(("Internal error: Unrecognized value for 'noann': %s"):format(dump(noann))) end if not nohead then table.insert(anns, ("headword=%s"):format(data.headword)) end if not novform then table.insert(anns, ("verb form=%s"):format(data.vform)) end anns = table.concat(anns, "، ") if anns ~= "" then anns = ": " .. anns end error(msg .. anns) end local len = ulen(headword) local expected_length -- extract the headword letters into an array for i = 1, len do table.insert(ch, usub(headword, i, i)) end -- check that the letter at the given index is the given string, or -- is one of the members of the given array local function check(index, must) local letter = ch[index] if type(must) == "string" then if not letter then infer_err("Letter " .. index .. " is nil") end if letter ~= must then infer_err(("For verb form %s, letter %s must be %s, not %s"):format(vform, index, must, letter), "novform") end elseif not m_table.contains(must, letter) then infer_err("For verb form " .. vform .. ", radical " .. index .. " must be one of " .. table.concat(must, " ") .. ", not " .. letter, "novform") end end -- Check that length of headword is within [min, max] local function check_len(min, max) if min and len < min then infer_err(("Not enough letters for verb form %s, expected at least %s"):format(vform, min), "novform") end if max and len > max then infer_err(("Too many letters for verb form %s, expected at most %s"):format(vform, max), "novform") end end -- If the vowels are i~a or u~u, a form I verb beginning with w- normally keeps the w in the non-past. Otherwise it -- loses it (i.e. it is "assimilated"). local function form_I_w_non_assimilated() return req(past_vowel, I) and req(nonpast_vowel, A) or req(past_vowel, U) and req(nonpast_vowel, U) end -- Convert radicals to canonical form (handle various hamza varieties and check for misplaced alif or alif maqṣūra; -- legitimate cases of these letters are handled above). local function convert(rad, index) if type(rad) == "table" then for i, r in ipairs(rad) do rad[i] = convert(r, index) end return rad elseif rad == HAMZA_ON_ALIF or rad == HAMZA_UNDER_ALIF or rad == HAMZA_ON_W or rad == HAMZA_ON_Y then return HAMZA elseif rad == AMAQ then infer_err("Radical " .. index .. " must not be alif maqṣūra") elseif rad == ALIF then infer_err("Radical " .. index .. " must not be alif") else return rad end end local quadlit = vform:find("q$") -- find first radical, start of second/third radicals, check for -- required letters local radstart, rad1, rad2, rad3, rad4 local weakness if vform == "I" or vform == "II" then rad1 = ch[1] radstart = 2 elseif vform == "III" then rad1 = ch[1] check(2, {ALIF, W}) -- W occurs in passive-only verbs radstart = 3 elseif vform == "IV" then -- this would be alif-madda but we replaced it with hamza-alif above. if ch[1] == HAMZA and ch[2] == ALIF then rad1 = HAMZA else check(1, HAMZA_ON_ALIF) rad1 = ch[2] end radstart = 3 elseif vform == "V" then check(1, is_reduced and ALIF or T) rad1 = ch[2] radstart = 3 elseif vform == "VI" then check(1, is_reduced and ALIF or T) if ch[2] == AMAD then rad1 = HAMZA radstart = 3 else rad1 = ch[2] check(3, {ALIF, W}) -- W occurs in passive-only verbs radstart = 4 end elseif vform == "VII" then check(1, ALIF) if is_reduced then check(2, M) rad1 = M radstart = 3 else check(2, N) rad1 = ch[3] radstart = 4 end elseif vform == "VIII" then check(1, ALIF) rad1 = ch[2] if rad1 == "د" then rad1 = {"د", "ذ"} -- not considered ambiguous since it's usually د radstart = 3 form_viii_assim = "دّ" elseif rad1 == "ظ" and ch[3] == "ط" and len >= 5 then -- [[اظطلم]], variant of [[اظلم]] radstart = 4 form_viii_assim = "ظْط" elseif rad1 == "ذ" and ch[3] == "د" and len >= 5 then -- [[اذدكر]], variant of [[اذكر]] radstart = 4 form_viii_assim = "ذْد" elseif rad1 == T or rad1 == "ث" or rad1 == "ذ" or rad1 == "ط" or rad1 == "ظ" then radstart = 3 form_viii_assim = rad1 .. SH elseif rad1 == "ز" then check(3, "د") radstart = 4 form_viii_assim = "زْد" elseif rad1 == "ص" or rad1 == "ض" then check(3, "ط") radstart = 4 form_viii_assim = rad1 .. SK .. "ط" else check(3, T) radstart = 4 rad1 = convert(rad1, 1) form_viii_assim = rad1 .. SK .. "ت" end if rad1 == T then -- Radical is ambiguous, might be ت or و or ي but doesn't affect conjugation. Note that there are no -- form-VIII verbs with initial radical ي given in Hans Wehr but Lane mentions at least: -- - (page 2973) اِتَّأَسَ, with assimilation of the ي to ت, from root ي ء س; -- - (page 2975) اِتَّبَسَ non-past يَتَّبِسُ and alternative اِيتَبَسَ non-past يَاتَبِسُ from the root ي ب س; -- - (page 2976) اِتَّسَرَ non-past يَتَّسِرُ or alternatively يَأْتَسِرُ with hamza preserved from the root ي س ر. -- These alternative forms seem very rare and probably not worth worrying about, but if we want to handle -- them, we can do it when the time comes. rad1 = {T, W, Y, ambig = true} -- اِتَّخَذَ irregularly has hamza as the radical but assimilates like و if ch[3] == "خ" and ch[4] == "ذ" then rad1[4] = HAMZA end end elseif vform == "IX" then check(1, ALIF) rad1 = ch[2] radstart = 3 elseif vform == "X" then check(1, ALIF) check(2, S) if is_reduced then rad1 = ch[3] radstart = 4 else check(3, T) rad1 = ch[4] radstart = 5 end elseif vform == "Iq" then rad1 = ch[1] rad2 = ch[2] radstart = 3 elseif vform == "IIq" then check(1, T) rad1 = ch[2] rad2 = ch[3] radstart = 4 elseif vform == "IIIq" then check(1, ALIF) rad1 = ch[2] rad2 = ch[3] check(4, N) radstart = 5 elseif vform == "IVq" then check(1, ALIF) rad1 = ch[2] rad2 = ch[3] radstart = 4 elseif vform == "XI" then check_len(5, 5) check(1, ALIF) rad1 = ch[2] rad2 = ch[3] check(4, ALIF) rad3 = ch[5] weakness = "sound" elseif vform == "XII" then check(1, ALIF) rad1 = ch[2] if ch[3] ~= ch[5] then infer_err("For verb form XII, letters 3 and 5 should be the same", "novform") end check(4, W) radstart = 5 elseif vform == "XIII" then check_len(5, 5) check(1, ALIF) rad1 = ch[2] rad2 = ch[3] check(4, W) rad3 = ch[5] if rad3 == AMAQ then weakness = "final-weak" else weakness = "sound" end elseif vform == "XIV" then check_len(6, 6) check(1, ALIF) rad1 = ch[2] rad2 = ch[3] check(4, N) rad3 = ch[5] if ch[6] == AMAQ then check_waw_ya(rad3) weakness = "final-weak" else if ch[5] ~= ch[6] then infer_err("For verb form XIV, letters 5 and 6 should be the same", "novform") end weakness = "sound" end elseif vform == "XV" then check_len(6, 6) check(1, ALIF) rad1 = ch[2] rad2 = ch[3] check(4, N) rad3 = ch[5] if rad3 == Y then check(6, ALIF) else check(6, AMAQ) end weakness = "sound" else error("Internal error: Unrecognized verb form " .. vform) end -- Process the last two radicals. RADSTART is the index of the first of the two. If it's nil then all radicals have -- already been processed above, and we don't do anything. if radstart then -- There must (normally) be one or two letters left. if len == radstart then if vform == "I" and ch[len] == Y then -- short form حَيَّ weakness = "final-weak" rad2 = Y rad3 = Y variant = "short" elseif vform == "IV" and rad1 == "ر" and ch[len] == AMAQ then -- irregular verb أَرَى weakness = "final-weak" rad2 = HAMZA rad3 = Y elseif vform == "X" and rad1 == "ح" and ch[len] == AMAQ then -- irregular verb اِسْتَحَى weakness = "final-weak" rad2 = Y rad3 = Y variant = "short" else -- If one letter left, then it's a geminate verb. If the letter is alif or alif maqṣūra, it will trigger -- an error down the line. if vform_supports_geminate(vform) then weakness = "geminate" rad2 = ch[len] rad3 = ch[len] if vform == "III" or vform == "VI" then variant = "short" end else infer_err("Apparent geminate verb, but geminate verbs not allowed for this verb form") end end elseif quadlit then -- Process last two radicals of a quadriliteral verb form. rad3 = ch[radstart] rad4 = ch[radstart + 1] expected_length = radstart + 1 check_len(expected_length) if rad4 == AMAQ or rad4 == ALIF and rad3 == Y or rad4 == Y then -- rad4 can be Y in passive-only verbs. if vform_supports_final_weak(vform) then weakness = "final-weak" -- Ambiguous radical; randomly pick wāw as radical (but avoid two wāws in a row); it could be wāw or -- yāʾ, but doesn't affect the conjugation. rad4 = rad3 == W and {Y, W, ambig = true} or {W, Y, ambig = true} else infer_err("Last radical is " .. rad4 .. " but verb form " .. vform .. " doesn't support final-weak verbs", "novform") end else weakness = "sound" end else -- Process last two radicals of a triliteral verb form. rad2 = ch[radstart] rad3 = ch[radstart + 1] expected_length = radstart + 1 check_len(expected_length) if vform == "I" and (is_waw_ya(rad3) or rad3 == ALIF or rad3 == AMAQ) then local inferred_past_vowel, inferred_nonpast_vowel -- Check for final-weak form I verb. It can end in tall alif (rad3 = wāw) or alif maqṣūra (rad3 = yāʾ) -- or a wāw or yāʾ (with a past vowel of i or u, e.g. nasiya/yansā "forget" or with a passive-only -- verb). if rad1 == W and not form_I_w_non_assimilated() then weakness = "assimilated+final-weak" else weakness = "final-weak" end if rad3 == ALIF then rad3 = W inferred_past_vowel = A inferred_nonpast_vowel = U if is_passive_only(passive) then infer_err("Final-weak form-I passive verbs should end in yāʔ (ي), not tall alif (ا)", "novform") end elseif rad3 == AMAQ then rad3 = Y inferred_past_vowel = A inferred_nonpast_vowel = I if is_passive_only(passive) then infer_err("Final-weak form-I passive verbs should end in yāʔ (ي), not alif maqṣūra (ى)", "novform") end elseif rad1 == "ح" and rad2 == Y and rad3 == Y then -- Long variant حَيِيَ. inferred_past_vowel = I inferred_nonpast_vowel = A variant = "long" else if not is_passive_only(passive) then -- does a non-passive final-weak verb in -uwa ever happen? (YES: e.g. [[رجو]] "to be slack") inferred_past_vowel = rad3 == Y and I or U inferred_nonpast_vowel = A end -- Ambiguous radical; randomly pick wāw as radical (but avoid two wāws); it could be wāw or yāʾ, but -- doesn't affect the conjugation. rad3 = (rad1 == W or rad2 == W) and {Y, W, ambig = true} or {W, Y, ambig = true} -- ambiguous end if inferred_past_vowel then local raw_past_vowel = rget(past_vowel) local raw_nonpast_vowel = rget(nonpast_vowel) if raw_past_vowel ~= "-" then if raw_past_vowel ~= inferred_past_vowel then infer_err(("Final-weak form-I verb inferred past vowel %s, which disagrees with " .. "explicitly specified %s"):format(undia[inferred_past_vowel], undia[raw_past_vowel]), "novform") else -- in case of footnote in past_vowel inferred_past_vowel = past_vowel end end if raw_nonpast_vowel ~= "-" and raw_nonpast_vowel ~= A and inferred_nonpast_vowel == U then -- if inferred as I or A, the reality can be the reverse; form-I final-weak verbs with a~a and -- i~i exist, e.g. سَعَى/يَسْعَى, وَلِيَ/يَلِي. Weird verb [[صها]] (also written [[صهى]]) has non-past -- يصهى so we can't throw an error in this situation. if raw_nonpast_vowel ~= inferred_nonpast_vowel then infer_err(("Final-weak form-I verb inferred non-past vowel %s, which disagrees with " .. "explicitly specified %s"):format(undia[inferred_nonpast_vowel], undia[raw_nonpast_vowel]), "novform") else -- in case of footnote in nonpast_vowel inferred_nonpast_vowel = nonpast_vowel end end end if not is_passive_only(passive) then if rget(past_vowel) == "-" then past_vowel = inferred_past_vowel end if rget(nonpast_vowel) == "-" then nonpast_vowel = inferred_nonpast_vowel end end elseif vform == "IX" and is_waw_ya(rad3) and len == radstart + 2 and ch[len] == AMAQ then -- Final-weak form IX verbs like اِرْعَوَى "to desist, to repent, to see the light". weakness = "final-weak" expected_length = radstart + 2 elseif vform == "X" and rad1 == "ح" and rad2 == Y and rad3 == ALIF then -- Long variant اِسْتَحْيَا. weakness = "final-weak" rad3 = Y variant = "long" elseif rad3 == AMAQ or rad2 == Y and rad3 == ALIF or rad3 == Y then -- rad3 == Y happens in passive-only verbs. if vform_supports_final_weak(vform) then weakness = "final-weak" else infer_err("Last radical is " .. rad3 .. " but verb form doesn't support final-weak verbs") end -- Ambiguous radical; randomly pick wāw as radical (but avoid two wāws); it could be wāw or yāʾ, but -- doesn't affect the conjugation. rad3 = (rad1 == W or rad2 == W) and {Y, W, ambig = true} or {W, Y, ambig = true} elseif rad2 == ALIF then if vform_supports_hollow(vform) then weakness = "hollow" local function set_past_to_a() if req(past_vowel, A) then -- already set elseif req(past_vowel, "-") or req(past_vowel, rget(nonpast_vowel)) then past_vowel = A else infer_err(("Form I hollow verb with nonpast vowel set to '%s' must have past vowel set to 'a' or the same value, not %s"): format(undia[rget(nonpast_vowel)], undia[rget(past_vowel)]), "novform") end end if vform == "I" and req(nonpast_vowel, U) then rad2 = W set_past_to_a() elseif vform == "I" and req(nonpast_vowel, I) then rad2 = Y set_past_to_a() else if req(nonpast_vowel, A) and not req(past_vowel, I) then infer_err(("Form I hollow verb with nonpast vowel set to 'a' must have past vowel set to 'i', not %s"): format(undia[rget(past_vowel)]), "novform") end -- Ambiguous radical; could be wāw or yāʾ; if verb form I, it's critical to get this right, and -- the caller checks for this situation and throws an error if non-past vowel is "a" and second -- radical isn't explicitly given. rad2 = {W, Y, ambig = true, need_radical = true} end else infer_err("Second radical is alif but verb form doesn't support hollow verbs") end elseif vform == "I" and rad1 == W and not form_I_w_non_assimilated() then weakness = "assimilated" elseif rad2 == rad3 and (vform == "III" or vform == "VI") then weakness = "geminate" variant = "long" else weakness = "sound" end end if expected_length then check_len(expected_length, expected_length) end end rad1 = convert(rad1, 1) rad2 = convert(rad2, 2) rad3 = convert(rad3, 3) rad4 = convert(rad4, 4) if not weakness then error("Internal error: Returned weakness from infer_radicals() is nil") end return { weakness = weakness, rad1 = rad1, rad2 = rad2, rad3 = rad3, rad4 = rad4, past_vowel = past_vowel, nonpast_vowel = nonpast_vowel, form_viii_assim = form_viii_assim, variant = variant, } end -- bot interface to infer_radicals() function export.infer_radicals_json(frame) local iparams = { headword = {}, vform = {}, passive = {}, past_vowel = {}, nonpast_vowel = {}, is_reduced = {type = "boolean"}, } local iargs = require("Module:parameters").process(frame.args, iparams) return require("Module:JSON").toJSON(export.infer_radicals(iargs)) end -- Infer vocalization from participle headword (active or passive), verb form (I, II, etc.) and whether the headword is -- active or passive. Throw an error if headword is malformed. Returned radicals may contain Latin letters "t", "w" or "y" -- indicating ambiguous radicals guessed to be tāʾ, wāw or yāʾ respectively. function export.infer_participle_vocalization(headword, vform, weakness, is_active) local chars = {} local orig_headword = headword -- Sub out alif-madda for easier processing. headword = rsub(headword, AMAD, HAMZA .. ALIF) local len = ulen(headword) -- Extract the headword letters into an array. for i = 1, len do table.insert(chars, usub(headword, i, i)) end local function form_intro_error_msg() return ("For verb form %s %s%s participle %s, "):format(vform, orig_headword ~= headword and "normalized " or "", is_active and "active" or "passive", headword) end local function err(msg) error(form_intro_error_msg() .. msg, 1) end -- Check that length of headword is within [min, max]. local function check_len(min, max) if min and len < min then err(("expected at least %s letters but saw %s"):format(min, len)) elseif max and len > max then err(("expected at most %s letters but saw %s"):format(max, len)) end end -- Get the character at `ind`, making sure it exists. local function c(ind) check_len(ind) return chars[ind] end -- Check that the letter at the given index is the given string, or is one of the members of the given array local function check(index, must) local letter = chars[index] local function make_possible_values() if type(must) == "string" then return must else return list_to_text(must, nil, " or ") end end if not letter then err(("expected a letter (specifically %s) at position %s, but participle is too short"):format( make_possible_values(), index)) end local matches if type(must) == "string" then matches = letter == must else matches = m_table.contains(must, letter) end if not matches then err(("letter %s at index %s must be %s"):format(letter, index, make_possible_values())) end end local function check_weakness(values, allow_missing, invert_condition) local function make_possible_weaknesses() for i, val in ipairs(values) do values[i] = "'" .. val .. "'" end return list_to_text(values, nil, " or ") end if allow_missing and invert_condition then error("Internal error: Can't specify both allow_missing and invert_condition") end if not weakness then if allow_missing or invert_condition then return else err(("weakness is unspecified but must be %s"):format(make_possible_weaknesses())) end else local matches = m_table.contains(values, weakness) if invert_condition and matches then err(("weakness '%s' must not be %s"):format(weakness, make_possible_weaknesses())) elseif not invert_condition and not matches then err(("weakness '%s' must be %s"):format(weakness, make_possible_weaknesses())) end end end local vocalized local function handle_possibly_final_weak(sound_prefix, expected_length) check_len(expected_length, expected_length) if c(expected_length) == AMAQ then -- passive final-weak if is_active then err("participle in -ِى only allowed for passive participles") end check_weakness({"final-weak", "assimilated+final-weak"}, "allow missing") vocalized = sound_prefix .. AN .. AMAQ else -- all others behave as if sound check_weakness({"final-weak", "assimilated+final-weak"}, nil, "invert condition") vocalized = sound_prefix .. (is_active and I or A) .. c(expected_length) end end if not (vform == "I" and is_active) then -- all participles except verb form I active begin in م-. check(1, M) end if vform == "I" then if is_active then check(2, ALIF) local sound_prefix = c(1) .. AA .. c(3) if len == 3 then if c(3) == HAMZA then -- Either hollow with hamzated third radical, e.g. [[شاء]] active participle 'شَاءٍ', or final-weak -- with hamzated second radical, e.g. [[رأى]] active participle 'رَاءٍ'. Theoretically (?), also -- geminate with hamzated second/third radical, but I don't know if any such verbs exist. if weakness == "geminate" then vocalized = sound_prefix .. SH else check_weakness({"hollow", "final-weak"}, "allow missing") vocalized = sound_prefix .. IN end else check_weakness({"final-weak", "geminate"}) if weakness == "geminate" then vocalized = sound_prefix .. SH else vocalized = sound_prefix .. IN end end else check_len(4, 4) -- we will convert back to alif maqṣūra below as needed vocalized = sound_prefix .. I .. c(4) end else -- assimilated verbs: regular, e.g. مَوْزُون "weighed" -- geminate verbs: regular, e.g. مَبْلُول "moistened" -- third-hamzated verbs: مَبْرُوء -- hollow verbs: مَقُود "led, driven"; مَزِيد "added, increased" -- hollow first-hamzated verbs: مَئِيض "returned, reverted"; مَأْيُوس "despaired" (NOTE: formation is sound); -- مَأُود or مَؤُود "bent; depleted" -- hollow third-hamzated verbs: مَشِيء "willed, intended", مَضُوء "glittered?" -- final-weak: مَلْقِيّ "found, encountered"; مَصْغُوّ "inclined" -- hollow + final-weak: مَشْوِيّ "fried, grilled", مَهْوِيّ "loved" -- first-hamzated + hollow + final-weak: مَأْوِيّ "received hospitably" local sound_prefix = MA .. c(2) .. SK .. c(3) if len == 5 then -- sound, assimilated or geminate check(4, W) vocalized = sound_prefix .. UU .. c(5) else check_len(4, 4) if c(4) == W then -- final-weak third-wāw vocalized = sound_prefix .. U .. W .. SH elseif c(4) == Y then -- final-weak third-yāʾ vocalized = sound_prefix .. I .. Y .. SH else -- hollow check(3, {W, Y}) if c(3) == W then vocalized = MA .. c(2) .. UU .. c(4) else vocalized = MA .. c(2) .. II .. c(4) end end end end elseif vform == "II" or vform == "V" or vform == "XII" or vform == "XIII" or vform == "Iq" or vform == "IIq" or vform == "IIIq" then local sound_prefix, expected_length if vform == "II" then sound_prefix = MU .. c(2) .. A .. c(3) .. SH expected_length = 4 elseif vform == "V" then check(2, T) sound_prefix = MU .. T .. A .. c(3) .. A .. c(4) .. SH expected_length = 5 elseif vform == "XII" then -- e.g. [[احدودب]] "to be or become convex or humpbacked", مُحْدَوْدِب (active); -- [[اثنونى]] "to be bent; to be doubled up", مُثْنَوْنٍ (active) check(4, W) if c(3) ~= c(5) then err(("third letter %s should be the same as the fifth letter %s"):format(c(3), c(5))) end sound_prefix = MU .. c(2) .. SK .. c(3) .. A .. W .. SK .. c(5) expected_length = 6 elseif vform == "XIII" then -- e.g. [[اخروط]] "to get entangled; to extend", مُخْرَوِّط (active), مُخْرَوَّط (passive) check(4, W) sound_prefix = MU .. c(2) .. SK .. c(3) .. A .. W .. SH expected_length = 5 elseif vform == "Iq" then sound_prefix = MU .. c(2) .. A .. c(3) .. SK .. c(4) expected_length = 5 elseif vform == "IIq" then check(2, T) sound_prefix = MU .. T .. A .. c(3) .. A .. c(4) .. SK .. c(5) expected_length = 6 elseif vform == "IIIq" then -- e.g. [[اخرنطم]] "to be proud and angry" check(4, T) sound_prefix = MU .. c(2) .. SK .. c(3) .. A .. N .. SK .. c(5) expected_length = 6 else error("Internal error: Unhandled verb form " .. vform) end if len == expected_length - 1 then -- active final-weak if not is_active then err(("length-%s participle only allowed for active participles"):format(len)) end check_weakness({"final-weak", "assimilated+final-weak"}, "allow missing") vocalized = sound_prefix .. IN else handle_possibly_final_weak(sound_prefix, expected_length) end elseif vform == "III" or vform == "VI" then local sound_prefix, expected_length if vform == "VI" then check(2, T) check(4, ALIF) sound_prefix = MU .. T .. A .. c(3) .. AA .. c(5) expected_length = 6 else sound_prefix = MU .. c(2) .. AA .. c(4) expected_length = 5 end if len == expected_length - 1 then -- active final-weak or active or passive geminate if is_active then check_weakness({"geminate", "final-weak", "assimilated+final-weak"}) if weakness == "geminate" then vocalized = sound_prefix .. SH else vocalized = sound_prefix .. IN end else check_weakness({"geminate"}, "allow missing") vocalized = sound_prefix .. SH end else handle_possibly_final_weak(sound_prefix, expected_length) end elseif vform == "IV" or vform == "X" then -- form IV: -- sound: مُرْسِخ (active, "entrenching"), مُرْسَخ (passive, "entrenched") -- first-hamzated (like sound): مُؤْيِس (active, "causing to despair"), مُؤْيَس (passive, "caused to despair") -- final-weak: مُكْرٍ (active, "renting out"), مُكْرًى (passive, "rented out") -- assimilated: مُورِد (active, "transferring"), مُورَد (passive, "transferred"); same when first-Y, e.g. -- أَيْقَنَ "to be certain of": مُوقِن (active), مُوقَن (passive) -- assimilated + final-weak: مُورٍ (active, "setting fire, kindling"), مُورًى (passive, "set fire, kindled") -- geminate: مُمِدّ (active, "granting, helping"), مُمَدّ (passive, "granted, helped") -- hollow: مُزِيل (active, "eliminating"), مُزَال (passive, "eliminated") -- hollow + final-weak: مُعْيٍ (active, "tiring"), مُعْيًى (passive, "tired") local sound_prefix, expected_length if vform == "X" then check(2, S) check(3, T) sound_prefix = MU .. S .. SK .. T .. A .. c(4) expected_length = 6 else sound_prefix = MU .. c(2) expected_length = 4 end if len == expected_length and c(len - 1) == Y and c(len) ~= AMAQ then -- active hollow if not is_active then err("this shape only allowed for active participles") end check_weakness({"hollow"}, "allow missing") vocalized = sound_prefix .. II .. c(len) elseif len == expected_length and c(len - 1) == ALIF then -- passive hollow if is_active then err("this shape only allowed for passive participles") end check_weakness({"hollow"}, "allow missing") vocalized = sound_prefix .. AA .. c(len) elseif len == expected_length - 1 then -- active final-weak or active or passive geminate if is_active then check_weakness({"geminate", "final-weak", "assimilated+final-weak"}) if weakness == "geminate" then vocalized = sound_prefix .. I .. c(len) .. SH elseif vform == "IV" and c(2) == W then -- assimilated final-weak vocalized = sound_prefix .. c(len) .. IN else vocalized = sound_prefix .. SK .. c(len) .. IN end else check_weakness({"geminate"}, "allow missing") vocalized = sound_prefix .. A .. c(len) .. SH end else if vform == "IV" and c(2) == W then -- assimilated, possibly final-weak sound_prefix = sound_prefix .. c(expected_length - 1) else sound_prefix = sound_prefix .. SK .. c(expected_length - 1) end handle_possibly_final_weak(sound_prefix, expected_length) end elseif vform == "VII" or vform == "VIII" then -- form VII (passive participles are fairly rare but do exist): -- sound: مُنْكَتِب (active "subscribing"), مُنْكَتَب (passive "subscribed") -- geminate: مُنْضَمّ (both active "joining, containing" and passive "joined, contained") -- final-weak: مُنْطَلٍ (active "fooling (someone)"), مُنْطَلًى (passive "fooled") -- final-weak with medial wāw: مُنْطَوٍ (active "involving"), مُنْطَوًى (passive "involved") -- hollow: مُنْقَاد (both active "complying with" and passive "complied with") -- -- for form VIII, the same variants exist but things are complicated by assimilations involving the template T. -- sound third-hamzated no assimilation: مُبْتَدِئ (active "beginning"), مُبْتَدَأ (passive "begun") -- geminate no assimilation: مُبْتَزّ (both active "robbing" and passive "robbed") -- final-weak no assimilation: مُبْتَنٍ (active "building"), مُبْتَنًى (passive "built") -- final-weak with medial wāw no assimilation: مُحْتَوٍ (active "containing"), مُحْتَوًى (passive "contained") -- hollow no assimilation: مُخْتَار (both active "choosing" and passive "chosen") -- -- sound with total assimilation: مُتَّبِع (active "following"), مُتَّبَع (passive "followed") -- sound with total assimilation, assimilating wāw: مُتَّعِد (active "threatening"), مُتَّعَد (passive "threatened") -- sound with total assimilation, irregularly assimilating hamza: مُتَّخِذ (active "taking"), مُتَّخَذ (passive "taken") -- sound with total assimilation (to ḏāl, producing dāl): مُدَّخِر (active "reserving"), مُدَّخَر (passive "reserved") -- sound with total assimilation (to ḏāl): مُذَّكِر (active "remembering"), مُذَّكَر (passive "remembered") -- sound with total assimilation (to ṭāʔ): مُطَّرِح (active "discarding"), مُطَّرَح (passive "discarded") -- sound with total assimilation (to ẓāʔ): مُظَّلِم (active "tolerating"), مُظَّلَم (passive "tolerated") -- final-weak with total assimilation, assimilating wāw: مُتَّقٍ (active "guarding against"), مُتَّقًى (passive "guarded against") -- final-weak with total assimilation (to ṯāʔ): مُثَّنٍ (active "undulating"), مُثَّنًى (passive "undulated") -- final-weak with total assimilation (to dāl): مُدَّعٍ (active "claiming"), مُدَّعًى (passive "claimed") -- sound with partial assimilation (to zayn): مُزْدَهِر (active "thriving"), مُزْدَهَر (passive "thrived") -- sound with medial wāw with partial assimilation (to zayn): مُزْدَوِج (active "appearing twice") -- sound with partial assimilation (to ṣād): مُصْطَبِح (active "illuminating"), مُصْطَبَح (passive, "illuminated") -- sound with partial assimilation (to ḍād): مُضْطَرِب (active "to be disturbed"; no passive) -- geminate with partial assimilation (to ṣād): مُصْطَبّ (both active "effusing" and passive "effused") -- geminate with partial assimilation (to ḍād): مُضْطَرّ (both active "forcing" and passive "forced") -- final-weak with partial assimilation (to ṣād): مُصْطَلٍ (active "warming"), مُصْطَلًى (passive "warmed") -- hollow with partial assimilation (to zayn): مُزْدَاد (both active "increasing" and passive "increased") -- hollow with partial assimilation (to ṣad): مُصْطَاد (both active "hunting" and passive "hunted") local sound_prefix, sufind if vform == "VII" then check(2, N) sound_prefix = MU .. N .. SK .. c(3) sufind = 4 else local c2 = c(2) if c2 == T or c2 == "د" or c2 == "ث" or c2 == "ذ" or c2 == "ط" or c2 == "ظ" then -- full assimilation sound_prefix = MU .. c2 .. SH sufind = 3 else -- partial or no assimilation if c2 == "ز" then check(3, "د") elseif c2 == "ص" or c2 == "ض" then check(3, "ط") else check(3, T) end sound_prefix = MU .. c2 .. SK .. c(3) sufind = 4 end end if c(sufind) == ALIF then -- hollow, active or passive check_len(sufind + 1, sufind + 1) check_weakness({"hollow"}, "allow missing") vocalized = sound_prefix .. AA .. c(sufind + 1) elseif len == sufind then -- active final-weak or active or passive geminate if is_active then check_weakness({"geminate", "final-weak", "assimilated+final-weak"}) if weakness == "geminate" then vocalized = sound_prefix .. A .. c(len) .. SH else vocalized = sound_prefix .. A .. c(len) .. IN end else check_weakness({"geminate"}, "allow missing") vocalized = sound_prefix .. A .. c(len) .. SH end else sound_prefix = sound_prefix .. A .. c(sufind) handle_possibly_final_weak(sound_prefix, sufind + 1) end elseif vform == "IX" then check_len(4, 4) vocalized = MU .. c(2) .. SK .. c(3) .. A .. c(4) .. SH elseif vform == "IVq" then -- e.g. [[اذلعب]] "to scamper away", مُذْلَعِبّ (active), مُذْلَعَبّ (passive); -- [[اطمأن]] "to remain quietly; to be certain", مُطْمَئِنّ (active), مُطْمَأَنّ (passive) check_len(5, 5) local sound_prefix = MU .. c(2) .. SK .. c(3) .. A .. c(4) if is_active then vocalized = sound_prefix .. I .. c(5) .. SH else vocalized = sound_prefix .. A .. c(5) .. SH end elseif vform == "XI" then check_len(5, 5) check(4, ALIF) vocalized = MU .. c(2) .. SK .. c(3) .. AA .. c(5) .. SH -- e.g. [[احمار]] "to turn red, to blush", مُحْمَارّ (active) elseif vform == "XIV" or vform == "XV" then -- FIXME: Implement. No examples in Wiktionary currently; need to look up in a grammar. error("Support for verb form " .. vform .. " not implemented yet") else error("Don't recognize verb form " .. vform) end vocalized = rsub(vocalized, HAMZA .. AA, AMAD) local reconstructed_headword = lang:makeEntryName(vocalized) if reconstructed_headword ~= orig_headword then error(("Internal error: Vocalized participle %s doesn't match original participle %s"):format( vocalized, orig_headword)) end -- Apply NFC-style normalization to match MediaWiki's automatic normalization return apply_nfc_shadda(vocalized) end function export.infer_participle_vocalization_json(frame) local iparams = { [1] = {required = true}, [2] = {required = true}, ["weakness"] = {}, ["passive"] = {type = "boolean"} } local iargs = require("Module:parameters").process(frame.args, iparams) return export.infer_participle_vocalization(iargs[1], iargs[2], iargs.weakness, not iargs.passive) end return export dprwwtdym8nmdc9ce0hoitpts8adtje نقاش المستخدم:ForzaGreen 3 209034 1096877 1096851 2026-07-20T13:58:11Z ForzaGreen 28665 /* مفردة أَتْيَسَ */ ردّ 1096877 wikitext text/x-wiki <div style="width:auto" style="margin-bottom:1.25em;border:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}}; background:white;padding:0"> <div style="height:8px;margin:0;border:0;border-bottom:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}};background: #{{#switch:bleu|bleu=C8D8FF|vert=D7FFC7|jaune=FFFFB9|or=FFE040|orange=FFDD88|violet=C9AEF1|saumon=FBDFBE|sable=F1E2AE|vertmoyen=99CC66|bleufoncé=003399|rouge=FFDAB9|écarlate=FF3333|#default=E0E0E0}};font-size:1px"></div> <div style="padding:5px;font-size:small"><center style="word-spacing:1ex"><small>[[ويكاموس:سفارة|Welcome!]] [[ويكاموس:سفارة|Bienvenue!]] [[ويكاموس:سفارة|Willkommen!]] [[ويكاموس:سفارة|Benvenuti]] [[ويكاموس:سفارة|¡Bienvenido!]] [[ويكاموس:سفارة|ようこそ]] [[ويكاموس:سفارة|Dobrodosli]] [[ويكاموس:سفارة|환영합니다]] [[ويكاموس:سفارة|Добро пожаловать]] [[ويكاموس:سفارة|Bem-vindo!]] [[ويكاموس:سفارة|欢迎]] [[ويكاموس:سفارة|Bonvenon]] [[ويكاموس:سفارة|Welkom]]</small></center></div> <center><big>'''[[ويكاموس:ترحيب بالقادمين الجدد|مرحبا بك]] في [[ويكاموس]]، ForzaGreen !'''</big></center> {| |[[ملف:WiktionaryAr.svg|يمين|40بك]] | [[ويكاموس]] هو <u>مشروع تحرير جماعي لـ'''قاموس علمي وثقافي''' '''بمختلف اللغات'''</u>. لطلب المساعدة في أي وقت تجد وصلة ([[مساعدة:محتويات|'''مساعدة''']]) في هامش كل صفحة على اليمين. لا تتردد في قراءة '''الوصايا الأولى''' [[ويكاموس:دروس (التحرير)|للتحرير]] و[[ويكاموس:دليل سريع|التعديل]] و[[مساعدة:إنشاء صفحة جديدة|إنشاء المفردات الجديدة]] و[[ويكاموس:دليل سريع|تنسيقها]] وفقا [[ويكاموس:الركائز الخمس|لمعايير ويكاموس]]. تم تخصيص '''[[ويكاموس:ساحة التجربة|ساحة التجربة]]''' لاحتواء تجاربك وخطواتك الأولى في التحرير والتعديل. |-- |[[ملف:Presa de decissions.png|يمين|40بك]] | يمكنك الاستفسار و[[ويكاموس:أسئلة|طرح الأسئلة]] المتعلقة بطبيعة العمل في ويكاموس. يمكنك أيضا [{{fullurl:مستخدم:ForzaGreen|action=edit}} التعريف] بنفسك في [[مستخدم:ForzaGreen|'''صفحتك الشخصية''']]، بكتابة معلومات عنك: [[ويكاموس:بابل|اللغات التي تتكلمها]]، [[ويكاموس:صناديق المستخدم|من أي بلد أنت، ما هي محاور اهتمامك]]... |--- |[[ملف:Crystal Clear app ktip.png|يمين|40بك]] | لا تنس [[ويكاموس:توقيع|'''التوقيع''']] في [[مساعدة:صفحة النقاش|'''صفحات النقاش''']] بكتابة أربع مدّات، هكذا (<nowiki>~~~~</nowiki>). ولكن يجب <u>'''عدم التوقيع في صفحات المقالات القاموسية'''</u>، لأنها تصبح ملكًا للجميع لحظة إنشائها. نرجو منك ألاّ تنسى [[ويكاموس:حقوق التأليف والنشر|<u>'''عدم النسخ من الإنترنت'''</u>]] لأسباب [[ويكاموس:حقوق التأليف والنشر|<u>'''حقوق التأليف والنشر'''</u>]]. |-- |[[ملف:Crystal Clear app amor.png|يمين|40بك]] | أخيرا، وهو أهم شيء، نتمى لك أن [[ويكاموس:كن جريئا|'''تتمتع''']] بالمساهمة [[ويكاموس:بوابة المجتمع|'''معنا''']] في هذا المشروع! إذا كانت لديك أي استفسارات أو أسئلة أخرى، يمكنك طرحها في [[ويكاموس:أسئلة|هذه الصفحة]] أو في صفحة نقاشي. |} </div></div> --[[مستخدم:Meno25|Meno25]] ([[نقاش المستخدم:Meno25|نقاش]] • [[خاص:مساهمات/Meno25|مساهمات]]) 12:33، 17 أبريل 2020 (ت ع م) == قالب: تصريف == مرحبا، ألاحظ عملك في قالب تصريف، نسأل الله لك التوفيق، هل القالب جاهز لعمل، وإذا لم يكن جاهزا ما هي أوجه القصور؟ هل هي في أوزان معينة، لأنه إذا كان جاهزا نريد ضمه للدورة. [[مستخدم:حبيشان|حبيشان]] ([[نقاش المستخدم:حبيشان|نقاش]]) 13:09، 16 نوفمبر 2025 (ت ع م) :مرحبا، شكرا لك على المتابعة وعلى الدورة التدريبية. القالب جاهز تقريبا وكل الأوزان شغالة. مازالت فقط بعض الإصلاحات والتغييرات الطفيفة. يمكنكم ضمه إلى الدورة التدريبية. سأحاول توثيقه غدا ليكون جاهزا في التدريب القادم. :شكرا — [[مستخدم:ForzaGreen|وائل]] ([[نقاش المستخدم:ForzaGreen|نقاش]]) 13:57، 16 نوفمبر 2025 (ت ع م) ::شكرا سيكون قفزة كبيرة في التصريفات. [[مستخدم:حبيشان|حبيشان]] ([[نقاش المستخدم:حبيشان|نقاش]]) 17:52، 16 نوفمبر 2025 (ت ع م) :::صار شرح القالب جاهزا، وكذلك بيانات القالب مع قيم الأوزان الصرفية وشرحها. لو ممكن أن تجربها @[[مستخدم:حبيشان|حبيشان]] وتؤكد لي إذا كان كل شيء واضحا ؟ :::ما زالت تعديلات خفيفة سأُضيفها لاحقا. :::أكيد إن شاء الله سيكون قفزة كبيرة. فهذا قالب مُوَحَّد ويعتمد على وحدة Lua. أخذنا الوحدة من ويكاموس الإنجليزي (تطلب الأمر إنشاء وتحديث عشرات الوحدات) وعدلناها لتبسيطها ولتُلائِم قواعد النحو العربي، خصوصا في مسألة توليد الأفعال انطلاقا من الجذور والأوزان الصرفية. ما زلنا نشتغل على بعض التفاصيل ونُدقق نتائج الخوارزمية مع مُختصين. [[مستخدم:ForzaGreen|وائل]] ([[نقاش المستخدم:ForzaGreen|نقاش]]) 09:13، 17 نوفمبر 2025 (ت ع م) ::::أرجو مراجعة [[أَخْيَلَ]] لمعرفة وجه الخلل في القالب. [[مستخدم:حبيشان|حبيشان]] ([[نقاش المستخدم:حبيشان|نقاش]]) 19:21، 28 نوفمبر 2025 (ت ع م) :::::فعلا هناك مشكلة في الأفعال على وزن "أفعل" في الجذور الثلاثية التي وسطها ياء (أَخْيَلَ، أبْيَضَ، أَطْيَبَ...). شكرا جزيلا على التنبيه. لاحظنا كذلك أخطاء في صيغة الأمر في بعض الأفعال المهموزة والمعتلة. ما زلنا نراجع بالاعتماد على معجم تصريف الأفعال العربية (الدحداح). نسجل الأخطاء ونُضيفها إلى [[نقاش الوحدة:ar-verb/مختبر|مختبر الوحدة]]، إلى أن نُغَطي جميع الحالات إن شاء الله. [[مستخدم:ForzaGreen|وائل]] ([[نقاش المستخدم:ForzaGreen|نقاش]]) 10:23، 29 نوفمبر 2025 (ت ع م) :::::تم تصحيح تصريف فعل [[أَخْيَلَ]] (والأفعال المُشابهة). شكرا. [[مستخدم:ForzaGreen|وائل]] ([[نقاش المستخدم:ForzaGreen|نقاش]]) 00:19، 30 نوفمبر 2025 (ت ع م) == مفردة أَتْيَسَ == مرحبا، أراسلت بخصوص مفردة [[أَتْيَسَ]]، حسب المصدر فإن المفردة الصحيحة أتاس وليس أتيس، ولم أجد تصريف أتيس بهذا الشكل في المصادر، لذلك حاولت إصلاح المفردة لتكون موافقة للمصدر، لكنك تراجعت عن تعديلاتي. [[مستخدم:إسلام|إسلام]] ([[نقاش المستخدم:إسلام|نقاش]]) 21:24، 18 يوليو 2026 (ت ع م) :نفس الأمر أجده في مفردة [[أَتَاعَ]]. تحياتي. [[مستخدم:إسلام|إسلام]] ([[نقاش المستخدم:إسلام|نقاش]]) 21:52، 18 يوليو 2026 (ت ع م) ::مرحبا @[[مستخدم:إسلام|إسلام]]. أنا مُبرمج [https://ar-senses.toolforge.org/ أداة مراجعة معاني الأفعال]. شكرا لك على التنبيه وعلى التصحيح، وشكرا كذلك على مساهماتك العديدة في الأداة. ::ما دفني للشك في المُفردة "أَتْاسَ" وتغييرها هو حرف السكون فوق التاء والمتبوع بحرف المد. يبدو أن الرسم الصحيح هو "أَتَاسَ" كما أشرت. ::بحثت في قائمة الأفعال في الأداة ووجدت 25 فعلا أجوفا يائيا على وزن أَفْعَلَ (من بينها جذر ت-ي-س وجذر ت-ي-ع). سأبحث عن القاعدة الصحيحة لتصريف هذا النوع من الأفعال وأصحح في ويكاموس وويكي بيانات. إذا عندك التصريف الصحيح في أحد المراجع، أرسله لي من فضلك. شكرا. [[مستخدم:ForzaGreen|وائل]] ([[نقاش المستخدم:ForzaGreen|نقاش]]) 08:26، 19 يوليو 2026 (ت ع م) :::فعلا، الصحيح هو '''أَتَاسَ'''، والدلائل عن ذلك: :::- صيغة أتاس هي ما يظهر في [https://archive.org/details/RDA1958AR/1-%20%D9%85%D8%B9%D8%AC%D9%85%20%D9%85%D8%AA%D9%86%20%D8%A7%D9%84%D9%84%D8%BA%D8%A9/page/n414/mode/1up معجم متن اللغة، ص415]. :::- هذا الفعل من النوع الأجوف اليائي المزيد بحرف الألف في أوله، على وزن أفعل. ومن نفس صنف الأفعال: أَبَانَ يُبِين (جذر ب-ي-ن)، أَضَاعَ يُضِيع (جذر ض-ي-ع)، أَطَاحَ يُطيح (جذر ط-ي-ح). :::شكرا لك مرة على انتباهك وعلى التصحيح. سأُصحح باقي الأفعال في قاعدة البيانات. [[مستخدم:ForzaGreen|وائل]] ([[نقاش المستخدم:ForzaGreen|نقاش]]) 09:02، 19 يوليو 2026 (ت ع م) ::::لكن يوجد فعل [[أَخْيَلَ]] من نفس النوع، وهو مذكور في المعاجم، ولا يتبع نفس القاعدة. ربما هو حالة شاذة. سنسأل مختصا في التصريف ونصحح. [[مستخدم:ForzaGreen|وائل]] ([[نقاش المستخدم:ForzaGreen|نقاش]]) 09:51، 19 يوليو 2026 (ت ع م) :::::شكرا لك، وتقديري الشديد لجهودك. تحياتي. [[مستخدم:إسلام|إسلام]] ([[نقاش المستخدم:إسلام|نقاش]]) 18:21، 19 يوليو 2026 (ت ع م) ::::::بعد استشارة الخبير، قاعدة الأجوف الواوي واليائي على وزن أفعل هي كالتالي: ::::::* جذر ض-و-ع => في الأصل: أَضْوَعَ => الواو أُعِلَّت ألِفا تبعا لإعلالها في الثلاثي المُجرد (ضاع) => أضَاعَ ::::::* جذر ض-ي-ع => في الأصل: أَضْيَعَ => الياء أُعِلَّت ألِفا تبعا لإعلالها في الثلاثي المُجرد (ضاع) => أضَاعَ ::::::فعل [[أَخْيَلَ]] حالة خاصة لا تتبع القاعدة. ::::::أضفت التعديلات إلى الوحدة المسؤولة عن قالب {{قا|تصريف}} لأخذ هذه القاعدة واستثناءاتها بعين الاعتبار. [[مستخدم:ForzaGreen|وائل]] ([[نقاش المستخدم:ForzaGreen|نقاش]]) 13:58، 20 يوليو 2026 (ت ع م) hl4pn7k7fa9nohbv81tsxf7tlzkkbpe نقاش المستخدم:ايـوب 3 219254 1097209 965816 2026-07-22T07:41:55Z MenoBot 1177 بوت: إصلاح التحويلة المزدوجة من [[نقاش المستخدم:أيوب]] إلى [[نقاش المستخدم:جيمي]] 1097209 wikitext text/x-wiki #تحويل [[نقاش المستخدم:جيمي]] o146pty4o7l1ixbleupymew55lr9xtg وَعَظَ 0 224552 1096970 1090820 2026-07-21T02:43:47Z CommonsDelinker 273 Removing [[:c:File:الشيخ_يعظ_مجموعة_من_المسلمين_داخل_المسجد.jpg|الشيخ_يعظ_مجموعة_من_المسلمين_داخل_المسجد.jpg]], it has been deleted from Commons by [[:c:User:Infrogmation|Infrogmation]] because: per [[:c:Commons:Deletion requests/File:الشيخ يعظ مجموعة من 1096970 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1483652}} === المعاني === '''وَعَظَ''' [[فعل]] ثلاثي متعدي. # ألقى إرشادًا بطريقة تهدف إلى التأثير الأخلاقي أو الديني.. #: ''وعظ الشيخ المصلين بضرورة الصبر والتقوى."'' # تذكيرك للإِنسان بما يُلَيِّن قلبَه من ثواب وعِقاب. #: ''{وَإِذْ قَالَ لُقْمَانُ لِابْنِهِ وَهُوَ يَعِظُهُ يَا بُنَيَّ لَا تُشْرِكْ بِاللَّهِ ۖ إِنَّ الشِّرْكَ لَظُلْمٌ عَظِيمٌ13}'' سورة لقمان # نصحه وذكره بالعواقب. #: ''السعيد من وعظ بغيره والشقي من اتعظ به غيره. [مثل]'' {{-}} === التصريفات === {{تصريف|جذر=وعظ|وزن=فعَل يفعِل}} === كلمات ذات علاقة === ;المرادفات: * [[أرشد]] (للمعنى الاول) * [[هدى]] (للمعنى الثاني) * [[نصح]] (للمعنى الثالت) ;الأضداد: * [[أَبْعَدَ عن الهُدَى]] (للمعنى الاول) * [[أضل]] (للمعنى الثاني) * [[ضللَ]] (للمعنى الثالت) === من الجذر نفسه === * '''وَعَظَ''' {{مشتقة من/الجذر|و ع ظ}} وهو {{وزن|فَعَلَ}}. {{جذر321|و|ع|ظ}} === النطق === {{أصد|/wa.ʕaːðˤa/}} === الترجمات === * {{en}} {{t+|en|advise}} * {{fr}} {{t+|fr|conseiller}} === انظر أيضا === * [[واععِظ]] ، [[مَوعِظة]]. === المراجع === {{مرجع:العروس}} {{مرجع:الغني}} [[تصنيف:عربية]] [[تصنيف:أفعال]] [[تصنيف:خطابة]] [[تصنيف:تعليم]] ljqveohatk8l0w1a49egfen4k0ng5mk مستخدم:ForzaGreen/ملعب 2 230581 1096876 1096698 2026-07-20T13:49:15Z ForzaGreen 28665 1096876 wikitext text/x-wiki = معاني = {{معجمية|L1480727|معاني}} ----- {{معجمية|L1372434|معاني}} ----- {{معجمية|L12100|معاني}} ----- === [[أَدْرَجَ]] === {{معجمية|L1478139|معاني}} ----- * مثال مع الجزء والصفحة: {{استشهاد بويكي بيانات/ملعب|Q114878607|ج=14|ص=333}} * مثال مع الصفحة فقط: {{استشهاد بويكي بيانات/ملعب|Q108408025|ص=222}} * مثال آخر: {{استشهاد بويكي بيانات/ملعب|Q136804659|ج=7|ص=171}} تجريب إضافة الاستشهاد<ref>{{استشهاد بويكي بيانات|qid=Q136804659|ص=208|ج=9|المسار=https://archive.org/details/mhtalmktb/09_71568/page/n207/mode/1up}}</ref> === مراجع === {{مراجع}} = بطاقات = {{#function:Z20744|30 June 2020|15 April 2025}} {{#function:Z10018|Hello from Thessaloniki}} {{تصريف|جذر=رأي|وزن=فعَل يفعَل}} - إضافة نوع الفعل في العنوان الفرعي: فعل ثلاثي مُجرَّد صحيح مهموز العين، إلخ... {{صندوق معلومات فعل|L12100}} {{صندوق معلومات فعل|L1324790}} {{صندوق معلومات فعل|L1487095}} {{صندوق معلومات فعل|L1372434}} {{بطاقة عامة|wikidata=L12100}} {{-}} -------- = القالب - تصريف = {{تصريف|جذر=تيس|وزن=أفعل}} {{تصريف|جذر=خيل|وزن=أفعل}} {{تصريف|جذر=كتب|وزن=فعَل يفعِل|كامل=1}} {{تصريف|جذر=جلس|وزن=فعَل يفعِل|كامل=1}} {{تصريف|جذر=وجل|وزن=فعَل يفعُل}} {{تصريف|جذر=يمن|وزن=فعَل يفعُل}} {{تصريف|جذر=أخذ|وزن=فعَل يفعُل}} {{تصريف|جذر=أمن|وزن=أفعل}} {{تصريف|جذر=درك|وزن=استفعل}} {{تصريف|جذر=يأس|وزن=فعِل يفعَل}} {{تصريف|جذر=دحرج|وزن=فعلل}} {{تصريف|جذر=بتت|وزن=فعَل يفعِل}} {{تصريف|جذر=و ع ي|وزن=فعَل يفعِل|كامل=0}} {{تصريف|جذر=قدم|وزن=فعّل}} [[w:مزيد|مزيد]] === القالب - تصريف - الجدول كاملا === {{تصريف|جذر=حسب|وزن=فعِل يفعِل|كامل=1}} {{تصريف|جذر=أمم|وزن=فعَل يفعَل|كامل=1}} {{تصريف|ردد<II.pass>|كامل=1}} {{#tag:syntaxhighlight|{{تصريف|جذر=كتب|وزن=فعَل يفعِل|json=1}}|lang=json}} == القالب - ar-conj == {{ar-conj|ردد<II.pass>}} {{ar-conj|I/a~u|pagename=ترك}} {{ar-conj|VIII|pagename=اضطر}} {{#tag:syntaxhighlight|{{ar-conj|I/i~a|pagename=يأس|json=1}}|lang=json}} {{#tag:syntaxhighlight|{{ar-conj|I/a~u.pass|pagename=حسب|json=1}}|lang=json}} {{ar-conj|I/i~a|pagename=يأس}} == الوحدة == {{#استدعاء:ar-verb |do_generate_forms |كتب<I/a~u>}} <!-- {{#invoke:ar-verb |show |1="كتب<I/a~u.pass>"}} {{#استدعاء:ar-verb |show |ردد<II.pass> }} {{#استدعاء:ar-verb |show |كتب<I/a~u.pass> }} {{#استدعاء:ar-verb |show |I/a~u.pass |pagename=حسب}} --> ------- {{قائمة صفحات فرعية}} صفحات أخرى: * [[وحدة:مستخدم:ForzaGreen/ملعب/ar-verb]] * [[وحدة:مستخدم:ForzaGreen/ملعب/mymodule]] rof2n28pew85g8rrh4j3n3843q4c4a0 قالب:استشهاد بويكي بيانات/مختبر 10 231222 1097108 1096618 2026-07-21T20:40:15Z حبيشان 31560 1097108 wikitext text/x-wiki * {{استشهاد بويكي بيانات/ملعب|Q115727209|مرجع=أبو السعود}} * {{استشهاد بويكي بيانات|Q115727209|مرجع=أبو السعود}} * {{استشهاد بويكي بيانات/ملعب|Q115641715|مرجع=الشربيني1868}} * {{استشهاد بويكي بيانات|Q115641715|مرجع=الشربيني1868}} * {{استشهاد بويكي بيانات/ملعب|Q115683910|مرجع=القرطبي1935}} * {{استشهاد بويكي بيانات|Q115683910|مرجع=القرطبي1935}} * {{استشهاد بويكي بيانات/ملعب|Q115728353|مرجع=السيوطي1974}} * {{استشهاد بويكي بيانات|Q115728353|مرجع=السيوطي1974}} * {{استشهاد بويكي بيانات/ملعب|Q115732199|مرجع=السيوطي1978}} * {{استشهاد بويكي بيانات|Q115732199|مرجع=السيوطي1978}} * {{استشهاد بويكي بيانات/ملعب|Q115641917|مرجع=القاضي1981}} * {{استشهاد بويكي بيانات|Q115641917|مرجع=القاضي1981}} * {{استشهاد بويكي بيانات/ملعب|Q115641984|مرجع=ابن عاشور1984}} * {{استشهاد بويكي بيانات|Q115641984|مرجع=ابن عاشور1984}} * {{استشهاد بويكي بيانات/ملعب|Q115683837}} * {{استشهاد بويكي بيانات|Q115683837}} * {{استشهاد بويكي بيانات/ملعب|Q115782668|مرجع=النحاس1985}} * {{استشهاد بويكي بيانات|Q115782668|مرجع=النحاس1985}} * {{استشهاد بويكي بيانات/ملعب|Q115746114|مرجع=القحطاني1989}} * {{استشهاد بويكي بيانات|Q115746114|مرجع=القحطاني1989}} * {{استشهاد بويكي بيانات/ملعب|Q19443162}} * {{استشهاد بويكي بيانات|Q19443162}} * {{استشهاد بويكي بيانات/ملعب|Q115640897|مرجع=درويش1992}} * {{استشهاد بويكي بيانات|Q115640897|مرجع=درويش1992}} * {{استشهاد بويكي بيانات/ملعب|Q115754123|مرجع=الواحدي1992}} * {{استشهاد بويكي بيانات|Q115754123|مرجع=الواحدي1992}} * {{استشهاد بويكي بيانات/ملعب|Q115651867|مرجع=الداني1994}} * {{استشهاد بويكي بيانات|Q115651867|مرجع=الداني1994}} * {{استشهاد بويكي بيانات/ملعب|Q115756452|مرجع=عطية1995}} * {{استشهاد بويكي بيانات|Q115756452|مرجع=عطية1995}} * {{استشهاد بويكي بيانات/ملعب|Q115701544|مرجع=ابن كثير1998}} * {{استشهاد بويكي بيانات|Q115701544|مرجع=ابن كثير1998}} * {{استشهاد بويكي بيانات/ملعب|Q115730072|مرجع=ابن عادل1998}} * {{استشهاد بويكي بيانات|Q115730072|مرجع=ابن عادل1998}} * {{استشهاد بويكي بيانات/ملعب|Q115730115|مرجع=الرازي2000}} * {{استشهاد بويكي بيانات|Q115730115|مرجع=الرازي2000}} * {{استشهاد بويكي بيانات/ملعب|Q97221368|مرجع=الطبري2001}} * {{استشهاد بويكي بيانات|Q97221368|مرجع=الطبري2001}} * {{استشهاد بويكي بيانات/ملعب|Q115484580|مرجع=أحمد2001}} * {{استشهاد بويكي بيانات|Q115484580|مرجع=أحمد2001}} * {{استشهاد بويكي بيانات/ملعب|Q115683684}} * {{استشهاد بويكي بيانات|Q115683684}} * {{استشهاد بويكي بيانات/ملعب|Q115640158|مرجع=الدعاس2004}} * {{استشهاد بويكي بيانات|Q115640158|مرجع=الدعاس2004}} * {{استشهاد بويكي بيانات/ملعب|Q115683765|مرجع=سلامة2006}} * {{استشهاد بويكي بيانات|Q115683765|مرجع=سلامة2006}} * {{استشهاد بويكي بيانات/ملعب|Q115701920|مرجع=ابن القيم2007}} * {{استشهاد بويكي بيانات|Q115701920|مرجع=ابن القيم2007}} * {{استشهاد بويكي بيانات/ملعب|Q115743500}} * {{استشهاد بويكي بيانات|Q115743500}} * {{استشهاد بويكي بيانات/ملعب|Q115615370|مرجع=الشايع2011}} * {{استشهاد بويكي بيانات|Q115615370|مرجع=الشايع2011}} * {{استشهاد بويكي بيانات/ملعب|Q140501357}} * {{استشهاد بويكي بيانات|Q140501357}} * {{استشهاد بويكي بيانات/ملعب|Q136804563|ج=2|ص=442}} * {{استشهاد بويكي بيانات|Q136804563|ج=2|ص=442}} * {{استشهاد بويكي بيانات/ملعب|Q115796840|ج=2|ص=100}} * {{استشهاد بويكي بيانات|Q115796840|ج=2|ص=100}} <div dir="ltr"> * {{استشهاد بويكي بيانات/ملعب|Q115917529|مرجع=Dyson1999}} * {{استشهاد بويكي بيانات|Q115917529|مرجع=Dyson1999}} * {{استشهاد بويكي بيانات/ملعب|Q118316084|مرجع=Javvin2005}} * {{استشهاد بويكي بيانات|Q118316084|مرجع=Javvin2005}} * {{استشهاد بويكي بيانات/ملعب|Q115917346|مرجع=Kozierok2005}} * {{استشهاد بويكي بيانات|Q115917346|مرجع=Kozierok2005}} * {{استشهاد بويكي بيانات/ملعب|Q115922106|مرجع=Fall2012}} * {{استشهاد بويكي بيانات|Q115922106|مرجع=Fall2012}} * {{استشهاد بويكي بيانات/ملعب|Q115919723|مرجع=Odom2013}} * {{استشهاد بويكي بيانات|Q115919723|مرجع=Odom2013}} * {{استشهاد بويكي بيانات/ملعب|Q9065143}} </div> 0vmjxmis342nlajmuluprazwdrd62ge وحدة:Cite Q/ملعب 828 231230 1097254 1096613 2026-07-22T15:58:48Z حبيشان 31560 1097254 Scribunto text/plain --[[ Cite Q النسخة العربية مشتق من النسخة الإنجليزية ]] require('strict') local sandbox = '' local WdItem = require('Module:WdItem' .. sandbox) local cfg = mw.loadData('Module:Cite Q/config' .. sandbox) local rtl_lang = {ar = true, fa = true, ur = true, ku = true, he = true, arc = true, dv = true, ha = true, khw = true, ks = true, ps = true, yi = true, ota = true } local ref_cash = {} --[[-------------------< A R G U M E N T _ W R A P P E R >---------------------- Argument wrapper. This function provides support for argument mapping defined in the configuration file so that multiple names can be transparently aliased to single internal variable. ]] local function argument_wrapper ( arglist ) local origin = {}; local nilargs = {}; return setmetatable({ ORIGIN = function ( self, k ) local dummy = self[k]; -- force the variable to be loaded. return origin[k]; end }, { __index = function ( tbl, k ) local v = rawget(tbl,k) if v then return v elseif nilargs[k] then return nil end local list = (type(k)=="number") and k or cfg.aliases_t[k]; if type( list ) == 'table' then for _, alias_key in pairs( list ) do if arglist[alias_key] then v = arglist[alias_key] origin[k] = alias_key break; end end elseif list ~= nil then v = arglist[list] if v then origin[k] = list end end if v == nil then nilargs[k] = true else rawset( tbl, k, v ) end return v end, }); end ------------------------------------------------------------------------------- -- makeOrdinal needs to be internationalised along with cfg.i18n_t -- takes cardinal number as a numeric and returns the ordinal as a string -- we need three exceptions in English for 1st, 2nd, 3rd, 21st, .. 31st, etc. ------------------------------------------------------------------------------- local makeOrdinal = function(cardinal) local card = tonumber(cardinal) if not card then return cardinal end local ordsuffix = cfg.i18n_t.ordinal.default if card % 10 == 1 then ordsuffix = cfg.i18n_t.ordinal[1] elseif card % 10 == 2 then ordsuffix = cfg.i18n_t.ordinal[2] elseif card % 10 == 3 then ordsuffix = cfg.i18n_t.ordinal[3] end -- In English, 1, 21, 31, etc. use 'st', but 11, 111, etc. use 'th' -- similarly for 12 and 13, etc. if (card % 100 == 11) or (card % 100 == 12) or (card % 100 == 13) then ordsuffix = cfg.i18n_t.ordinal.default end return card .. ordsuffix end --[[--------------------------< I S _ S E T >-------------------------------------------------------------- Returns true if argument is set; false otherwise. Argument is 'set' when it exists (not nil) or when it is not an empty string. ]] local function is_set( var ) return not (var == nil or var == '') end --[[--------------------------< I N _ A R R A Y >-------------------------------------------------------------- Whether needle is in haystack (taken from Module:Citation/CS1/Utilities) ]] local function in_array( needle, haystack ) if needle == nil then return false end for n, v in ipairs( haystack ) do if v == needle then return n end end return false end --[[--------------------------< A C C E P T _ V A L U E >------------------------------------------------------- Accept WD value by framing in ((...)) if param_val is equal to keyword; else pass-through WD value as is. ]] local function accept_value( param_val, wd_val ) local val = param_val if val then if in_array (val, {'accept', '))((', ':d:'}) then val = '((' .. wd_val .. '))' elseif '((accept))' == val then val = 'accept' elseif '(())(())' == val then val = '))((' elseif '((:d:))' == val then val = ':d:' else val = wd_val end end return val end -- function to fetch a value to display local function makelink(v, out, link, maxpos, wdl, lang) local label if v.mainsnak.snaktype == "value" then if v.mainsnak.datatype == "wikibase-item" then local qnumber = v.mainsnak.datavalue.value.id local sitelink = mw.wikibase.getSitelink(qnumber) if qnumber == "Q2818964" then sitelink = nil end -- suppress link to "Various authors" -- من المهم التحقق من وجود datavalue if v.qualifiers and v.qualifiers.P1932 and v.qualifiers.P1932[1].datavalue then label = v.qualifiers.P1932[1].datavalue.value else label = mw.wikibase.getLabelByLang(qnumber, lang) or mw.wikibase.getLabel(qnumber) if label then label = mw.text.nowiki(label) else label = qnumber -- should add tracking category end end local position = maxpos + 1 -- Default to 'next' author. -- use P1545 (series ordinal) instead of default position. if v["qualifiers"] and v.qualifiers["P1545"] and v.qualifiers["P1545"][1] then position = tonumber(v.qualifiers["P1545"][1].datavalue.value) end maxpos = math.max(maxpos, position) if sitelink then -- just the plain name, -- but keep a record of the links, using the same index out[position] = label link[position] = sitelink else if wdl then -- show that there's a Wikidata entry available out[position] = string.format( "[[:d:Q%s|%s]]&nbsp;<span title='%s'>[[File:Wikidata-logo.svg|16px|alt=|link=]]</span>", v.mainsnak.datavalue.value["numeric-id"], label, cfg.i18n_t["errors"]["local-article-not-found"] ) else -- no Wikidata links wanted, so just give the plain label out[position] = label end end elseif v.mainsnak.datatype == "string" then local position = maxpos + 1 -- Default to 'next' author. -- use P1545 (series ordinal) instead of default position. if v["qualifiers"] and v.qualifiers["P1545"] and v.qualifiers["P1545"][1] then position = tonumber(v.qualifiers["P1545"][1].datavalue.value) end maxpos = math.max(maxpos, position) out[position] = v.mainsnak.datavalue.value else -- not a wikibase-item or a string! end else -- code here if we want to return something when author is "unknown" -- من المهم التحقق من وجود datavalue if v.qualifiers and v.qualifiers.P1932 and v.qualifiers.P1932[1].datavalue then label = v.qualifiers.P1932[1].datavalue.value else label = cfg.i18n_t["unknown-author"][lang] or cfg.i18n_t["unknown-author"]["ar"] end maxpos = maxpos + 1 out[maxpos] = label end return maxpos end --[=[-------------------------< G E T _ N A M E _ L I S T >---------------------------------------------------- get_name_list -- adapted from getAuthors code taken from Module:RexxS arguments: nl_type - type of name list to fetch: nl_type = 'author' for authors; 'editor' for editors; 'translator' for translators args - pointer to the parameter arguments table from the template call qid - value from |qid= parameter; the Q-id of the source (book, etc.) in qid wdl - value from the |wdl= parameter; a Boolean passed to enable links to Wikidata when no article exists returns nothing; modifies the args table ]=] local function get_name_list (nl_type, args, Q, wdl, lang) local propertyID = "P50" local fallbackID = "P2093" -- author name string if nl_type =="author" then propertyID = 'P50' -- for authors fallbackID = 'P2093' -- author-string elseif nl_type =="editor" then propertyID = 'P5769' -- "editor-in-chief" fallbackID = 'P98' -- for editors - So-called "fallbacks" are actually a second set of properties processed -- TBD. Take book series editors into account as well (if they have a separate P code as well)? elseif nl_type == "translator" then propertyID = 'P655' -- for translators fallbackID = nil -- elseif 'contributor' == nl_type then -- f.e. author of forewords (P2679) and afterwords (P2680); requires |contribution=, |title= and |author= -- propertyID = 'P' -- for contributors -- fallbackID = nil else return -- not specified so return end -- wdl is a Boolean passed to enable links to Wikidata when no article exists -- if "false" or "no" or "0" is passed set it false -- if nothing or an empty string is passed set it false if wdl and (#wdl > 0) then wdl = wdl:lower() wdl = in_array (wdl, {"false", "no", "0"}) else -- wdl is empty, so wdl = false end local statements = Q:getStatements(propertyID) if statements:count() == 0 and fallbackID then statements = Q:getStatements(fallbackID) end -- Make sure it actually has at least one of the properties requested if statements:count() == 0 then return nil end local props = statements:getStatmentsTable() -- So now we have something to return: -- table 'out' is going to store the names(s): -- and table 'link' will store any links to the name's article local out = {} local link = {} local maxpos = 0 if props and props[1] then for _, v in pairs(props) do maxpos = makelink(v, out, link, maxpos, wdl, lang) end end -- if there's anything to return, then insert the additions in the template arguments table -- in the form |author1=firstname secondname |author2= ... -- Renumber, in case we have inconsistent numbering local keys = {} for k, v in pairs(out) do keys[#keys + 1] = k end table.sort(keys) -- as they might be out of order for i, k in ipairs(keys) do out[k] = out[k]:gsub ('&#39;', '\''); -- prevent cs1|2 multiple names categorization; replace html entity with the actual character if args[nl_type .. i] then -- name gets overwritten -- pull corresponding -link only if overwritten name is same as WD name if link[k] and (args[nl_type .. i] == out[k]) then args[nl_type .. '-link' .. i] = args[nl_type .. '-link' .. i] or link[k] -- author-linkn or editor-linkn end else -- name does not get overwritten, so pull name from WD args[nl_type .. i] = out[k] if link[k] then args[nl_type .. '-link' .. i] = args[nl_type .. '-link' .. i] or link[k] -- author-linkn or editor-linkn end end end end local function _getLangOfSnakProp(snak, pid) if not pid or not snak then return {} end local out = {} local props = snak[pid] for i, v in ipairs(props) do if v.datatype == "monolingualtext" and v.datavalue then out[#out + 1] = v.datavalue.value.language end end return out end local function getLangOfProp(frame) local pid = frame.args.pid or mw.text.trim(frame.args[1] or "") if pid == "" then return end local qid = frame.args.qid if qid == "" then qid = nil end local Q = WdItem.new(qid, { fwd = "ALL", osd = false, noicon = true }) return table.concat(Q:getLangOfProp(pid), ", ") end -- gets the language codes of a Wikidata entry as a table local function _lang_code(Qitem) local lc = Qitem:getPropOfProp( "P407", "P424") if lc then return mw.text.split( lc, "[,، ]+" ) end --modified lc = Qitem:getPropOfProp( "P407", "P218" ) if lc then return mw.text.split( lc, "[,، ]+" ) end --modified return Qitem:getLangOfProp("P1476") end local function lang_code(frame) local Q = WdItem.newItem(frame.args.qid or mw.text.trim(frame.args[1] or ""), { fwd = "ALL", osd = false, noicon = true }) return table.concat(_lang_code(Q), ", ") end -- wraps a string in nowiki unless disable flag is set local function wrap_nowiki(str, disable) if disable then return str or '' end return mw.text.nowiki(str or '') end -- sort sequence table whose values are key-value pairs by key local function comp_key(a, b) local param_a, enum_a = a[1]:match ('(%D+)(%d+)$'); -- get param name and enumerator from <a> local param_b, enum_b = b[1]:match ('(%D+)(%d+)$'); -- get param name and enumerator from <b> if enum_a and enum_b then -- if both parameters have neumerators if param_a == param_b then -- are parameter names the same? return tonumber (enum_a) < tonumber (enum_b); -- yes: compare enumerators end end return a[1] < b[1]; -- alpha sort if here end -- sort sequence table whose values are key-value pairs by value local function comp_val(a, b) return a[2] < b[2] end -- ref filtering for citing from wikidata local function is_rejected(item) -- rejected Q if cfg.rejected_t.sources[item]==true then return true; end -- rejected Properties local item_entity = mw.wikibase.getEntity(item); for _, v in pairs(cfg.rejected_t.properties) do if (#item_entity:getAllStatements( v )>0 ) then return true; end end -- Rejected InatanceOf local instance = item_entity:getAllStatements( "P31" ) for _,v in pairs(instance) do if cfg.rejected_t.instances[v.mainsnak.datavalue.value.id] then return true; end end --No used Properties local has_properties = false for k, _ in pairs(cfg.used_properties_t) do if (#item_entity:getAllStatements( k )>0 ) then has_properties = true; break; end end return not has_properties; end local function _cite_web(citeq_args) local refsnak= citeq_args.snak local Q citeq_args.snak = nil -- retrieve all the parameters local pqid = citeq_args.pqid citeq_args.pqid = nil local wdl = false local qid = nil local multi_args = { P50 = "author", P2093 = "author", P5769 = "editor", P98 = "editor", P655 = "translator", } Q = WdItem.newSnakItem(refsnak, {fwd = "ALL", osd = false, noicon = true}) -- find language local langcodes = {} if refsnak["P1476"] then langcodes = _getLangOfSnakProp(refsnak, "P1476") citeq_args.language = citeq_args.language or langcodes[1] end langcodes[#langcodes+1] = 'ar' langcodes[#langcodes+1] = 'en' Q:setOptions({ langs = langcodes }) local labellang = langcodes[1] local rtl = rtl_lang[langcodes[1]] or false local oth = {} for i in pairs(refsnak) do local label = "" -- multiple authors may be given if refsnak[i][1].snaktype ~= 'novalue' then if multi_args[i] then get_name_list (multi_args[i], citeq_args, Q, wdl, labellang) elseif cfg.used_properties_t[i] and type(cfg.used_properties_t[i]) == "table" then local data = cfg.used_properties_t[i] local langidx = 1 while citeq_args[data.arg] == nil and langidx<=#langcodes do citeq_args[data.arg] = Q:getValue( i, { maxvals = data.maxvals, linked = data.linked, rank = data.rank or "best", lang=langcodes[langidx] } ) if citeq_args[data.arg] == nil then break elseif citeq_args[data.arg]:find('[[تصنيف:Articles with missing Wikidata information]]', 1, true) then citeq_args[data.arg] = nil langidx = langidx + 1 else break end end if not citeq_args[data.arg] then citeq_args[data.arg] = Q:getValue( i, { maxvals = data.maxvals, linked = data.linked} ) if citeq_args[data.arg]:find('^Q%d+$') then -- qid was returned -- try fallback to qid's native language local qid_languages = _lang_code(WdItem.newItem( citeq_args[data.arg], { fwd = "ALL", osd = false, noicon = true } )) citeq_args[data.arg] = Q:getValue( i, { maxvals = data.maxvals, linked = data.linked, lang = qid_languages[1]} ) if citeq_args[data.arg]:find('^Q%d+$') then -- qid was returned again citeq_args[data.arg] = nil else -- record the language found if no lang specified citeq_args.language = citeq_args.language or qid_languages[1] end end end --- translate unknown value if citeq_args[data.arg] == "Unknown" then if rtl then citeq_args[data.arg] = cfg.i18n_t.ar["unknown-" .. data.arg] or cfg.i18n_t.ar["unknown"] else citeq_args[data.arg] = mw.wikibase.getLabelByLang("Q4233718", lang):gsub("^%l", mw.ustring.upper) end end ----------------- if data.others then oth[#oth + 1] = citeq_args[data.arg] and ((cfg.i18n_t.ar[data.arg] or data.arg:gsub("^%l", string.upper)) .. ": " .. citeq_args[data.arg]) citeq_args[data.arg] = nil end elseif cfg.used_properties_t[i] then if i == "P648" then citeq_args.ol = (Q:getValue( "P648", { maxvals = 1 } ) or ''):gsub("^OL(.+)$", "%1") if citeq_args.ol == "" then citeq_args.ol = nil end elseif i == "P957" then citeq_args.isbn = Q:getValue("P957", { maxvals = 1 } ) elseif in_array(i,{"P854", "P953", "P856", "P2699"}) then local url; for _, pr in ipairs( {"P854", "P953", "P856", "P2699"} ) do url = Q:getValue( pr, { maxvals = 1 } ) if url then citeq_args.url = mw.text.split( url, " (", true )[1] local arcurl = mw.ustring.match( url, " %((.*)%)" ) -- when there is an archive url, <url> holds: url<space>(archive url); here extract the archive url if present if arcurl then local arcy, arcm, arcd = arcurl:match("(20%d%d)%p?(%d%d)%p?(%d%d)") if arcy and arcm and arcd then citeq_args["archive-url"] = arcurl citeq_args["archive-date"] = tonumber(arcd) .. " " .. cfg.i18n_t.months[tonumber(arcm)] .. " " .. arcy end end break end end end end end end if citeq_args.url then if refsnak["P813"] then citeq_args.accessdate = Q:getValue("P813", { maxvals = 1 } ) end if refsnak["P1065"] and refsnak["P2960"] then citeq_args["archive-url"] = Q:getValue("P1065", { maxvals = 1 } ) citeq_args["archive-date"]= Q:getValue("P2960", { maxvals = 1 } ) end end citeq_args.others = citeq_args.others or table.concat(oth, ". ") if citeq_args.others == "" then citeq_args.others = nil end citeq_args.biorxiv = citeq_args.biorxiv and ("10.1101/" .. citeq_args.biorxiv) -- if url then see if there's an archive: citeq_args.url local url local title_display = citeq_args.title if citeq_args.url then citeq_args.title = wrap_nowiki(title_display) end -- TBD: incorporate |at, |sheets= and |sheet= here as well -- Sort out what should happen if several of them are given at the same time if citeq_args.page or citeq_args.p then -- let single take precedence over multiple citeq_args.pages = nil citeq_args.pp = nil end if citeq_args.pages then local _, count = string.gsub(citeq_args.pages, "[,;%s]%d+", "") if count == 1 then citeq_args.page = citeq_args.pages citeq_args.pages = nil end end for k, v in pairs(citeq_args) do if in_array (v, {'(())', 'unset', 'ignore'}) or 'string' ~= type(k) then -- empty accept-as-is-written (()) markup to indicate an empty/unused parameter value, other ((...)) markups are deliberately passed down to {{citation}} citeq_args[k] = nil elseif in_array (v, {'((unset))', '((ignore))'}) then -- strip off markup for free-text values clashing with local keywords citeq_args[k] = 'unset' end end local author_count = 0 for k, v in pairs(citeq_args) do if k:find("^author%d+$") then author_count = author_count + 1 end end if author_count > 8 then -- convention in astronomy journals, optional mode for this? if 'all' == citeq_args['display-authors'] then citeq_args['display-authors'] = nil; -- unset because no longer needed else citeq_args['display-authors'] = citeq_args['display-authors'] or 3 -- limit to three displayed names end end -- replace no-break space by space, User:Mr. Ibrahem if citeq_args.title then citeq_args.title = mw.ustring.gsub( citeq_args.title, "\194\160", " " ) end local editor_count = 0 for k, v in pairs(citeq_args) do if k:find("^editor%d+$") then editor_count = editor_count + 1 end end if editor_count > 8 then -- convention in astronomy journals, optional mode for this? if 'all' == citeq_args['display-editors'] then citeq_args['display-editors'] = nil; -- unset because no longer needed else citeq_args['display-editors'] = citeq_args['display-editors'] or 3 -- limit to three displayed names end end -- code to make a guess what template to use from the supplied parameters -- (first draft for proof-of-concept) local template = "بويب" -- |id= could hold more than one identifier pulled from Wikidata not supported by {{citation}}, right now only add our qid to the list local list_sep = '. ' if citeq_args.mode ~= 'cs1' then list_sep = ', ' end -- clean up any blank parameters for k, v in pairs(citeq_args) do if v == "" then citeq_args[k] = nil end end if template then -- citeq_args.mode = citeq_args.mode or "cs1" -- a cs1 template already knows that it is cs1 so this line is superfluous template = "استشهاد " .. template else -- citeq_args.mode = citeq_args.mode or "cs2" -- a cs2 template already knows that it is cs2 so this line is superfluous template = "استشهاد" end citeq_args['no-tracking'] = 'true' -- لإيقاف ظهور تصانيف التتبع return mw.getCurrentFrame():expandTemplate{title = template, args = citeq_args} -- render the template end --[[-------------------------< C I T E _ Q >------------------------------------------------------------------ Takes standard CS1|2 template parameters and passes all to {{citation}}. If neither of |author= and |author1= are set, calls get_authors() to try to get an author name-list from Wikidata. The result is passed to {{citation}} for rendering. --]] local function _cite_q (in_citeq_args) local frame = mw.getCurrentFrame() local citeq_args = {} local origin_args = {} local Q -- parameters that don't get passed to Citation local expand = in_citeq_args.expand -- when set to anything, causes {{cite q}} to render <code><nowiki>{{citation|...}}</nowiki></code> local qid = in_citeq_args.qid or in_citeq_args[1] local wdl = in_citeq_args.wdl local template = in_citeq_args.template local cite_class = 'citation' local rtl = true local snak = in_citeq_args.snak or {} local pqid = in_citeq_args.pqid local page_offset = 0 in_citeq_args.expand = nil in_citeq_args[1] = nil in_citeq_args.qid = nil in_citeq_args.wdl = nil in_citeq_args.template = nil in_citeq_args.snak = nil in_citeq_args.pqid = nil if in_citeq_args.wikidatacite then citeq_args = in_citeq_args else local A = argument_wrapper(in_citeq_args) local loaded_args ={} for _,args_table in pairs({cfg.simple_properties_t, cfg.used_args_t}) do for k,_ in pairs(args_table) do if A[k] then citeq_args[k] = A[k] if k ~= A:ORIGIN(k) then origin_args[k] = A:ORIGIN(k) table.insert(loaded_args, A:ORIGIN(k)) else table.insert(loaded_args, k) end end end end for k,v in pairs(in_citeq_args) do if not in_array(k,loaded_args) then citeq_args[k] = v end end end -- if title supplied, flag to not read html title local titleforced = (citeq_args.title ~= nil) local default_opt = {rank = "preferred normal", fetchwikidata = "ALL", onlysourced = false, noicon = true, linksproject = cfg.config_t.linksproject, linkprefix = cfg.config_t.wikilinkprefix } if citeq_args.volume or citeq_args.volume then local qualifiedaspossible = {} if citeq_args.volume then qualifiedaspossible['P478'] = citeq_args.volume end if citeq_args.chapter then qualifiedaspossible['P792'] = citeq_args.chapter end default_opt.qualifiedaspossible = qualifiedaspossible end if #snak > 0 then Q = WdItem.newSnakItem(snak,default_opt) else Q = WdItem.newItem(qid, default_opt) end local oth = {} -- put the language codes into a sequential table langcodes[] local langcodes = {} if citeq_args.language then -- check these are a supported language codes for lc in mw.text.gsplit( citeq_args.language, "[,، ]+", false ) do --modified langcodes[#langcodes+1] = mw.language.isSupportedLanguage(lc) and lc end end if not langcodes[1] then -- try to find language of work langcodes = _lang_code(Q) end if not langcodes[1] then -- try fallback to journal's language local journal_qid = Q:followQid("P1433") langcodes = journal_qid and _lang_code(journal_qid) end citeq_args.language = citeq_args.language or table.concat(langcodes, ", ") Q:setOptions( { langs = langcodes } ); local labellang = langcodes[1] or 'ar' rtl = rtl_lang[langcodes[1]] or false -- loop through list of simple properties and get their values in citeq_args for name, data in pairs(cfg.simple_properties_t) do local opt = { maxvals = data.maxvals, linked = data.linked, qual = data.qual } if data.no_vol_qual then opt.qualifiedaspossible = {}; end citeq_args[name] = citeq_args[name] or Q:getValue(data.id, opt ) if not citeq_args[name] and data.populate_from_journal then local publishedin = Q:getValue("P1433", {maxvals = 0, qual = data.id, qualsonly = true} ) citeq_args[name] = publishedin or Q:getPropOfProp("P1433", data.id, { maxvals = data.maxvals}) end if citeq_args[name] and snak[data.id] then snak[data.id] = nil end --- translate unknown value if citeq_args[name] == "Unknown" and rtl then citeq_args[name] = cfg.i18n_t.ar["unknown-" .. name] or cfg.i18n_t.ar["unknown"] end ----------------- if data.others then oth[#oth + 1] = citeq_args[name] and ((rtl and cfg.i18n_t.ar[name] or name:gsub("^%l", string.upper)) .. ": " .. citeq_args[name]) citeq_args[name] = nil end end citeq_args.others = citeq_args.others or table.concat(oth, ". ") if citeq_args.others == "" then citeq_args.others = nil end citeq_args.journal = citeq_args.journal and citeq_args.journal:gsub("^''", ""):gsub("''$", ""):gsub("|''", "|"):gsub("'']]", "]]") citeq_args.ol = citeq_args.ol or (Q:getValue("P648", { maxvals = 1 } ) or ''):gsub("^OL(.+)$", "%1") if citeq_args.ol == "" then citeq_args.ol = nil end -- TBD. Take care of |ol-access=? citeq_args.biorxiv = citeq_args.biorxiv and ("10.1101/" .. citeq_args.biorxiv) citeq_args.isbn = citeq_args.isbn or Q:getValue("P957", { maxvals = 1, rank="best" } ) -- try ISBN 10 (only one value accepted) if citeq_args.page then -- let single take precedence over multiple citeq_args.pages = nil citeq_args.pp = nil end if citeq_args.pages then local _, count = string.gsub(citeq_args.pages, "[,;%s]%d+", "") if count == 1 then citeq_args.page = citeq_args.pages citeq_args.pages = nil end end -- if url then see if there's an archive: citeq_args.url local url --find formatted url if snak ~= {} then for k, v in pairs(snak) do if (v[1].datatype == "external-id") then local furl = mw.wikibase.getBestStatements( k, "P1630" ) if 0 ~= #furl then furl = furl[1]["mainsnak"]["datavalue"]["value"] citeq_args.url = mw.message.newRawMessage(furl, {v[1]["datavalue"]["value"]}):plain() snak[k] = nil break; end end end if citeq_args.url == nil and pqid and qid then local refproperty = mw.wikibase.getBestStatements(qid , "P1687" ) if 0 ~= #refproperty then -- خطأ لوا في وحدة:Cite_Q على السطر 1124: attempt to index field 'datavalue' (a nil value). if refproperty[1]["mainsnak"] and refproperty[1]["mainsnak"]["datavalue"] and refproperty[1]["mainsnak"]["datavalue"]["value"] then refproperty=refproperty[1]["mainsnak"]["datavalue"]["value"]["id"] local furl = mw.wikibase.getBestStatements( refproperty, "P1630" ) if 0 ~= #furl then furl = furl[1]["mainsnak"]["datavalue"]["value"] local refval = mw.wikibase.getBestStatements( pqid, refproperty ) refval = (0 ~= #refval) and refval[1]["mainsnak"]["datavalue"]["value"] if refval then citeq_args.url = mw.message.newRawMessage(furl, {refval}):plain() end end end end end end if not citeq_args.url then local S953 = Q:getStatements("P953"):getBestOne() local S953_val = S953:getRawValue() citeq_args.url = S953_val and (S953_val ~= "novalue" and S953_val ~= "somevalue") and S953_val if citeq_args.url then if mw.ustring.match(citeq_args.url, "archive.org/details/") and citeq_args.page then page_offset = tonumber(S953:getRawQual('P8330')[1]) or 0 if not citeq_args.volume or (citeq_args.volume and citeq_args.volume == S953:getRawQual('P478')[1]) then citeq_args.url = mw.ustring.gsub(citeq_args.url, "/?$", "") .. "/page/n" .. (tonumber(citeq_args.page) + page_offset - 1) .. "/mode/1up" end end end end if not citeq_args.url then for i, pr in ipairs( {"P856", "P2699"} ) do url = Q:getValue(pr, { maxvals = 1, qual="P1065" } ) if url then citeq_args.url = mw.text.split( url, " (", true )[1] local arcurl = mw.ustring.match( url, " %((.*)%)" ) -- when there is an archive url, <url> holds: url<space>(archive url); here extract the archive url if present if arcurl then local arcy, arcm, arcd = arcurl:match("(20%d%d)%p?(%d%d)%p?(%d%d)") if arcy and arcm and arcd then citeq_args["archive-url"] = arcurl citeq_args["archive-date"] = arcy .. '-' .. arcm .. '-' .. arcd end end break; end end end if not titleforced then -- Handle subtitle. if citeq_args.title then local subtitle = Q:getValue('P1680'); if subtitle then citeq_args.title = citeq_args.title .. ": " .. subtitle end end local htmltitle = Q:getValue("P1476", {qual = "P6833", maxvals = 1, qualsonly = true} ) if htmltitle then citeq_args.title = htmltitle:gsub("</?i>", "''") else local title_display = citeq_args.title or (langcodes[1] and mw.wikibase.getLabelByLang(qid, langcodes[1])) or mw.wikibase.getLabel(qid) if title_display and snak and snak.P1810 then title_display=title_display .. " | " .. snak.P1810[1].datavalue.value snak.P1810 = nil end title_display = title_display or ("No label or title -- debug: " .. qid) if citeq_args.url then citeq_args.title = wrap_nowiki(title_display) else local slink = mw.wikibase.getSitelink(qid, cfg.config_t.linksproject) local slink_flag = false local wrap_title = '' local wslink = false if not slink then -- See if we have wikisource if not citeq_args.url then local wikisource_sitelink = mw.wikibase.getSitelink(qid, cfg.i18n_t.wikisource) or nil if wikisource_sitelink then slink = ':s:'..wikisource_sitelink wslink = true end end end if citeq_args.title then if slink then wrap_title = wrap_nowiki(citeq_args.title) slink_flag = true else citeq_args.title = wrap_nowiki(citeq_args.title) end else if slink and not wslink then if slink:lower() == title_display:lower() then citeq_args.title = '[[' .. slink .. ']]' else wrap_title = wrap_nowiki(slink:gsub("%s%(.+%)$", ""):gsub(",.+$", "")) slink_flag = true end elseif wslink then wrap_title = wrap_nowiki(title_display) slink_flag = true else citeq_args.title = wrap_nowiki(title_display) end end if slink_flag then if slink == wrap_title and not wslink then -- direct link citeq_args.title = '[[' .. slink .. ']]' else -- piped link citeq_args.title = '[[' .. slink .. '|' .. wrap_title .. ']]' end end end end end -- replace no-break space by space, User:Mr. Ibrahem if citeq_args.title then citeq_args.title = mw.ustring.gsub( citeq_args.title, "\194\160", " " ) end if is_set (qid) then if not is_set (citeq_args.author) and not is_set (citeq_args.author1) and not is_set (citeq_args.subject) and not is_set (citeq_args.subject1) and not is_set (citeq_args.host) and not is_set (citeq_args.host1) and not is_set (citeq_args.last) and not is_set (citeq_args.last1) and not is_set (citeq_args.surname) and not is_set (citeq_args.surname1) and not is_set (citeq_args['author-last']) and not is_set (citeq_args['author-last1']) and not is_set (citeq_args['author1-last']) and not is_set (citeq_args['author-surname']) and not is_set (citeq_args['author-surname1']) and not is_set (citeq_args['author1-surname1']) then -- if neither are set, try to get authors from Wikidata get_name_list ('author', citeq_args, Q, wdl, labellang) -- modify citeq_args table with authors from Wikidata end if not is_set (citeq_args.editor) and not is_set (citeq_args.editor1) and not is_set (citeq_args['editor-last']) and not is_set (citeq_args['editor-last1']) and not is_set (citeq_args['editor1-last']) and not is_set (citeq_args['editor-surname']) and not is_set (citeq_args['editor-surname1']) and not is_set (citeq_args['editor1-surname']) then -- if neither are set, try to get editors from Wikidata get_name_list ('editor', citeq_args, Q, wdl, labellang) -- modify citeq_args table with editors from Wikidata end if not is_set (citeq_args.translator) and not is_set (citeq_args.translator1) and not is_set (citeq_args['translator-last']) and not is_set (citeq_args['translator-last1']) and not is_set (citeq_args['translator1-last']) and not is_set (citeq_args['translator-surname']) and not is_set (citeq_args['translator-surname1']) and not is_set (citeq_args['translator1-surname']) then -- if neither are set, try to get translators from Wikidata get_name_list ('translator', citeq_args, Q, wdl, labellang) -- modify citeq_args table with translators from Wikidata end end for k, v in pairs(citeq_args) do if in_array (v, {'(())', 'unset', 'ignore'}) or 'string' ~= type(k) then -- empty accept-as-is-written (()) markup to indicate an empty/unused parameter value, other ((...)) markups are deliberately passed down to {{citation}} citeq_args[k] = nil elseif in_array (v, {'((unset))', '((ignore))'}) then -- strip off markup for free-text values clashing with local keywords citeq_args[k] = 'unset' end end local author_count = 0 for k, v in pairs(citeq_args) do if k:find("^author%d+$") then author_count = author_count + 1 end end if author_count > 8 then -- convention in astronomy journals, optional mode for this? if 'all' == citeq_args['display-authors'] then citeq_args['display-authors'] = nil; -- unset because no longer needed else citeq_args['display-authors'] = citeq_args['display-authors'] or 3 -- limit to three displayed names end end local editor_count = 0 for k, v in pairs(citeq_args) do if k:find("^editor%d+$") then editor_count = editor_count + 1 end end if editor_count > 8 then -- convention in astronomy journals, optional mode for this? if 'all' == citeq_args['display-editors'] then citeq_args['display-editors'] = nil; -- unset because no longer needed else citeq_args['display-editors'] = citeq_args['display-editors'] or 3 -- limit to three displayed names end end -- change edition to ordinal if it's set and numeric if (rtl == false) then citeq_args.edition = citeq_args.edition and makeOrdinal(citeq_args.edition) end -- code to make a guess what template to use from the supplied parameters -- (first draft for proof-of-concept) if citeq_args.journal then template = template or "بدورية محكمة" elseif citeq_args.isbn then template = template or "بكتاب" citeq_args.asin = nil -- suppress ASIN if ISBN exists elseif citeq_args.website then template = template or "بويب" end -- template is CS1 designator: journal, web, news, etc. if template then -- citeq_args.mode = citeq_args.mode or "cs1" -- a cs1 template already knows that it is cs1 so this line is superfluous local citeclasses = {["بدورية محكمة"] = 'journal', ["بكتاب"] = "book", ["بويب"] = "web" } cite_class = citeclasses[template] template = "استشهاد " .. template else -- citeq_args.mode = citeq_args.mode or "cs2" -- a cs2 template already knows that it is cs2 so this line is superfluous template = "استشهاد" end -- |id= could hold more than one identifier pulled from Wikidata not supported by {{citation}}, right now only add our qid to the list local list_sep = '. ' if citeq_args.mode ~= 'cs1' then list_sep = ', ' end local id = cfg.i18n_t.wdq .. ':[[:d:' .. qid .. '|' .. qid .. ']]' local old_id = citeq_args.id if wdl then -- show WD logo id = id .. '[[ملف:Wikidata-logo.svg|16px|alt=|link=]]' -- possibly replace by WD edit icon? end if is_set (old_id) then citeq_args.id = old_id .. list_sep .. id -- append to user-specified contents else citeq_args.id = id end -- clean up any blank parameters for k, v in pairs(citeq_args) do if v == "" then citeq_args[k] = nil end end -- use real param names for CS1 messages for k,v in pairs(origin_args) do if citeq_args[k] and citeq_args[k] == in_citeq_args[v] then citeq_args[v] = citeq_args[k] citeq_args[k] = nil end end -- if |expand=<anything>, write a nowiki'd version to see what the {{citation}} template call looks like if expand then local expand_args = { "{{" .. template .. "\n" } -- init with citation template if expand == "self" then citeq_args.id = old_id -- restore original |id= parameter expand_args = { cfg.i18n_t.cite_q .. qid } -- expand to itself end -- make a sortable table and sort it by param name local sorttable = {} for param, val in pairs (citeq_args) do table.insert(sorttable, {param, val}) end table.sort(sorttable, comp_key) -- add contents to expand_args for idx, val in ipairs(sorttable) do table.insert(expand_args, val[1] .. '=' .. val[2] .. "\n") end -- make the nowiki'd string and done return frame:preprocess (table.concat ({'<syntaxhighlight lang="wikitext" inline="1">', table.concat (expand_args, ' |') .. '}}', '</syntaxhighlight>'})); end local erratumid = Q:getPropertyIDs( "P2507", { maxvals = 1 } ) if erratumid then erratumid = " [[d:" .. erratumid .. "|" .. cfg.i18n_t.erratum .. "]]" .. cfg.i18n_t.trackingcats.erratum else erratumid = "" end local opt_cat = '' if Q:getValue( "P5824" ) then opt_cat = cfg.i18n_t.trackingcats.retracted end if Q:getValue( "P1366" ) then opt_cat = opt_cat .. cfg.i18n_t.trackingcats.replaced end if not citeq_args.title then -- emit category link if missing title opt_cat = opt_cat .. cfg.i18n_t.trackingcats['no-label-or-title']; end if citeq_args.wikidatacite then return frame:expandTemplate{title = template, args = citeq_args} .. erratumid .. opt_cat -- render the template else local CS = require("Module:Citation/CS1" .. sandbox) return CS._citation(frame , citeq_args, {['CitationClass'] = cite_class}) .. erratumid .. opt_cat end end --[[-------------------------< C I T E _ Q >------------------------------------------------------------------ Takes standard CS1|2 template parameters and passes all to {{citation}}. If neither of |author= and |author1= are set, calls get_authors() to try to get an author name-list from Wikidata. The result is passed to {{citation}} for rendering. --]] local function _cite_wikidata (ref, pqid) -- early exit if not ref then return nil end local snak = ref.snaks -- مراجع غير مقبولة if snak.P143 or snak.P3452 then return nil end local hash = ref.hash if hash and hash ~= "" and ref_cash[hash] then return ref_cash[hash] end local citeq_args = {} local frame = mw.getCurrentFrame() if snak.P248 then for _, prop in pairs(snak.P248) do if prop.snaktype == "value" then citeq_args.qid = "Q" .. prop.datavalue.value["numeric-id"] end end snak.P248 = nil; end if citeq_args.qid and is_rejected(citeq_args.qid) == true then return nil end local reference citeq_args.snak = snak citeq_args.pqid = pqid citeq_args.wikidatacite = 1 if citeq_args.qid then reference = _cite_q(citeq_args) else local has_properties = false for k, _ in pairs(cfg.used_properties_t) do if snak[k] then has_properties = true; break; end end reference = (has_properties and _cite_web(citeq_args) or nil) end if reference and reference ~= "" then reference = frame:extensionTag("ref", reference, {name = 'wikidata-' .. hash}) end if hash and hash ~= "" then ref_cash[hash] = reference end return reference end local function cite_q (frame) local args = {} for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end for k, v in pairs(frame.args) do if v ~= "" then args[k] = v end end args.qid = args.qid or args[1] or "" if args.qid == "" then return nil end args[1] = nil local citesep = (args.citesep or "") if citesep == "" then citesep = ", " end citesep = citesep:gsub('"', '') -- strip double quotes after setting default to allow |citesep="" as a blank separator args.citesep = nil local tag = args.tag or "" if tag == "" then tag = nil end args.tag = nil local list = args.list or "" if list == "" then list = nil end args.list = nil args.language = args.language or args.lang args.lang = nil local cites = {} for q in args.qid:gmatch("Q%d+") do -- make a new copy of the arguments local newargs = {} for k, v in pairs(args) do if k ~= "qid" then newargs[k] = v end end newargs.qid = q if tag == "ref" then cites[#cites + 1] = frame:callParserFunction{ name = "#tag:ref", args = { _cite_q(newargs), name = q } } -- expand like this: args = { _cite_q(newargs), name = 'foo', group = 'bar' } else cites[#cites + 1] = _cite_q(newargs) end end if list then return frame:expandTemplate{ title = list, args = cites } else return table.concat(cites, citesep) end end --[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------ ]] return { makeOrdinal = makeOrdinal, getLangOfProp = getLangOfProp, lang_code = lang_code, _cite_wikidata = _cite_wikidata, _cite_q = _cite_q, cite_q = cite_q } 5vv0f61tnw089i01mvuu6qpstqz9jqv 1097287 1097254 2026-07-22T21:27:04Z حبيشان 31560 1097287 Scribunto text/plain --[[ Cite Q النسخة العربية مشتق من النسخة الإنجليزية ]] require('strict') local sandbox = '' local WdItem = require('Module:WdItem' .. sandbox) local cfg = mw.loadData('Module:Cite Q/config' .. sandbox) local rtl_lang = {ar = true, fa = true, ur = true, ku = true, he = true, arc = true, dv = true, ha = true, khw = true, ks = true, ps = true, yi = true, ota = true } local ref_cash = {} --[[-------------------< A R G U M E N T _ W R A P P E R >---------------------- Argument wrapper. This function provides support for argument mapping defined in the configuration file so that multiple names can be transparently aliased to single internal variable. ]] local function argument_wrapper ( arglist ) local origin = {}; local nilargs = {}; return setmetatable({ ORIGIN = function ( self, k ) local dummy = self[k]; -- force the variable to be loaded. return origin[k]; end }, { __index = function ( tbl, k ) local v = rawget(tbl,k) if v then return v elseif nilargs[k] then return nil end local list = (type(k)=="number") and k or cfg.aliases_t[k]; if type( list ) == 'table' then for _, alias_key in pairs( list ) do if arglist[alias_key] then v = arglist[alias_key] origin[k] = alias_key break; end end elseif list ~= nil then v = arglist[list] if v then origin[k] = list end end if v == nil then nilargs[k] = true else rawset( tbl, k, v ) end return v end, }); end ------------------------------------------------------------------------------- -- makeOrdinal needs to be internationalised along with cfg.i18n_t -- takes cardinal number as a numeric and returns the ordinal as a string -- we need three exceptions in English for 1st, 2nd, 3rd, 21st, .. 31st, etc. ------------------------------------------------------------------------------- local makeOrdinal = function(cardinal) local card = tonumber(cardinal) if not card then return cardinal end local ordsuffix = cfg.i18n_t.ordinal.default if card % 10 == 1 then ordsuffix = cfg.i18n_t.ordinal[1] elseif card % 10 == 2 then ordsuffix = cfg.i18n_t.ordinal[2] elseif card % 10 == 3 then ordsuffix = cfg.i18n_t.ordinal[3] end -- In English, 1, 21, 31, etc. use 'st', but 11, 111, etc. use 'th' -- similarly for 12 and 13, etc. if (card % 100 == 11) or (card % 100 == 12) or (card % 100 == 13) then ordsuffix = cfg.i18n_t.ordinal.default end return card .. ordsuffix end --[[--------------------------< I S _ S E T >-------------------------------------------------------------- Returns true if argument is set; false otherwise. Argument is 'set' when it exists (not nil) or when it is not an empty string. ]] local function is_set( var ) return not (var == nil or var == '') end --[[--------------------------< I N _ A R R A Y >-------------------------------------------------------------- Whether needle is in haystack (taken from Module:Citation/CS1/Utilities) ]] local function in_array( needle, haystack ) if needle == nil then return false end for n, v in ipairs( haystack ) do if v == needle then return n end end return false end --[[--------------------------< A C C E P T _ V A L U E >------------------------------------------------------- Accept WD value by framing in ((...)) if param_val is equal to keyword; else pass-through WD value as is. ]] local function accept_value( param_val, wd_val ) local val = param_val if val then if in_array (val, {'accept', '))((', ':d:'}) then val = '((' .. wd_val .. '))' elseif '((accept))' == val then val = 'accept' elseif '(())(())' == val then val = '))((' elseif '((:d:))' == val then val = ':d:' else val = wd_val end end return val end -- function to fetch a value to display local function makelink(v, out, link, maxpos, wdl, lang) local label local snak = v.mainsnak or v if snak.snaktype == "value" then if snak.datatype == "wikibase-item" then local qnumber = snak.datavalue.value.id local sitelink = mw.wikibase.getSitelink(qnumber) if qnumber == "Q2818964" then sitelink = nil end -- suppress link to "Various authors" -- من المهم التحقق من وجود datavalue if v.qualifiers and v.qualifiers.P1932 and v.qualifiers.P1932[1].datavalue then label = v.qualifiers.P1932[1].datavalue.value else label = mw.wikibase.getLabelByLang(qnumber, lang) or mw.wikibase.getLabel(qnumber) if label then label = mw.text.nowiki(label) else label = qnumber -- should add tracking category end end local position = maxpos + 1 -- Default to 'next' author. -- use P1545 (series ordinal) instead of default position. if v["qualifiers"] and v.qualifiers["P1545"] and v.qualifiers["P1545"][1] then position = tonumber(v.qualifiers["P1545"][1].datavalue.value) end maxpos = math.max(maxpos, position) if sitelink then -- just the plain name, -- but keep a record of the links, using the same index out[position] = label link[position] = sitelink else if wdl then -- show that there's a Wikidata entry available out[position] = string.format( "[[:d:Q%s|%s]]&nbsp;<span title='%s'>[[File:Wikidata-logo.svg|16px|alt=|link=]]</span>", snak.datavalue.value["numeric-id"], label, cfg.i18n_t["errors"]["local-article-not-found"] ) else -- no Wikidata links wanted, so just give the plain label out[position] = label end end elseif snak.datatype == "string" then local position = maxpos + 1 -- Default to 'next' author. -- use P1545 (series ordinal) instead of default position. if v["qualifiers"] and v.qualifiers["P1545"] and v.qualifiers["P1545"][1] then position = tonumber(v.qualifiers["P1545"][1].datavalue.value) end maxpos = math.max(maxpos, position) out[position] = snak.datavalue.value else -- not a wikibase-item or a string! end else -- code here if we want to return something when author is "unknown" -- من المهم التحقق من وجود datavalue if v.qualifiers and v.qualifiers.P1932 and v.qualifiers.P1932[1].datavalue then label = v.qualifiers.P1932[1].datavalue.value else label = cfg.i18n_t["unknown-author"][lang] or cfg.i18n_t["unknown-author"]["ar"] end maxpos = maxpos + 1 out[maxpos] = label end return maxpos end --[=[-------------------------< G E T _ N A M E _ L I S T >---------------------------------------------------- get_name_list -- adapted from getAuthors code taken from Module:RexxS arguments: nl_type - type of name list to fetch: nl_type = 'author' for authors; 'editor' for editors; 'translator' for translators args - pointer to the parameter arguments table from the template call qid - value from |qid= parameter; the Q-id of the source (book, etc.) in qid wdl - value from the |wdl= parameter; a Boolean passed to enable links to Wikidata when no article exists returns nothing; modifies the args table ]=] local function get_name_list (nl_type, args, Q, wdl, lang) local propertyID = "P50" local fallbackID = "P2093" -- author name string if nl_type =="author" then propertyID = 'P50' -- for authors fallbackID = 'P2093' -- author-string elseif nl_type =="editor" then propertyID = 'P5769' -- "editor-in-chief" fallbackID = 'P98' -- for editors - So-called "fallbacks" are actually a second set of properties processed -- TBD. Take book series editors into account as well (if they have a separate P code as well)? elseif nl_type == "translator" then propertyID = 'P655' -- for translators fallbackID = nil -- elseif 'contributor' == nl_type then -- f.e. author of forewords (P2679) and afterwords (P2680); requires |contribution=, |title= and |author= -- propertyID = 'P' -- for contributors -- fallbackID = nil else return -- not specified so return end -- wdl is a Boolean passed to enable links to Wikidata when no article exists -- if "false" or "no" or "0" is passed set it false -- if nothing or an empty string is passed set it false if wdl and (#wdl > 0) then wdl = wdl:lower() wdl = in_array (wdl, {"false", "no", "0"}) else -- wdl is empty, so wdl = false end local statements = Q:getStatements(propertyID) if statements:count() == 0 and fallbackID then statements = Q:getStatements(fallbackID) end -- Make sure it actually has at least one of the properties requested if statements:count() == 0 then return nil end local props = statements:getStatmentsTable() -- So now we have something to return: -- table 'out' is going to store the names(s): -- and table 'link' will store any links to the name's article local out = {} local link = {} local maxpos = 0 if props and props[1] then for _, v in pairs(props) do maxpos = makelink(v, out, link, maxpos, wdl, lang) end end -- if there's anything to return, then insert the additions in the template arguments table -- in the form |author1=firstname secondname |author2= ... -- Renumber, in case we have inconsistent numbering local keys = {} for k, v in pairs(out) do keys[#keys + 1] = k end table.sort(keys) -- as they might be out of order for i, k in ipairs(keys) do out[k] = out[k]:gsub ('&#39;', '\''); -- prevent cs1|2 multiple names categorization; replace html entity with the actual character if args[nl_type .. i] then -- name gets overwritten -- pull corresponding -link only if overwritten name is same as WD name if link[k] and (args[nl_type .. i] == out[k]) then args[nl_type .. '-link' .. i] = args[nl_type .. '-link' .. i] or link[k] -- author-linkn or editor-linkn end else -- name does not get overwritten, so pull name from WD args[nl_type .. i] = out[k] if link[k] then args[nl_type .. '-link' .. i] = args[nl_type .. '-link' .. i] or link[k] -- author-linkn or editor-linkn end end end end local function _getLangOfSnakProp(snak, pid) if not pid or not snak then return {} end local out = {} local props = snak[pid] for i, v in ipairs(props) do if v.datatype == "monolingualtext" and v.datavalue then out[#out + 1] = v.datavalue.value.language end end return out end local function getLangOfProp(frame) local pid = frame.args.pid or mw.text.trim(frame.args[1] or "") if pid == "" then return end local qid = frame.args.qid if qid == "" then qid = nil end local Q = WdItem.new(qid, { fwd = "ALL", osd = false, noicon = true }) return table.concat(Q:getLangOfProp(pid), ", ") end -- gets the language codes of a Wikidata entry as a table local function _lang_code(Qitem) local lc = Qitem:getPropOfProp( "P407", "P424") if lc then return mw.text.split( lc, "[,، ]+" ) end --modified lc = Qitem:getPropOfProp( "P407", "P218" ) if lc then return mw.text.split( lc, "[,، ]+" ) end --modified return Qitem:getLangOfProp("P1476") end local function lang_code(frame) local Q = WdItem.newItem(frame.args.qid or mw.text.trim(frame.args[1] or ""), { fwd = "ALL", osd = false, noicon = true }) return table.concat(_lang_code(Q), ", ") end -- wraps a string in nowiki unless disable flag is set local function wrap_nowiki(str, disable) if disable then return str or '' end return mw.text.nowiki(str or '') end -- sort sequence table whose values are key-value pairs by key local function comp_key(a, b) local param_a, enum_a = a[1]:match ('(%D+)(%d+)$'); -- get param name and enumerator from <a> local param_b, enum_b = b[1]:match ('(%D+)(%d+)$'); -- get param name and enumerator from <b> if enum_a and enum_b then -- if both parameters have neumerators if param_a == param_b then -- are parameter names the same? return tonumber (enum_a) < tonumber (enum_b); -- yes: compare enumerators end end return a[1] < b[1]; -- alpha sort if here end -- sort sequence table whose values are key-value pairs by value local function comp_val(a, b) return a[2] < b[2] end -- ref filtering for citing from wikidata local function is_rejected(item) -- rejected Q if cfg.rejected_t.sources[item]==true then return true; end -- rejected Properties local item_entity = mw.wikibase.getEntity(item); for _, v in pairs(cfg.rejected_t.properties) do if (#item_entity:getAllStatements( v )>0 ) then return true; end end -- Rejected InatanceOf local instance = item_entity:getAllStatements( "P31" ) for _,v in pairs(instance) do local vsnak = v.mainsnak or v if cfg.rejected_t.instances[vsnak.datavalue.value.id] then return true; end end --No used Properties local has_properties = false for k, _ in pairs(cfg.used_properties_t) do if (#item_entity:getAllStatements( k )>0 ) then has_properties = true; break; end end return not has_properties; end local function _cite_web(citeq_args) local refsnak= citeq_args.snak local Q citeq_args.snak = nil -- retrieve all the parameters local pqid = citeq_args.pqid citeq_args.pqid = nil local wdl = false local qid = nil local multi_args = { P50 = "author", P2093 = "author", P5769 = "editor", P98 = "editor", P655 = "translator", } Q = WdItem.newSnakItem(refsnak, {fwd = "ALL", osd = false, noicon = true}) -- find language local langcodes = {} if refsnak["P1476"] then langcodes = _getLangOfSnakProp(refsnak, "P1476") citeq_args.language = citeq_args.language or langcodes[1] end langcodes[#langcodes+1] = 'ar' langcodes[#langcodes+1] = 'en' Q:setOptions({ langs = langcodes }) local labellang = langcodes[1] local rtl = rtl_lang[langcodes[1]] or false local oth = {} for i in pairs(refsnak) do local label = "" -- multiple authors may be given if refsnak[i][1].snaktype ~= 'novalue' then if multi_args[i] then get_name_list (multi_args[i], citeq_args, Q, wdl, labellang) elseif cfg.used_properties_t[i] and type(cfg.used_properties_t[i]) == "table" then local data = cfg.used_properties_t[i] local langidx = 1 while citeq_args[data.arg] == nil and langidx<=#langcodes do citeq_args[data.arg] = Q:getValue( i, { maxvals = data.maxvals, linked = data.linked, rank = data.rank or "best", lang=langcodes[langidx] } ) if citeq_args[data.arg] == nil then break elseif citeq_args[data.arg]:find('[[تصنيف:Articles with missing Wikidata information]]', 1, true) then citeq_args[data.arg] = nil langidx = langidx + 1 else break end end if not citeq_args[data.arg] then citeq_args[data.arg] = Q:getValue( i, { maxvals = data.maxvals, linked = data.linked} ) if citeq_args[data.arg]:find('^Q%d+$') then -- qid was returned -- try fallback to qid's native language local qid_languages = _lang_code(WdItem.newItem( citeq_args[data.arg], { fwd = "ALL", osd = false, noicon = true } )) citeq_args[data.arg] = Q:getValue( i, { maxvals = data.maxvals, linked = data.linked, lang = qid_languages[1]} ) if citeq_args[data.arg]:find('^Q%d+$') then -- qid was returned again citeq_args[data.arg] = nil else -- record the language found if no lang specified citeq_args.language = citeq_args.language or qid_languages[1] end end end --- translate unknown value if citeq_args[data.arg] == "Unknown" then if rtl then citeq_args[data.arg] = cfg.i18n_t.ar["unknown-" .. data.arg] or cfg.i18n_t.ar["unknown"] else citeq_args[data.arg] = mw.wikibase.getLabelByLang("Q4233718", lang):gsub("^%l", mw.ustring.upper) end end ----------------- if data.others then oth[#oth + 1] = citeq_args[data.arg] and ((cfg.i18n_t.ar[data.arg] or data.arg:gsub("^%l", string.upper)) .. ": " .. citeq_args[data.arg]) citeq_args[data.arg] = nil end elseif cfg.used_properties_t[i] then if i == "P648" then citeq_args.ol = (Q:getValue( "P648", { maxvals = 1 } ) or ''):gsub("^OL(.+)$", "%1") if citeq_args.ol == "" then citeq_args.ol = nil end elseif i == "P957" then citeq_args.isbn = Q:getValue("P957", { maxvals = 1 } ) elseif in_array(i,{"P854", "P953", "P856", "P2699"}) then local url; for _, pr in ipairs( {"P854", "P953", "P856", "P2699"} ) do url = Q:getValue( pr, { maxvals = 1 } ) if url then citeq_args.url = mw.text.split( url, " (", true )[1] local arcurl = mw.ustring.match( url, " %((.*)%)" ) -- when there is an archive url, <url> holds: url<space>(archive url); here extract the archive url if present if arcurl then local arcy, arcm, arcd = arcurl:match("(20%d%d)%p?(%d%d)%p?(%d%d)") if arcy and arcm and arcd then citeq_args["archive-url"] = arcurl citeq_args["archive-date"] = tonumber(arcd) .. " " .. cfg.i18n_t.months[tonumber(arcm)] .. " " .. arcy end end break end end end end end end if citeq_args.url then if refsnak["P813"] then citeq_args.accessdate = Q:getValue("P813", { maxvals = 1 } ) end if refsnak["P1065"] and refsnak["P2960"] then citeq_args["archive-url"] = Q:getValue("P1065", { maxvals = 1 } ) citeq_args["archive-date"]= Q:getValue("P2960", { maxvals = 1 } ) end end citeq_args.others = citeq_args.others or table.concat(oth, ". ") if citeq_args.others == "" then citeq_args.others = nil end citeq_args.biorxiv = citeq_args.biorxiv and ("10.1101/" .. citeq_args.biorxiv) -- if url then see if there's an archive: citeq_args.url local url local title_display = citeq_args.title if citeq_args.url then citeq_args.title = wrap_nowiki(title_display) end -- TBD: incorporate |at, |sheets= and |sheet= here as well -- Sort out what should happen if several of them are given at the same time if citeq_args.page or citeq_args.p then -- let single take precedence over multiple citeq_args.pages = nil citeq_args.pp = nil end if citeq_args.pages then local _, count = string.gsub(citeq_args.pages, "[,;%s]%d+", "") if count == 1 then citeq_args.page = citeq_args.pages citeq_args.pages = nil end end for k, v in pairs(citeq_args) do if in_array (v, {'(())', 'unset', 'ignore'}) or 'string' ~= type(k) then -- empty accept-as-is-written (()) markup to indicate an empty/unused parameter value, other ((...)) markups are deliberately passed down to {{citation}} citeq_args[k] = nil elseif in_array (v, {'((unset))', '((ignore))'}) then -- strip off markup for free-text values clashing with local keywords citeq_args[k] = 'unset' end end local author_count = 0 for k, v in pairs(citeq_args) do if k:find("^author%d+$") then author_count = author_count + 1 end end if author_count > 8 then -- convention in astronomy journals, optional mode for this? if 'all' == citeq_args['display-authors'] then citeq_args['display-authors'] = nil; -- unset because no longer needed else citeq_args['display-authors'] = citeq_args['display-authors'] or 3 -- limit to three displayed names end end -- replace no-break space by space, User:Mr. Ibrahem if citeq_args.title then citeq_args.title = mw.ustring.gsub( citeq_args.title, "\194\160", " " ) end local editor_count = 0 for k, v in pairs(citeq_args) do if k:find("^editor%d+$") then editor_count = editor_count + 1 end end if editor_count > 8 then -- convention in astronomy journals, optional mode for this? if 'all' == citeq_args['display-editors'] then citeq_args['display-editors'] = nil; -- unset because no longer needed else citeq_args['display-editors'] = citeq_args['display-editors'] or 3 -- limit to three displayed names end end -- code to make a guess what template to use from the supplied parameters -- (first draft for proof-of-concept) local template = "بويب" -- |id= could hold more than one identifier pulled from Wikidata not supported by {{citation}}, right now only add our qid to the list local list_sep = '. ' if citeq_args.mode ~= 'cs1' then list_sep = ', ' end -- clean up any blank parameters for k, v in pairs(citeq_args) do if v == "" then citeq_args[k] = nil end end mw.logObject(citeq_args) if template then -- citeq_args.mode = citeq_args.mode or "cs1" -- a cs1 template already knows that it is cs1 so this line is superfluous template = "استشهاد " .. template else -- citeq_args.mode = citeq_args.mode or "cs2" -- a cs2 template already knows that it is cs2 so this line is superfluous template = "استشهاد" end citeq_args['no-tracking'] = 'true' -- لإيقاف ظهور تصانيف التتبع return mw.getCurrentFrame():expandTemplate{title = template, args = citeq_args} -- render the template end --[[-------------------------< C I T E _ Q >------------------------------------------------------------------ Takes standard CS1|2 template parameters and passes all to {{citation}}. If neither of |author= and |author1= are set, calls get_authors() to try to get an author name-list from Wikidata. The result is passed to {{citation}} for rendering. --]] local function _cite_q (in_citeq_args) local frame = mw.getCurrentFrame() local citeq_args = {} local origin_args = {} local Q -- parameters that don't get passed to Citation local expand = in_citeq_args.expand -- when set to anything, causes {{cite q}} to render <code><nowiki>{{citation|...}}</nowiki></code> local qid = in_citeq_args.qid or in_citeq_args[1] local wdl = in_citeq_args.wdl local template = in_citeq_args.template local cite_class = 'citation' local rtl = true local snak = in_citeq_args.snak or {} local pqid = in_citeq_args.pqid local page_offset = 0 in_citeq_args.expand = nil in_citeq_args[1] = nil in_citeq_args.qid = nil in_citeq_args.wdl = nil in_citeq_args.template = nil in_citeq_args.snak = nil in_citeq_args.pqid = nil mw.logObject(expand) if in_citeq_args.wikidatacite then citeq_args = in_citeq_args else local A = argument_wrapper(in_citeq_args) local loaded_args ={} for _,args_table in pairs({cfg.simple_properties_t, cfg.used_args_t}) do for k,_ in pairs(args_table) do if A[k] then citeq_args[k] = A[k] if k ~= A:ORIGIN(k) then origin_args[k] = A:ORIGIN(k) table.insert(loaded_args, A:ORIGIN(k)) else table.insert(loaded_args, k) end end end end for k,v in pairs(in_citeq_args) do if not in_array(k,loaded_args) then citeq_args[k] = v end end end -- if title supplied, flag to not read html title local titleforced = (citeq_args.title ~= nil) local default_opt = {rank = "preferred normal", fetchwikidata = "ALL", onlysourced = false, noicon = true, linksproject = cfg.config_t.linksproject, wikilinkprefix = cfg.config_t.wikilinkprefix } if citeq_args.volume or citeq_args.volume then local qualifiedaspossible = {} if citeq_args.volume then qualifiedaspossible['P478'] = citeq_args.volume end if citeq_args.chapter then qualifiedaspossible['P792'] = citeq_args.chapter end default_opt.qualifiedaspossible = qualifiedaspossible end Q = WdItem.WdItem:new(qid, default_opt, snak) local oth = {} -- put the language codes into a sequential table langcodes[] local langcodes = {} if citeq_args.language then -- check these are a supported language codes for lc in mw.text.gsplit( citeq_args.language, "[,، ]+", false ) do --modified langcodes[#langcodes+1] = mw.language.isSupportedLanguage(lc) and lc end end if not langcodes[1] then -- try to find language of work langcodes = _lang_code(Q) end if not langcodes[1] then -- try fallback to journal's language local journal_qid = Q:followQid("P1433") langcodes = journal_qid and _lang_code(journal_qid) end citeq_args.language = citeq_args.language or table.concat(langcodes, ", ") Q:setOptions( { langs = langcodes } ); local labellang = langcodes[1] or 'ar' rtl = rtl_lang[langcodes[1]] or false -- loop through list of simple properties and get their values in citeq_args for name, data in pairs(cfg.simple_properties_t) do local opt = { maxvals = data.maxvals, linked = data.linked, qual = data.qual } if data.no_vol_qual then opt.qualifiedaspossible = {}; end citeq_args[name] = citeq_args[name] or Q:getValue(data.id, opt ) if not citeq_args[name] and data.populate_from_journal then local publishedin = Q:getValue("P1433", {maxvals = 0, qual = data.id, qualsonly = true} ) citeq_args[name] = publishedin or Q:getPropOfProp("P1433", data.id, { maxvals = data.maxvals}) end if citeq_args[name] and snak[data.id] then snak[data.id] = nil end --- translate unknown value if citeq_args[name] == "Unknown" and rtl then citeq_args[name] = cfg.i18n_t.ar["unknown-" .. name] or cfg.i18n_t.ar["unknown"] end ----------------- if data.others then oth[#oth + 1] = citeq_args[name] and ((rtl and cfg.i18n_t.ar[name] or name:gsub("^%l", string.upper)) .. ": " .. citeq_args[name]) citeq_args[name] = nil end end citeq_args.others = citeq_args.others or table.concat(oth, ". ") if citeq_args.others == "" then citeq_args.others = nil end citeq_args.journal = citeq_args.journal and citeq_args.journal:gsub("^''", ""):gsub("''$", ""):gsub("|''", "|"):gsub("'']]", "]]") citeq_args.ol = citeq_args.ol or (Q:getValue("P648", { maxvals = 1 } ) or ''):gsub("^OL(.+)$", "%1") if citeq_args.ol == "" then citeq_args.ol = nil end -- TBD. Take care of |ol-access=? citeq_args.biorxiv = citeq_args.biorxiv and ("10.1101/" .. citeq_args.biorxiv) citeq_args.isbn = citeq_args.isbn or Q:getValue("P957", { maxvals = 1, rank="best" } ) -- try ISBN 10 (only one value accepted) if citeq_args.page then -- let single take precedence over multiple citeq_args.pages = nil citeq_args.pp = nil end if citeq_args.pages then local _, count = string.gsub(citeq_args.pages, "[,;%s]%d+", "") if count == 1 then citeq_args.page = citeq_args.pages citeq_args.pages = nil end end -- if url then see if there's an archive: citeq_args.url local url --find formatted url if snak ~= {} then for k, v in pairs(snak) do if (v[1].datatype == "external-id") then local furl = mw.wikibase.getBestStatements( k, "P1630" ) if 0 ~= #furl then furl = furl[1]["mainsnak"]["datavalue"]["value"] citeq_args.url = mw.message.newRawMessage(furl, {v[1]["datavalue"]["value"]}):plain() snak[k] = nil break; end end end if citeq_args.url == nil and pqid and qid then local refproperty = mw.wikibase.getBestStatements(qid , "P1687" ) if 0 ~= #refproperty then -- خطأ لوا في وحدة:Cite_Q على السطر 1124: attempt to index field 'datavalue' (a nil value). if refproperty[1]["mainsnak"] and refproperty[1]["mainsnak"]["datavalue"] and refproperty[1]["mainsnak"]["datavalue"]["value"] then refproperty=refproperty[1]["mainsnak"]["datavalue"]["value"]["id"] local furl = mw.wikibase.getBestStatements( refproperty, "P1630" ) if 0 ~= #furl then furl = furl[1]["mainsnak"]["datavalue"]["value"] local refval = mw.wikibase.getBestStatements( pqid, refproperty ) refval = (0 ~= #refval) and refval[1]["mainsnak"]["datavalue"]["value"] if refval then citeq_args.url = mw.message.newRawMessage(furl, {refval}):plain() end end end end end end if not citeq_args.url then local S953 = Q:getStatements("P953"):getBestOne() local S953_val = S953:getRawValue() citeq_args.url = S953_val and (S953_val ~= "novalue" and S953_val ~= "somevalue") and S953_val if citeq_args.url then if mw.ustring.match(citeq_args.url, "archive.org/details/") and citeq_args.page then page_offset = tonumber(S953:getRawQual('P8330')[1]) or 0 if not citeq_args.volume or (citeq_args.volume and citeq_args.volume == S953:getRawQual('P478')[1]) then citeq_args.url = mw.ustring.gsub(citeq_args.url, "/?$", "") .. "/page/n" .. (tonumber(citeq_args.page) + page_offset - 1) .. "/mode/1up" end end end end if not citeq_args.url then for i, pr in ipairs( {"P856", "P2699"} ) do url = Q:getValue(pr, { maxvals = 1, qual="P1065" } ) if url then citeq_args.url = mw.text.split( url, " (", true )[1] local arcurl = mw.ustring.match( url, " %((.*)%)" ) -- when there is an archive url, <url> holds: url<space>(archive url); here extract the archive url if present if arcurl then local arcy, arcm, arcd = arcurl:match("(20%d%d)%p?(%d%d)%p?(%d%d)") if arcy and arcm and arcd then citeq_args["archive-url"] = arcurl citeq_args["archive-date"] = arcy .. '-' .. arcm .. '-' .. arcd end end break; end end end if not titleforced then -- Handle subtitle. if citeq_args.title then local subtitle = Q:getValue('P1680'); if subtitle then citeq_args.title = citeq_args.title .. ": " .. subtitle end end local htmltitle = Q:getValue("P1476", {qual = "P6833", maxvals = 1, qualsonly = true} ) if htmltitle then citeq_args.title = htmltitle:gsub("</?i>", "''") else local title_display = citeq_args.title or (langcodes[1] and mw.wikibase.getLabelByLang(qid, langcodes[1])) or mw.wikibase.getLabel(qid) if title_display and snak and snak.P1810 then title_display=title_display .. " | " .. snak.P1810[1].datavalue.value snak.P1810 = nil end title_display = title_display or ("No label or title -- debug: " .. qid) if citeq_args.url then citeq_args.title = wrap_nowiki(title_display) else local slink = mw.wikibase.getSitelink(qid, cfg.config_t.linksproject) local slink_flag = false local wrap_title = '' local wslink = false if not slink then -- See if we have wikisource if not citeq_args.url then local wikisource_sitelink = mw.wikibase.getSitelink(qid, cfg.i18n_t.wikisource) or nil if wikisource_sitelink then slink = ':s:'..wikisource_sitelink wslink = true end end end if citeq_args.title then if slink then wrap_title = wrap_nowiki(citeq_args.title) slink_flag = true else citeq_args.title = wrap_nowiki(citeq_args.title) end else if slink and not wslink then if slink:lower() == title_display:lower() then citeq_args.title = '[[' .. slink .. ']]' else wrap_title = wrap_nowiki(slink:gsub("%s%(.+%)$", ""):gsub(",.+$", "")) slink_flag = true end elseif wslink then wrap_title = wrap_nowiki(title_display) slink_flag = true else citeq_args.title = wrap_nowiki(title_display) end end if slink_flag then if slink == wrap_title and not wslink then -- direct link citeq_args.title = '[[' .. slink .. ']]' else -- piped link citeq_args.title = '[[' .. slink .. '|' .. wrap_title .. ']]' end end end end end -- replace no-break space by space, User:Mr. Ibrahem if citeq_args.title then citeq_args.title = mw.ustring.gsub( citeq_args.title, "\194\160", " " ) end if is_set (qid) then if not is_set (citeq_args.author) and not is_set (citeq_args.author1) and not is_set (citeq_args.subject) and not is_set (citeq_args.subject1) and not is_set (citeq_args.host) and not is_set (citeq_args.host1) and not is_set (citeq_args.last) and not is_set (citeq_args.last1) and not is_set (citeq_args.surname) and not is_set (citeq_args.surname1) and not is_set (citeq_args['author-last']) and not is_set (citeq_args['author-last1']) and not is_set (citeq_args['author1-last']) and not is_set (citeq_args['author-surname']) and not is_set (citeq_args['author-surname1']) and not is_set (citeq_args['author1-surname1']) then -- if neither are set, try to get authors from Wikidata get_name_list ('author', citeq_args, Q, wdl, labellang) -- modify citeq_args table with authors from Wikidata end if not is_set (citeq_args.editor) and not is_set (citeq_args.editor1) and not is_set (citeq_args['editor-last']) and not is_set (citeq_args['editor-last1']) and not is_set (citeq_args['editor1-last']) and not is_set (citeq_args['editor-surname']) and not is_set (citeq_args['editor-surname1']) and not is_set (citeq_args['editor1-surname']) then -- if neither are set, try to get editors from Wikidata get_name_list ('editor', citeq_args, Q, wdl, labellang) -- modify citeq_args table with editors from Wikidata end if not is_set (citeq_args.translator) and not is_set (citeq_args.translator1) and not is_set (citeq_args['translator-last']) and not is_set (citeq_args['translator-last1']) and not is_set (citeq_args['translator1-last']) and not is_set (citeq_args['translator-surname']) and not is_set (citeq_args['translator-surname1']) and not is_set (citeq_args['translator1-surname']) then -- if neither are set, try to get translators from Wikidata get_name_list ('translator', citeq_args, Q, wdl, labellang) -- modify citeq_args table with translators from Wikidata end end for k, v in pairs(citeq_args) do if in_array (v, {'(())', 'unset', 'ignore'}) or 'string' ~= type(k) then -- empty accept-as-is-written (()) markup to indicate an empty/unused parameter value, other ((...)) markups are deliberately passed down to {{citation}} citeq_args[k] = nil elseif in_array (v, {'((unset))', '((ignore))'}) then -- strip off markup for free-text values clashing with local keywords citeq_args[k] = 'unset' end end local author_count = 0 for k, v in pairs(citeq_args) do if k:find("^author%d+$") then author_count = author_count + 1 end end if author_count > 8 then -- convention in astronomy journals, optional mode for this? if 'all' == citeq_args['display-authors'] then citeq_args['display-authors'] = nil; -- unset because no longer needed else citeq_args['display-authors'] = citeq_args['display-authors'] or 3 -- limit to three displayed names end end local editor_count = 0 for k, v in pairs(citeq_args) do if k:find("^editor%d+$") then editor_count = editor_count + 1 end end if editor_count > 8 then -- convention in astronomy journals, optional mode for this? if 'all' == citeq_args['display-editors'] then citeq_args['display-editors'] = nil; -- unset because no longer needed else citeq_args['display-editors'] = citeq_args['display-editors'] or 3 -- limit to three displayed names end end -- change edition to ordinal if it's set and numeric if (rtl == false) then citeq_args.edition = citeq_args.edition and makeOrdinal(citeq_args.edition) end -- code to make a guess what template to use from the supplied parameters -- (first draft for proof-of-concept) if citeq_args.journal then template = template or "بدورية محكمة" elseif citeq_args.isbn then template = template or "بكتاب" citeq_args.asin = nil -- suppress ASIN if ISBN exists elseif citeq_args.website then template = template or "بويب" end -- template is CS1 designator: journal, web, news, etc. if template then -- citeq_args.mode = citeq_args.mode or "cs1" -- a cs1 template already knows that it is cs1 so this line is superfluous local citeclasses = {["بدورية محكمة"] = 'journal', ["بكتاب"] = "book", ["بويب"] = "web" } cite_class = citeclasses[template] template = "استشهاد " .. template else -- citeq_args.mode = citeq_args.mode or "cs2" -- a cs2 template already knows that it is cs2 so this line is superfluous template = "استشهاد" end -- |id= could hold more than one identifier pulled from Wikidata not supported by {{citation}}, right now only add our qid to the list local list_sep = '. ' if citeq_args.mode ~= 'cs1' then list_sep = ', ' end local id = cfg.i18n_t.wdq .. ':[[:d:' .. qid .. '|' .. qid .. ']]' local old_id = citeq_args.id if wdl then -- show WD logo id = id .. '[[ملف:Wikidata-logo.svg|16px|alt=|link=]]' -- possibly replace by WD edit icon? end if is_set (old_id) then citeq_args.id = old_id .. list_sep .. id -- append to user-specified contents else citeq_args.id = id end -- clean up any blank parameters for k, v in pairs(citeq_args) do if v == "" then citeq_args[k] = nil end end -- use real param names for CS1 messages for k,v in pairs(origin_args) do if citeq_args[k] and citeq_args[k] == in_citeq_args[v] then citeq_args[v] = citeq_args[k] citeq_args[k] = nil end end mw.logObject(citeq_args) -- if |expand=<anything>, write a nowiki'd version to see what the {{citation}} template call looks like if expand then local expand_args = { "{{" .. template .. "\n" } -- init with citation template if expand == "self" then citeq_args.id = old_id -- restore original |id= parameter expand_args = { cfg.i18n_t.cite_q .. qid } -- expand to itself end -- make a sortable table and sort it by param name local sorttable = {} for param, val in pairs (citeq_args) do table.insert(sorttable, {param, val}) end table.sort(sorttable, comp_key) -- add contents to expand_args for idx, val in ipairs(sorttable) do table.insert(expand_args, val[1] .. '=' .. val[2] .. "\n") end -- make the nowiki'd string and done return frame:preprocess (table.concat ({'<syntaxhighlight lang="wikitext" inline="1">', table.concat (expand_args, ' |') .. '}}', '</syntaxhighlight>'})); end local erratumid = Q:getPropertyIDs( "P2507", { maxvals = 1 } ) if erratumid then erratumid = " [[d:" .. erratumid .. "|" .. cfg.i18n_t.erratum .. "]]" .. cfg.i18n_t.trackingcats.erratum else erratumid = "" end local opt_cat = '' if Q:getValue( "P5824" ) then opt_cat = cfg.i18n_t.trackingcats.retracted end if Q:getValue( "P1366" ) then opt_cat = opt_cat .. cfg.i18n_t.trackingcats.replaced end if not citeq_args.title then -- emit category link if missing title opt_cat = opt_cat .. cfg.i18n_t.trackingcats['no-label-or-title']; end if citeq_args.wikidatacite then return frame:expandTemplate{title = template, args = citeq_args} .. erratumid .. opt_cat -- render the template else local CS = require("Module:Citation/CS1" .. sandbox) return CS._citation(frame , citeq_args, {['CitationClass'] = cite_class}) .. erratumid .. opt_cat end end --[[-------------------------< C I T E W I K I D A T A >------------------------------------------------------------------ format wikidata reference --]] local function _cite_wikidata (ref, pqid, expand) -- early exit if not ref then return nil end local snak = ref.snaks -- مراجع غير مقبولة if snak.P143 or snak.P3452 then return nil end local hash = ref.hash if hash and hash ~= "" and ref_cash[hash] then return ref_cash[hash] end local citeq_args = {} local frame = mw.getCurrentFrame() -- مذكور في if snak.P248 then for _, prop in pairs(snak.P248) do if prop.snaktype == "value" then citeq_args.qid = "Q" .. prop.datavalue.value["numeric-id"] end end snak.P248 = nil; end if citeq_args.qid and is_rejected(citeq_args.qid) == true then return nil end local reference citeq_args.snak = snak citeq_args.pqid = pqid citeq_args.wikidatacite = 1 citeq_args.expand = expand if citeq_args.qid then reference = _cite_q(citeq_args) else local has_properties = false for k, _ in pairs(cfg.used_properties_t) do if snak[k] then has_properties = true; break; end end reference = (has_properties and _cite_web(citeq_args) or nil) end if reference and reference ~= "" then reference = frame:extensionTag("ref", reference, {name = 'wikidata-' .. hash}) end if hash and hash ~= "" then ref_cash[hash] = reference end return reference end local function cite_q (frame) local args = {} for k, v in pairs(frame:getParent().args) do if v ~= "" then args[k] = v end end for k, v in pairs(frame.args) do if v ~= "" then args[k] = v end end args.qid = args.qid or args[1] or "" if args.qid == "" then return nil end args[1] = nil local citesep = (args.citesep or "") if citesep == "" then citesep = ", " end citesep = citesep:gsub('"', '') -- strip double quotes after setting default to allow |citesep="" as a blank separator args.citesep = nil local tag = args.tag or "" if tag == "" then tag = nil end args.tag = nil local list = args.list or "" if list == "" then list = nil end args.list = nil args.language = args.language or args.lang args.lang = nil local cites = {} for q in args.qid:gmatch("Q%d+") do -- make a new copy of the arguments local newargs = {} for k, v in pairs(args) do if k ~= "qid" then newargs[k] = v end end newargs.qid = q if tag == "ref" then cites[#cites + 1] = frame:callParserFunction{ name = "#tag:ref", args = { _cite_q(newargs), name = q } } -- expand like this: args = { _cite_q(newargs), name = 'foo', group = 'bar' } else cites[#cites + 1] = _cite_q(newargs) end end if list then return frame:expandTemplate{ title = list, args = cites } else return table.concat(cites, citesep) end end --[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------ ]] return { makeOrdinal = makeOrdinal, getLangOfProp = getLangOfProp, lang_code = lang_code, _cite_wikidata = _cite_wikidata, _cite_q = _cite_q, cite_q = cite_q } 66f2x7szc5u50rlcw0d3beozvhypg8g وحدة:ar-verb/مختبر 828 231313 1096875 1007304 2026-07-20T13:46:51Z ForzaGreen 28665 اختبارات الأجوف على وزن أفعل 1096875 Scribunto text/plain -- Unit tests for [[Module:ar-verb]]. Click talk page to run tests. -- اختبارات الوحدة. انقر على صفحة النقاش لعرض النتائج -- 🚧 Work In Progress !! local tests = require("Module:UnitTests") local m_ar_verb = require("Module:ar-verb") -- ═══════════════════════════════════════════════════════════ -- Utilities required for some tests -- ═══════════════════════════════════════════════════════════ local m_string_utilities = require("Module:string utilities") local u = m_string_utilities.char -- ═══════════════════════════════════════════════════════════ function tests:test_conj_form_I() local result = m_ar_verb.do_generate_forms({["جذر"] = "كتب", ["وزن"] = "فعَل يفعُل"}, "ar-conj") self:equals("كتب، فعَل يفعُل، هو، الماضي", "كَتَبَ", result.forms.past_3ms[1].form) self:equals("كتب، فعَل يفعُل، هو، المضارع", "يَكْتُبُ", result.forms.ind_3ms[1].form) self:equals("كتب، فعَل يفعُل، أنتَ، الأمر", "اُكْتُبْ", result.forms.imp_2ms[1].form) self:equals("كتب، فعَل يفعُل، اسم الفاعل", "كَاتِب", result.forms.ap[1].form) self:equals("كتب، فعَل يفعُل، اسم المفعول", "مَكْتُوب", result.forms.pp[1].form) self:equals("كتب، فعَل يفعُل، له معلوم", true, result.has_active) self:equals("كتب، فعَل يفعُل، له مجهول", true, result.has_passive) self:equals("كتب، فعَل يفعُل، الوزن I", "I", result.verb_forms[1]) end function tests:test_conj_form_II() local result = m_ar_verb.do_generate_forms({["جذر"] = "درس", ["وزن"] = "فعّل"}, "ar-conj") self:equals("درس، فعّل، هو، الماضي", "دَرَّسَ", result.forms.past_3ms[1].form) self:equals("درس، فعّل، هو، المضارع", "يُدَرِّسُ", result.forms.ind_3ms[1].form) self:equals("درس، فعّل، أنتَ، الأمر", "دَرِّسْ", result.forms.imp_2ms[1].form) self:equals("درس، فعّل، اسم الفاعل", "مُدَرِّس", result.forms.ap[1].form) self:equals("درس، فعّل، اسم المفعول", "مُدَرَّس", result.forms.pp[1].form) self:equals("درس، فعّل، المصدر", "تَدْرِيس", result.forms.vn[1].form) end function tests:test_conj_form_III() local result = m_ar_verb.do_generate_forms({["جذر"] = "قتل", ["وزن"] = "فاعل"}, "ar-conj") self:equals("قتل، فاعل، هو، الماضي", "قَاتَلَ", result.forms.past_3ms[1].form) self:equals("قتل، فاعل، هو، المضارع", "يُقَاتِلُ", result.forms.ind_3ms[1].form) self:equals("قتل، فاعل، أنتَ، الأمر", "قَاتِلْ", result.forms.imp_2ms[1].form) self:equals("قتل، فاعل، اسم الفاعل", "مُقَاتِل", result.forms.ap[1].form) self:equals("قتل، فاعل، اسم المفعول", "مُقَاتَل", result.forms.pp[1].form) end function tests:test_conj_form_IV() local result = m_ar_verb.do_generate_forms({["جذر"] = "رسل", ["وزن"] = "أفعل"}, "ar-conj") self:equals("رسل، أفعل، هو، الماضي", "أَرْسَلَ", result.forms.past_3ms[1].form) self:equals("رسل، أفعل، هو، المضارع", "يُرْسِلُ", result.forms.ind_3ms[1].form) self:equals("رسل، أفعل، أنتَ، الأمر", "أَرْسِلْ", result.forms.imp_2ms[1].form) self:equals("رسل، أفعل، اسم الفاعل", "مُرْسِل", result.forms.ap[1].form) self:equals("رسل، أفعل، اسم المفعول", "مُرْسَل", result.forms.pp[1].form) end -- وزن «أفعل» من الأجوف: تُعَلّ العين ألفًا (أَفَالَ) في الواوي واليائي معًا، -- تبعًا لإعلالها في الثلاثي المجرد (معجم متن اللغة). function tests:test_conj_form_IV_hollow() -- أجوف واوي local qwl = m_ar_verb.do_generate_forms({["جذر"] = "قول", ["وزن"] = "أفعل"}, "ar-conj") self:equals("قول، أفعل، هو، الماضي", "أَقَالَ", qwl.forms.past_3ms[1].form) -- أجوف يائي: يُعَلّ كنظيره الواوي local yaa_cases = { {"تيس", "أَتَاسَ"}, {"طيب", "أَطَابَ"}, {"بين", "أَبَانَ"}, {"ضيع", "أَضَاعَ"}, {"طيح", "أَطَاحَ"}, } for _, case in ipairs(yaa_cases) do local root, expected = case[1], case[2] local result = m_ar_verb.do_generate_forms({["جذر"] = root, ["وزن"] = "أفعل"}, "ar-conj") self:equals(root .. "، أفعل، هو، الماضي", expected, result.forms.past_3ms[1].form) end -- الاستثناء يخصّ «أفعل» وحده؛ الأوزان الأخرى من الأجوف اليائي تبقى معلّة local tys_x = m_ar_verb.do_generate_forms({["جذر"] = "تيس", ["وزن"] = "استفعل"}, "ar-conj") self:equals("تيس، استفعل، هو، الماضي", "اِسْتَتَاسَ", tys_x.forms.past_3ms[1].form) end -- 7 جذور يائية شاذّة يبقى وزن «أفعل» منها صحيحًا (أَفْيَلَ) — أفعال مسموعة موثّقة، -- لا الصفة المشبهة (مثل أَخْيَف/خَيْفاء). انظر SOUND_FORM_IV_ROOTS في الوحدة. function tests:test_conj_form_IV_sound_exceptions() local cases = { {"خيل", "أَخْيَلَ"}, -- أخيلت السماء — المعجم الوسيط 1/266 {"غيل", "أَغْيَلَ"}, -- أغيلته سقته الغَيْل — لسان العرب 11/111 {"حيج", "أَحْيَجَ"}, -- أحيجت الأرض — تاج العروس 5/500 {"حين", "أَحْيَنَ"}, -- أحين القوم — المعجم الوسيط 1/212 {"خيف", "أَخْيَفَ"}, -- أخيف الحاج — كتاب الأفعال لابن القوطية 35 {"ريف", "أَرْيَفَ"}, -- أريفت الأرض — المحيط في اللغة 10/256 {"زين", "أَزْيَنَ"}, -- أزينت الأرض — مقاييس اللغة 3/41 } for _, case in ipairs(cases) do local root, expected = case[1], case[2] local result = m_ar_verb.do_generate_forms({["جذر"] = root, ["وزن"] = "أفعل"}, "ar-conj") self:equals(root .. "، أفعل، هو، الماضي (شاذّ صحيح)", expected, result.forms.past_3ms[1].form) end end function tests:test_conj_weak() local result = m_ar_verb.do_generate_forms({["جذر"] = "قول", ["وزن"] = "فعَل يفعُل"}, "ar-conj") self:equals("قول، فعَل يفعُل، هو، الماضي", "قَالَ", result.forms.past_3ms[1].form) self:equals("قول، فعَل يفعُل، هو، المضارع", "يَقُولُ", result.forms.ind_3ms[1].form) self:equals("قول، فعَل يفعُل، أنتَ، الأمر", "قُلْ", result.forms.imp_2ms[1].form) local result = m_ar_verb.do_generate_forms({["جذر"] = "رمي", ["وزن"] = "فعَل يفعِل"}, "ar-conj") self:equals("رمي، فعَل يفعِل، هو، الماضي", "رَمَى", result.forms.past_3ms[1].form) self:equals("رمي، فعَل يفعِل، هو، المضارع", "يَرْمِي", result.forms.ind_3ms[1].form) self:equals("رمي، فعَل يفعِل، أنتَ، الأمر", "اِرْمِ", result.forms.imp_2ms[1].form) self:equals("رمي، فعَل يفعِل، اسم الفاعل", "رَامٍ", result.forms.ap[1].form) local result = m_ar_verb.do_generate_forms({["جذر"] = "م_د_د", ["وزن"] = "فعَل يفعُل"}, "ar-conj") self:equals("مدد، فعَل يفعُل، مضعَّف، هو، الماضي", "مَدَّ", result.forms.past_3ms[1].form) local result = m_ar_verb.do_generate_forms({["جذر"] = "وصل", ["وزن"] = "فعَل يفعِل"}, "ar-conj") self:equals("وصل، فعَل يفعِل، مثال، هو، الماضي", "وَصَلَ", result.forms.past_3ms[1].form) self:equals("وصل، فعَل يفعِل، مثال، هو، المضارع", "يَصِلُ", result.forms.ind_3ms[1].form) self:equals("وصل، فعَل يفعِل، مثال، أنت، الأمر", "صِلْ", result.forms.imp_2ms[1].form) end function tests:test_conj_with_underscores() local result = m_ar_verb.do_generate_forms({["جذر"] = "ك_ت_ب", ["وزن"] = "فعَل يفعُل"}, "ar-conj") self:equals("كتب، فعَل يفعُل، هو، الماضي", "كَتَبَ", result.forms.past_3ms[1].form) self:equals("كتب، فعَل يفعُل، هو، المضارع", "يَكْتُبُ", result.forms.ind_3ms[1].form) end function tests:test_conj_with_spaces() local result = m_ar_verb.do_generate_forms({["جذر"] = "ك ت ب", ["وزن"] = "فعَل يفعُل"}, "ar-conj") self:equals("كتب، فعَل يفعُل، هو، الماضي", "كَتَبَ", result.forms.past_3ms[1].form) self:equals("كتب، فعَل يفعُل، هو، المضارع", "يَكْتُبُ", result.forms.ind_3ms[1].form) end function tests:test_conj_passive_types() local result_pass = m_ar_verb.do_generate_forms({[1] = "كتب<I/a~u.pass>"}, "ar-conj") self:equals("كتب، مبني للمجهول فقط", "pass", result_pass.passive) local result_ipass = m_ar_verb.do_generate_forms({[1] = "كتب<I/a~u.ipass>"}, "ar-conj") self:equals("كتب، مجهول غير شخصي", "ipass", result_ipass.passive) local result_nopass = m_ar_verb.do_generate_forms({[1] = "كتب<I/a~u.nopass>"}, "ar-conj") self:equals("كتب، بدون مجهول", "nopass", result_nopass.passive) self:equals("كتب، بدون مجهول، has_passive خطأ", false, result_nopass.has_passive) end function tests:test_conj_overrides() local result = m_ar_verb.do_generate_forms({[1] = "كتب<I/a~u.vn:كِتَابَة>"}, "ar-conj") self:equals("كتب، تجاوز المصدر", "كِتَابَة", result.forms.vn[1].form) end function tests:test_infer_radicals() local result = m_ar_verb.infer_radicals({ headword = "كتب", vform = "I" }) self:equals("كتب، نوع الضعف: صحيح", "sound", result.weakness) self:equals("كتب، حرف الجذر الأول: ك", "ك", result.rad1) self:equals("كتب، حرف الجذر الثاني: ت", "ت", result.rad2) self:equals("كتب، حرف الجذر الثالث: ب", "ب", result.rad3) local U = u(0x064F) -- ḍamma local result = m_ar_verb.infer_radicals({ headword = "قال", vform = "I", nonpast_vowel = U }) self:equals("قال، نوع الضعف: أجوف", "hollow", result.weakness) self:equals("قال، حرف الجذر الأول: ق", "ق", result.rad1) self:equals("قال، حرف الجذر الثاني: و (مستنتج)", "و", result.rad2) self:equals("قال، حرف الجذر الثالث: ل", "ل", result.rad3) local result = m_ar_verb.infer_radicals({ headword = "رمى", vform = "I" }) self:equals("رمى، نوع الضعف: ناقص", "final-weak", result.weakness) self:equals("رمى، حرف الجذر الأول: ر", "ر", result.rad1) self:equals("رمى، حرف الجذر الثاني: م", "م", result.rad2) self:equals("رمى، حرف الجذر الثالث: ي", "ي", result.rad3) end function tests:test_infer_participle_vocalization() local result = m_ar_verb.infer_participle_vocalization("كاتب", "I", "sound", true) self:equals("كاتب، تشكيل اسم الفاعل", "كَاتِب", result) local result = m_ar_verb.infer_participle_vocalization("مكتوب", "I", "sound", false) self:equals("مكتوب، تشكيل اسم المفعول", "مَكْتُوب", result) local result = m_ar_verb.infer_participle_vocalization("مدرس", "II", "sound", true) self:equals("مدرس، فعّل، تشكيل اسم الفاعل", "مُدَرِّس", result) end -- ═══════════════════════════════════════════════════════════ -- Tests for classify_triliteral_verb function -- ═══════════════════════════════════════════════════════════ -- الصحيح function tests:test_verb_classify_sound() self:equals("كتب", "صحيح سالم", m_ar_verb.classify_triliteral_verb("ك", "ت", "ب")) self:equals("ذهب", "صحيح سالم", m_ar_verb.classify_triliteral_verb("ذ", "ه", "ب")) self:equals("فعل", "صحيح سالم", m_ar_verb.classify_triliteral_verb("ف", "ع", "ل")) self:equals("مدّ", "صحيح مُضعَّف", m_ar_verb.classify_triliteral_verb("م", "د", "د")) self:equals("شدّ", "صحيح مُضعَّف", m_ar_verb.classify_triliteral_verb("ش", "د", "د")) self:equals("عدّ", "صحيح مُضعَّف", m_ar_verb.classify_triliteral_verb("ع", "د", "د")) self:equals("أخذ", "صحيح مهموز الفاء", m_ar_verb.classify_triliteral_verb("أ", "خ", "ذ")) self:equals("أكل", "صحيح مهموز الفاء", m_ar_verb.classify_triliteral_verb("أ", "ك", "ل")) self:equals("سأل", "صحيح مهموز العين", m_ar_verb.classify_triliteral_verb("س", "أ", "ل")) self:equals("قرأ", "صحيح مهموز اللام", m_ar_verb.classify_triliteral_verb("ق", "ر", "أ")) self:equals("أبأ", "صحيح مهموز الفاء واللام", m_ar_verb.classify_triliteral_verb("أ", "ب", "أ")) end -- المعتل function tests:test_verb_classify_weak() self:equals("وجد", "معتل مثال واوي", m_ar_verb.classify_triliteral_verb("و", "ج", "د")) self:equals("وقف", "معتل مثال واوي", m_ar_verb.classify_triliteral_verb("و", "ق", "ف")) self:equals("وضأ", "معتل مثال واوي مهموز اللام", m_ar_verb.classify_triliteral_verb("و", "ض", "أ")) self:equals("يسر", "معتل مثال يائي", m_ar_verb.classify_triliteral_verb("ي", "س", "ر")) self:equals("يئس", "معتل مثال يائي مهموز العين", m_ar_verb.classify_triliteral_verb("ي", "أ", "س")) self:equals("قال", "معتل أجوف واوي", m_ar_verb.classify_triliteral_verb("ق", "و", "ل")) self:equals("صام", "معتل أجوف واوي", m_ar_verb.classify_triliteral_verb("ص", "و", "م")) self:equals("باع", "معتل أجوف يائي", m_ar_verb.classify_triliteral_verb("ب", "ي", "ع")) self:equals("نام", "معتل أجوف واوي", m_ar_verb.classify_triliteral_verb("ن", "و", "م")) self:equals("دعا", "معتل ناقص واوي", m_ar_verb.classify_triliteral_verb("د", "ع", "و")) self:equals("سما", "معتل ناقص واوي", m_ar_verb.classify_triliteral_verb("س", "م", "و")) self:equals("رمى", "معتل ناقص يائي", m_ar_verb.classify_triliteral_verb("ر", "م", "ي")) self:equals("بكى", "معتل ناقص يائي", m_ar_verb.classify_triliteral_verb("ب", "ك", "ي")) -- لفيف مقرون (adjacent weak letters) self:equals("ويّ", "معتل لفيف مقرون", m_ar_verb.classify_triliteral_verb("و", "ي", "ي")) self:equals("أوى", "معتل لفيف مقرون مهموز الفاء", m_ar_verb.classify_triliteral_verb("أ", "و", "ي")) -- لفيف مفروق (separated weak letters) self:equals("وقى", "معتل لفيف مفروق", m_ar_verb.classify_triliteral_verb("و", "ق", "ي")) self:equals("وأى", "معتل لفيف مفروق مهموز العين", m_ar_verb.classify_triliteral_verb("و", "أ", "ي")) -- Combined weaknesses self:equals("أول", "معتل أجوف واوي مهموز الفاء", m_ar_verb.classify_triliteral_verb("أ", "و", "ل")) self:equals("قوأ", "معتل أجوف واوي مهموز اللام", m_ar_verb.classify_triliteral_verb("ق", "و", "أ")) self:equals("أيب", "معتل أجوف يائي مهموز الفاء", m_ar_verb.classify_triliteral_verb("أ", "ي", "ب")) self:equals("جيأ", "معتل أجوف يائي مهموز اللام", m_ar_verb.classify_triliteral_verb("ج", "ي", "أ")) self:equals("رأو", "معتل ناقص واوي مهموز العين", m_ar_verb.classify_triliteral_verb("ر", "أ", "و")) self:equals("شأي", "معتل ناقص يائي مهموز العين", m_ar_verb.classify_triliteral_verb("ش", "أ", "ي")) self:equals("ودد", "معتل مثال واوي مُضعَّف", m_ar_verb.classify_triliteral_verb("و", "د", "د")) self:equals("ينن", "معتل مثال يائي مُضعَّف", m_ar_verb.classify_triliteral_verb("ي", "ن", "ن")) self:equals("وأب", "معتل مثال واوي مهموز العين", m_ar_verb.classify_triliteral_verb("و", "أ", "ب")) self:equals("أبب", "صحيح مُضعَّف مهموز الفاء", m_ar_verb.classify_triliteral_verb("أ", "ب", "ب")) self:equals("أتى", "معتل ناقص يائي مهموز الفاء", m_ar_verb.classify_triliteral_verb("أ", "ت", "ي")) self:equals("قلا", "معتل ناقص واوي", m_ar_verb.classify_triliteral_verb("ق", "ل", "و")) self:equals("نما (و)", "معتل ناقص واوي", m_ar_verb.classify_triliteral_verb("ن", "م", "و")) self:equals("نمى (ي)", "معتل ناقص يائي", m_ar_verb.classify_triliteral_verb("ن", "م", "ي")) self:equals("يئس", "معتل مثال يائي مهموز العين", m_ar_verb.classify_triliteral_verb("ي", "أ", "س")) end return tests f6b7jjnmxghgup2n5qeusrw937piqr8 وحدة:WdItem 828 235573 1097062 1096563 2026-07-21T19:41:34Z حبيشان 31560 1097062 Scribunto text/plain -- Module: WdItem -- Object-oriented Wikidata access module for Lua -- Refactored from WikidataIB for direct Lua usage require("strict") local p = {} -- i18n configuration local i18n = { ["errors"] = { ["property-not-found"] = "الخاصية غير موجودة.", ["entity-not-found"] = "الكيان على ويكي بيانات غير موجود.", ["unknown-claim-type"] = "نوع الادعاء غير معروف.", ["local-article-not-found"] = "المعرف متاح على ويكي بيانات، ولكن المقال غير متاح على ويكيبيديا", }, ["months"] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, ["Unknown"] = "Unknown", ["NaN"] = "Not a number", ["missinginfocat"] = "[[تصنيف:Articles with missing Wikidata information]]", ["list separator"] = ", ", ["list separator-ar"] = "، ", } -- Date precision constants local dp = { [6] = "millennium", [7] = "century", [8] = "decade", [9] = "year", [10] = "month", [11] = "day", } local options_aliases = { ["osd"] = "onlysourced", ["wdlinks"] = "wdl", ["uabbr"] = "unitabbr", ["qo"] = "qualsonly", ["lp"] = "linkprefix", ["lprefix"] = "linkprefix", ["qlp"] = "qlinkprefix", ["sn"] = "shortname", ["uselabel"] = "uselbl", ["plaindate"] = "pd", ["qualifierdateformat"] = "qdf", ["df"] = "qdf", ["qshortname"] = "qsn" } setmetatable(options_aliases, { __index = function(t, k) return k end }) ------------------------------------------------------------------------------- -- Internal helper functions ------------------------------------------------------------------------------- local function findLang(langcode) local langobj langcode = mw.text.trim(langcode or "") if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langcode = mw.getCurrentFrame():callParserFunction('int', {'lang'}) if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langobj = mw.language.getContentLanguage() end end return langobj end local function parseParam(param, default) if param == nil then return default end return param end local function setRanks(rank) rank = (rank or ""):lower() local ranks = {} for w in string.gmatch(rank, "%a+") do if w == "best" or w == "preferred" or w == "normal" or w == "deprecated" then ranks[w] = true end end if ranks.best or not next(ranks) then ranks.preferred = true ranks.normal = true ranks.deprecated = false end return ranks end local function labelOrId(id, lang) if lang == "default" then lang = findLang().code end local label if lang then label = mw.wikibase.getLabelByLang(id, lang) end if not label then local trylang = {"ar","en","fr", "mul"} local triedlang = lang for _,lang in pairs(trylang) do if triedlang ~= lang then label = mw.wikibase.getLabelByLang(id, lang) if label ~= "" then break end end end end if label then return mw.text.nowiki(label), true else return id, false end end local function roundto(x, sf) if x == 0 then return 0 end local s = 1 if x < 0 then x = -x s = -1 end if sf < 1 then sf = 1 end local p = 10 ^ (math.floor(math.log10(x)) - sf + 1) x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end return x end local function decimalPrecision(x, p) local s = 1 if x < 0 then x = -x s = -1 end if not tonumber(p) then p = 1e-4 elseif p > 1 then p = 1 elseif p < 1e-6 then p = 1e-6 else p = 10 ^ math.floor(math.log10(p)) end x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end if math.abs(x) < 1e-4 then x = string.format("%f", x) end return x end local function decimalToDMS(x, p) if not tonumber(p) then p = 1e-4 end local d = math.floor(x) local ms = (x - d) * 60 if p > 0.5 then if ms > 30 then d = d + 1 end ms = 0 end local m = math.floor(ms) local s = (ms - m) * 60 if p > 0.008 then if s > 30 then m = m +1 end s = 0 elseif p > 0.00014 then s = math.floor(s + 0.5) elseif p > 0.000014 then s = math.floor(10 * s + 0.5) / 10 elseif p > 0.0000014 then s = math.floor(100 * s + 0.5) / 100 else s = math.floor(1000 * s + 0.5) / 1000 end return d, m, s end local function rawValue(dataValue) if dataValue.type == "string" then return dataValue.value elseif dataValue.type == "wikibase-entityid" then return dataValue.value and dataValue.value.id elseif dataValue.type == "monolingualtext" then return dataValue.value.text elseif dataValue.type == "quantity" then return tonumber(dataValue.value.amount) elseif dataValue.type == 'time' then return dataValue.value.time elseif dataValue.type == "globecoordinate" then return dataValue.value.latitude .. '/' .. dataValue.value.longitude end end local function compareValue(dataValue, strValue) return rawValue(dataValue) == strValue end local function dateFormat(timestamp, dprec, df, bcf, pd, qualifiers, lang, adj, model) df = (df or ""):lower() if df == "ymd" then if timestamp:sub(1,1) == "+" then return timestamp:sub(2,11) else local yr = tonumber(timestamp:sub(2,5)) - 1 yr = ("000" .. yr):sub(-4) if yr ~= "0000" then yr = "-" .. yr end return yr .. timestamp:sub(6,11) end end timestamp = timestamp:gsub("%-00%-00T", "-01-01T") dprec = dprec or 11 if df == "y" and dprec > 9 then dprec = 9 end dprec = dprec>11 and 11 or dprec dprec = dprec<6 and 6 or dprec bcf = (bcf or ""):upper() pd = (pd or ""):sub(1,1):lower() if pd == "" or pd == "n" or pd == "f" or pd == "0" then pd = false end lang = lang or findLang().code adj = adj or "" local bc = timestamp:sub(1, 1)=="-" and "BC" or "" local year, month, day = timestamp:match("[+-](%d*)-(%d*)-(%d*)T") local iso = tonumber(year) if dprec == 6 then iso = math.floor( (iso - 1) / 1000 ) + 1 end if dprec == 7 then iso = math.floor( (iso - 1) / 100 ) + 1 end if dprec == 8 then iso = math.floor( iso / 10 ) .. "0" end if dprec == 10 then iso = year .. "-" .. month end if dprec == 11 then iso = year .. "-" .. month .. "-" .. day end local sc = not pd and qualifiers and qualifiers.P1480 if sc then for k1, v1 in pairs(sc) do if v1.datavalue and v1.datavalue.value.id == "Q5727902" then adj = "circa" break end end end local calendarmodel = "" if tonumber(year) > 1582 and dprec > 8 and not pd and model == "http://www.wikidata.org/entity/Q1985786" then calendarmodel = "julian" end -- Simplified date formatting (complex date module not available) local fdate = tostring(iso) if bc ~= "" then fdate = fdate .. " " .. (bcf == "BC" and "BC" or "BCE") end if adj == "circa" then fdate = "c. " .. fdate end return fdate end local function hijriFormat(qualifiers, dateformat, lang) if not qualifiers.P4241 then return; end local year, month, day local val local qhmonths = {["Q1952053"]=1,["Q489557"]=2, ["Q474167"] = 3, ["Q273815"] = 4, ["Q852002"] = 5, ["Q822218"] = 6, ["Q194210"] = 7, ["Q220914"] = 8, ["Q8867089"]=9, ["Q685440"]=10,["Q150853"]=11,["Q186022"]=12 } local hmonths = {"محرم","صفر","ربيع الأول","ربيع الآخر","جمادى الأولى","جمادى الآخرة","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة"} local hmonths_inv = {["محرم"] = 1, ["صفر"]=2, ["ربيع الأول"]=3, ["ربيع الآخر"]=4, ["جمادى الأولى"]=5, ["جمادى الآخرة"]=6, ["رجب"]=7, ["شعبان"]=8, ["رمضان"]=9, ["شوال"]=10, ["ذو القعدة"]=11, ["ذو الحجة"]=12} for _, item in ipairs(qualifiers.P4241) do local timeQ = item.datavalue and item.datavalue.value and item.datavalue.value.id local hastime = false if timeQ then local timeQt = mw.wikibase.getBestStatements(timeQ, "P361") for _,timeQsnak in pairs(timeQt) do local timeType = timeQsnak.mainsnak and timeQsnak.mainsnak.datavalue and timeQsnak.mainsnak.datavalue.value and timeQsnak.mainsnak.datavalue.value.id if timeType == "Q28892" then local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then year = mw.ustring.match(timeLableAr, "^(%d+) *هـ$") end if not year then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then year = mw.ustring.match(timeLableAr, "^(%d+) *AH$") end end hastime=true elseif qhmonths[timeType] then month = qhmonths[timeType] if month>0 and month<13 then month = hmonths[month] end local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end if not day then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end end hastime=true end end if not hastime then timeQt = mw.wikibase.getBestStatements(timeQ, "P31") if "Q125390868" == (timeQt[1].mainsnak and timeQt[1].mainsnak.datavalue and timeQt[1].mainsnak.datavalue.value and timeQt[1].mainsnak.datavalue.value.id ) then val = mw.wikibase.getLabelByLang(timeQ, "ar") month, year = mw.ustring.match(val, "^(%a[%a ]+%a) *(%d+) *هـ?$") end end end end if year then if dateformat == "y" then return year; elseif day and month then return day .. ' ' .. month .. ' ' .. year; elseif month then return month .. ' ' .. year; end end return nil; end local function sourced(claim) if claim.references then for kr, vr in pairs(claim.references) do local ref = mw.wikibase.renderSnaks(vr.snaks) if not ref:find("Wiki") then return true end end end end local function linkedItem(id, args) local lprefix = (args.linkprefix or ""):gsub('"', '') local lpostfix = (args.lpostfix or ""):gsub('"', '') local prefix = (args.prefix or ""):gsub('"', '') local postfix = (args.postfix or ""):gsub('"', '') local dtxt = args.dtxt local uselbl = parseParam( args.uselbl, true) local disp local sitelink = mw.wikibase.getSitelink(id, args.linksproject) local label, islabel if dtxt then label, islabel = dtxt, true else label, islabel = labelOrId(id, args.lang) end if sitelink then if not uselbl then local pos = sitelink:find(":") or 0 local slink = sitelink if pos > 0 then local pfx = sitelink:sub(1,pos-1) if mw.site.namespaces[pfx] then slink = sitelink:sub(pos+1) end end slink = slink:gsub("%s%(.+%)$", ""):gsub(",.+$", "") if label:find("^%u") then label = slink:gsub("^(%l)", string.upper) else label = slink:gsub("^(%u)", string.lower) end end disp = "[[" .. lprefix .. sitelink .. lpostfix .. "|" .. prefix .. label .. postfix .. "]]" elseif islabel then disp = prefix .. label .. postfix else disp = prefix .. label .. postfix .. i18n.missinginfocat end return disp end local function rendersnak(propval, args, linked, lpre, lpost, pre, post, uabbr, filter) lpre = lpre or "" lpost = lpost or "" pre = pre or "" post = post or "" args.lang = args.lang or findLang().code local snak = propval.mainsnak or propval local dtype = snak.datatype local dv = snak.datavalue dv = dv and dv.value local val, mlt local namedas; namedas = propval.qualifiers and propval.qualifiers.P1932 and propval.qualifiers.P1932[1].datavalue and propval.qualifiers.P1932[1].datavalue.value or nil args.dtxt = namedas if propval.rank and not args.reqranks[propval.rank] then return nil elseif snak.snaktype == "somevalue" then val = namedas or i18n["Unknown"] elseif snak.snaktype == "novalue" then -- return nothing elseif dtype == "wikibase-item" then local qnumber = dv.id if linked then val = linkedItem(qnumber, args) else if namedas then val = pre .. namedas .. post else local label, islabel = labelOrId(qnumber, args.lang) val = pre .. label .. post end end elseif dtype == "time" then if args.hijri then val = hijriFormat(propval.qualifiers, args.df, args.lang) else val = dateFormat(dv.time, dv.precision, args.df, args.bc, args.pd, propval.qualifiers, args.lang, "", dv.calendarmodel) end elseif dtype == "commonsMedia" or dtype == "external-id" or dtype == "string" or dtype == "url" then if (lpre == "" or lpre == ":") and lpost == "" then val = pre .. dv .. post elseif dtype == "external-id" then val = "[" .. lpre .. dv .. lpost .. " " .. pre .. dv .. post .. "]" else val = "[[" .. lpre .. dv .. lpost .. "|" .. pre .. dv .. post .. "]]" end elseif dtype == "quantity" then local amount = tonumber(dv.amount) or i18n["NaN"] local unit = "" local unitqid = string.match(dv.unit, "(Q%d+)") if filter and unitqid ~= filter then return nil end if unitqid then local uname = mw.wikibase.getLabelByLang(unitqid, args.lang) or "" if uname ~= "" then unit = " " .. uname end end val = tostring(amount) .. unit elseif dtype == "globe-coordinate" then local lat, long, prec = dv.latitude, dv.longitude, dv.precision local show = (args.show or ""):lower() if show == "lat" then val = decimalPrecision(lat, prec) elseif show == "lon" then val = decimalPrecision(long, prec) elseif show == "longlat" then val = decimalPrecision(long, prec) .. ", " .. decimalPrecision(lat, prec) else local ns = lat < 0 and "S" or "N" local ew = long < 0 and "W" or "E" if lat < 0 then lat = -lat end if long < 0 then long = -long end val = decimalPrecision(lat, prec) .. "°" .. ns .. " " .. decimalPrecision(long, prec) .. "°" .. ew end elseif dtype == "monolingualtext" then val = pre .. dv.text .. post mlt = dv.language else val = "unknown data type: " .. dtype end return val, mlt end local function assembleoutput(out, args, entityID, propertyID) local sorted = parseParam(args.sorted, false) local noic = parseParam(args.noicon, false) local list = args.list or "" local separator = args.sep or "" separator = string.gsub(separator, '"', '') if separator == "" then local rtl_lang = {ar = true, fa = true, ur = true, ku = true, he = true} separator = rtl_lang[args.lang] and i18n["list separator-ar"] or i18n["list separator"] end local strout if #out > 0 then if sorted then table.sort(out) end if list == "" then strout = table.concat(out, separator) elseif list:lower() == "prose" then strout = mw.text.listToText(out) else strout = mw.getCurrentFrame():expandTemplate{title = list, args = out} end else strout = nil end return strout end local function propertyvalueandquals(objproperty, args, qualID) -- needs this style of declaration because it's re-entrant -- onlysourced is a boolean passed to return only values sourced to other than Wikipedia -- if nothing or an empty string is passed set it true local onlysrc = parseParam(args.onlysourced, false) -- linked is a a boolean that enables the link to a local page via sitelink -- if nothing or an empty string is passed set it true local linked = parseParam(args.linked, true) -- prefix is a string that may be nil, empty (""), or a string of characters -- this is prefixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local prefix = (args.prefix or ""):gsub('"', '') -- postfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local postfix = (args.postfix or ""):gsub('"', '') -- linkprefix is a string that may be nil, empty (""), or a string of characters -- this creates a link and is then prefixed to each value -- useful when when multiple values are returned and indirect links are needed -- any double-quotes " are stripped out, so that spaces may be passed local lprefix = (args.linkprefix or ""):gsub('"', '') -- linkpostfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value when linking is enabled with lprefix -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local lpostfix = (args.linkpostfix or ""):gsub('"', '') -- wdlinks is a boolean passed to enable links to Wikidata when no article exists -- if nothing or an empty string is passed set it false local wdl = parseParam(args.wdl, false) -- unitabbr is a boolean passed to enable unit abbreviations for common units -- if nothing or an empty string is passed set it false local uabbr = parseParam(args.unitabbr, false) -- qualsonly is a boolean passed to return just the qualifiers -- if nothing or an empty string is passed set it false local qualsonly = parseParam(args.qualsonly, false) -- maxvals is a string that may be nil, empty (""), or a number -- this determines how many items may be returned when multiple values are available -- setting it = 1 is useful where the returned string is used within another call, e.g. image local maxvals = tonumber(args.maxvals) or 0 -- pd boolean -- to disable/enable "sourcing cirumstances" or use adjectival form for the plain date local pd = args.pd or false args.pd = pd -- allow qualifiers to have a different date format; default to year unless qualsonly is set args.qdf = args.qdf or (not qualsonly and "y") local lang = args.lang or (args.langs and args.langs[1]) or findLang().code -- qualID is a string list of wanted qualifiers or "ALL" qualID = qualID or "" -- capitalise list of wanted qualifiers and substitute "DATES" qualID = qualID:upper():gsub("DATES", "P580, P582") local allflag = (qualID == "ALL") -- create table of wanted qualifiers as key local qwanted = {} -- create sequence of wanted qualifiers local qorder = {} for q in mw.text.gsplit(qualID, "%p") do -- split at punctuation and iterate local qtrim = mw.text.trim(q) if qtrim ~= "" then qwanted[mw.text.trim(q)] = true qorder[#qorder+1] = qtrim end end -- qsep is the output separator for rendering qualifier list local qsep = (args.qsep or ""):gsub('"', '') -- qargs are the arguments to supply to assembleoutput() local qargs = { ["osd"] = "false", ["linked"] = tostring(linked), ["prefix"] = args.qprefix, ["postfix"] = args.qpostfix, ["linkprefix"] = args.qlinkprefix, ["linkpostfix"] = args.qlinkpostfix, ["wdl"] = "false", ["unitabbr"] = tostring(uabbr), ["maxvals"] = 0, ["sorted"] = tostring(args.qsorted), ["noicon"] = "true", ["list"] = args.qlist, ["sep"] = qsep, -- ["langobj"] = args.langobj, ["lang"] = args.lang or (args.langs and args.lang[1]), ["df"] = args.qdf, ["sn"] = parseParam(args.qsn, false), } -- all proper values of a Wikidata property will be the same type as the first -- qualifiers don't have a mainsnak, properties do --#Modified line local datatype = objproperty[1].datatype or (objproperty[1].mainsnak and objproperty[1].mainsnak.datatype) -- out[] holds the a list of returned values for this property -- mlt[] holds the language code if the datatype is monolingual text local out = {} local mlt = {} for k, v in ipairs(objproperty) do local hasvalue = true if (onlysrc and not sourced(v)) then -- no value: it isn't sourced when onlysourced=true hasvalue = false else local val, lcode = rendersnak(v, args, linked, lprefix, lpostfix, prefix, postfix, uabbr) if not val then hasvalue = false -- rank doesn't match elseif qualsonly and qualID then -- suppress value returned: only qualifiers are requested else out[#out+1], mlt[#out+1] = val, lcode end end -- See if qualifiers are to be returned: local snak = v.mainsnak or v if hasvalue and v.qualifiers and qualID ~= "" and snak.snaktype~="novalue" then -- collect all wanted qualifier values returned in qlist, indexed by propertyID local qlist = {} local timestart, timeend = "", "" -- loop through qualifiers for k1, v1 in pairs(v.qualifiers) do if allflag or qwanted[k1] then if k1 == "P1326" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before") elseif k1 == "P1319" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after") elseif k1 == "P580" then timestart = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one start time as valid elseif k1 == "P582" then timeend = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one end time as valid else local q = assembleoutput(propertyvalueandquals(v1, qargs), qargs) -- we already deal with circa via 'sourcing circumstances' if the datatype was time -- circa may be either linked or unlinked *** internationalise later *** if datatype ~= "time" or q ~= "circa" and not (type(q) == "string" and q:find("circa]]")) then qlist[k1] = q end end end -- of test for wanted end -- of loop through qualifiers -- set date separator local t = timestart .. timeend -- *** internationalise date separators later *** local dsep = "&ndash;" if t:find("%s") or t:find("&nbsp;") then dsep = " &ndash; " end -- set the order for the list of qualifiers returned; start time and end time go last if next(qlist) then local qlistout = {} if allflag then for k2, v2 in pairs(qlist) do qlistout[#qlistout+1] = v2 end else for i2, v2 in ipairs(qorder) do qlistout[#qlistout+1] = qlist[v2] end end if t ~= "" then qlistout[#qlistout+1] = timestart .. dsep .. timeend end local qstr = assembleoutput(qlistout, qargs) if qualsonly then out[#out+1] = qstr else out[#out] = out[#out] .. " (" .. qstr .. ")" end elseif t ~= "" then if qualsonly then if timestart == "" then out[#out+1] = timeend elseif timeend == "" then out[#out+1] = timestart else out[#out+1] = timestart .. dsep .. timeend end else out[#out] = out[#out] .. " (" .. timestart .. dsep .. timeend .. ")" end end end -- of test for qualifiers wanted if maxvals > 0 and #out >= maxvals then break end end -- of for each value loop -- we need to pick one value to return if the datatype was "monolingualtext" -- if there's only one value, use that -- otherwise look through the fallback languages for a match if datatype == "monolingualtext" and #out >1 then lang = mw.text.split( lang, '-', true )[1] local fbtbl = mw.language.getFallbacksFor( lang ) table.insert( fbtbl, 1, lang ) local bestval = "" local found = false for idx1, lang1 in ipairs(fbtbl) do for idx2, lang2 in ipairs(mlt) do if (lang1 == lang2) and not found then bestval = out[idx2] found = true break end end -- loop through values of property end -- loop through fallback languages if found then -- replace output table with a table containing the best value out = { bestval } else -- more than one value and none of them on the list of fallback languages -- sod it, just give them the first one out = { out[1] } end end return out end local function mergeOptions(defaults, overrides) overrides = overrides or {} defaults = defaults or {} local result = {} for k, v in pairs(defaults) do result[k] = v end for k, v in pairs(overrides) do result[k] = v if k == 'rank' then result.reqranks = setRanks(v) end end return result end local function filterbyqualifier(statements,qual,value) local filtered_statements = {} for _, statement in ipairs(statements) do if statement.qualifiers and statement.qualifiers[qual] then if '*' == value then table.insert(filtered_statements, statement) else for _, qual in ipairs(statement.qualifiers[qual]) do if qual.datavalue and (rawValue(qual.datavalue) == value) then table.insert(filtered_statements, statement) break end end end end end return filtered_statements end local function rankFilter(statements, rank, sourcedonly, sortbyqualifier) end ------------------------------------------------------------------------------- -- Statement Class Definition ------------------------------------------------------------------------------- local WdStatement = {} WdStatement.__index = WdStatement ------------------------------------------------------------------------------- -- Statements Class Definition ------------------------------------------------------------------------------- local WdStatements = {} WdStatements.__index = WdStatements function WdStatements:getStatmentsTable() return self._statements end function WdStatements:count() return #self._statements end function WdStatements:getFilters() return self.filtered_by end function WdStatements:filter(filter_t) local statements = self._statements if #statements == 0 then return self end local ret = setmetatable({}, WdStatements) ret.parent = self.parent ret.filtered_by = self.filtered_by local filtered_statements = {} for k,v in pairs(filter_t) do filtered_statements = filterbyqualifier(statements, k, v) table.insert(ret.filtered_by, {[k] = v}) if #filtered_statements == 0 then break; else statements = filtered_statements end end ret._statements = filtered_statements return ret end function WdStatements:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end mw.logObject(mergedOpts) local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getRawValue(opts) local mergedOpts = mergeOptions(self.options, opts or {}) local ret = {} for _,v in pairs(self._statements) do if v.mainsnak.snaktype=="value" then table.insert(ret,rawValue(v.mainsnak.datavalue)) else table.insert(ret,v.mainsnak.snaktype) end end return ret end ------------------------------------------------------------------------------- -- WdItem Class Definition ------------------------------------------------------------------------------- local WdItem = {} WdItem.__index = WdItem function WdItem:__tostring() return "WdItem: " .. (self.qid or "no QID") end function WdItem:UpdateOptions(newOpts) for k, v in pairs(newOpts or {}) do local key = options_aliases[k] self.options[key] = v -- Set default options if key == 'langs' and #v > 0 then self.options.langobj = findLang(self.options.langs[1]) self.options.lang = self.options.langobj.code if not self.options.langobj then self.options.langobj = findLang(self.options.lang) self.options.lang = self.options.langobj.code end end if key == 'rank' then self.options.reqranks = setRanks(self.options.rank) end end if not self.options.reqranks then self.options.reqranks = setRanks('preferred normal') end end function WdItem.new(qid, options) local self = setmetatable({}, WdItem) if qid == "" then qid = nil end if (not qid) and mw.wikibase then qid = mw.wikibase.getEntityIdForCurrentPage() end self.qid = qid self.snak = nil self.options = options or {} self:UpdateOptions(options) return self end function WdItem.newFromSnaks(snakTable, options) local self = setmetatable({}, WdItem) self.qid = nil self.snak = snakTable or {} self.options = options or {} self:UpdateOptions(options) return self end function WdItem:setOptions(newOpts) self:UpdateOptions(newOpts) end function WdItem:getStatements(pid, opts) local mergedOpts = mergeOptions(self.options, opts or {}) local statements local ret = setmetatable({}, WdStatements) ret.parent = self ret.filtered_by = {} ret._statements = {} ret.pid = pid if self.snak and self.snak[pid] then statements = self.snak[pid] elseif not self.qid or not mw.wikibase then statements = {} elseif mergedOpts.reqranks and mergedOpts.reqranks.best then mw.log('best') statements = mw.wikibase.getBestStatements(self.qid, pid) or {} else mw.log('not best') statements = mw.wikibase.getAllStatements(self.qid, pid) or {} local filtered_statements = {} if not (mergedOpts.reqranks.deprecated == true and mergedOpts.reqranks.preferred == true and mergedOpts.reqranks.normal == true) then for _,s in pairs(statements) do if mergedOpts.reqranks[s.rank] then table.insert(filtered_statements,s) end end end statements = filtered_statements end if #statements > 0 and mergedOpts.qualifiedaspossible and #mergedOpts.qualifiedaspossible then mw.log('qualifiedaspossible') local filtered_statements = {} for q,qv in pairs(mergedOpts.qualifiedaspossible) do filtered_statements = filterbyqualifier(statements, q, qv) if #filtered_statements > 0 then table.insert(ret.filtered_by, {[q] = qv}) statements = filtered_statements end end end if #statements > 0 and mergedOpts.qualified and #mergedOpts.qualified then mw.log('qualified') for q,qv in pairs(mergedOpts.qualified) do statements = filterbyqualifier(statements, q, qv) table.insert(ret.filtered_by, {[q] = qv}) if #statements == 0 then break; end end end ret._statements = statements return ret end function WdItem:getValue(pid, opts) local mergedOpts = mergeOptions(self.options, opts) -- Handle local value override if mergedOpts[2] and mergedOpts[2] ~= "" then return mergedOpts[2] end local statements if mergedOpts.no_vol_qual then statements = mw.wikibase.getBestStatements(self.qid, pid) else statements = self:getStatements(pid, {vol = mergedOpts.vol, chapter = mergedOpts.chapter}) end if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.qid, pid) end function WdItem:getValueFromSnaks(pid, opts) if not self.snak or not self.snak[pid] then return nil end local mergedOpts = mergeOptions(self.options, opts) local props = self.snak[pid] local out = propertyvalueandquals(props, mergedOpts) return assembleoutput(out, mergedOpts, nil, pid) end function WdItem:getPropertyIDsTable(pid, opts) local mergedOpts = mergeOptions(self.options, opts) mergedOpts.noicon = tostring(parseParam(mergedOpts.noicon or "", true)) local statements = self:getStatements(pid, opts) if not statements or #statements == 0 then return {} end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local out = {} for i, v in ipairs(statements) do local snak = v.mainsnak if (snak.datatype == "wikibase-item") and (v.rank and mergedOpts.reqranks[v.rank:sub(1, 1)]) and (snak.snaktype == "value") and (sourced(v) or not onlysrc) then out[#out+1] = snak.datavalue.value.id end if maxvals > 0 and #out >= maxvals then break end end return out end function WdItem:getPropertyIDs(pid, opts) local out = WdItem:getPropertyIDsTable(pid, opts) if #out == 0 then return nil end return assembleoutput(out, mergeOptions(self.options, opts), self.qid, pid) end function WdItem:getPropOfProp(prop1, prop2, opts) local mergedOpts = mergeOptions(self.options, opts) if not self.qid then return nil end local statements1 = self:getStatements(prop1, opts) if not statements1 or #statements1 == 0 then return nil end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = {} for k, v in ipairs(statements1) do if not onlysrc or sourced(v) then local snak = v.mainsnak if snak.datatype == "wikibase-item" and snak.snaktype == "value" then local qid2 = snak.datavalue.value.id local item2 = WdItem.new(qid2, mergedOpts) local statements2 = item2:getStatements(prop2, opts) if statements2 and statements2[1] then local out2 = propertyvalueandquals(statements2, mergedOpts, qualID) out[#out+1] = assembleoutput(out2, mergedOpts, qid2, prop2) end end end if maxvals > 0 and #out >= maxvals then break end end return assembleoutput(out, mergedOpts, self.qid, prop1) end function WdItem:getLangOfProp(pid) if not pid or not self.qid then return {} end local out = {} local props = mw.wikibase.getAllStatements(self.qid, pid) for _, v in ipairs(props) do if v.mainsnak.datatype == "monolingualtext" and v.mainsnak.datavalue then out[#out + 1] = v.mainsnak.datavalue.value.language end end return out end function WdItem:followQid(props, all) all = parseParam(all, false) props = (props or ""):upper() if not self.qid then return nil end if props == "" then return self.qid end local out = {} for p in mw.text.gsplit(props, "%p") do p = mw.text.trim(p) for i, v in ipairs(mw.wikibase.getBestStatements(self.qid, p)) do local linkedid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id if linkedid then if all then out[#out+1] = linkedid else return linkedid end end end end if #out > 0 then return table.concat(out, " ") else return self.qid end end ------------------------------------------------------------------------------- -- Public API - Utility Functions ------------------------------------------------------------------------------- p.getStatementsByVol = function(qid, pid, vol, chapter) local statements = mw.wikibase.getBestStatements(qid, pid) local filtered_by = {} if #statements ==0 then return {},{}; end local filtered_statements = {} if chapter then for _, statement in ipairs(statements) do if statement.qualifiers and statement.qualifiers["P792"] then for _, qual in ipairs(statement.qualifiers["P792"]) do if qual.datavalue and tostring(qual.datavalue.value) == tostring(chapter) then table.insert(filtered_statements, statement) table.insert(filtered_by, {["P792"] = chapter}) break end end end end end if #filtered_statements == 0 and vol then for _, statement in ipairs(statements) do local vol_match = true if vol and statement.qualifiers and statement.qualifiers["P478"] then vol_match = false for _, qual in ipairs(statement.qualifiers["P478"]) do if qual.datavalue and tostring(qual.datavalue.value) == tostring(vol) then vol_match = true break end end end if vol_match then table.insert(filtered_statements, statement) end end if #filtered_statements > 0 then table.insert(filtered_by, {["P478"] = vol}) end else filtered_statements = statements end return filtered_statements, filtered_by end ------------------------------------------------------------------------------- -- Public API - WdItem Constructors ------------------------------------------------------------------------------- p.WdItem = WdItem function p.newItem(qid, opts) return WdItem.new(qid, opts) end function p.currentItem(opts) return WdItem.new(nil, opts) end function p.newSnakItem(snakTable, opts) return WdItem.newFromSnaks(snakTable, opts) end return p jmyx1kz96boymqt7xf4tb4efoci9v81 1097064 1097062 2026-07-21T19:50:04Z حبيشان 31560 1097064 Scribunto text/plain -- Module: WdItem -- Object-oriented Wikidata access module for Lua -- Refactored from WikidataIB for direct Lua usage require("strict") local p = {} -- i18n configuration local i18n = { ["errors"] = { ["property-not-found"] = "الخاصية غير موجودة.", ["entity-not-found"] = "الكيان على ويكي بيانات غير موجود.", ["unknown-claim-type"] = "نوع الادعاء غير معروف.", ["local-article-not-found"] = "المعرف متاح على ويكي بيانات، ولكن المقال غير متاح على ويكيبيديا", }, ["months"] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, ["Unknown"] = "Unknown", ["NaN"] = "Not a number", ["missinginfocat"] = "[[تصنيف:Articles with missing Wikidata information]]", ["list separator"] = ", ", ["list separator-ar"] = "، ", } -- Date precision constants local dp = { [6] = "millennium", [7] = "century", [8] = "decade", [9] = "year", [10] = "month", [11] = "day", } local options_aliases = { ["osd"] = "onlysourced", ["wdlinks"] = "wdl", ["uabbr"] = "unitabbr", ["qo"] = "qualsonly", ["lp"] = "linkprefix", ["lprefix"] = "linkprefix", ["qlp"] = "qlinkprefix", ["sn"] = "shortname", ["uselabel"] = "uselbl", ["plaindate"] = "pd", ["qualifierdateformat"] = "qdf", ["df"] = "qdf", ["qshortname"] = "qsn" } setmetatable(options_aliases, { __index = function(t, k) return k end }) ------------------------------------------------------------------------------- -- Internal helper functions ------------------------------------------------------------------------------- local function findLang(langcode) local langobj langcode = mw.text.trim(langcode or "") if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langcode = mw.getCurrentFrame():callParserFunction('int', {'lang'}) if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langobj = mw.language.getContentLanguage() end end return langobj end local function parseParam(param, default) if param == nil then return default end return param end local function setRanks(rank) rank = (rank or ""):lower() local ranks = {} for w in string.gmatch(rank, "%a+") do if w == "best" or w == "preferred" or w == "normal" or w == "deprecated" then ranks[w] = true end end if ranks.best or not next(ranks) then ranks.preferred = true ranks.normal = true ranks.deprecated = false end return ranks end local function labelOrId(id, lang) if lang == "default" then lang = findLang().code end local label if lang then label = mw.wikibase.getLabelByLang(id, lang) end if not label then local trylang = {"ar","en","fr", "mul"} local triedlang = lang for _,lang in pairs(trylang) do if triedlang ~= lang then label = mw.wikibase.getLabelByLang(id, lang) if label ~= "" then break end end end end if label then return mw.text.nowiki(label), true else return id, false end end local function roundto(x, sf) if x == 0 then return 0 end local s = 1 if x < 0 then x = -x s = -1 end if sf < 1 then sf = 1 end local p = 10 ^ (math.floor(math.log10(x)) - sf + 1) x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end return x end local function decimalPrecision(x, p) local s = 1 if x < 0 then x = -x s = -1 end if not tonumber(p) then p = 1e-4 elseif p > 1 then p = 1 elseif p < 1e-6 then p = 1e-6 else p = 10 ^ math.floor(math.log10(p)) end x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end if math.abs(x) < 1e-4 then x = string.format("%f", x) end return x end local function decimalToDMS(x, p) if not tonumber(p) then p = 1e-4 end local d = math.floor(x) local ms = (x - d) * 60 if p > 0.5 then if ms > 30 then d = d + 1 end ms = 0 end local m = math.floor(ms) local s = (ms - m) * 60 if p > 0.008 then if s > 30 then m = m +1 end s = 0 elseif p > 0.00014 then s = math.floor(s + 0.5) elseif p > 0.000014 then s = math.floor(10 * s + 0.5) / 10 elseif p > 0.0000014 then s = math.floor(100 * s + 0.5) / 100 else s = math.floor(1000 * s + 0.5) / 1000 end return d, m, s end local function rawValue(dataValue) if dataValue.type == "string" then return dataValue.value elseif dataValue.type == "wikibase-entityid" then return dataValue.value and dataValue.value.id elseif dataValue.type == "monolingualtext" then return dataValue.value.text elseif dataValue.type == "quantity" then return tonumber(dataValue.value.amount) elseif dataValue.type == 'time' then return dataValue.value.time elseif dataValue.type == "globecoordinate" then return dataValue.value.latitude .. '/' .. dataValue.value.longitude end end local function compareValue(dataValue, strValue) return rawValue(dataValue) == strValue end local function dateFormat(timestamp, dprec, df, bcf, pd, qualifiers, lang, adj, model) df = (df or ""):lower() if df == "ymd" then if timestamp:sub(1,1) == "+" then return timestamp:sub(2,11) else local yr = tonumber(timestamp:sub(2,5)) - 1 yr = ("000" .. yr):sub(-4) if yr ~= "0000" then yr = "-" .. yr end return yr .. timestamp:sub(6,11) end end timestamp = timestamp:gsub("%-00%-00T", "-01-01T") dprec = dprec or 11 if df == "y" and dprec > 9 then dprec = 9 end dprec = dprec>11 and 11 or dprec dprec = dprec<6 and 6 or dprec bcf = (bcf or ""):upper() pd = (pd or ""):sub(1,1):lower() if pd == "" or pd == "n" or pd == "f" or pd == "0" then pd = false end lang = lang or findLang().code adj = adj or "" local bc = timestamp:sub(1, 1)=="-" and "BC" or "" local year, month, day = timestamp:match("[+-](%d*)-(%d*)-(%d*)T") local iso = tonumber(year) if dprec == 6 then iso = math.floor( (iso - 1) / 1000 ) + 1 end if dprec == 7 then iso = math.floor( (iso - 1) / 100 ) + 1 end if dprec == 8 then iso = math.floor( iso / 10 ) .. "0" end if dprec == 10 then iso = year .. "-" .. month end if dprec == 11 then iso = year .. "-" .. month .. "-" .. day end local sc = not pd and qualifiers and qualifiers.P1480 if sc then for k1, v1 in pairs(sc) do if v1.datavalue and v1.datavalue.value.id == "Q5727902" then adj = "circa" break end end end local calendarmodel = "" if tonumber(year) > 1582 and dprec > 8 and not pd and model == "http://www.wikidata.org/entity/Q1985786" then calendarmodel = "julian" end -- Simplified date formatting (complex date module not available) local fdate = tostring(iso) if bc ~= "" then fdate = fdate .. " " .. (bcf == "BC" and "BC" or "BCE") end if adj == "circa" then fdate = "c. " .. fdate end return fdate end local function hijriFormat(qualifiers, dateformat, lang) if not qualifiers.P4241 then return; end local year, month, day local val local qhmonths = {["Q1952053"]=1,["Q489557"]=2, ["Q474167"] = 3, ["Q273815"] = 4, ["Q852002"] = 5, ["Q822218"] = 6, ["Q194210"] = 7, ["Q220914"] = 8, ["Q8867089"]=9, ["Q685440"]=10,["Q150853"]=11,["Q186022"]=12 } local hmonths = {"محرم","صفر","ربيع الأول","ربيع الآخر","جمادى الأولى","جمادى الآخرة","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة"} local hmonths_inv = {["محرم"] = 1, ["صفر"]=2, ["ربيع الأول"]=3, ["ربيع الآخر"]=4, ["جمادى الأولى"]=5, ["جمادى الآخرة"]=6, ["رجب"]=7, ["شعبان"]=8, ["رمضان"]=9, ["شوال"]=10, ["ذو القعدة"]=11, ["ذو الحجة"]=12} for _, item in ipairs(qualifiers.P4241) do local timeQ = item.datavalue and item.datavalue.value and item.datavalue.value.id local hastime = false if timeQ then local timeQt = mw.wikibase.getBestStatements(timeQ, "P361") for _,timeQsnak in pairs(timeQt) do local timeType = timeQsnak.mainsnak and timeQsnak.mainsnak.datavalue and timeQsnak.mainsnak.datavalue.value and timeQsnak.mainsnak.datavalue.value.id if timeType == "Q28892" then local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then year = mw.ustring.match(timeLableAr, "^(%d+) *هـ$") end if not year then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then year = mw.ustring.match(timeLableAr, "^(%d+) *AH$") end end hastime=true elseif qhmonths[timeType] then month = qhmonths[timeType] if month>0 and month<13 then month = hmonths[month] end local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end if not day then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end end hastime=true end end if not hastime then timeQt = mw.wikibase.getBestStatements(timeQ, "P31") if "Q125390868" == (timeQt[1].mainsnak and timeQt[1].mainsnak.datavalue and timeQt[1].mainsnak.datavalue.value and timeQt[1].mainsnak.datavalue.value.id ) then val = mw.wikibase.getLabelByLang(timeQ, "ar") month, year = mw.ustring.match(val, "^(%a[%a ]+%a) *(%d+) *هـ?$") end end end end if year then if dateformat == "y" then return year; elseif day and month then return day .. ' ' .. month .. ' ' .. year; elseif month then return month .. ' ' .. year; end end return nil; end local function sourced(claim) if claim.references then for kr, vr in pairs(claim.references) do local ref = mw.wikibase.renderSnaks(vr.snaks) if not ref:find("Wiki") then return true end end end end local function linkedItem(id, args) local lprefix = (args.linkprefix or ""):gsub('"', '') local lpostfix = (args.lpostfix or ""):gsub('"', '') local prefix = (args.prefix or ""):gsub('"', '') local postfix = (args.postfix or ""):gsub('"', '') local dtxt = args.dtxt local uselbl = parseParam( args.uselbl, true) local disp local sitelink = mw.wikibase.getSitelink(id, args.linksproject) local label, islabel if dtxt then label, islabel = dtxt, true else label, islabel = labelOrId(id, args.lang) end if sitelink then if not uselbl then local pos = sitelink:find(":") or 0 local slink = sitelink if pos > 0 then local pfx = sitelink:sub(1,pos-1) if mw.site.namespaces[pfx] then slink = sitelink:sub(pos+1) end end slink = slink:gsub("%s%(.+%)$", ""):gsub(",.+$", "") if label:find("^%u") then label = slink:gsub("^(%l)", string.upper) else label = slink:gsub("^(%u)", string.lower) end end disp = "[[" .. lprefix .. sitelink .. lpostfix .. "|" .. prefix .. label .. postfix .. "]]" elseif islabel then disp = prefix .. label .. postfix else disp = prefix .. label .. postfix .. i18n.missinginfocat end return disp end local function rendersnak(propval, args, linked, lpre, lpost, pre, post, uabbr, filter) lpre = lpre or "" lpost = lpost or "" pre = pre or "" post = post or "" args.lang = args.lang or findLang().code local snak = propval.mainsnak or propval local dtype = snak.datatype local dv = snak.datavalue dv = dv and dv.value local val, mlt local namedas; namedas = propval.qualifiers and propval.qualifiers.P1932 and propval.qualifiers.P1932[1].datavalue and propval.qualifiers.P1932[1].datavalue.value or nil args.dtxt = namedas if propval.rank and not args.reqranks[propval.rank] then return nil elseif snak.snaktype == "somevalue" then val = namedas or i18n["Unknown"] elseif snak.snaktype == "novalue" then -- return nothing elseif dtype == "wikibase-item" then local qnumber = dv.id if linked then val = linkedItem(qnumber, args) else if namedas then val = pre .. namedas .. post else local label, islabel = labelOrId(qnumber, args.lang) val = pre .. label .. post end end elseif dtype == "time" then if args.hijri then val = hijriFormat(propval.qualifiers, args.df, args.lang) else val = dateFormat(dv.time, dv.precision, args.df, args.bc, args.pd, propval.qualifiers, args.lang, "", dv.calendarmodel) end elseif dtype == "commonsMedia" or dtype == "external-id" or dtype == "string" or dtype == "url" then if (lpre == "" or lpre == ":") and lpost == "" then val = pre .. dv .. post elseif dtype == "external-id" then val = "[" .. lpre .. dv .. lpost .. " " .. pre .. dv .. post .. "]" else val = "[[" .. lpre .. dv .. lpost .. "|" .. pre .. dv .. post .. "]]" end elseif dtype == "quantity" then local amount = tonumber(dv.amount) or i18n["NaN"] local unit = "" local unitqid = string.match(dv.unit, "(Q%d+)") if filter and unitqid ~= filter then return nil end if unitqid then local uname = mw.wikibase.getLabelByLang(unitqid, args.lang) or "" if uname ~= "" then unit = " " .. uname end end val = tostring(amount) .. unit elseif dtype == "globe-coordinate" then local lat, long, prec = dv.latitude, dv.longitude, dv.precision local show = (args.show or ""):lower() if show == "lat" then val = decimalPrecision(lat, prec) elseif show == "lon" then val = decimalPrecision(long, prec) elseif show == "longlat" then val = decimalPrecision(long, prec) .. ", " .. decimalPrecision(lat, prec) else local ns = lat < 0 and "S" or "N" local ew = long < 0 and "W" or "E" if lat < 0 then lat = -lat end if long < 0 then long = -long end val = decimalPrecision(lat, prec) .. "°" .. ns .. " " .. decimalPrecision(long, prec) .. "°" .. ew end elseif dtype == "monolingualtext" then val = pre .. dv.text .. post mlt = dv.language else val = "unknown data type: " .. dtype end return val, mlt end local function assembleoutput(out, args, entityID, propertyID) local sorted = parseParam(args.sorted, false) local noic = parseParam(args.noicon, false) local list = args.list or "" local separator = args.sep or "" separator = string.gsub(separator, '"', '') if separator == "" then local rtl_lang = {ar = true, fa = true, ur = true, ku = true, he = true} separator = rtl_lang[args.lang] and i18n["list separator-ar"] or i18n["list separator"] end local strout if #out > 0 then if sorted then table.sort(out) end if list == "" then strout = table.concat(out, separator) elseif list:lower() == "prose" then strout = mw.text.listToText(out) else strout = mw.getCurrentFrame():expandTemplate{title = list, args = out} end else strout = nil end return strout end local function propertyvalueandquals(objproperty, args, qualID) -- needs this style of declaration because it's re-entrant -- onlysourced is a boolean passed to return only values sourced to other than Wikipedia -- if nothing or an empty string is passed set it true local onlysrc = parseParam(args.onlysourced, false) -- linked is a a boolean that enables the link to a local page via sitelink -- if nothing or an empty string is passed set it true local linked = parseParam(args.linked, true) -- prefix is a string that may be nil, empty (""), or a string of characters -- this is prefixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local prefix = (args.prefix or ""):gsub('"', '') -- postfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local postfix = (args.postfix or ""):gsub('"', '') -- linkprefix is a string that may be nil, empty (""), or a string of characters -- this creates a link and is then prefixed to each value -- useful when when multiple values are returned and indirect links are needed -- any double-quotes " are stripped out, so that spaces may be passed local lprefix = (args.linkprefix or ""):gsub('"', '') -- linkpostfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value when linking is enabled with lprefix -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local lpostfix = (args.linkpostfix or ""):gsub('"', '') -- wdlinks is a boolean passed to enable links to Wikidata when no article exists -- if nothing or an empty string is passed set it false local wdl = parseParam(args.wdl, false) -- unitabbr is a boolean passed to enable unit abbreviations for common units -- if nothing or an empty string is passed set it false local uabbr = parseParam(args.unitabbr, false) -- qualsonly is a boolean passed to return just the qualifiers -- if nothing or an empty string is passed set it false local qualsonly = parseParam(args.qualsonly, false) -- maxvals is a string that may be nil, empty (""), or a number -- this determines how many items may be returned when multiple values are available -- setting it = 1 is useful where the returned string is used within another call, e.g. image local maxvals = tonumber(args.maxvals) or 0 -- pd boolean -- to disable/enable "sourcing cirumstances" or use adjectival form for the plain date local pd = args.pd or false args.pd = pd -- allow qualifiers to have a different date format; default to year unless qualsonly is set args.qdf = args.qdf or (not qualsonly and "y") local lang = args.lang or (args.langs and args.langs[1]) or findLang().code -- qualID is a string list of wanted qualifiers or "ALL" qualID = qualID or "" -- capitalise list of wanted qualifiers and substitute "DATES" qualID = qualID:upper():gsub("DATES", "P580, P582") local allflag = (qualID == "ALL") -- create table of wanted qualifiers as key local qwanted = {} -- create sequence of wanted qualifiers local qorder = {} for q in mw.text.gsplit(qualID, "%p") do -- split at punctuation and iterate local qtrim = mw.text.trim(q) if qtrim ~= "" then qwanted[mw.text.trim(q)] = true qorder[#qorder+1] = qtrim end end -- qsep is the output separator for rendering qualifier list local qsep = (args.qsep or ""):gsub('"', '') -- qargs are the arguments to supply to assembleoutput() local qargs = { ["osd"] = "false", ["linked"] = tostring(linked), ["prefix"] = args.qprefix, ["postfix"] = args.qpostfix, ["linkprefix"] = args.qlinkprefix, ["linkpostfix"] = args.qlinkpostfix, ["wdl"] = "false", ["unitabbr"] = tostring(uabbr), ["maxvals"] = 0, ["sorted"] = tostring(args.qsorted), ["noicon"] = "true", ["list"] = args.qlist, ["sep"] = qsep, -- ["langobj"] = args.langobj, ["lang"] = args.lang or (args.langs and args.lang[1]), ["df"] = args.qdf, ["sn"] = parseParam(args.qsn, false), } -- all proper values of a Wikidata property will be the same type as the first -- qualifiers don't have a mainsnak, properties do --#Modified line local datatype = objproperty[1].datatype or (objproperty[1].mainsnak and objproperty[1].mainsnak.datatype) -- out[] holds the a list of returned values for this property -- mlt[] holds the language code if the datatype is monolingual text local out = {} local mlt = {} for k, v in ipairs(objproperty) do local hasvalue = true if (onlysrc and not sourced(v)) then -- no value: it isn't sourced when onlysourced=true hasvalue = false else local val, lcode = rendersnak(v, args, linked, lprefix, lpostfix, prefix, postfix, uabbr) if not val then hasvalue = false -- rank doesn't match elseif qualsonly and qualID then -- suppress value returned: only qualifiers are requested else out[#out+1], mlt[#out+1] = val, lcode end end -- See if qualifiers are to be returned: local snak = v.mainsnak or v if hasvalue and v.qualifiers and qualID ~= "" and snak.snaktype~="novalue" then -- collect all wanted qualifier values returned in qlist, indexed by propertyID local qlist = {} local timestart, timeend = "", "" -- loop through qualifiers for k1, v1 in pairs(v.qualifiers) do if allflag or qwanted[k1] then if k1 == "P1326" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before") elseif k1 == "P1319" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after") elseif k1 == "P580" then timestart = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one start time as valid elseif k1 == "P582" then timeend = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one end time as valid else local q = assembleoutput(propertyvalueandquals(v1, qargs), qargs) -- we already deal with circa via 'sourcing circumstances' if the datatype was time -- circa may be either linked or unlinked *** internationalise later *** if datatype ~= "time" or q ~= "circa" and not (type(q) == "string" and q:find("circa]]")) then qlist[k1] = q end end end -- of test for wanted end -- of loop through qualifiers -- set date separator local t = timestart .. timeend -- *** internationalise date separators later *** local dsep = "&ndash;" if t:find("%s") or t:find("&nbsp;") then dsep = " &ndash; " end -- set the order for the list of qualifiers returned; start time and end time go last if next(qlist) then local qlistout = {} if allflag then for k2, v2 in pairs(qlist) do qlistout[#qlistout+1] = v2 end else for i2, v2 in ipairs(qorder) do qlistout[#qlistout+1] = qlist[v2] end end if t ~= "" then qlistout[#qlistout+1] = timestart .. dsep .. timeend end local qstr = assembleoutput(qlistout, qargs) if qualsonly then out[#out+1] = qstr else out[#out] = out[#out] .. " (" .. qstr .. ")" end elseif t ~= "" then if qualsonly then if timestart == "" then out[#out+1] = timeend elseif timeend == "" then out[#out+1] = timestart else out[#out+1] = timestart .. dsep .. timeend end else out[#out] = out[#out] .. " (" .. timestart .. dsep .. timeend .. ")" end end end -- of test for qualifiers wanted if maxvals > 0 and #out >= maxvals then break end end -- of for each value loop -- we need to pick one value to return if the datatype was "monolingualtext" -- if there's only one value, use that -- otherwise look through the fallback languages for a match if datatype == "monolingualtext" and #out >1 then lang = mw.text.split( lang, '-', true )[1] local fbtbl = mw.language.getFallbacksFor( lang ) table.insert( fbtbl, 1, lang ) local bestval = "" local found = false for idx1, lang1 in ipairs(fbtbl) do for idx2, lang2 in ipairs(mlt) do if (lang1 == lang2) and not found then bestval = out[idx2] found = true break end end -- loop through values of property end -- loop through fallback languages if found then -- replace output table with a table containing the best value out = { bestval } else -- more than one value and none of them on the list of fallback languages -- sod it, just give them the first one out = { out[1] } end end return out end local function mergeOptions(defaults, overrides) overrides = overrides or {} defaults = defaults or {} local result = {} for k, v in pairs(defaults) do result[k] = v end for k, v in pairs(overrides) do result[k] = v if k == 'rank' then result.reqranks = setRanks(v) end end return result end local function filterbyqualifier(statements,qual,value) local filtered_statements = {} for _, statement in ipairs(statements) do if statement.qualifiers and statement.qualifiers[qual] then if '*' == value then table.insert(filtered_statements, statement) else for _, qual in ipairs(statement.qualifiers[qual]) do if qual.datavalue and (rawValue(qual.datavalue) == value) then table.insert(filtered_statements, statement) break end end end end end return filtered_statements end local function rankFilter(statements, rank, sourcedonly, sortbyqualifier) end ------------------------------------------------------------------------------- -- Statement Class Definition ------------------------------------------------------------------------------- local WdStatement = {} WdStatement.__index = WdStatement ------------------------------------------------------------------------------- -- Statements Class Definition ------------------------------------------------------------------------------- local WdStatements = {} WdStatements.__index = WdStatements function WdStatements:getStatmentsTable() return self._statements end function WdStatements:count() return #self._statements end function WdStatements:getFilters() return self.filtered_by end function WdStatements:filter(filter_t) local statements = self._statements if #statements == 0 then return self end local ret = setmetatable({}, WdStatements) ret.parent = self.parent ret.filtered_by = self.filtered_by local filtered_statements = {} for k,v in pairs(filter_t) do filtered_statements = filterbyqualifier(statements, k, v) table.insert(ret.filtered_by, {[k] = v}) if #filtered_statements == 0 then break; else statements = filtered_statements end end ret._statements = filtered_statements return ret end function WdStatements:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getRawValue(opts) local mergedOpts = mergeOptions(self.options, opts or {}) local ret = {} for _,v in pairs(self._statements) do if v.mainsnak.snaktype=="value" then table.insert(ret,rawValue(v.mainsnak.datavalue)) else table.insert(ret,v.mainsnak.snaktype) end end return ret end ------------------------------------------------------------------------------- -- WdItem Class Definition ------------------------------------------------------------------------------- local WdItem = {} WdItem.__index = WdItem function WdItem:__tostring() return "WdItem: " .. (self.qid or "no QID") end function WdItem:UpdateOptions(newOpts) for k, v in pairs(newOpts or {}) do local key = options_aliases[k] self.options[key] = v -- Set default options if key == 'langs' and #v > 0 then self.options.langobj = findLang(self.options.langs[1]) self.options.lang = self.options.langobj.code if not self.options.langobj then self.options.langobj = findLang(self.options.lang) self.options.lang = self.options.langobj.code end end if key == 'rank' then self.options.reqranks = setRanks(self.options.rank) end end if not self.options.reqranks then self.options.reqranks = setRanks('preferred normal') end end function WdItem.new(qid, options) local self = setmetatable({}, WdItem) if qid == "" then qid = nil end if (not qid) and mw.wikibase then qid = mw.wikibase.getEntityIdForCurrentPage() end self.qid = qid self.snak = nil self.options = options or {} self:UpdateOptions(options) return self end function WdItem.newFromSnaks(snakTable, options) local self = setmetatable({}, WdItem) self.qid = nil self.snak = snakTable or {} self.options = options or {} self:UpdateOptions(options) return self end function WdItem:setOptions(newOpts) self:UpdateOptions(newOpts) end function WdItem:getStatements(pid, opts) local mergedOpts = mergeOptions(self.options, opts or {}) local statements local ret = setmetatable({}, WdStatements) ret.parent = self ret.filtered_by = {} ret._statements = {} ret.pid = pid if self.snak and self.snak[pid] then statements = self.snak[pid] elseif not self.qid or not mw.wikibase then statements = {} elseif mergedOpts.reqranks and mergedOpts.reqranks.best then statements = mw.wikibase.getBestStatements(self.qid, pid) or {} else statements = mw.wikibase.getAllStatements(self.qid, pid) or {} local filtered_statements = {} if not (mergedOpts.reqranks.deprecated == true and mergedOpts.reqranks.preferred == true and mergedOpts.reqranks.normal == true) then for _,s in pairs(statements) do if mergedOpts.reqranks[s.rank] then table.insert(filtered_statements,s) end end end statements = filtered_statements end if #statements > 0 and mergedOpts.qualifiedaspossible and #mergedOpts.qualifiedaspossible then local filtered_statements = {} for q,qv in pairs(mergedOpts.qualifiedaspossible) do filtered_statements = filterbyqualifier(statements, q, qv) if #filtered_statements > 0 then table.insert(ret.filtered_by, {[q] = qv}) statements = filtered_statements end end end if #statements > 0 and mergedOpts.qualified and #mergedOpts.qualified then for q,qv in pairs(mergedOpts.qualified) do statements = filterbyqualifier(statements, q, qv) table.insert(ret.filtered_by, {[q] = qv}) if #statements == 0 then break; end end end ret._statements = statements return ret end function WdItem:getValue(pid, opts) local mergedOpts = mergeOptions(self.options, opts) -- Handle local value override if mergedOpts[2] and mergedOpts[2] ~= "" then return mergedOpts[2] end local statements if mergedOpts.no_vol_qual then statements = mw.wikibase.getBestStatements(self.qid, pid) else statements = self:getStatements(pid, {vol = mergedOpts.vol, chapter = mergedOpts.chapter}) end if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.qid, pid) end function WdItem:getValueFromSnaks(pid, opts) if not self.snak or not self.snak[pid] then return nil end local mergedOpts = mergeOptions(self.options, opts) local props = self.snak[pid] local out = propertyvalueandquals(props, mergedOpts) return assembleoutput(out, mergedOpts, nil, pid) end function WdItem:getPropertyIDsTable(pid, opts) local mergedOpts = mergeOptions(self.options, opts) mergedOpts.noicon = tostring(parseParam(mergedOpts.noicon or "", true)) local statements = self:getStatements(pid, opts) if not statements or #statements == 0 then return {} end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local out = {} for i, v in ipairs(statements) do local snak = v.mainsnak if (snak.datatype == "wikibase-item") and (v.rank and mergedOpts.reqranks[v.rank:sub(1, 1)]) and (snak.snaktype == "value") and (sourced(v) or not onlysrc) then out[#out+1] = snak.datavalue.value.id end if maxvals > 0 and #out >= maxvals then break end end return out end function WdItem:getPropertyIDs(pid, opts) local out = WdItem:getPropertyIDsTable(pid, opts) if #out == 0 then return nil end return assembleoutput(out, mergeOptions(self.options, opts), self.qid, pid) end function WdItem:getPropOfProp(prop1, prop2, opts) local mergedOpts = mergeOptions(self.options, opts) if not self.qid then return nil end local statements1 = self:getStatements(prop1, opts) if not statements1 or #statements1 == 0 then return nil end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = {} for k, v in ipairs(statements1) do if not onlysrc or sourced(v) then local snak = v.mainsnak if snak.datatype == "wikibase-item" and snak.snaktype == "value" then local qid2 = snak.datavalue.value.id local item2 = WdItem.new(qid2, mergedOpts) local statements2 = item2:getStatements(prop2, opts) if statements2 and statements2[1] then local out2 = propertyvalueandquals(statements2, mergedOpts, qualID) out[#out+1] = assembleoutput(out2, mergedOpts, qid2, prop2) end end end if maxvals > 0 and #out >= maxvals then break end end return assembleoutput(out, mergedOpts, self.qid, prop1) end function WdItem:getLangOfProp(pid) if not pid or not self.qid then return {} end local out = {} local props = mw.wikibase.getAllStatements(self.qid, pid) for _, v in ipairs(props) do if v.mainsnak.datatype == "monolingualtext" and v.mainsnak.datavalue then out[#out + 1] = v.mainsnak.datavalue.value.language end end return out end function WdItem:followQid(props, all) all = parseParam(all, false) props = (props or ""):upper() if not self.qid then return nil end if props == "" then return self.qid end local out = {} for p in mw.text.gsplit(props, "%p") do p = mw.text.trim(p) for i, v in ipairs(mw.wikibase.getBestStatements(self.qid, p)) do local linkedid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id if linkedid then if all then out[#out+1] = linkedid else return linkedid end end end end if #out > 0 then return table.concat(out, " ") else return self.qid end end ------------------------------------------------------------------------------- -- Public API - Utility Functions ------------------------------------------------------------------------------- p.getStatementsByVol = function(qid, pid, vol, chapter) local statements = mw.wikibase.getBestStatements(qid, pid) local filtered_by = {} if #statements ==0 then return {},{}; end local filtered_statements = {} if chapter then for _, statement in ipairs(statements) do if statement.qualifiers and statement.qualifiers["P792"] then for _, qual in ipairs(statement.qualifiers["P792"]) do if qual.datavalue and tostring(qual.datavalue.value) == tostring(chapter) then table.insert(filtered_statements, statement) table.insert(filtered_by, {["P792"] = chapter}) break end end end end end if #filtered_statements == 0 and vol then for _, statement in ipairs(statements) do local vol_match = true if vol and statement.qualifiers and statement.qualifiers["P478"] then vol_match = false for _, qual in ipairs(statement.qualifiers["P478"]) do if qual.datavalue and tostring(qual.datavalue.value) == tostring(vol) then vol_match = true break end end end if vol_match then table.insert(filtered_statements, statement) end end if #filtered_statements > 0 then table.insert(filtered_by, {["P478"] = vol}) end else filtered_statements = statements end return filtered_statements, filtered_by end ------------------------------------------------------------------------------- -- Public API - WdItem Constructors ------------------------------------------------------------------------------- p.WdItem = WdItem function p.newItem(qid, opts) return WdItem.new(qid, opts) end function p.currentItem(opts) return WdItem.new(nil, opts) end function p.newSnakItem(snakTable, opts) return WdItem.newFromSnaks(snakTable, opts) end return p 5bg9lrfgkuxq8qwh5hyoqihnlmzk6jc 1097091 1097064 2026-07-21T20:20:00Z حبيشان 31560 1097091 Scribunto text/plain -- Module: WdItem -- Object-oriented Wikidata access module for Lua -- Refactored from WikidataIB for direct Lua usage require("strict") local p = {} -- i18n configuration local i18n = { ["errors"] = { ["property-not-found"] = "الخاصية غير موجودة.", ["entity-not-found"] = "الكيان على ويكي بيانات غير موجود.", ["unknown-claim-type"] = "نوع الادعاء غير معروف.", ["local-article-not-found"] = "المعرف متاح على ويكي بيانات، ولكن المقال غير متاح على ويكيبيديا", }, ["months"] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, ["Unknown"] = "Unknown", ["NaN"] = "Not a number", ["missinginfocat"] = "[[تصنيف:Articles with missing Wikidata information]]", ["list separator"] = ", ", ["list separator-ar"] = "، ", } -- Date precision constants local dp = { [6] = "millennium", [7] = "century", [8] = "decade", [9] = "year", [10] = "month", [11] = "day", } local options_aliases = { ["osd"] = "onlysourced", ["wdlinks"] = "wdl", ["uabbr"] = "unitabbr", ["qo"] = "qualsonly", ["lp"] = "linkprefix", ["lprefix"] = "linkprefix", ["qlp"] = "qlinkprefix", ["sn"] = "shortname", ["uselabel"] = "uselbl", ["plaindate"] = "pd", ["qualifierdateformat"] = "qdf", ["df"] = "qdf", ["qshortname"] = "qsn" } setmetatable(options_aliases, { __index = function(t, k) return k end }) ------------------------------------------------------------------------------- -- Internal helper functions ------------------------------------------------------------------------------- local function findLang(langcode) local langobj langcode = mw.text.trim(langcode or "") if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langcode = mw.getCurrentFrame():callParserFunction('int', {'lang'}) if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langobj = mw.language.getContentLanguage() end end return langobj end local function parseParam(param, default) if param == nil then return default end return param end local function setRanks(rank) rank = (rank or ""):lower() local ranks = {} for w in string.gmatch(rank, "%a+") do if w == "best" or w == "preferred" or w == "normal" or w == "deprecated" then ranks[w] = true end end if ranks.best or not next(ranks) then ranks.preferred = true ranks.normal = true ranks.deprecated = false end return ranks end local function labelOrId(id, lang) if lang == "default" then lang = findLang().code end local label if lang then label = mw.wikibase.getLabelByLang(id, lang) end if not label then local trylang = {"ar","en","fr", "mul"} local triedlang = lang for _,lang in pairs(trylang) do if triedlang ~= lang then label = mw.wikibase.getLabelByLang(id, lang) if label ~= "" then break end end end end if label then return mw.text.nowiki(label), true else return id, false end end local function roundto(x, sf) if x == 0 then return 0 end local s = 1 if x < 0 then x = -x s = -1 end if sf < 1 then sf = 1 end local p = 10 ^ (math.floor(math.log10(x)) - sf + 1) x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end return x end local function decimalPrecision(x, p) local s = 1 if x < 0 then x = -x s = -1 end if not tonumber(p) then p = 1e-4 elseif p > 1 then p = 1 elseif p < 1e-6 then p = 1e-6 else p = 10 ^ math.floor(math.log10(p)) end x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end if math.abs(x) < 1e-4 then x = string.format("%f", x) end return x end local function decimalToDMS(x, p) if not tonumber(p) then p = 1e-4 end local d = math.floor(x) local ms = (x - d) * 60 if p > 0.5 then if ms > 30 then d = d + 1 end ms = 0 end local m = math.floor(ms) local s = (ms - m) * 60 if p > 0.008 then if s > 30 then m = m +1 end s = 0 elseif p > 0.00014 then s = math.floor(s + 0.5) elseif p > 0.000014 then s = math.floor(10 * s + 0.5) / 10 elseif p > 0.0000014 then s = math.floor(100 * s + 0.5) / 100 else s = math.floor(1000 * s + 0.5) / 1000 end return d, m, s end local function rawValue(dataValue) if dataValue.type == "string" then return dataValue.value elseif dataValue.type == "wikibase-entityid" then return dataValue.value and dataValue.value.id elseif dataValue.type == "monolingualtext" then return dataValue.value.text elseif dataValue.type == "quantity" then return tonumber(dataValue.value.amount) elseif dataValue.type == 'time' then return dataValue.value.time elseif dataValue.type == "globecoordinate" then return dataValue.value.latitude .. '/' .. dataValue.value.longitude end end local function compareValue(dataValue, strValue) return rawValue(dataValue) == strValue end local function dateFormat(timestamp, dprec, df, bcf, pd, qualifiers, lang, adj, model) df = (df or ""):lower() if df == "ymd" then if timestamp:sub(1,1) == "+" then return timestamp:sub(2,11) else local yr = tonumber(timestamp:sub(2,5)) - 1 yr = ("000" .. yr):sub(-4) if yr ~= "0000" then yr = "-" .. yr end return yr .. timestamp:sub(6,11) end end timestamp = timestamp:gsub("%-00%-00T", "-01-01T") dprec = dprec or 11 if df == "y" and dprec > 9 then dprec = 9 end dprec = dprec>11 and 11 or dprec dprec = dprec<6 and 6 or dprec bcf = (bcf or ""):upper() pd = (pd or ""):sub(1,1):lower() if pd == "" or pd == "n" or pd == "f" or pd == "0" then pd = false end lang = lang or findLang().code adj = adj or "" local bc = timestamp:sub(1, 1)=="-" and "BC" or "" local year, month, day = timestamp:match("[+-](%d*)-(%d*)-(%d*)T") local iso = tonumber(year) if dprec == 6 then iso = math.floor( (iso - 1) / 1000 ) + 1 end if dprec == 7 then iso = math.floor( (iso - 1) / 100 ) + 1 end if dprec == 8 then iso = math.floor( iso / 10 ) .. "0" end if dprec == 10 then iso = year .. "-" .. month end if dprec == 11 then iso = year .. "-" .. month .. "-" .. day end local sc = not pd and qualifiers and qualifiers.P1480 if sc then for k1, v1 in pairs(sc) do if v1.datavalue and v1.datavalue.value.id == "Q5727902" then adj = "circa" break end end end local calendarmodel = "" if tonumber(year) > 1582 and dprec > 8 and not pd and model == "http://www.wikidata.org/entity/Q1985786" then calendarmodel = "julian" end -- Simplified date formatting (complex date module not available) local fdate = tostring(iso) if bc ~= "" then fdate = fdate .. " " .. (bcf == "BC" and "BC" or "BCE") end if adj == "circa" then fdate = "c. " .. fdate end return fdate end local function hijriFormat(qualifiers, dateformat, lang) if not qualifiers.P4241 then return; end local year, month, day local val local qhmonths = {["Q1952053"]=1,["Q489557"]=2, ["Q474167"] = 3, ["Q273815"] = 4, ["Q852002"] = 5, ["Q822218"] = 6, ["Q194210"] = 7, ["Q220914"] = 8, ["Q8867089"]=9, ["Q685440"]=10,["Q150853"]=11,["Q186022"]=12 } local hmonths = {"محرم","صفر","ربيع الأول","ربيع الآخر","جمادى الأولى","جمادى الآخرة","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة"} local hmonths_inv = {["محرم"] = 1, ["صفر"]=2, ["ربيع الأول"]=3, ["ربيع الآخر"]=4, ["جمادى الأولى"]=5, ["جمادى الآخرة"]=6, ["رجب"]=7, ["شعبان"]=8, ["رمضان"]=9, ["شوال"]=10, ["ذو القعدة"]=11, ["ذو الحجة"]=12} for _, item in ipairs(qualifiers.P4241) do local timeQ = item.datavalue and item.datavalue.value and item.datavalue.value.id local hastime = false if timeQ then local timeQt = mw.wikibase.getBestStatements(timeQ, "P361") for _,timeQsnak in pairs(timeQt) do local timeType = timeQsnak.mainsnak and timeQsnak.mainsnak.datavalue and timeQsnak.mainsnak.datavalue.value and timeQsnak.mainsnak.datavalue.value.id if timeType == "Q28892" then local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then year = mw.ustring.match(timeLableAr, "^(%d+) *هـ$") end if not year then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then year = mw.ustring.match(timeLableAr, "^(%d+) *AH$") end end hastime=true elseif qhmonths[timeType] then month = qhmonths[timeType] if month>0 and month<13 then month = hmonths[month] end local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end if not day then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end end hastime=true end end if not hastime then timeQt = mw.wikibase.getBestStatements(timeQ, "P31") if "Q125390868" == (timeQt[1].mainsnak and timeQt[1].mainsnak.datavalue and timeQt[1].mainsnak.datavalue.value and timeQt[1].mainsnak.datavalue.value.id ) then val = mw.wikibase.getLabelByLang(timeQ, "ar") month, year = mw.ustring.match(val, "^(%a[%a ]+%a) *(%d+) *هـ?$") end end end end if year then if dateformat == "y" then return year; elseif day and month then return day .. ' ' .. month .. ' ' .. year; elseif month then return month .. ' ' .. year; end end return nil; end local function sourced(claim) if claim.references then for kr, vr in pairs(claim.references) do local ref = mw.wikibase.renderSnaks(vr.snaks) if not ref:find("Wiki") then return true end end end end local function linkedItem(id, args) local lprefix = (args.linkprefix or ""):gsub('"', '') local lpostfix = (args.lpostfix or ""):gsub('"', '') local prefix = (args.prefix or ""):gsub('"', '') local postfix = (args.postfix or ""):gsub('"', '') local dtxt = args.dtxt local uselbl = parseParam( args.uselbl, true) local disp local sitelink = mw.wikibase.getSitelink(id, args.linksproject) local label, islabel if dtxt then label, islabel = dtxt, true else label, islabel = labelOrId(id, args.lang) end if sitelink then if not uselbl then local pos = sitelink:find(":") or 0 local slink = sitelink if pos > 0 then local pfx = sitelink:sub(1,pos-1) if mw.site.namespaces[pfx] then slink = sitelink:sub(pos+1) end end slink = slink:gsub("%s%(.+%)$", ""):gsub(",.+$", "") if label:find("^%u") then label = slink:gsub("^(%l)", string.upper) else label = slink:gsub("^(%u)", string.lower) end end disp = "[[" .. lprefix .. sitelink .. lpostfix .. "|" .. prefix .. label .. postfix .. "]]" elseif islabel then disp = prefix .. label .. postfix else disp = prefix .. label .. postfix .. i18n.missinginfocat end return disp end local function rendersnak(propval, args, linked, lpre, lpost, pre, post, uabbr, filter) lpre = lpre or "" lpost = lpost or "" pre = pre or "" post = post or "" args.lang = args.lang or findLang().code local snak = propval.mainsnak or propval local dtype = snak.datatype local dv = snak.datavalue dv = dv and dv.value local val, mlt local namedas; namedas = propval.qualifiers and propval.qualifiers.P1932 and propval.qualifiers.P1932[1].datavalue and propval.qualifiers.P1932[1].datavalue.value or nil args.dtxt = namedas if propval.rank and not args.reqranks[propval.rank] then return nil elseif snak.snaktype == "somevalue" then val = namedas or i18n["Unknown"] elseif snak.snaktype == "novalue" then -- return nothing elseif dtype == "wikibase-item" then local qnumber = dv.id if linked then val = linkedItem(qnumber, args) else if namedas then val = pre .. namedas .. post else local label, islabel = labelOrId(qnumber, args.lang) val = pre .. label .. post end end elseif dtype == "time" then if args.hijri then val = hijriFormat(propval.qualifiers, args.df, args.lang) else val = dateFormat(dv.time, dv.precision, args.df, args.bc, args.pd, propval.qualifiers, args.lang, "", dv.calendarmodel) end elseif dtype == "commonsMedia" or dtype == "external-id" or dtype == "string" or dtype == "url" then if (lpre == "" or lpre == ":") and lpost == "" then val = pre .. dv .. post elseif dtype == "external-id" then val = "[" .. lpre .. dv .. lpost .. " " .. pre .. dv .. post .. "]" else val = "[[" .. lpre .. dv .. lpost .. "|" .. pre .. dv .. post .. "]]" end elseif dtype == "quantity" then local amount = tonumber(dv.amount) or i18n["NaN"] local unit = "" local unitqid = string.match(dv.unit, "(Q%d+)") if filter and unitqid ~= filter then return nil end if unitqid then local uname = mw.wikibase.getLabelByLang(unitqid, args.lang) or "" if uname ~= "" then unit = " " .. uname end end val = tostring(amount) .. unit elseif dtype == "globe-coordinate" then local lat, long, prec = dv.latitude, dv.longitude, dv.precision local show = (args.show or ""):lower() if show == "lat" then val = decimalPrecision(lat, prec) elseif show == "lon" then val = decimalPrecision(long, prec) elseif show == "longlat" then val = decimalPrecision(long, prec) .. ", " .. decimalPrecision(lat, prec) else local ns = lat < 0 and "S" or "N" local ew = long < 0 and "W" or "E" if lat < 0 then lat = -lat end if long < 0 then long = -long end val = decimalPrecision(lat, prec) .. "°" .. ns .. " " .. decimalPrecision(long, prec) .. "°" .. ew end elseif dtype == "monolingualtext" then val = pre .. dv.text .. post mlt = dv.language else val = "unknown data type: " .. dtype end return val, mlt end local function assembleoutput(out, args, entityID, propertyID) local sorted = parseParam(args.sorted, false) local noic = parseParam(args.noicon, false) local list = args.list or "" local separator = args.sep or "" separator = string.gsub(separator, '"', '') if separator == "" then local rtl_lang = {ar = true, fa = true, ur = true, ku = true, he = true} separator = rtl_lang[args.lang] and i18n["list separator-ar"] or i18n["list separator"] end local strout if #out > 0 then if sorted then table.sort(out) end if list == "" then strout = table.concat(out, separator) elseif list:lower() == "prose" then strout = mw.text.listToText(out) else strout = mw.getCurrentFrame():expandTemplate{title = list, args = out} end else strout = nil end return strout end local function propertyvalueandquals(objproperty, args, qualID) -- needs this style of declaration because it's re-entrant -- onlysourced is a boolean passed to return only values sourced to other than Wikipedia -- if nothing or an empty string is passed set it true local onlysrc = parseParam(args.onlysourced, false) -- linked is a a boolean that enables the link to a local page via sitelink -- if nothing or an empty string is passed set it true local linked = parseParam(args.linked, true) -- prefix is a string that may be nil, empty (""), or a string of characters -- this is prefixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local prefix = (args.prefix or ""):gsub('"', '') -- postfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local postfix = (args.postfix or ""):gsub('"', '') -- linkprefix is a string that may be nil, empty (""), or a string of characters -- this creates a link and is then prefixed to each value -- useful when when multiple values are returned and indirect links are needed -- any double-quotes " are stripped out, so that spaces may be passed local lprefix = (args.linkprefix or ""):gsub('"', '') -- linkpostfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value when linking is enabled with lprefix -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local lpostfix = (args.linkpostfix or ""):gsub('"', '') -- wdlinks is a boolean passed to enable links to Wikidata when no article exists -- if nothing or an empty string is passed set it false local wdl = parseParam(args.wdl, false) -- unitabbr is a boolean passed to enable unit abbreviations for common units -- if nothing or an empty string is passed set it false local uabbr = parseParam(args.unitabbr, false) -- qualsonly is a boolean passed to return just the qualifiers -- if nothing or an empty string is passed set it false local qualsonly = parseParam(args.qualsonly, false) -- maxvals is a string that may be nil, empty (""), or a number -- this determines how many items may be returned when multiple values are available -- setting it = 1 is useful where the returned string is used within another call, e.g. image local maxvals = tonumber(args.maxvals) or 0 -- pd boolean -- to disable/enable "sourcing cirumstances" or use adjectival form for the plain date local pd = args.pd or false args.pd = pd -- allow qualifiers to have a different date format; default to year unless qualsonly is set args.qdf = args.qdf or (not qualsonly and "y") local lang = args.lang or (args.langs and args.langs[1]) or findLang().code -- qualID is a string list of wanted qualifiers or "ALL" qualID = qualID or "" -- capitalise list of wanted qualifiers and substitute "DATES" qualID = qualID:upper():gsub("DATES", "P580, P582") local allflag = (qualID == "ALL") -- create table of wanted qualifiers as key local qwanted = {} -- create sequence of wanted qualifiers local qorder = {} for q in mw.text.gsplit(qualID, "%p") do -- split at punctuation and iterate local qtrim = mw.text.trim(q) if qtrim ~= "" then qwanted[mw.text.trim(q)] = true qorder[#qorder+1] = qtrim end end -- qsep is the output separator for rendering qualifier list local qsep = (args.qsep or ""):gsub('"', '') -- qargs are the arguments to supply to assembleoutput() local qargs = { ["osd"] = "false", ["linked"] = tostring(linked), ["prefix"] = args.qprefix, ["postfix"] = args.qpostfix, ["linkprefix"] = args.qlinkprefix, ["linkpostfix"] = args.qlinkpostfix, ["wdl"] = "false", ["unitabbr"] = tostring(uabbr), ["maxvals"] = 0, ["sorted"] = tostring(args.qsorted), ["noicon"] = "true", ["list"] = args.qlist, ["sep"] = qsep, -- ["langobj"] = args.langobj, ["lang"] = args.lang or (args.langs and args.lang[1]), ["df"] = args.qdf, ["sn"] = parseParam(args.qsn, false), } -- all proper values of a Wikidata property will be the same type as the first -- qualifiers don't have a mainsnak, properties do --#Modified line local datatype = objproperty[1].datatype or (objproperty[1].mainsnak and objproperty[1].mainsnak.datatype) -- out[] holds the a list of returned values for this property -- mlt[] holds the language code if the datatype is monolingual text local out = {} local mlt = {} for k, v in ipairs(objproperty) do local hasvalue = true if (onlysrc and not sourced(v)) then -- no value: it isn't sourced when onlysourced=true hasvalue = false else local val, lcode = rendersnak(v, args, linked, lprefix, lpostfix, prefix, postfix, uabbr) if not val then hasvalue = false -- rank doesn't match elseif qualsonly and qualID then -- suppress value returned: only qualifiers are requested else out[#out+1], mlt[#out+1] = val, lcode end end -- See if qualifiers are to be returned: local snak = v.mainsnak or v if hasvalue and v.qualifiers and qualID ~= "" and snak.snaktype~="novalue" then -- collect all wanted qualifier values returned in qlist, indexed by propertyID local qlist = {} local timestart, timeend = "", "" -- loop through qualifiers for k1, v1 in pairs(v.qualifiers) do if allflag or qwanted[k1] then if k1 == "P1326" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before") elseif k1 == "P1319" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after") elseif k1 == "P580" then timestart = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one start time as valid elseif k1 == "P582" then timeend = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one end time as valid else local q = assembleoutput(propertyvalueandquals(v1, qargs), qargs) -- we already deal with circa via 'sourcing circumstances' if the datatype was time -- circa may be either linked or unlinked *** internationalise later *** if datatype ~= "time" or q ~= "circa" and not (type(q) == "string" and q:find("circa]]")) then qlist[k1] = q end end end -- of test for wanted end -- of loop through qualifiers -- set date separator local t = timestart .. timeend -- *** internationalise date separators later *** local dsep = "&ndash;" if t:find("%s") or t:find("&nbsp;") then dsep = " &ndash; " end -- set the order for the list of qualifiers returned; start time and end time go last if next(qlist) then local qlistout = {} if allflag then for k2, v2 in pairs(qlist) do qlistout[#qlistout+1] = v2 end else for i2, v2 in ipairs(qorder) do qlistout[#qlistout+1] = qlist[v2] end end if t ~= "" then qlistout[#qlistout+1] = timestart .. dsep .. timeend end local qstr = assembleoutput(qlistout, qargs) if qualsonly then out[#out+1] = qstr else out[#out] = out[#out] .. " (" .. qstr .. ")" end elseif t ~= "" then if qualsonly then if timestart == "" then out[#out+1] = timeend elseif timeend == "" then out[#out+1] = timestart else out[#out+1] = timestart .. dsep .. timeend end else out[#out] = out[#out] .. " (" .. timestart .. dsep .. timeend .. ")" end end end -- of test for qualifiers wanted if maxvals > 0 and #out >= maxvals then break end end -- of for each value loop -- we need to pick one value to return if the datatype was "monolingualtext" -- if there's only one value, use that -- otherwise look through the fallback languages for a match if datatype == "monolingualtext" and #out >1 then lang = mw.text.split( lang, '-', true )[1] local fbtbl = mw.language.getFallbacksFor( lang ) table.insert( fbtbl, 1, lang ) local bestval = "" local found = false for idx1, lang1 in ipairs(fbtbl) do for idx2, lang2 in ipairs(mlt) do if (lang1 == lang2) and not found then bestval = out[idx2] found = true break end end -- loop through values of property end -- loop through fallback languages if found then -- replace output table with a table containing the best value out = { bestval } else -- more than one value and none of them on the list of fallback languages -- sod it, just give them the first one out = { out[1] } end end return out end local function mergeOptions(defaults, overrides) overrides = overrides or {} defaults = defaults or {} local result = {} for k, v in pairs(defaults) do result[k] = v end for k, v in pairs(overrides) do result[k] = v if k == 'rank' then result.reqranks = setRanks(v) end end return result end local function filterbyqualifier(statements,qual,value) local filtered_statements = {} for _, statement in ipairs(statements) do if statement.qualifiers and statement.qualifiers[qual] then if '*' == value then table.insert(filtered_statements, statement) else for _, qual in ipairs(statement.qualifiers[qual]) do if qual.datavalue and (rawValue(qual.datavalue) == value) then table.insert(filtered_statements, statement) break end end end end end return filtered_statements end local function rankFilter(statements, rank, sourcedonly, sortbyqualifier) end ------------------------------------------------------------------------------- -- Statement Class Definition ------------------------------------------------------------------------------- local WdStatement = {} WdStatement.__index = WdStatement ------------------------------------------------------------------------------- -- Statements Class Definition ------------------------------------------------------------------------------- local WdStatements = {} WdStatements.__index = WdStatements function WdStatements:getStatmentsTable() return self._statements end function WdStatements:count() return #self._statements end function WdStatements:getFilters() return self.filtered_by end function WdStatements:filter(filter_t) local statements = self._statements if #statements == 0 then return self end local ret = setmetatable({}, WdStatements) ret.parent = self.parent ret.filtered_by = self.filtered_by local filtered_statements = {} for k,v in pairs(filter_t) do filtered_statements = filterbyqualifier(statements, k, v) table.insert(ret.filtered_by, {[k] = v}) if #filtered_statements == 0 then break; else statements = filtered_statements end end ret._statements = filtered_statements return ret end function WdStatements:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getRawValue(opts) local mergedOpts = mergeOptions(self.options, opts or {}) local ret = {} for _,v in pairs(self._statements) do if v.mainsnak.snaktype=="value" then table.insert(ret,rawValue(v.mainsnak.datavalue)) else table.insert(ret,v.mainsnak.snaktype) end end return ret end ------------------------------------------------------------------------------- -- WdItem Class Definition ------------------------------------------------------------------------------- local WdItem = {} WdItem.__index = WdItem function WdItem:__tostring() return "WdItem: " .. (self.qid or "no QID") end function WdItem:UpdateOptions(newOpts) for k, v in pairs(newOpts or {}) do local key = options_aliases[k] self.options[key] = v -- Set default options if key == 'langs' and #v > 0 then self.options.langobj = findLang(self.options.langs[1]) self.options.lang = self.options.langobj.code if not self.options.langobj then self.options.langobj = findLang(self.options.lang) self.options.lang = self.options.langobj.code end end if key == 'rank' then self.options.reqranks = setRanks(self.options.rank) end end if not self.options.reqranks then self.options.reqranks = setRanks('preferred normal') end end function WdItem.new(qid, options) local self = setmetatable({}, WdItem) if qid == "" then qid = nil end if (not qid) and mw.wikibase then qid = mw.wikibase.getEntityIdForCurrentPage() end self.qid = qid self.snak = nil self.options = options or {} self:UpdateOptions(options) return self end function WdItem.newFromSnaks(snakTable, options) local self = setmetatable({}, WdItem) self.qid = nil self.snak = snakTable or {} self.options = options or {} self:UpdateOptions(options) return self end function WdItem:setOptions(newOpts) self:UpdateOptions(newOpts) end function WdItem:getStatements(pid, opts) local mergedOpts = mergeOptions(self.options, opts or {}) local statements local ret = setmetatable({}, WdStatements) ret.parent = self ret.filtered_by = {} ret._statements = {} ret.pid = pid if self.snak and self.snak[pid] then statements = self.snak[pid] elseif not self.qid or not mw.wikibase then statements = {} elseif mergedOpts.reqranks and mergedOpts.reqranks.best then statements = mw.wikibase.getBestStatements(self.qid, pid) or {} else statements = mw.wikibase.getAllStatements(self.qid, pid) or {} local filtered_statements = {} if not (mergedOpts.reqranks.deprecated == true and mergedOpts.reqranks.preferred == true and mergedOpts.reqranks.normal == true) then for _,s in pairs(statements) do if mergedOpts.reqranks[s.rank] then table.insert(filtered_statements,s) end end end statements = filtered_statements end if #statements > 0 and mergedOpts.qualifiedaspossible and #mergedOpts.qualifiedaspossible then local filtered_statements = {} for q,qv in pairs(mergedOpts.qualifiedaspossible) do filtered_statements = filterbyqualifier(statements, q, qv) if #filtered_statements > 0 then table.insert(ret.filtered_by, {[q] = qv}) statements = filtered_statements end end end if #statements > 0 and mergedOpts.qualified and #mergedOpts.qualified then for q,qv in pairs(mergedOpts.qualified) do statements = filterbyqualifier(statements, q, qv) table.insert(ret.filtered_by, {[q] = qv}) if #statements == 0 then break; end end end ret._statements = statements return ret end function WdItem:getValue(pid, opts) local mergedOpts = mergeOptions(self.options, opts) local statements = self:getStatements(pid, mergedOpts):getStatmentsTable() if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.qid, pid) end function WdItem:getValueFromSnaks(pid, opts) if not self.snak or not self.snak[pid] then return nil end local mergedOpts = mergeOptions(self.options, opts) local props = self.snak[pid] local out = propertyvalueandquals(props, mergedOpts) return assembleoutput(out, mergedOpts, nil, pid) end function WdItem:getPropertyIDsTable(pid, opts) local mergedOpts = mergeOptions(self.options, opts) mergedOpts.noicon = tostring(parseParam(mergedOpts.noicon or "", true)) local statements = self:getStatements(pid, opts) if not statements or #statements == 0 then return {} end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local out = {} for i, v in ipairs(statements) do local snak = v.mainsnak if (snak.datatype == "wikibase-item") and (v.rank and mergedOpts.reqranks[v.rank:sub(1, 1)]) and (snak.snaktype == "value") and (sourced(v) or not onlysrc) then out[#out+1] = snak.datavalue.value.id end if maxvals > 0 and #out >= maxvals then break end end return out end function WdItem:getPropertyIDs(pid, opts) local out = WdItem:getPropertyIDsTable(pid, opts) if #out == 0 then return nil end return assembleoutput(out, mergeOptions(self.options, opts), self.qid, pid) end function WdItem:getPropOfProp(prop1, prop2, opts) local mergedOpts = mergeOptions(self.options, opts) if not self.qid then return nil end local statements1 = self:getStatements(prop1, opts) if not statements1 or #statements1 == 0 then return nil end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = {} for k, v in ipairs(statements1) do if not onlysrc or sourced(v) then local snak = v.mainsnak if snak.datatype == "wikibase-item" and snak.snaktype == "value" then local qid2 = snak.datavalue.value.id local item2 = WdItem.new(qid2, mergedOpts) local statements2 = item2:getStatements(prop2, opts) if statements2 and statements2[1] then local out2 = propertyvalueandquals(statements2, mergedOpts, qualID) out[#out+1] = assembleoutput(out2, mergedOpts, qid2, prop2) end end end if maxvals > 0 and #out >= maxvals then break end end return assembleoutput(out, mergedOpts, self.qid, prop1) end function WdItem:getLangOfProp(pid) if not pid or not self.qid then return {} end local out = {} local props = mw.wikibase.getAllStatements(self.qid, pid) for _, v in ipairs(props) do if v.mainsnak.datatype == "monolingualtext" and v.mainsnak.datavalue then out[#out + 1] = v.mainsnak.datavalue.value.language end end return out end function WdItem:followQid(props, all) all = parseParam(all, false) props = (props or ""):upper() if not self.qid then return nil end if props == "" then return self.qid end local out = {} for p in mw.text.gsplit(props, "%p") do p = mw.text.trim(p) for i, v in ipairs(mw.wikibase.getBestStatements(self.qid, p)) do local linkedid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id if linkedid then if all then out[#out+1] = linkedid else return linkedid end end end end if #out > 0 then return table.concat(out, " ") else return self.qid end end ------------------------------------------------------------------------------- -- Public API - Utility Functions ------------------------------------------------------------------------------- p.getStatementsByVol = function(qid, pid, vol, chapter) local statements = mw.wikibase.getBestStatements(qid, pid) local filtered_by = {} if #statements ==0 then return {},{}; end local filtered_statements = {} if chapter then for _, statement in ipairs(statements) do if statement.qualifiers and statement.qualifiers["P792"] then for _, qual in ipairs(statement.qualifiers["P792"]) do if qual.datavalue and tostring(qual.datavalue.value) == tostring(chapter) then table.insert(filtered_statements, statement) table.insert(filtered_by, {["P792"] = chapter}) break end end end end end if #filtered_statements == 0 and vol then for _, statement in ipairs(statements) do local vol_match = true if vol and statement.qualifiers and statement.qualifiers["P478"] then vol_match = false for _, qual in ipairs(statement.qualifiers["P478"]) do if qual.datavalue and tostring(qual.datavalue.value) == tostring(vol) then vol_match = true break end end end if vol_match then table.insert(filtered_statements, statement) end end if #filtered_statements > 0 then table.insert(filtered_by, {["P478"] = vol}) end else filtered_statements = statements end return filtered_statements, filtered_by end ------------------------------------------------------------------------------- -- Public API - WdItem Constructors ------------------------------------------------------------------------------- p.WdItem = WdItem function p.newItem(qid, opts) return WdItem.new(qid, opts) end function p.currentItem(opts) return WdItem.new(nil, opts) end function p.newSnakItem(snakTable, opts) return WdItem.newFromSnaks(snakTable, opts) end return p 5d9g9q04skr1jh9w4cpbcdmbiwfvkap 1097235 1097091 2026-07-22T13:49:03Z حبيشان 31560 1097235 Scribunto text/plain -- Module: WdItem -- Object-oriented Wikidata access module for Lua -- Refactored from WikidataIB for direct Lua usage require("strict") local p = {} -- i18n configuration local i18n = { ["errors"] = { ["property-not-found"] = "الخاصية غير موجودة.", ["entity-not-found"] = "الكيان على ويكي بيانات غير موجود.", ["unknown-claim-type"] = "نوع الادعاء غير معروف.", ["local-article-not-found"] = "المعرف متاح على ويكي بيانات، ولكن المقال غير متاح على ويكيبيديا", }, ["months"] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, ["Unknown"] = "Unknown", ["NaN"] = "Not a number", ["missinginfocat"] = "[[تصنيف:Articles with missing Wikidata information]]", ["list separator"] = ", ", ["list separator-ar"] = "، ", } -- Date precision constants local dp = { [6] = "millennium", [7] = "century", [8] = "decade", [9] = "year", [10] = "month", [11] = "day", } local options_aliases = { ["osd"] = "onlysourced", ["wdlinks"] = "wdl", ["uabbr"] = "unitabbr", ["qo"] = "qualsonly", ["lp"] = "linkprefix", ["lprefix"] = "linkprefix", ["qlp"] = "qlinkprefix", ["sn"] = "shortname", ["uselabel"] = "uselbl", ["plaindate"] = "pd", ["qualifierdateformat"] = "qdf", ["df"] = "qdf", ["qshortname"] = "qsn" } setmetatable(options_aliases, { __index = function(t, k) return k end }) ------------------------------------------------------------------------------- -- Internal helper functions ------------------------------------------------------------------------------- local function findLang(langcode) local langobj langcode = mw.text.trim(langcode or "") if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langcode = mw.getCurrentFrame():callParserFunction('int', {'lang'}) if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langobj = mw.language.getContentLanguage() end end return langobj end local function parseParam(param, default) if param == nil then return default end return param end local function setRanks(rank) rank = (rank or ""):lower() local ranks = {} for w in string.gmatch(rank, "%a+") do if w == "best" or w == "preferred" or w == "normal" or w == "deprecated" then ranks[w] = true end end if ranks.best or not next(ranks) then ranks.preferred = true ranks.normal = true ranks.deprecated = false end return ranks end local function labelOrId(id, lang) if lang == "default" then lang = findLang().code end local label if lang then label = mw.wikibase.getLabelByLang(id, lang) end if not label then local trylang = {"ar","en","fr", "mul"} local triedlang = lang for _,lang in pairs(trylang) do if triedlang ~= lang then label = mw.wikibase.getLabelByLang(id, lang) if label ~= "" then break end end end end if label then return mw.text.nowiki(label), true else return id, false end end local function roundto(x, sf) if x == 0 then return 0 end local s = 1 if x < 0 then x = -x s = -1 end if sf < 1 then sf = 1 end local p = 10 ^ (math.floor(math.log10(x)) - sf + 1) x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end return x end local function decimalPrecision(x, p) local s = 1 if x < 0 then x = -x s = -1 end if not tonumber(p) then p = 1e-4 elseif p > 1 then p = 1 elseif p < 1e-6 then p = 1e-6 else p = 10 ^ math.floor(math.log10(p)) end x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end if math.abs(x) < 1e-4 then x = string.format("%f", x) end return x end local function decimalToDMS(x, p) if not tonumber(p) then p = 1e-4 end local d = math.floor(x) local ms = (x - d) * 60 if p > 0.5 then if ms > 30 then d = d + 1 end ms = 0 end local m = math.floor(ms) local s = (ms - m) * 60 if p > 0.008 then if s > 30 then m = m +1 end s = 0 elseif p > 0.00014 then s = math.floor(s + 0.5) elseif p > 0.000014 then s = math.floor(10 * s + 0.5) / 10 elseif p > 0.0000014 then s = math.floor(100 * s + 0.5) / 100 else s = math.floor(1000 * s + 0.5) / 1000 end return d, m, s end local function rawValue(dataValue) if dataValue.type == "string" then return dataValue.value elseif dataValue.type == "wikibase-entityid" then return dataValue.value and dataValue.value.id elseif dataValue.type == "monolingualtext" then return dataValue.value.text elseif dataValue.type == "quantity" then return tonumber(dataValue.value.amount) elseif dataValue.type == 'time' then return dataValue.value.time elseif dataValue.type == "globecoordinate" then return dataValue.value.latitude .. '/' .. dataValue.value.longitude end end local function compareValue(dataValue, strValue) return rawValue(dataValue) == strValue end local function dateFormat(timestamp, dprec, df, bcf, pd, qualifiers, lang, adj, model) df = (df or ""):lower() if df == "ymd" then if timestamp:sub(1,1) == "+" then return timestamp:sub(2,11) else local yr = tonumber(timestamp:sub(2,5)) - 1 yr = ("000" .. yr):sub(-4) if yr ~= "0000" then yr = "-" .. yr end return yr .. timestamp:sub(6,11) end end timestamp = timestamp:gsub("%-00%-00T", "-01-01T") dprec = dprec or 11 if df == "y" and dprec > 9 then dprec = 9 end dprec = dprec>11 and 11 or dprec dprec = dprec<6 and 6 or dprec bcf = (bcf or ""):upper() pd = (pd or ""):sub(1,1):lower() if pd == "" or pd == "n" or pd == "f" or pd == "0" then pd = false end lang = lang or findLang().code adj = adj or "" local bc = timestamp:sub(1, 1)=="-" and "BC" or "" local year, month, day = timestamp:match("[+-](%d*)-(%d*)-(%d*)T") local iso = tonumber(year) if dprec == 6 then iso = math.floor( (iso - 1) / 1000 ) + 1 end if dprec == 7 then iso = math.floor( (iso - 1) / 100 ) + 1 end if dprec == 8 then iso = math.floor( iso / 10 ) .. "0" end if dprec == 10 then iso = year .. "-" .. month end if dprec == 11 then iso = year .. "-" .. month .. "-" .. day end local sc = not pd and qualifiers and qualifiers.P1480 if sc then for k1, v1 in pairs(sc) do if v1.datavalue and v1.datavalue.value.id == "Q5727902" then adj = "circa" break end end end local calendarmodel = "" if tonumber(year) > 1582 and dprec > 8 and not pd and model == "http://www.wikidata.org/entity/Q1985786" then calendarmodel = "julian" end -- Simplified date formatting (complex date module not available) local fdate = tostring(iso) if bc ~= "" then fdate = fdate .. " " .. (bcf == "BC" and "BC" or "BCE") end if adj == "circa" then fdate = "c. " .. fdate end return fdate end local function hijriFormat(qualifiers, dateformat, lang) if not qualifiers.P4241 then return; end local year, month, day local val local qhmonths = {["Q1952053"]=1,["Q489557"]=2, ["Q474167"] = 3, ["Q273815"] = 4, ["Q852002"] = 5, ["Q822218"] = 6, ["Q194210"] = 7, ["Q220914"] = 8, ["Q8867089"]=9, ["Q685440"]=10,["Q150853"]=11,["Q186022"]=12 } local hmonths = {"محرم","صفر","ربيع الأول","ربيع الآخر","جمادى الأولى","جمادى الآخرة","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة"} local hmonths_inv = {["محرم"] = 1, ["صفر"]=2, ["ربيع الأول"]=3, ["ربيع الآخر"]=4, ["جمادى الأولى"]=5, ["جمادى الآخرة"]=6, ["رجب"]=7, ["شعبان"]=8, ["رمضان"]=9, ["شوال"]=10, ["ذو القعدة"]=11, ["ذو الحجة"]=12} for _, item in ipairs(qualifiers.P4241) do local timeQ = item.datavalue and item.datavalue.value and item.datavalue.value.id local hastime = false if timeQ then local timeQt = mw.wikibase.getBestStatements(timeQ, "P361") for _,timeQsnak in pairs(timeQt) do local timeType = timeQsnak.mainsnak and timeQsnak.mainsnak.datavalue and timeQsnak.mainsnak.datavalue.value and timeQsnak.mainsnak.datavalue.value.id if timeType == "Q28892" then local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then year = mw.ustring.match(timeLableAr, "^(%d+) *هـ$") end if not year then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then year = mw.ustring.match(timeLableAr, "^(%d+) *AH$") end end hastime=true elseif qhmonths[timeType] then month = qhmonths[timeType] if month>0 and month<13 then month = hmonths[month] end local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end if not day then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end end hastime=true end end if not hastime then timeQt = mw.wikibase.getBestStatements(timeQ, "P31") if "Q125390868" == (timeQt[1].mainsnak and timeQt[1].mainsnak.datavalue and timeQt[1].mainsnak.datavalue.value and timeQt[1].mainsnak.datavalue.value.id ) then val = mw.wikibase.getLabelByLang(timeQ, "ar") month, year = mw.ustring.match(val, "^(%a[%a ]+%a) *(%d+) *هـ?$") end end end end if year then if dateformat == "y" then return year; elseif day and month then return day .. ' ' .. month .. ' ' .. year; elseif month then return month .. ' ' .. year; end end return nil; end local function sourced(claim) if claim.references then for kr, vr in pairs(claim.references) do local ref = mw.wikibase.renderSnaks(vr.snaks) if not ref:find("Wiki") then return true end end end end local function linkedItem(id, args) local lprefix = (args.linkprefix or ""):gsub('"', '') local lpostfix = (args.lpostfix or ""):gsub('"', '') local prefix = (args.prefix or ""):gsub('"', '') local postfix = (args.postfix or ""):gsub('"', '') local dtxt = args.dtxt local uselbl = parseParam( args.uselbl, true) local disp local sitelink = mw.wikibase.getSitelink(id, args.linksproject) local label, islabel if dtxt then label, islabel = dtxt, true else label, islabel = labelOrId(id, args.lang) end if sitelink then if not uselbl then local pos = sitelink:find(":") or 0 local slink = sitelink if pos > 0 then local pfx = sitelink:sub(1,pos-1) if mw.site.namespaces[pfx] then slink = sitelink:sub(pos+1) end end slink = slink:gsub("%s%(.+%)$", ""):gsub(",.+$", "") if label:find("^%u") then label = slink:gsub("^(%l)", string.upper) else label = slink:gsub("^(%u)", string.lower) end end disp = "[[" .. lprefix .. sitelink .. lpostfix .. "|" .. prefix .. label .. postfix .. "]]" elseif islabel then disp = prefix .. label .. postfix else disp = prefix .. label .. postfix .. i18n.missinginfocat end return disp end local function rendersnak(propval, args, linked, lpre, lpost, pre, post, uabbr, filter) lpre = lpre or "" lpost = lpost or "" pre = pre or "" post = post or "" args.lang = args.lang or findLang().code local snak = propval.mainsnak or propval local dtype = snak.datatype local dv = snak.datavalue dv = dv and dv.value local val, mlt local namedas; namedas = propval.qualifiers and propval.qualifiers.P1932 and propval.qualifiers.P1932[1].datavalue and propval.qualifiers.P1932[1].datavalue.value or nil args.dtxt = namedas if propval.rank and not args.reqranks[propval.rank] then return nil elseif snak.snaktype == "somevalue" then val = namedas or i18n["Unknown"] elseif snak.snaktype == "novalue" then -- return nothing elseif dtype == "wikibase-item" then local qnumber = dv.id if linked then val = linkedItem(qnumber, args) else if namedas then val = pre .. namedas .. post else local label, islabel = labelOrId(qnumber, args.lang) val = pre .. label .. post end end elseif dtype == "time" then if args.hijri then val = hijriFormat(propval.qualifiers, args.df, args.lang) else val = dateFormat(dv.time, dv.precision, args.df, args.bc, args.pd, propval.qualifiers, args.lang, "", dv.calendarmodel) end elseif dtype == "commonsMedia" or dtype == "external-id" or dtype == "string" or dtype == "url" then if (lpre == "" or lpre == ":") and lpost == "" then val = pre .. dv .. post elseif dtype == "external-id" then val = "[" .. lpre .. dv .. lpost .. " " .. pre .. dv .. post .. "]" else val = "[[" .. lpre .. dv .. lpost .. "|" .. pre .. dv .. post .. "]]" end elseif dtype == "quantity" then local amount = tonumber(dv.amount) or i18n["NaN"] local unit = "" local unitqid = string.match(dv.unit, "(Q%d+)") if filter and unitqid ~= filter then return nil end if unitqid then local uname = mw.wikibase.getLabelByLang(unitqid, args.lang) or "" if uname ~= "" then unit = " " .. uname end end val = tostring(amount) .. unit elseif dtype == "globe-coordinate" then local lat, long, prec = dv.latitude, dv.longitude, dv.precision local show = (args.show or ""):lower() if show == "lat" then val = decimalPrecision(lat, prec) elseif show == "lon" then val = decimalPrecision(long, prec) elseif show == "longlat" then val = decimalPrecision(long, prec) .. ", " .. decimalPrecision(lat, prec) else local ns = lat < 0 and "S" or "N" local ew = long < 0 and "W" or "E" if lat < 0 then lat = -lat end if long < 0 then long = -long end val = decimalPrecision(lat, prec) .. "°" .. ns .. " " .. decimalPrecision(long, prec) .. "°" .. ew end elseif dtype == "monolingualtext" then val = pre .. dv.text .. post mlt = dv.language else val = "unknown data type: " .. dtype end return val, mlt end local function assembleoutput(out, args, entityID, propertyID) local sorted = parseParam(args.sorted, false) local noic = parseParam(args.noicon, false) local list = args.list or "" local separator = args.sep or "" separator = string.gsub(separator, '"', '') if separator == "" then local rtl_lang = {ar = true, fa = true, ur = true, ku = true, he = true} separator = rtl_lang[args.lang] and i18n["list separator-ar"] or i18n["list separator"] end local strout if #out > 0 then if sorted then table.sort(out) end if list == "" then strout = table.concat(out, separator) elseif list:lower() == "prose" then strout = mw.text.listToText(out) else strout = mw.getCurrentFrame():expandTemplate{title = list, args = out} end else strout = nil end return strout end local function propertyvalueandquals(objproperty, args, qualID) -- needs this style of declaration because it's re-entrant -- onlysourced is a boolean passed to return only values sourced to other than Wikipedia -- if nothing or an empty string is passed set it true local onlysrc = parseParam(args.onlysourced, false) -- linked is a a boolean that enables the link to a local page via sitelink -- if nothing or an empty string is passed set it true local linked = parseParam(args.linked, true) -- prefix is a string that may be nil, empty (""), or a string of characters -- this is prefixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local prefix = (args.prefix or ""):gsub('"', '') -- postfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local postfix = (args.postfix or ""):gsub('"', '') -- linkprefix is a string that may be nil, empty (""), or a string of characters -- this creates a link and is then prefixed to each value -- useful when when multiple values are returned and indirect links are needed -- any double-quotes " are stripped out, so that spaces may be passed local lprefix = (args.linkprefix or ""):gsub('"', '') -- linkpostfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value when linking is enabled with lprefix -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local lpostfix = (args.linkpostfix or ""):gsub('"', '') -- wdlinks is a boolean passed to enable links to Wikidata when no article exists -- if nothing or an empty string is passed set it false local wdl = parseParam(args.wdl, false) -- unitabbr is a boolean passed to enable unit abbreviations for common units -- if nothing or an empty string is passed set it false local uabbr = parseParam(args.unitabbr, false) -- qualsonly is a boolean passed to return just the qualifiers -- if nothing or an empty string is passed set it false local qualsonly = parseParam(args.qualsonly, false) -- maxvals is a string that may be nil, empty (""), or a number -- this determines how many items may be returned when multiple values are available -- setting it = 1 is useful where the returned string is used within another call, e.g. image local maxvals = tonumber(args.maxvals) or 0 -- pd boolean -- to disable/enable "sourcing cirumstances" or use adjectival form for the plain date local pd = args.pd or false args.pd = pd -- allow qualifiers to have a different date format; default to year unless qualsonly is set args.qdf = args.qdf or (not qualsonly and "y") local lang = args.lang or (args.langs and args.langs[1]) or findLang().code -- qualID is a string list of wanted qualifiers or "ALL" qualID = qualID or "" -- capitalise list of wanted qualifiers and substitute "DATES" qualID = qualID:upper():gsub("DATES", "P580, P582") local allflag = (qualID == "ALL") -- create table of wanted qualifiers as key local qwanted = {} -- create sequence of wanted qualifiers local qorder = {} for q in mw.text.gsplit(qualID, "%p") do -- split at punctuation and iterate local qtrim = mw.text.trim(q) if qtrim ~= "" then qwanted[mw.text.trim(q)] = true qorder[#qorder+1] = qtrim end end -- qsep is the output separator for rendering qualifier list local qsep = (args.qsep or ""):gsub('"', '') -- qargs are the arguments to supply to assembleoutput() local qargs = { ["osd"] = "false", ["linked"] = tostring(linked), ["prefix"] = args.qprefix, ["postfix"] = args.qpostfix, ["linkprefix"] = args.qlinkprefix, ["linkpostfix"] = args.qlinkpostfix, ["wdl"] = "false", ["unitabbr"] = tostring(uabbr), ["maxvals"] = 0, ["sorted"] = tostring(args.qsorted), ["noicon"] = "true", ["list"] = args.qlist, ["sep"] = qsep, -- ["langobj"] = args.langobj, ["lang"] = args.lang or (args.langs and args.lang[1]), ["df"] = args.qdf, ["sn"] = parseParam(args.qsn, false), } -- all proper values of a Wikidata property will be the same type as the first -- qualifiers don't have a mainsnak, properties do --#Modified line local datatype = objproperty[1].datatype or (objproperty[1].mainsnak and objproperty[1].mainsnak.datatype) -- out[] holds the a list of returned values for this property -- mlt[] holds the language code if the datatype is monolingual text local out = {} local mlt = {} for k, v in ipairs(objproperty) do local hasvalue = true if (onlysrc and not sourced(v)) then -- no value: it isn't sourced when onlysourced=true hasvalue = false else local val, lcode = rendersnak(v, args, linked, lprefix, lpostfix, prefix, postfix, uabbr) if not val then hasvalue = false -- rank doesn't match elseif qualsonly and qualID then -- suppress value returned: only qualifiers are requested else out[#out+1], mlt[#out+1] = val, lcode end end -- See if qualifiers are to be returned: local snak = v.mainsnak or v if hasvalue and v.qualifiers and qualID ~= "" and snak.snaktype~="novalue" then -- collect all wanted qualifier values returned in qlist, indexed by propertyID local qlist = {} local timestart, timeend = "", "" -- loop through qualifiers for k1, v1 in pairs(v.qualifiers) do if allflag or qwanted[k1] then if k1 == "P1326" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before") elseif k1 == "P1319" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after") elseif k1 == "P580" then timestart = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one start time as valid elseif k1 == "P582" then timeend = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one end time as valid else local q = assembleoutput(propertyvalueandquals(v1, qargs), qargs) -- we already deal with circa via 'sourcing circumstances' if the datatype was time -- circa may be either linked or unlinked *** internationalise later *** if datatype ~= "time" or q ~= "circa" and not (type(q) == "string" and q:find("circa]]")) then qlist[k1] = q end end end -- of test for wanted end -- of loop through qualifiers -- set date separator local t = timestart .. timeend -- *** internationalise date separators later *** local dsep = "&ndash;" if t:find("%s") or t:find("&nbsp;") then dsep = " &ndash; " end -- set the order for the list of qualifiers returned; start time and end time go last if next(qlist) then local qlistout = {} if allflag then for k2, v2 in pairs(qlist) do qlistout[#qlistout+1] = v2 end else for i2, v2 in ipairs(qorder) do qlistout[#qlistout+1] = qlist[v2] end end if t ~= "" then qlistout[#qlistout+1] = timestart .. dsep .. timeend end local qstr = assembleoutput(qlistout, qargs) if qualsonly then out[#out+1] = qstr else out[#out] = out[#out] .. " (" .. qstr .. ")" end elseif t ~= "" then if qualsonly then if timestart == "" then out[#out+1] = timeend elseif timeend == "" then out[#out+1] = timestart else out[#out+1] = timestart .. dsep .. timeend end else out[#out] = out[#out] .. " (" .. timestart .. dsep .. timeend .. ")" end end end -- of test for qualifiers wanted if maxvals > 0 and #out >= maxvals then break end end -- of for each value loop -- we need to pick one value to return if the datatype was "monolingualtext" -- if there's only one value, use that -- otherwise look through the fallback languages for a match if datatype == "monolingualtext" and #out >1 then lang = mw.text.split( lang, '-', true )[1] local fbtbl = mw.language.getFallbacksFor( lang ) table.insert( fbtbl, 1, lang ) local bestval = "" local found = false for idx1, lang1 in ipairs(fbtbl) do for idx2, lang2 in ipairs(mlt) do if (lang1 == lang2) and not found then bestval = out[idx2] found = true break end end -- loop through values of property end -- loop through fallback languages if found then -- replace output table with a table containing the best value out = { bestval } else -- more than one value and none of them on the list of fallback languages -- sod it, just give them the first one out = { out[1] } end end return out end local function mergeOptions(defaults, overrides) overrides = overrides or {} defaults = defaults or {} local result = {} for k, v in pairs(defaults) do result[k] = v end for k, v in pairs(overrides) do result[k] = v if k == 'rank' then result.reqranks = setRanks(v) end end return result end local function filterbyqualifier(statements,qual,value) local filtered_statements = {} for _, statement in ipairs(statements) do if statement.qualifiers and statement.qualifiers[qual] then if '*' == value then table.insert(filtered_statements, statement) else for _, q in ipairs(statement.qualifiers[qual]) do if q.datavalue and (rawValue(q.datavalue) == value) then table.insert(filtered_statements, statement) break end end end end end return filtered_statements end local function orderbyrank(statements) local pref_count = 0 local sorted_statements = {} for k,v in ipairs(statements) do if v.rank == 'preferred' then pref_count = pref_count + 1 table.insert(sorted_statements, pref_count, v) else table.insert(sorted_statements, v) end end return sorted_statements end ------------------------------------------------------------------------------- -- helper class functions ------------------------------------------------------------------------------- local function class() local c = {} c.__index = c function c:new(...) local o = setmetatable({}, c) if o.init then o:init(...) end return o end return c end ------------------------------------------------------------------------------- -- Statement Class Definition ------------------------------------------------------------------------------- local WdStatement = class() function WdStatement:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statement = self._statement if not statement then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals({statement}, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatement:getRawQual(qualID) local ret = {} local s = self._statement if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(ret,rawValue(q.datavalue)) else table.insert(ret,q.snaktype) end end end return ret end ------------------------------------------------------------------------------- -- Statements Class Definition ------------------------------------------------------------------------------- local WdStatements = class() function WdStatements:getStatmentsTable() return self._statements end function WdStatements:count() return #self._statements end function WdStatements:getFilters() return self.filtered_by end function WdStatements:filter(filter_t) local statements = self._statements if #statements == 0 then return self; end local ret = WdStatements:new() ret.parent = self.parent ret.filtered_by = {} for _,v in ipairs(self.filtered_by) do table.insert(ret.filtered_by, v) end local filtered_statements = {} for k,v in pairs(filter_t) do filtered_statements = filterbyqualifier(statements, k, v) table.insert(ret.filtered_by, {[k] = v}) if #filtered_statements == 0 then break; else statements = filtered_statements end end ret._statements = filtered_statements return ret end function WdStatements:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getQual(qualID, opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getRawQual(qualID) local ret = {} for _,s in pairs(self._statements) do local qual_t = {} if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(qual_t, rawValue(q.datavalue)) else table.insert(qual_t, q.snaktype) end end end table.insert(ret,qual_t) end return ret end function WdStatements:getRawValue() local ret = {} for _,v in pairs(self._statements) do if v.mainsnak.snaktype=="value" then table.insert(ret,rawValue(v.mainsnak.datavalue)) else table.insert(ret,v.mainsnak.snaktype) end end return ret end function WdStatements:get(index) local ret = WdStatement:new() ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = self._statements[index] ret.pid = ret.pid return ret end function WdStatements:getBestOne() local orderd_statements = orderbyrank(self._statements) local ret = WdStatement:new() --setmetatable({}, WdStatement) ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = orderd_statements[1] ret.pid = ret.pid return ret end ------------------------------------------------------------------------------- -- WdItem Class Definition ------------------------------------------------------------------------------- local WdItem = class() function WdItem:__tostring() return "WdItem: " .. (self.qid or "no QID") end function WdItem:UpdateOptions(newOpts) for k, v in pairs(newOpts or {}) do local key = options_aliases[k] self.options[key] = v -- Set default options if key == 'langs' and #v > 0 then self.options.langobj = findLang(self.options.langs[1]) self.options.lang = self.options.langobj.code if not self.options.langobj then self.options.langobj = findLang(self.options.lang) self.options.lang = self.options.langobj.code end end if key == 'rank' then self.options.reqranks = setRanks(self.options.rank) end end if not self.options.reqranks then self.options.reqranks = setRanks('preferred normal') end end function WdItem:init(qid, options) if qid == "" then qid = nil end if not qid then qid = mw.wikibase.getEntityIdForCurrentPage() end self.qid = qid self.snak = nil self.options = options or {} self:UpdateOptions(options) return self end function WdItem:newFromSnaks(snakTable, options) local self = WdItem:new() self.qid = nil self.snak = snakTable or {} self.options = options or {} self:UpdateOptions(options) return self end function WdItem:setOptions(newOpts) self:UpdateOptions(newOpts) end function WdItem:getStatements(pid, opts) local mergedOpts = mergeOptions(self.options, opts or {}) local statements local ret = WdStatements:new() ret.parent = self ret.filtered_by = {} ret._statements = {} ret.pid = pid if self.snak and self.snak[pid] then statements = self.snak[pid] elseif not self.qid or not mw.wikibase then statements = {} elseif mergedOpts.reqranks and mergedOpts.reqranks.best then statements = mw.wikibase.getBestStatements(self.qid, pid) or {} else statements = mw.wikibase.getAllStatements(self.qid, pid) or {} local filtered_statements = {} if not (mergedOpts.reqranks.deprecated == true and mergedOpts.reqranks.preferred == true and mergedOpts.reqranks.normal == true) then for _,s in pairs(statements) do if mergedOpts.reqranks[s.rank] then table.insert(filtered_statements,s) end end end statements = filtered_statements end if #statements > 0 and mergedOpts.qualifiedaspossible and mergedOpts.qualifiedaspossible ~= {} then local filtered_statements = {} for q,qv in pairs(mergedOpts.qualifiedaspossible) do filtered_statements = filterbyqualifier(statements, q, qv) if #filtered_statements > 0 then table.insert(ret.filtered_by, {[q] = qv}) statements = filtered_statements end end end if #statements > 0 and mergedOpts.qualified and mergedOpts.qualified ~= {} then for q,qv in pairs(mergedOpts.qualified) do statements = filterbyqualifier(statements, q, qv) table.insert(ret.filtered_by, {[q] = qv}) if #statements == 0 then break; end end end ret._statements = statements return ret end function WdItem:getValue(pid, opts) local mergedOpts = mergeOptions(self.options, opts) local statements = self:getStatements(pid, mergedOpts):getStatmentsTable() if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.qid, pid) end function WdItem:getValueFromSnaks(pid, opts) if not self.snak or not self.snak[pid] then return nil end local mergedOpts = mergeOptions(self.options, opts) local props = self.snak[pid] local out = propertyvalueandquals(props, mergedOpts) return assembleoutput(out, mergedOpts, nil, pid) end function WdItem:getPropertyIDsTable(pid, opts) local mergedOpts = mergeOptions(self.options, opts) mergedOpts.noicon = tostring(parseParam(mergedOpts.noicon or "", true)) local statements = self:getStatements(pid, opts) if not statements or #statements == 0 then return {} end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local out = {} for i, v in ipairs(statements) do local snak = v.mainsnak if (snak.datatype == "wikibase-item") and (v.rank and mergedOpts.reqranks[v.rank:sub(1, 1)]) and (snak.snaktype == "value") and (sourced(v) or not onlysrc) then out[#out+1] = snak.datavalue.value.id end if maxvals > 0 and #out >= maxvals then break end end return out end function WdItem:getPropertyIDs(pid, opts) local out = WdItem:getPropertyIDsTable(pid, opts) if #out == 0 then return nil end return assembleoutput(out, mergeOptions(self.options, opts), self.qid, pid) end function WdItem:getPropOfProp(prop1, prop2, opts) local mergedOpts = mergeOptions(self.options, opts) if not self.qid then return nil end local statements1 = self:getStatements(prop1, opts) if not statements1 or #statements1 == 0 then return nil end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = {} for k, v in ipairs(statements1) do if not onlysrc or sourced(v) then local snak = v.mainsnak if snak.datatype == "wikibase-item" and snak.snaktype == "value" then local qid2 = snak.datavalue.value.id local item2 = WdItem.new(qid2, mergedOpts) local statements2 = item2:getStatements(prop2, opts) if statements2 and statements2[1] then local out2 = propertyvalueandquals(statements2, mergedOpts, qualID) out[#out+1] = assembleoutput(out2, mergedOpts, qid2, prop2) end end end if maxvals > 0 and #out >= maxvals then break end end return assembleoutput(out, mergedOpts, self.qid, prop1) end function WdItem:getLangOfProp(pid) if not pid or not self.qid then return {} end local out = {} local props = mw.wikibase.getAllStatements(self.qid, pid) for _, v in ipairs(props) do if v.mainsnak.datatype == "monolingualtext" and v.mainsnak.datavalue then out[#out + 1] = v.mainsnak.datavalue.value.language end end return out end function WdItem:followQid(props, all) all = parseParam(all, false) props = (props or ""):upper() if not self.qid then return nil end if props == "" then return self.qid end local out = {} for p in mw.text.gsplit(props, "%p") do p = mw.text.trim(p) for i, v in ipairs(mw.wikibase.getBestStatements(self.qid, p)) do local linkedid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id if linkedid then if all then out[#out+1] = linkedid else return linkedid end end end end if #out > 0 then return table.concat(out, " ") else return self.qid end end ------------------------------------------------------------------------------- -- Public API - WdItem Constructors ------------------------------------------------------------------------------- p.WdItem = WdItem function p.newItem(qid, opts) return WdItem.new(qid, opts) end function p.currentItem(opts) return WdItem.new(nil, opts) end function p.newSnakItem(snakTable, opts) return WdItem.newFromSnaks(snakTable, opts) end return p 01k9ttsokmtoap4ife40p4tz7gt2whz 1097236 1097235 2026-07-22T13:58:26Z حبيشان 31560 1097236 Scribunto text/plain -- Module: WdItem -- Object-oriented Wikidata access module for Lua -- Refactored from WikidataIB for direct Lua usage require("strict") local p = {} -- i18n configuration local i18n = { ["errors"] = { ["property-not-found"] = "الخاصية غير موجودة.", ["entity-not-found"] = "الكيان على ويكي بيانات غير موجود.", ["unknown-claim-type"] = "نوع الادعاء غير معروف.", ["local-article-not-found"] = "المعرف متاح على ويكي بيانات، ولكن المقال غير متاح على ويكيبيديا", }, ["months"] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, ["Unknown"] = "Unknown", ["NaN"] = "Not a number", ["missinginfocat"] = "[[تصنيف:Articles with missing Wikidata information]]", ["list separator"] = ", ", ["list separator-ar"] = "، ", } -- Date precision constants local dp = { [6] = "millennium", [7] = "century", [8] = "decade", [9] = "year", [10] = "month", [11] = "day", } local options_aliases = { ["osd"] = "onlysourced", ["wdlinks"] = "wdl", ["uabbr"] = "unitabbr", ["qo"] = "qualsonly", ["lp"] = "linkprefix", ["lprefix"] = "linkprefix", ["qlp"] = "qlinkprefix", ["sn"] = "shortname", ["uselabel"] = "uselbl", ["plaindate"] = "pd", ["qualifierdateformat"] = "qdf", ["df"] = "qdf", ["qshortname"] = "qsn" } setmetatable(options_aliases, { __index = function(t, k) return k end }) ------------------------------------------------------------------------------- -- Internal helper functions ------------------------------------------------------------------------------- local function findLang(langcode) local langobj langcode = mw.text.trim(langcode or "") if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langcode = mw.getCurrentFrame():callParserFunction('int', {'lang'}) if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langobj = mw.language.getContentLanguage() end end return langobj end local function parseParam(param, default) if param == nil then return default end return param end local function setRanks(rank) rank = (rank or ""):lower() local ranks = {} for w in string.gmatch(rank, "%a+") do if w == "best" or w == "preferred" or w == "normal" or w == "deprecated" then ranks[w] = true end end if ranks.best or not next(ranks) then ranks.preferred = true ranks.normal = true ranks.deprecated = false end return ranks end local function labelOrId(id, lang) if lang == "default" then lang = findLang().code end local label if lang then label = mw.wikibase.getLabelByLang(id, lang) end if not label then local trylang = {"ar","en","fr", "mul"} local triedlang = lang for _,lang in pairs(trylang) do if triedlang ~= lang then label = mw.wikibase.getLabelByLang(id, lang) if label ~= "" then break end end end end if label then return mw.text.nowiki(label), true else return id, false end end local function roundto(x, sf) if x == 0 then return 0 end local s = 1 if x < 0 then x = -x s = -1 end if sf < 1 then sf = 1 end local p = 10 ^ (math.floor(math.log10(x)) - sf + 1) x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end return x end local function decimalPrecision(x, p) local s = 1 if x < 0 then x = -x s = -1 end if not tonumber(p) then p = 1e-4 elseif p > 1 then p = 1 elseif p < 1e-6 then p = 1e-6 else p = 10 ^ math.floor(math.log10(p)) end x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end if math.abs(x) < 1e-4 then x = string.format("%f", x) end return x end local function decimalToDMS(x, p) if not tonumber(p) then p = 1e-4 end local d = math.floor(x) local ms = (x - d) * 60 if p > 0.5 then if ms > 30 then d = d + 1 end ms = 0 end local m = math.floor(ms) local s = (ms - m) * 60 if p > 0.008 then if s > 30 then m = m +1 end s = 0 elseif p > 0.00014 then s = math.floor(s + 0.5) elseif p > 0.000014 then s = math.floor(10 * s + 0.5) / 10 elseif p > 0.0000014 then s = math.floor(100 * s + 0.5) / 100 else s = math.floor(1000 * s + 0.5) / 1000 end return d, m, s end local function rawValue(dataValue) if dataValue.type == "string" then return dataValue.value elseif dataValue.type == "wikibase-entityid" then return dataValue.value and dataValue.value.id elseif dataValue.type == "monolingualtext" then return dataValue.value.text elseif dataValue.type == "quantity" then return tonumber(dataValue.value.amount) elseif dataValue.type == 'time' then return dataValue.value.time elseif dataValue.type == "globecoordinate" then return dataValue.value.latitude .. '/' .. dataValue.value.longitude end end local function compareValue(dataValue, strValue) return rawValue(dataValue) == strValue end local function dateFormat(timestamp, dprec, df, bcf, pd, qualifiers, lang, adj, model) df = (df or ""):lower() if df == "ymd" then if timestamp:sub(1,1) == "+" then return timestamp:sub(2,11) else local yr = tonumber(timestamp:sub(2,5)) - 1 yr = ("000" .. yr):sub(-4) if yr ~= "0000" then yr = "-" .. yr end return yr .. timestamp:sub(6,11) end end timestamp = timestamp:gsub("%-00%-00T", "-01-01T") dprec = dprec or 11 if df == "y" and dprec > 9 then dprec = 9 end dprec = dprec>11 and 11 or dprec dprec = dprec<6 and 6 or dprec bcf = (bcf or ""):upper() pd = (pd or ""):sub(1,1):lower() if pd == "" or pd == "n" or pd == "f" or pd == "0" then pd = false end lang = lang or findLang().code adj = adj or "" local bc = timestamp:sub(1, 1)=="-" and "BC" or "" local year, month, day = timestamp:match("[+-](%d*)-(%d*)-(%d*)T") local iso = tonumber(year) if dprec == 6 then iso = math.floor( (iso - 1) / 1000 ) + 1 end if dprec == 7 then iso = math.floor( (iso - 1) / 100 ) + 1 end if dprec == 8 then iso = math.floor( iso / 10 ) .. "0" end if dprec == 10 then iso = year .. "-" .. month end if dprec == 11 then iso = year .. "-" .. month .. "-" .. day end local sc = not pd and qualifiers and qualifiers.P1480 if sc then for k1, v1 in pairs(sc) do if v1.datavalue and v1.datavalue.value.id == "Q5727902" then adj = "circa" break end end end local calendarmodel = "" if tonumber(year) > 1582 and dprec > 8 and not pd and model == "http://www.wikidata.org/entity/Q1985786" then calendarmodel = "julian" end -- Simplified date formatting (complex date module not available) local fdate = tostring(iso) if bc ~= "" then fdate = fdate .. " " .. (bcf == "BC" and "BC" or "BCE") end if adj == "circa" then fdate = "c. " .. fdate end return fdate end local function hijriFormat(qualifiers, dateformat, lang) if not qualifiers.P4241 then return; end local year, month, day local val local qhmonths = {["Q1952053"]=1,["Q489557"]=2, ["Q474167"] = 3, ["Q273815"] = 4, ["Q852002"] = 5, ["Q822218"] = 6, ["Q194210"] = 7, ["Q220914"] = 8, ["Q8867089"]=9, ["Q685440"]=10,["Q150853"]=11,["Q186022"]=12 } local hmonths = {"محرم","صفر","ربيع الأول","ربيع الآخر","جمادى الأولى","جمادى الآخرة","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة"} local hmonths_inv = {["محرم"] = 1, ["صفر"]=2, ["ربيع الأول"]=3, ["ربيع الآخر"]=4, ["جمادى الأولى"]=5, ["جمادى الآخرة"]=6, ["رجب"]=7, ["شعبان"]=8, ["رمضان"]=9, ["شوال"]=10, ["ذو القعدة"]=11, ["ذو الحجة"]=12} for _, item in ipairs(qualifiers.P4241) do local timeQ = item.datavalue and item.datavalue.value and item.datavalue.value.id local hastime = false if timeQ then local timeQt = mw.wikibase.getBestStatements(timeQ, "P361") for _,timeQsnak in pairs(timeQt) do local timeType = timeQsnak.mainsnak and timeQsnak.mainsnak.datavalue and timeQsnak.mainsnak.datavalue.value and timeQsnak.mainsnak.datavalue.value.id if timeType == "Q28892" then local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then year = mw.ustring.match(timeLableAr, "^(%d+) *هـ$") end if not year then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then year = mw.ustring.match(timeLableAr, "^(%d+) *AH$") end end hastime=true elseif qhmonths[timeType] then month = qhmonths[timeType] if month>0 and month<13 then month = hmonths[month] end local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end if not day then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end end hastime=true end end if not hastime then timeQt = mw.wikibase.getBestStatements(timeQ, "P31") if "Q125390868" == (timeQt[1].mainsnak and timeQt[1].mainsnak.datavalue and timeQt[1].mainsnak.datavalue.value and timeQt[1].mainsnak.datavalue.value.id ) then val = mw.wikibase.getLabelByLang(timeQ, "ar") month, year = mw.ustring.match(val, "^(%a[%a ]+%a) *(%d+) *هـ?$") end end end end if year then if dateformat == "y" then return year; elseif day and month then return day .. ' ' .. month .. ' ' .. year; elseif month then return month .. ' ' .. year; end end return nil; end local function sourced(claim) if claim.references then for kr, vr in pairs(claim.references) do local ref = mw.wikibase.renderSnaks(vr.snaks) if not ref:find("Wiki") then return true end end end end local function linkedItem(id, args) local lprefix = (args.linkprefix or ""):gsub('"', '') local lpostfix = (args.lpostfix or ""):gsub('"', '') local prefix = (args.prefix or ""):gsub('"', '') local postfix = (args.postfix or ""):gsub('"', '') local dtxt = args.dtxt local uselbl = parseParam( args.uselbl, true) local disp local sitelink = mw.wikibase.getSitelink(id, args.linksproject) local label, islabel if dtxt then label, islabel = dtxt, true else label, islabel = labelOrId(id, args.lang) end if sitelink then if not uselbl then local pos = sitelink:find(":") or 0 local slink = sitelink if pos > 0 then local pfx = sitelink:sub(1,pos-1) if mw.site.namespaces[pfx] then slink = sitelink:sub(pos+1) end end slink = slink:gsub("%s%(.+%)$", ""):gsub(",.+$", "") if label:find("^%u") then label = slink:gsub("^(%l)", string.upper) else label = slink:gsub("^(%u)", string.lower) end end disp = "[[" .. lprefix .. sitelink .. lpostfix .. "|" .. prefix .. label .. postfix .. "]]" elseif islabel then disp = prefix .. label .. postfix else disp = prefix .. label .. postfix .. i18n.missinginfocat end return disp end local function rendersnak(propval, args, linked, lpre, lpost, pre, post, uabbr, filter) lpre = lpre or "" lpost = lpost or "" pre = pre or "" post = post or "" args.lang = args.lang or findLang().code local snak = propval.mainsnak or propval local dtype = snak.datatype local dv = snak.datavalue dv = dv and dv.value local val, mlt local namedas; namedas = propval.qualifiers and propval.qualifiers.P1932 and propval.qualifiers.P1932[1].datavalue and propval.qualifiers.P1932[1].datavalue.value or nil args.dtxt = namedas if propval.rank and not args.reqranks[propval.rank] then return nil elseif snak.snaktype == "somevalue" then val = namedas or i18n["Unknown"] elseif snak.snaktype == "novalue" then -- return nothing elseif dtype == "wikibase-item" then local qnumber = dv.id if linked then val = linkedItem(qnumber, args) else if namedas then val = pre .. namedas .. post else local label, islabel = labelOrId(qnumber, args.lang) val = pre .. label .. post end end elseif dtype == "time" then if args.hijri then val = hijriFormat(propval.qualifiers, args.df, args.lang) else val = dateFormat(dv.time, dv.precision, args.df, args.bc, args.pd, propval.qualifiers, args.lang, "", dv.calendarmodel) end elseif dtype == "commonsMedia" or dtype == "external-id" or dtype == "string" or dtype == "url" then if (lpre == "" or lpre == ":") and lpost == "" then val = pre .. dv .. post elseif dtype == "external-id" then val = "[" .. lpre .. dv .. lpost .. " " .. pre .. dv .. post .. "]" else val = "[[" .. lpre .. dv .. lpost .. "|" .. pre .. dv .. post .. "]]" end elseif dtype == "quantity" then local amount = tonumber(dv.amount) or i18n["NaN"] local unit = "" local unitqid = string.match(dv.unit, "(Q%d+)") if filter and unitqid ~= filter then return nil end if unitqid then local uname = mw.wikibase.getLabelByLang(unitqid, args.lang) or "" if uname ~= "" then unit = " " .. uname end end val = tostring(amount) .. unit elseif dtype == "globe-coordinate" then local lat, long, prec = dv.latitude, dv.longitude, dv.precision local show = (args.show or ""):lower() if show == "lat" then val = decimalPrecision(lat, prec) elseif show == "lon" then val = decimalPrecision(long, prec) elseif show == "longlat" then val = decimalPrecision(long, prec) .. ", " .. decimalPrecision(lat, prec) else local ns = lat < 0 and "S" or "N" local ew = long < 0 and "W" or "E" if lat < 0 then lat = -lat end if long < 0 then long = -long end val = decimalPrecision(lat, prec) .. "°" .. ns .. " " .. decimalPrecision(long, prec) .. "°" .. ew end elseif dtype == "monolingualtext" then val = pre .. dv.text .. post mlt = dv.language else val = "unknown data type: " .. dtype end return val, mlt end local function assembleoutput(out, args, entityID, propertyID) local sorted = parseParam(args.sorted, false) local noic = parseParam(args.noicon, false) local list = args.list or "" local separator = args.sep or "" separator = string.gsub(separator, '"', '') if separator == "" then local rtl_lang = {ar = true, fa = true, ur = true, ku = true, he = true} separator = rtl_lang[args.lang] and i18n["list separator-ar"] or i18n["list separator"] end local strout if #out > 0 then if sorted then table.sort(out) end if list == "" then strout = table.concat(out, separator) elseif list:lower() == "prose" then strout = mw.text.listToText(out) else strout = mw.getCurrentFrame():expandTemplate{title = list, args = out} end else strout = nil end return strout end local function propertyvalueandquals(objproperty, args, qualID) -- needs this style of declaration because it's re-entrant -- onlysourced is a boolean passed to return only values sourced to other than Wikipedia -- if nothing or an empty string is passed set it true local onlysrc = parseParam(args.onlysourced, false) -- linked is a a boolean that enables the link to a local page via sitelink -- if nothing or an empty string is passed set it true local linked = parseParam(args.linked, true) -- prefix is a string that may be nil, empty (""), or a string of characters -- this is prefixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local prefix = (args.prefix or ""):gsub('"', '') -- postfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local postfix = (args.postfix or ""):gsub('"', '') -- linkprefix is a string that may be nil, empty (""), or a string of characters -- this creates a link and is then prefixed to each value -- useful when when multiple values are returned and indirect links are needed -- any double-quotes " are stripped out, so that spaces may be passed local lprefix = (args.linkprefix or ""):gsub('"', '') -- linkpostfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value when linking is enabled with lprefix -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local lpostfix = (args.linkpostfix or ""):gsub('"', '') -- wdlinks is a boolean passed to enable links to Wikidata when no article exists -- if nothing or an empty string is passed set it false local wdl = parseParam(args.wdl, false) -- unitabbr is a boolean passed to enable unit abbreviations for common units -- if nothing or an empty string is passed set it false local uabbr = parseParam(args.unitabbr, false) -- qualsonly is a boolean passed to return just the qualifiers -- if nothing or an empty string is passed set it false local qualsonly = parseParam(args.qualsonly, false) -- maxvals is a string that may be nil, empty (""), or a number -- this determines how many items may be returned when multiple values are available -- setting it = 1 is useful where the returned string is used within another call, e.g. image local maxvals = tonumber(args.maxvals) or 0 -- pd boolean -- to disable/enable "sourcing cirumstances" or use adjectival form for the plain date local pd = args.pd or false args.pd = pd -- allow qualifiers to have a different date format; default to year unless qualsonly is set args.qdf = args.qdf or (not qualsonly and "y") local lang = args.lang or (args.langs and args.langs[1]) or findLang().code -- qualID is a string list of wanted qualifiers or "ALL" qualID = qualID or "" -- capitalise list of wanted qualifiers and substitute "DATES" qualID = qualID:upper():gsub("DATES", "P580, P582") local allflag = (qualID == "ALL") -- create table of wanted qualifiers as key local qwanted = {} -- create sequence of wanted qualifiers local qorder = {} for q in mw.text.gsplit(qualID, "%p") do -- split at punctuation and iterate local qtrim = mw.text.trim(q) if qtrim ~= "" then qwanted[mw.text.trim(q)] = true qorder[#qorder+1] = qtrim end end -- qsep is the output separator for rendering qualifier list local qsep = (args.qsep or ""):gsub('"', '') -- qargs are the arguments to supply to assembleoutput() local qargs = { ["osd"] = "false", ["linked"] = tostring(linked), ["prefix"] = args.qprefix, ["postfix"] = args.qpostfix, ["linkprefix"] = args.qlinkprefix, ["linkpostfix"] = args.qlinkpostfix, ["wdl"] = "false", ["unitabbr"] = tostring(uabbr), ["maxvals"] = 0, ["sorted"] = tostring(args.qsorted), ["noicon"] = "true", ["list"] = args.qlist, ["sep"] = qsep, -- ["langobj"] = args.langobj, ["lang"] = args.lang or (args.langs and args.lang[1]), ["df"] = args.qdf, ["sn"] = parseParam(args.qsn, false), } -- all proper values of a Wikidata property will be the same type as the first -- qualifiers don't have a mainsnak, properties do --#Modified line local datatype = objproperty[1].datatype or (objproperty[1].mainsnak and objproperty[1].mainsnak.datatype) -- out[] holds the a list of returned values for this property -- mlt[] holds the language code if the datatype is monolingual text local out = {} local mlt = {} for k, v in ipairs(objproperty) do local hasvalue = true if (onlysrc and not sourced(v)) then -- no value: it isn't sourced when onlysourced=true hasvalue = false else local val, lcode = rendersnak(v, args, linked, lprefix, lpostfix, prefix, postfix, uabbr) if not val then hasvalue = false -- rank doesn't match elseif qualsonly and qualID then -- suppress value returned: only qualifiers are requested else out[#out+1], mlt[#out+1] = val, lcode end end -- See if qualifiers are to be returned: local snak = v.mainsnak or v if hasvalue and v.qualifiers and qualID ~= "" and snak.snaktype~="novalue" then -- collect all wanted qualifier values returned in qlist, indexed by propertyID local qlist = {} local timestart, timeend = "", "" -- loop through qualifiers for k1, v1 in pairs(v.qualifiers) do if allflag or qwanted[k1] then if k1 == "P1326" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before") elseif k1 == "P1319" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after") elseif k1 == "P580" then timestart = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one start time as valid elseif k1 == "P582" then timeend = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one end time as valid else local q = assembleoutput(propertyvalueandquals(v1, qargs), qargs) -- we already deal with circa via 'sourcing circumstances' if the datatype was time -- circa may be either linked or unlinked *** internationalise later *** if datatype ~= "time" or q ~= "circa" and not (type(q) == "string" and q:find("circa]]")) then qlist[k1] = q end end end -- of test for wanted end -- of loop through qualifiers -- set date separator local t = timestart .. timeend -- *** internationalise date separators later *** local dsep = "&ndash;" if t:find("%s") or t:find("&nbsp;") then dsep = " &ndash; " end -- set the order for the list of qualifiers returned; start time and end time go last if next(qlist) then local qlistout = {} if allflag then for k2, v2 in pairs(qlist) do qlistout[#qlistout+1] = v2 end else for i2, v2 in ipairs(qorder) do qlistout[#qlistout+1] = qlist[v2] end end if t ~= "" then qlistout[#qlistout+1] = timestart .. dsep .. timeend end local qstr = assembleoutput(qlistout, qargs) if qualsonly then out[#out+1] = qstr else out[#out] = out[#out] .. " (" .. qstr .. ")" end elseif t ~= "" then if qualsonly then if timestart == "" then out[#out+1] = timeend elseif timeend == "" then out[#out+1] = timestart else out[#out+1] = timestart .. dsep .. timeend end else out[#out] = out[#out] .. " (" .. timestart .. dsep .. timeend .. ")" end end end -- of test for qualifiers wanted if maxvals > 0 and #out >= maxvals then break end end -- of for each value loop -- we need to pick one value to return if the datatype was "monolingualtext" -- if there's only one value, use that -- otherwise look through the fallback languages for a match if datatype == "monolingualtext" and #out >1 then lang = mw.text.split( lang, '-', true )[1] local fbtbl = mw.language.getFallbacksFor( lang ) table.insert( fbtbl, 1, lang ) local bestval = "" local found = false for idx1, lang1 in ipairs(fbtbl) do for idx2, lang2 in ipairs(mlt) do if (lang1 == lang2) and not found then bestval = out[idx2] found = true break end end -- loop through values of property end -- loop through fallback languages if found then -- replace output table with a table containing the best value out = { bestval } else -- more than one value and none of them on the list of fallback languages -- sod it, just give them the first one out = { out[1] } end end return out end local function mergeOptions(defaults, overrides) overrides = overrides or {} defaults = defaults or {} local result = {} for k, v in pairs(defaults) do result[k] = v end for k, v in pairs(overrides) do result[k] = v if k == 'rank' then result.reqranks = setRanks(v) end end return result end local function filterbyqualifier(statements,qual,value) local filtered_statements = {} for _, statement in ipairs(statements) do if statement.qualifiers and statement.qualifiers[qual] then if '*' == value then table.insert(filtered_statements, statement) else for _, q in ipairs(statement.qualifiers[qual]) do if q.datavalue and (rawValue(q.datavalue) == value) then table.insert(filtered_statements, statement) break end end end end end return filtered_statements end local function orderbyrank(statements) local pref_count = 0 local sorted_statements = {} for k,v in ipairs(statements) do if v.rank == 'preferred' then pref_count = pref_count + 1 table.insert(sorted_statements, pref_count, v) else table.insert(sorted_statements, v) end end return sorted_statements end ------------------------------------------------------------------------------- -- helper class functions ------------------------------------------------------------------------------- local function class() local c = {} c.__index = c function c:new(...) local o = setmetatable({}, c) if o.init then o:init(...) end return o end return c end ------------------------------------------------------------------------------- -- Statement Class Definition ------------------------------------------------------------------------------- local WdStatement = class() function WdStatement:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statement = self._statement if not statement then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals({statement}, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatement:getRawQual(qualID) local ret = {} local s = self._statement if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(ret,rawValue(q.datavalue)) else table.insert(ret,q.snaktype) end end end return ret end ------------------------------------------------------------------------------- -- Statements Class Definition ------------------------------------------------------------------------------- local WdStatements = class() function WdStatements:getStatmentsTable() return self._statements end function WdStatements:count() return #self._statements end function WdStatements:getFilters() return self.filtered_by end function WdStatements:filter(filter_t) local statements = self._statements if #statements == 0 then return self; end local ret = WdStatements:new() ret.parent = self.parent ret.filtered_by = {} for _,v in ipairs(self.filtered_by) do table.insert(ret.filtered_by, v) end local filtered_statements = {} for k,v in pairs(filter_t) do filtered_statements = filterbyqualifier(statements, k, v) table.insert(ret.filtered_by, {[k] = v}) if #filtered_statements == 0 then break; else statements = filtered_statements end end ret._statements = filtered_statements return ret end function WdStatements:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getQual(qualID, opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getRawQual(qualID) local ret = {} for _,s in pairs(self._statements) do local qual_t = {} if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(qual_t, rawValue(q.datavalue)) else table.insert(qual_t, q.snaktype) end end end table.insert(ret,qual_t) end return ret end function WdStatements:getRawValue() local ret = {} for _,v in pairs(self._statements) do if v.mainsnak.snaktype=="value" then table.insert(ret,rawValue(v.mainsnak.datavalue)) else table.insert(ret,v.mainsnak.snaktype) end end return ret end function WdStatements:get(index) local ret = WdStatement:new() ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = self._statements[index] ret.pid = ret.pid return ret end function WdStatements:getBestOne() local orderd_statements = orderbyrank(self._statements) local ret = WdStatement:new() --setmetatable({}, WdStatement) ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = orderd_statements[1] ret.pid = ret.pid return ret end ------------------------------------------------------------------------------- -- WdItem Class Definition ------------------------------------------------------------------------------- local WdItem = class() function WdItem:__tostring() return "WdItem: " .. (self.qid or "no QID") end function WdItem:UpdateOptions(newOpts) for k, v in pairs(newOpts or {}) do local key = options_aliases[k] self.options[key] = v -- Set default options if key == 'langs' and #v > 0 then self.options.langobj = findLang(self.options.langs[1]) self.options.lang = self.options.langobj.code if not self.options.langobj then self.options.langobj = findLang(self.options.lang) self.options.lang = self.options.langobj.code end end if key == 'rank' then self.options.reqranks = setRanks(self.options.rank) end end if not self.options.reqranks then self.options.reqranks = setRanks('preferred normal') end end function WdItem:init(qid, options) if qid == "" then qid = nil end if not qid then qid = mw.wikibase.getEntityIdForCurrentPage() end self.qid = qid self.snak = nil self.options = options or {} self:UpdateOptions(options) return self end function WdItem:newFromSnaks(snakTable, options) local self = WdItem:new() self.qid = nil self.snak = snakTable or {} self.options = options or {} self:UpdateOptions(options) return self end function WdItem:setOptions(newOpts) self:UpdateOptions(newOpts) end function WdItem:getStatements(pid, opts) local mergedOpts = mergeOptions(self.options, opts or {}) local statements local ret = WdStatements:new() ret.parent = self ret.filtered_by = {} ret._statements = {} ret.pid = pid if self.snak and self.snak[pid] then statements = self.snak[pid] elseif not self.qid or not mw.wikibase then statements = {} elseif mergedOpts.reqranks and mergedOpts.reqranks.best then statements = mw.wikibase.getBestStatements(self.qid, pid) or {} else statements = mw.wikibase.getAllStatements(self.qid, pid) or {} local filtered_statements = {} if not (mergedOpts.reqranks.deprecated == true and mergedOpts.reqranks.preferred == true and mergedOpts.reqranks.normal == true) then for _,s in pairs(statements) do if mergedOpts.reqranks[s.rank] then table.insert(filtered_statements,s) end end end statements = filtered_statements end if #statements > 0 and mergedOpts.qualifiedaspossible and mergedOpts.qualifiedaspossible ~= {} then local filtered_statements = {} for q,qv in pairs(mergedOpts.qualifiedaspossible) do filtered_statements = filterbyqualifier(statements, q, qv) if #filtered_statements > 0 then table.insert(ret.filtered_by, {[q] = qv}) statements = filtered_statements end end end if #statements > 0 and mergedOpts.qualified and mergedOpts.qualified ~= {} then for q,qv in pairs(mergedOpts.qualified) do statements = filterbyqualifier(statements, q, qv) table.insert(ret.filtered_by, {[q] = qv}) if #statements == 0 then break; end end end ret._statements = statements return ret end function WdItem:getValue(pid, opts) local mergedOpts = mergeOptions(self.options, opts) local statements = self:getStatements(pid, mergedOpts):getStatmentsTable() if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.qid, pid) end function WdItem:getValueFromSnaks(pid, opts) if not self.snak or not self.snak[pid] then return nil end local mergedOpts = mergeOptions(self.options, opts) local props = self.snak[pid] local out = propertyvalueandquals(props, mergedOpts) return assembleoutput(out, mergedOpts, nil, pid) end function WdItem:getPropertyIDsTable(pid, opts) local mergedOpts = mergeOptions(self.options, opts) mergedOpts.noicon = tostring(parseParam(mergedOpts.noicon or "", true)) local statements = self:getStatements(pid, opts) if not statements or #statements == 0 then return {} end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local out = {} for i, v in ipairs(statements) do local snak = v.mainsnak if (snak.datatype == "wikibase-item") and (v.rank and mergedOpts.reqranks[v.rank:sub(1, 1)]) and (snak.snaktype == "value") and (sourced(v) or not onlysrc) then out[#out+1] = snak.datavalue.value.id end if maxvals > 0 and #out >= maxvals then break end end return out end function WdItem:getPropertyIDs(pid, opts) local out = WdItem:getPropertyIDsTable(pid, opts) if #out == 0 then return nil end return assembleoutput(out, mergeOptions(self.options, opts), self.qid, pid) end function WdItem:getPropOfProp(prop1, prop2, opts) local mergedOpts = mergeOptions(self.options, opts) if not self.qid then return nil end local statements1 = self:getStatements(prop1, opts) if not statements1 or #statements1 == 0 then return nil end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = {} for k, v in ipairs(statements1) do if not onlysrc or sourced(v) then local snak = v.mainsnak if snak.datatype == "wikibase-item" and snak.snaktype == "value" then local qid2 = snak.datavalue.value.id local item2 = WdItem.new(qid2, mergedOpts) local statements2 = item2:getStatements(prop2, opts) if statements2 and statements2[1] then local out2 = propertyvalueandquals(statements2, mergedOpts, qualID) out[#out+1] = assembleoutput(out2, mergedOpts, qid2, prop2) end end end if maxvals > 0 and #out >= maxvals then break end end return assembleoutput(out, mergedOpts, self.qid, prop1) end function WdItem:getLangOfProp(pid) if not pid or not self.qid then return {} end local out = {} local props = mw.wikibase.getAllStatements(self.qid, pid) for _, v in ipairs(props) do if v.mainsnak.datatype == "monolingualtext" and v.mainsnak.datavalue then out[#out + 1] = v.mainsnak.datavalue.value.language end end return out end function WdItem:followQid(props, all) all = parseParam(all, false) props = (props or ""):upper() if not self.qid then return nil end if props == "" then return self.qid end local out = {} for p in mw.text.gsplit(props, "%p") do p = mw.text.trim(p) for i, v in ipairs(mw.wikibase.getBestStatements(self.qid, p)) do local linkedid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id if linkedid then if all then out[#out+1] = linkedid else return linkedid end end end end if #out > 0 then return table.concat(out, " ") else return self.qid end end ------------------------------------------------------------------------------- -- Public API - WdItem Constructors ------------------------------------------------------------------------------- p.WdItem = WdItem function p.newItem(qid, opts) return WdItem:new(qid, opts) end function p.newSnakItem(snakTable, opts) return WdItem:newFromSnaks(snakTable, opts) end return p gb0qmwyjbhd1n1y3cv1383lko6t8il8 1097237 1097236 2026-07-22T14:39:23Z حبيشان 31560 1097237 Scribunto text/plain -- Module: WdItem -- Object-oriented Wikidata access module for Lua -- Refactored from WikidataIB for direct Lua usage require("strict") local p = {} -- i18n configuration local i18n = { ["errors"] = { ["property-not-found"] = "الخاصية غير موجودة.", ["entity-not-found"] = "الكيان على ويكي بيانات غير موجود.", ["unknown-claim-type"] = "نوع الادعاء غير معروف.", ["local-article-not-found"] = "المعرف متاح على ويكي بيانات، ولكن المقال غير متاح على ويكيبيديا", }, ["months"] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, ["Unknown"] = "Unknown", ["NaN"] = "Not a number", ["missinginfocat"] = "[[تصنيف:Articles with missing Wikidata information]]", ["list separator"] = ", ", ["list separator-ar"] = "، ", } -- Date precision constants local dp = { [6] = "millennium", [7] = "century", [8] = "decade", [9] = "year", [10] = "month", [11] = "day", } local options_aliases = { ["osd"] = "onlysourced", ["wdlinks"] = "wdl", ["uabbr"] = "unitabbr", ["qo"] = "qualsonly", ["lp"] = "linkprefix", ["lprefix"] = "linkprefix", ["qlp"] = "qlinkprefix", ["sn"] = "shortname", ["uselabel"] = "uselbl", ["plaindate"] = "pd", ["qualifierdateformat"] = "qdf", ["df"] = "qdf", ["qshortname"] = "qsn" } setmetatable(options_aliases, { __index = function(t, k) return k end }) ------------------------------------------------------------------------------- -- Internal helper functions ------------------------------------------------------------------------------- local function findLang(langcode) local langobj langcode = mw.text.trim(langcode or "") if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langcode = mw.getCurrentFrame():callParserFunction('int', {'lang'}) if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langobj = mw.language.getContentLanguage() end end return langobj end local function parseParam(param, default) if param == nil then return default end return param end local function setRanks(rank) rank = (rank or ""):lower() local ranks = {} for w in string.gmatch(rank, "%a+") do if w == "best" or w == "preferred" or w == "normal" or w == "deprecated" then ranks[w] = true end end if ranks.best or not next(ranks) then ranks.preferred = true ranks.normal = true ranks.deprecated = false end return ranks end local function labelOrId(id, lang) if lang == "default" then lang = findLang().code end local label if lang then label = mw.wikibase.getLabelByLang(id, lang) end if not label then local trylang = {"ar","en","fr", "mul"} local triedlang = lang for _,lang in pairs(trylang) do if triedlang ~= lang then label = mw.wikibase.getLabelByLang(id, lang) if label ~= "" then break end end end end if label then return mw.text.nowiki(label), true else return id, false end end local function roundto(x, sf) if x == 0 then return 0 end local s = 1 if x < 0 then x = -x s = -1 end if sf < 1 then sf = 1 end local p = 10 ^ (math.floor(math.log10(x)) - sf + 1) x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end return x end local function decimalPrecision(x, p) local s = 1 if x < 0 then x = -x s = -1 end if not tonumber(p) then p = 1e-4 elseif p > 1 then p = 1 elseif p < 1e-6 then p = 1e-6 else p = 10 ^ math.floor(math.log10(p)) end x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end if math.abs(x) < 1e-4 then x = string.format("%f", x) end return x end local function decimalToDMS(x, p) if not tonumber(p) then p = 1e-4 end local d = math.floor(x) local ms = (x - d) * 60 if p > 0.5 then if ms > 30 then d = d + 1 end ms = 0 end local m = math.floor(ms) local s = (ms - m) * 60 if p > 0.008 then if s > 30 then m = m +1 end s = 0 elseif p > 0.00014 then s = math.floor(s + 0.5) elseif p > 0.000014 then s = math.floor(10 * s + 0.5) / 10 elseif p > 0.0000014 then s = math.floor(100 * s + 0.5) / 100 else s = math.floor(1000 * s + 0.5) / 1000 end return d, m, s end local function rawValue(dataValue) if dataValue.type == "string" then return dataValue.value elseif dataValue.type == "wikibase-entityid" then return dataValue.value and dataValue.value.id elseif dataValue.type == "monolingualtext" then return dataValue.value.text elseif dataValue.type == "quantity" then return tonumber(dataValue.value.amount) elseif dataValue.type == 'time' then return dataValue.value.time elseif dataValue.type == "globecoordinate" then return dataValue.value.latitude .. '/' .. dataValue.value.longitude end end local function compareValue(dataValue, strValue) return rawValue(dataValue) == strValue end local function dateFormat(timestamp, dprec, df, bcf, pd, qualifiers, lang, adj, model) df = (df or ""):lower() if df == "ymd" then if timestamp:sub(1,1) == "+" then return timestamp:sub(2,11) else local yr = tonumber(timestamp:sub(2,5)) - 1 yr = ("000" .. yr):sub(-4) if yr ~= "0000" then yr = "-" .. yr end return yr .. timestamp:sub(6,11) end end timestamp = timestamp:gsub("%-00%-00T", "-01-01T") dprec = dprec or 11 if df == "y" and dprec > 9 then dprec = 9 end dprec = dprec>11 and 11 or dprec dprec = dprec<6 and 6 or dprec bcf = (bcf or ""):upper() pd = (pd or ""):sub(1,1):lower() if pd == "" or pd == "n" or pd == "f" or pd == "0" then pd = false end lang = lang or findLang().code adj = adj or "" local bc = timestamp:sub(1, 1)=="-" and "BC" or "" local year, month, day = timestamp:match("[+-](%d*)-(%d*)-(%d*)T") local iso = tonumber(year) if dprec == 6 then iso = math.floor( (iso - 1) / 1000 ) + 1 end if dprec == 7 then iso = math.floor( (iso - 1) / 100 ) + 1 end if dprec == 8 then iso = math.floor( iso / 10 ) .. "0" end if dprec == 10 then iso = year .. "-" .. month end if dprec == 11 then iso = year .. "-" .. month .. "-" .. day end local sc = not pd and qualifiers and qualifiers.P1480 if sc then for k1, v1 in pairs(sc) do if v1.datavalue and v1.datavalue.value.id == "Q5727902" then adj = "circa" break end end end local calendarmodel = "" if tonumber(year) > 1582 and dprec > 8 and not pd and model == "http://www.wikidata.org/entity/Q1985786" then calendarmodel = "julian" end -- Simplified date formatting (complex date module not available) local fdate = tostring(iso) if bc ~= "" then fdate = fdate .. " " .. (bcf == "BC" and "BC" or "BCE") end if adj == "circa" then fdate = "c. " .. fdate end return fdate end local function hijriFormat(qualifiers, dateformat, lang) if not qualifiers.P4241 then return; end local year, month, day local val local qhmonths = {["Q1952053"]=1,["Q489557"]=2, ["Q474167"] = 3, ["Q273815"] = 4, ["Q852002"] = 5, ["Q822218"] = 6, ["Q194210"] = 7, ["Q220914"] = 8, ["Q8867089"]=9, ["Q685440"]=10,["Q150853"]=11,["Q186022"]=12 } local hmonths = {"محرم","صفر","ربيع الأول","ربيع الآخر","جمادى الأولى","جمادى الآخرة","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة"} local hmonths_inv = {["محرم"] = 1, ["صفر"]=2, ["ربيع الأول"]=3, ["ربيع الآخر"]=4, ["جمادى الأولى"]=5, ["جمادى الآخرة"]=6, ["رجب"]=7, ["شعبان"]=8, ["رمضان"]=9, ["شوال"]=10, ["ذو القعدة"]=11, ["ذو الحجة"]=12} for _, item in ipairs(qualifiers.P4241) do local timeQ = item.datavalue and item.datavalue.value and item.datavalue.value.id local hastime = false if timeQ then local timeQt = mw.wikibase.getBestStatements(timeQ, "P361") for _,timeQsnak in pairs(timeQt) do local timeType = timeQsnak.mainsnak and timeQsnak.mainsnak.datavalue and timeQsnak.mainsnak.datavalue.value and timeQsnak.mainsnak.datavalue.value.id if timeType == "Q28892" then local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then year = mw.ustring.match(timeLableAr, "^(%d+) *هـ$") end if not year then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then year = mw.ustring.match(timeLableAr, "^(%d+) *AH$") end end hastime=true elseif qhmonths[timeType] then month = qhmonths[timeType] if month>0 and month<13 then month = hmonths[month] end local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end if not day then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end end hastime=true end end if not hastime then timeQt = mw.wikibase.getBestStatements(timeQ, "P31") if "Q125390868" == (timeQt[1].mainsnak and timeQt[1].mainsnak.datavalue and timeQt[1].mainsnak.datavalue.value and timeQt[1].mainsnak.datavalue.value.id ) then val = mw.wikibase.getLabelByLang(timeQ, "ar") month, year = mw.ustring.match(val, "^(%a[%a ]+%a) *(%d+) *هـ?$") end end end end if year then if dateformat == "y" then return year; elseif day and month then return day .. ' ' .. month .. ' ' .. year; elseif month then return month .. ' ' .. year; end end return nil; end local function sourced(claim) if claim.references then for kr, vr in pairs(claim.references) do local ref = mw.wikibase.renderSnaks(vr.snaks) if not ref:find("Wiki") then return true end end end end local function linkedItem(id, args) local lprefix = (args.linkprefix or ""):gsub('"', '') local lpostfix = (args.lpostfix or ""):gsub('"', '') local prefix = (args.prefix or ""):gsub('"', '') local postfix = (args.postfix or ""):gsub('"', '') local dtxt = args.dtxt local uselbl = parseParam( args.uselbl, true) local disp local sitelink = mw.wikibase.getSitelink(id, args.linksproject) local label, islabel if dtxt then label, islabel = dtxt, true else label, islabel = labelOrId(id, args.lang) end if sitelink then if not uselbl then local pos = sitelink:find(":") or 0 local slink = sitelink if pos > 0 then local pfx = sitelink:sub(1,pos-1) if mw.site.namespaces[pfx] then slink = sitelink:sub(pos+1) end end slink = slink:gsub("%s%(.+%)$", ""):gsub(",.+$", "") if label:find("^%u") then label = slink:gsub("^(%l)", string.upper) else label = slink:gsub("^(%u)", string.lower) end end disp = "[[" .. lprefix .. sitelink .. lpostfix .. "|" .. prefix .. label .. postfix .. "]]" elseif islabel then disp = prefix .. label .. postfix else disp = prefix .. label .. postfix .. i18n.missinginfocat end return disp end local function rendersnak(propval, args, linked, lpre, lpost, pre, post, uabbr, filter) lpre = lpre or "" lpost = lpost or "" pre = pre or "" post = post or "" args.lang = args.lang or findLang().code local snak = propval.mainsnak or propval local dtype = snak.datatype local dv = snak.datavalue dv = dv and dv.value local val, mlt local namedas; namedas = propval.qualifiers and propval.qualifiers.P1932 and propval.qualifiers.P1932[1].datavalue and propval.qualifiers.P1932[1].datavalue.value or nil args.dtxt = namedas if propval.rank and not args.reqranks[propval.rank] then return nil elseif snak.snaktype == "somevalue" then val = namedas or i18n["Unknown"] elseif snak.snaktype == "novalue" then -- return nothing elseif dtype == "wikibase-item" then local qnumber = dv.id if linked then val = linkedItem(qnumber, args) else if namedas then val = pre .. namedas .. post else local label, islabel = labelOrId(qnumber, args.lang) val = pre .. label .. post end end elseif dtype == "time" then if args.hijri then val = hijriFormat(propval.qualifiers, args.df, args.lang) else val = dateFormat(dv.time, dv.precision, args.df, args.bc, args.pd, propval.qualifiers, args.lang, "", dv.calendarmodel) end elseif dtype == "commonsMedia" or dtype == "external-id" or dtype == "string" or dtype == "url" then if (lpre == "" or lpre == ":") and lpost == "" then val = pre .. dv .. post elseif dtype == "external-id" then val = "[" .. lpre .. dv .. lpost .. " " .. pre .. dv .. post .. "]" else val = "[[" .. lpre .. dv .. lpost .. "|" .. pre .. dv .. post .. "]]" end elseif dtype == "quantity" then local amount = tonumber(dv.amount) or i18n["NaN"] local unit = "" local unitqid = string.match(dv.unit, "(Q%d+)") if filter and unitqid ~= filter then return nil end if unitqid then local uname = mw.wikibase.getLabelByLang(unitqid, args.lang) or "" if uname ~= "" then unit = " " .. uname end end val = tostring(amount) .. unit elseif dtype == "globe-coordinate" then local lat, long, prec = dv.latitude, dv.longitude, dv.precision local show = (args.show or ""):lower() if show == "lat" then val = decimalPrecision(lat, prec) elseif show == "lon" then val = decimalPrecision(long, prec) elseif show == "longlat" then val = decimalPrecision(long, prec) .. ", " .. decimalPrecision(lat, prec) else local ns = lat < 0 and "S" or "N" local ew = long < 0 and "W" or "E" if lat < 0 then lat = -lat end if long < 0 then long = -long end val = decimalPrecision(lat, prec) .. "°" .. ns .. " " .. decimalPrecision(long, prec) .. "°" .. ew end elseif dtype == "monolingualtext" then val = pre .. dv.text .. post mlt = dv.language else val = "unknown data type: " .. dtype end return val, mlt end local function assembleoutput(out, args, entityID, propertyID) local sorted = parseParam(args.sorted, false) local noic = parseParam(args.noicon, false) local list = args.list or "" local separator = args.sep or "" separator = string.gsub(separator, '"', '') if separator == "" then local rtl_lang = {ar = true, fa = true, ur = true, ku = true, he = true} separator = rtl_lang[args.lang] and i18n["list separator-ar"] or i18n["list separator"] end local strout if #out > 0 then if sorted then table.sort(out) end if list == "" then strout = table.concat(out, separator) elseif list:lower() == "prose" then strout = mw.text.listToText(out) else strout = mw.getCurrentFrame():expandTemplate{title = list, args = out} end else strout = nil end return strout end local function propertyvalueandquals(objproperty, args, qualID) -- needs this style of declaration because it's re-entrant -- onlysourced is a boolean passed to return only values sourced to other than Wikipedia -- if nothing or an empty string is passed set it true local onlysrc = parseParam(args.onlysourced, false) -- linked is a a boolean that enables the link to a local page via sitelink -- if nothing or an empty string is passed set it true local linked = parseParam(args.linked, true) -- prefix is a string that may be nil, empty (""), or a string of characters -- this is prefixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local prefix = (args.prefix or ""):gsub('"', '') -- postfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local postfix = (args.postfix or ""):gsub('"', '') -- linkprefix is a string that may be nil, empty (""), or a string of characters -- this creates a link and is then prefixed to each value -- useful when when multiple values are returned and indirect links are needed -- any double-quotes " are stripped out, so that spaces may be passed local lprefix = (args.linkprefix or ""):gsub('"', '') -- linkpostfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value when linking is enabled with lprefix -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local lpostfix = (args.linkpostfix or ""):gsub('"', '') -- wdlinks is a boolean passed to enable links to Wikidata when no article exists -- if nothing or an empty string is passed set it false local wdl = parseParam(args.wdl, false) -- unitabbr is a boolean passed to enable unit abbreviations for common units -- if nothing or an empty string is passed set it false local uabbr = parseParam(args.unitabbr, false) -- qualsonly is a boolean passed to return just the qualifiers -- if nothing or an empty string is passed set it false local qualsonly = parseParam(args.qualsonly, false) -- maxvals is a string that may be nil, empty (""), or a number -- this determines how many items may be returned when multiple values are available -- setting it = 1 is useful where the returned string is used within another call, e.g. image local maxvals = tonumber(args.maxvals) or 0 -- pd boolean -- to disable/enable "sourcing cirumstances" or use adjectival form for the plain date local pd = args.pd or false args.pd = pd -- allow qualifiers to have a different date format; default to year unless qualsonly is set args.qdf = args.qdf or (not qualsonly and "y") local lang = args.lang or (args.langs and args.langs[1]) or findLang().code -- qualID is a string list of wanted qualifiers or "ALL" qualID = qualID or "" -- capitalise list of wanted qualifiers and substitute "DATES" qualID = qualID:upper():gsub("DATES", "P580, P582") local allflag = (qualID == "ALL") -- create table of wanted qualifiers as key local qwanted = {} -- create sequence of wanted qualifiers local qorder = {} for q in mw.text.gsplit(qualID, "%p") do -- split at punctuation and iterate local qtrim = mw.text.trim(q) if qtrim ~= "" then qwanted[mw.text.trim(q)] = true qorder[#qorder+1] = qtrim end end -- qsep is the output separator for rendering qualifier list local qsep = (args.qsep or ""):gsub('"', '') -- qargs are the arguments to supply to assembleoutput() local qargs = { ["osd"] = "false", ["linked"] = tostring(linked), ["prefix"] = args.qprefix, ["postfix"] = args.qpostfix, ["linkprefix"] = args.qlinkprefix, ["linkpostfix"] = args.qlinkpostfix, ["wdl"] = "false", ["unitabbr"] = tostring(uabbr), ["maxvals"] = 0, ["sorted"] = tostring(args.qsorted), ["noicon"] = "true", ["list"] = args.qlist, ["sep"] = qsep, -- ["langobj"] = args.langobj, ["lang"] = args.lang or (args.langs and args.lang[1]), ["df"] = args.qdf, ["sn"] = parseParam(args.qsn, false), } -- all proper values of a Wikidata property will be the same type as the first -- qualifiers don't have a mainsnak, properties do --#Modified line local datatype = objproperty[1].datatype or (objproperty[1].mainsnak and objproperty[1].mainsnak.datatype) -- out[] holds the a list of returned values for this property -- mlt[] holds the language code if the datatype is monolingual text local out = {} local mlt = {} for k, v in ipairs(objproperty) do local hasvalue = true if (onlysrc and not sourced(v)) then -- no value: it isn't sourced when onlysourced=true hasvalue = false else local val, lcode = rendersnak(v, args, linked, lprefix, lpostfix, prefix, postfix, uabbr) if not val then hasvalue = false -- rank doesn't match elseif qualsonly and qualID then -- suppress value returned: only qualifiers are requested else out[#out+1], mlt[#out+1] = val, lcode end end -- See if qualifiers are to be returned: local snak = v.mainsnak or v if hasvalue and v.qualifiers and qualID ~= "" and snak.snaktype~="novalue" then -- collect all wanted qualifier values returned in qlist, indexed by propertyID local qlist = {} local timestart, timeend = "", "" -- loop through qualifiers for k1, v1 in pairs(v.qualifiers) do if allflag or qwanted[k1] then if k1 == "P1326" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before") elseif k1 == "P1319" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after") elseif k1 == "P580" then timestart = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one start time as valid elseif k1 == "P582" then timeend = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one end time as valid else local q = assembleoutput(propertyvalueandquals(v1, qargs), qargs) -- we already deal with circa via 'sourcing circumstances' if the datatype was time -- circa may be either linked or unlinked *** internationalise later *** if datatype ~= "time" or q ~= "circa" and not (type(q) == "string" and q:find("circa]]")) then qlist[k1] = q end end end -- of test for wanted end -- of loop through qualifiers -- set date separator local t = timestart .. timeend -- *** internationalise date separators later *** local dsep = "&ndash;" if t:find("%s") or t:find("&nbsp;") then dsep = " &ndash; " end -- set the order for the list of qualifiers returned; start time and end time go last if next(qlist) then local qlistout = {} if allflag then for k2, v2 in pairs(qlist) do qlistout[#qlistout+1] = v2 end else for i2, v2 in ipairs(qorder) do qlistout[#qlistout+1] = qlist[v2] end end if t ~= "" then qlistout[#qlistout+1] = timestart .. dsep .. timeend end local qstr = assembleoutput(qlistout, qargs) if qualsonly then out[#out+1] = qstr else out[#out] = out[#out] .. " (" .. qstr .. ")" end elseif t ~= "" then if qualsonly then if timestart == "" then out[#out+1] = timeend elseif timeend == "" then out[#out+1] = timestart else out[#out+1] = timestart .. dsep .. timeend end else out[#out] = out[#out] .. " (" .. timestart .. dsep .. timeend .. ")" end end end -- of test for qualifiers wanted if maxvals > 0 and #out >= maxvals then break end end -- of for each value loop -- we need to pick one value to return if the datatype was "monolingualtext" -- if there's only one value, use that -- otherwise look through the fallback languages for a match if datatype == "monolingualtext" and #out >1 then lang = mw.text.split( lang, '-', true )[1] local fbtbl = mw.language.getFallbacksFor( lang ) table.insert( fbtbl, 1, lang ) local bestval = "" local found = false for idx1, lang1 in ipairs(fbtbl) do for idx2, lang2 in ipairs(mlt) do if (lang1 == lang2) and not found then bestval = out[idx2] found = true break end end -- loop through values of property end -- loop through fallback languages if found then -- replace output table with a table containing the best value out = { bestval } else -- more than one value and none of them on the list of fallback languages -- sod it, just give them the first one out = { out[1] } end end return out end local function mergeOptions(defaults, overrides) overrides = overrides or {} defaults = defaults or {} local result = {} for k, v in pairs(defaults) do result[k] = v end for k, v in pairs(overrides) do result[k] = v if k == 'rank' then result.reqranks = setRanks(v) end end return result end local function filterbyqualifier(statements,qual,value) local filtered_statements = {} for _, statement in ipairs(statements) do if statement.qualifiers and statement.qualifiers[qual] then if '*' == value then table.insert(filtered_statements, statement) else for _, q in ipairs(statement.qualifiers[qual]) do if q.datavalue and (rawValue(q.datavalue) == value) then table.insert(filtered_statements, statement) break end end end end end return filtered_statements end local function orderbyrank(statements) local pref_count = 0 local sorted_statements = {} for k,v in ipairs(statements) do if v.rank == 'preferred' then pref_count = pref_count + 1 table.insert(sorted_statements, pref_count, v) else table.insert(sorted_statements, v) end end return sorted_statements end ------------------------------------------------------------------------------- -- helper class functions ------------------------------------------------------------------------------- local function class() local c = {} c.__index = c function c:new(...) local o = setmetatable({}, c) if o.init then o:init(...) end return o end return c end ------------------------------------------------------------------------------- -- Statement Class Definition ------------------------------------------------------------------------------- local WdStatement = class() function WdStatement:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statement = self._statement if not statement then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals({statement}, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatement:getRawValue() if not self._statement then return nil end if self._statement.mainsnak.snaktype == "value" then return rawValue(self._statements.mainsnak.datavalue) else return self._statement.mainsnak.snaktype end end function WdStatement:getRawQual(qualID) local ret = {} local s = self._statement if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(ret, rawValue(q.datavalue)) else table.insert(ret, q.snaktype) end end end return ret end ------------------------------------------------------------------------------- -- Statements Class Definition ------------------------------------------------------------------------------- local WdStatements = class() function WdStatements:getStatmentsTable() return self._statements end function WdStatements:count() return #self._statements end function WdStatements:getFilters() return self.filtered_by end function WdStatements:filter(filter_t) local statements = self._statements if #statements == 0 then return self; end local ret = WdStatements:new() ret.parent = self.parent ret.filtered_by = {} for _,v in ipairs(self.filtered_by) do table.insert(ret.filtered_by, v) end local filtered_statements = {} for k,v in pairs(filter_t) do filtered_statements = filterbyqualifier(statements, k, v) table.insert(ret.filtered_by, {[k] = v}) if #filtered_statements == 0 then break; else statements = filtered_statements end end ret._statements = filtered_statements return ret end function WdStatements:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getQual(qualID, opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getRawQual(qualID) local ret = {} for _,s in pairs(self._statements) do local qual_t = {} if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(qual_t, rawValue(q.datavalue)) else table.insert(qual_t, q.snaktype) end end end table.insert(ret,qual_t) end return ret end function WdStatements:getRawValue() local ret = {} for _,v in pairs(self._statements) do if v.mainsnak.snaktype=="value" then table.insert(ret, rawValue(v.mainsnak.datavalue)) else table.insert(ret, v.mainsnak.snaktype) end end return ret end function WdStatements:get(index) local ret = WdStatement:new() ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = self._statements[index] ret.pid = ret.pid return ret end function WdStatements:getBestOne() local orderd_statements = orderbyrank(self._statements) local ret = WdStatement:new() --setmetatable({}, WdStatement) ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = orderd_statements[1] ret.pid = ret.pid return ret end ------------------------------------------------------------------------------- -- WdItem Class Definition ------------------------------------------------------------------------------- local WdItem = class() function WdItem:__tostring() return "WdItem: " .. (self.qid or "no QID") end function WdItem:UpdateOptions(newOpts) for k, v in pairs(newOpts or {}) do local key = options_aliases[k] self.options[key] = v -- Set default options if key == 'langs' and #v > 0 then self.options.langobj = findLang(self.options.langs[1]) self.options.lang = self.options.langobj.code if not self.options.langobj then self.options.langobj = findLang(self.options.lang) self.options.lang = self.options.langobj.code end end if key == 'rank' then self.options.reqranks = setRanks(self.options.rank) end end if not self.options.reqranks then self.options.reqranks = setRanks('preferred normal') end end function WdItem:init(qid, options) if qid == "" then qid = nil end if not qid then qid = mw.wikibase.getEntityIdForCurrentPage() end self.qid = qid self.snak = nil self.options = options or {} self:UpdateOptions(options) return self end function WdItem:newFromSnaks(snakTable, options) local self = WdItem:new() self.qid = nil self.snak = snakTable or {} self.options = options or {} self:UpdateOptions(options) return self end function WdItem:setOptions(newOpts) self:UpdateOptions(newOpts) end function WdItem:getStatements(pid, opts) local mergedOpts = mergeOptions(self.options, opts or {}) local statements local ret = WdStatements:new() ret.parent = self ret.filtered_by = {} ret._statements = {} ret.pid = pid if self.snak and self.snak[pid] then statements = self.snak[pid] elseif not self.qid or not mw.wikibase then statements = {} elseif mergedOpts.reqranks and mergedOpts.reqranks.best then statements = mw.wikibase.getBestStatements(self.qid, pid) or {} else statements = mw.wikibase.getAllStatements(self.qid, pid) or {} local filtered_statements = {} if not (mergedOpts.reqranks.deprecated == true and mergedOpts.reqranks.preferred == true and mergedOpts.reqranks.normal == true) then for _,s in pairs(statements) do if mergedOpts.reqranks[s.rank] then table.insert(filtered_statements,s) end end end statements = filtered_statements end if #statements > 0 and mergedOpts.qualifiedaspossible and mergedOpts.qualifiedaspossible ~= {} then local filtered_statements = {} for q,qv in pairs(mergedOpts.qualifiedaspossible) do filtered_statements = filterbyqualifier(statements, q, qv) if #filtered_statements > 0 then table.insert(ret.filtered_by, {[q] = qv}) statements = filtered_statements end end end if #statements > 0 and mergedOpts.qualified and mergedOpts.qualified ~= {} then for q,qv in pairs(mergedOpts.qualified) do statements = filterbyqualifier(statements, q, qv) table.insert(ret.filtered_by, {[q] = qv}) if #statements == 0 then break; end end end ret._statements = statements return ret end function WdItem:getValue(pid, opts) local mergedOpts = mergeOptions(self.options, opts) local statements = self:getStatements(pid, mergedOpts):getStatmentsTable() if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.qid, pid) end function WdItem:getValueFromSnaks(pid, opts) if not self.snak or not self.snak[pid] then return nil end local mergedOpts = mergeOptions(self.options, opts) local props = self.snak[pid] local out = propertyvalueandquals(props, mergedOpts) return assembleoutput(out, mergedOpts, nil, pid) end function WdItem:getPropertyIDsTable(pid, opts) local mergedOpts = mergeOptions(self.options, opts) mergedOpts.noicon = tostring(parseParam(mergedOpts.noicon or "", true)) local statements = self:getStatements(pid, opts) if not statements or #statements == 0 then return {} end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local out = {} for i, v in ipairs(statements) do local snak = v.mainsnak if (snak.datatype == "wikibase-item") and (v.rank and mergedOpts.reqranks[v.rank:sub(1, 1)]) and (snak.snaktype == "value") and (sourced(v) or not onlysrc) then out[#out+1] = snak.datavalue.value.id end if maxvals > 0 and #out >= maxvals then break end end return out end function WdItem:getPropertyIDs(pid, opts) local out = WdItem:getPropertyIDsTable(pid, opts) if #out == 0 then return nil end return assembleoutput(out, mergeOptions(self.options, opts), self.qid, pid) end function WdItem:getPropOfProp(prop1, prop2, opts) local mergedOpts = mergeOptions(self.options, opts) if not self.qid then return nil end local statements1 = self:getStatements(prop1, opts) if not statements1 or #statements1 == 0 then return nil end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = {} for k, v in ipairs(statements1) do if not onlysrc or sourced(v) then local snak = v.mainsnak if snak.datatype == "wikibase-item" and snak.snaktype == "value" then local qid2 = snak.datavalue.value.id local item2 = WdItem.new(qid2, mergedOpts) local statements2 = item2:getStatements(prop2, opts) if statements2 and statements2[1] then local out2 = propertyvalueandquals(statements2, mergedOpts, qualID) out[#out+1] = assembleoutput(out2, mergedOpts, qid2, prop2) end end end if maxvals > 0 and #out >= maxvals then break end end return assembleoutput(out, mergedOpts, self.qid, prop1) end function WdItem:getLangOfProp(pid) if not pid or not self.qid then return {} end local out = {} local props = mw.wikibase.getAllStatements(self.qid, pid) for _, v in ipairs(props) do if v.mainsnak.datatype == "monolingualtext" and v.mainsnak.datavalue then out[#out + 1] = v.mainsnak.datavalue.value.language end end return out end function WdItem:followQid(props, all) all = parseParam(all, false) props = (props or ""):upper() if not self.qid then return nil end if props == "" then return self.qid end local out = {} for p in mw.text.gsplit(props, "%p") do p = mw.text.trim(p) for i, v in ipairs(mw.wikibase.getBestStatements(self.qid, p)) do local linkedid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id if linkedid then if all then out[#out+1] = linkedid else return linkedid end end end end if #out > 0 then return table.concat(out, " ") else return self.qid end end ------------------------------------------------------------------------------- -- Public API - WdItem Constructors ------------------------------------------------------------------------------- p.WdItem = WdItem function p.newItem(qid, opts) return WdItem:new(qid, opts) end function p.newSnakItem(snakTable, opts) return WdItem:newFromSnaks(snakTable, opts) end return p b63h56bcli3e9zwetwnjzkwhrzeclnz 1097238 1097237 2026-07-22T14:45:43Z حبيشان 31560 1097238 Scribunto text/plain -- Module: WdItem -- Object-oriented Wikidata access module for Lua -- Refactored from WikidataIB for direct Lua usage require("strict") local p = {} -- i18n configuration local i18n = { ["errors"] = { ["property-not-found"] = "الخاصية غير موجودة.", ["entity-not-found"] = "الكيان على ويكي بيانات غير موجود.", ["unknown-claim-type"] = "نوع الادعاء غير معروف.", ["local-article-not-found"] = "المعرف متاح على ويكي بيانات، ولكن المقال غير متاح على ويكيبيديا", }, ["months"] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, ["Unknown"] = "Unknown", ["NaN"] = "Not a number", ["missinginfocat"] = "[[تصنيف:Articles with missing Wikidata information]]", ["list separator"] = ", ", ["list separator-ar"] = "، ", } -- Date precision constants local dp = { [6] = "millennium", [7] = "century", [8] = "decade", [9] = "year", [10] = "month", [11] = "day", } local options_aliases = { ["osd"] = "onlysourced", ["wdlinks"] = "wdl", ["uabbr"] = "unitabbr", ["qo"] = "qualsonly", ["lp"] = "linkprefix", ["lprefix"] = "linkprefix", ["qlp"] = "qlinkprefix", ["sn"] = "shortname", ["uselabel"] = "uselbl", ["plaindate"] = "pd", ["qualifierdateformat"] = "qdf", ["df"] = "qdf", ["qshortname"] = "qsn" } setmetatable(options_aliases, { __index = function(t, k) return k end }) ------------------------------------------------------------------------------- -- Internal helper functions ------------------------------------------------------------------------------- local function findLang(langcode) local langobj langcode = mw.text.trim(langcode or "") if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langcode = mw.getCurrentFrame():callParserFunction('int', {'lang'}) if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langobj = mw.language.getContentLanguage() end end return langobj end local function parseParam(param, default) if param == nil then return default end return param end local function setRanks(rank) rank = (rank or ""):lower() local ranks = {} for w in string.gmatch(rank, "%a+") do if w == "best" or w == "preferred" or w == "normal" or w == "deprecated" then ranks[w] = true end end if ranks.best or not next(ranks) then ranks.preferred = true ranks.normal = true ranks.deprecated = false end return ranks end local function labelOrId(id, lang) if lang == "default" then lang = findLang().code end local label if lang then label = mw.wikibase.getLabelByLang(id, lang) end if not label then local trylang = {"ar","en","fr", "mul"} local triedlang = lang for _,lang in pairs(trylang) do if triedlang ~= lang then label = mw.wikibase.getLabelByLang(id, lang) if label ~= "" then break end end end end if label then return mw.text.nowiki(label), true else return id, false end end local function roundto(x, sf) if x == 0 then return 0 end local s = 1 if x < 0 then x = -x s = -1 end if sf < 1 then sf = 1 end local p = 10 ^ (math.floor(math.log10(x)) - sf + 1) x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end return x end local function decimalPrecision(x, p) local s = 1 if x < 0 then x = -x s = -1 end if not tonumber(p) then p = 1e-4 elseif p > 1 then p = 1 elseif p < 1e-6 then p = 1e-6 else p = 10 ^ math.floor(math.log10(p)) end x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end if math.abs(x) < 1e-4 then x = string.format("%f", x) end return x end local function decimalToDMS(x, p) if not tonumber(p) then p = 1e-4 end local d = math.floor(x) local ms = (x - d) * 60 if p > 0.5 then if ms > 30 then d = d + 1 end ms = 0 end local m = math.floor(ms) local s = (ms - m) * 60 if p > 0.008 then if s > 30 then m = m +1 end s = 0 elseif p > 0.00014 then s = math.floor(s + 0.5) elseif p > 0.000014 then s = math.floor(10 * s + 0.5) / 10 elseif p > 0.0000014 then s = math.floor(100 * s + 0.5) / 100 else s = math.floor(1000 * s + 0.5) / 1000 end return d, m, s end local function rawValue(dataValue) if dataValue.type == "string" then return dataValue.value elseif dataValue.type == "wikibase-entityid" then return dataValue.value and dataValue.value.id elseif dataValue.type == "monolingualtext" then return dataValue.value.text elseif dataValue.type == "quantity" then return tonumber(dataValue.value.amount) elseif dataValue.type == 'time' then return dataValue.value.time elseif dataValue.type == "globecoordinate" then return dataValue.value.latitude .. '/' .. dataValue.value.longitude end end local function compareValue(dataValue, strValue) return rawValue(dataValue) == strValue end local function dateFormat(timestamp, dprec, df, bcf, pd, qualifiers, lang, adj, model) df = (df or ""):lower() if df == "ymd" then if timestamp:sub(1,1) == "+" then return timestamp:sub(2,11) else local yr = tonumber(timestamp:sub(2,5)) - 1 yr = ("000" .. yr):sub(-4) if yr ~= "0000" then yr = "-" .. yr end return yr .. timestamp:sub(6,11) end end timestamp = timestamp:gsub("%-00%-00T", "-01-01T") dprec = dprec or 11 if df == "y" and dprec > 9 then dprec = 9 end dprec = dprec>11 and 11 or dprec dprec = dprec<6 and 6 or dprec bcf = (bcf or ""):upper() pd = (pd or ""):sub(1,1):lower() if pd == "" or pd == "n" or pd == "f" or pd == "0" then pd = false end lang = lang or findLang().code adj = adj or "" local bc = timestamp:sub(1, 1)=="-" and "BC" or "" local year, month, day = timestamp:match("[+-](%d*)-(%d*)-(%d*)T") local iso = tonumber(year) if dprec == 6 then iso = math.floor( (iso - 1) / 1000 ) + 1 end if dprec == 7 then iso = math.floor( (iso - 1) / 100 ) + 1 end if dprec == 8 then iso = math.floor( iso / 10 ) .. "0" end if dprec == 10 then iso = year .. "-" .. month end if dprec == 11 then iso = year .. "-" .. month .. "-" .. day end local sc = not pd and qualifiers and qualifiers.P1480 if sc then for k1, v1 in pairs(sc) do if v1.datavalue and v1.datavalue.value.id == "Q5727902" then adj = "circa" break end end end local calendarmodel = "" if tonumber(year) > 1582 and dprec > 8 and not pd and model == "http://www.wikidata.org/entity/Q1985786" then calendarmodel = "julian" end -- Simplified date formatting (complex date module not available) local fdate = tostring(iso) if bc ~= "" then fdate = fdate .. " " .. (bcf == "BC" and "BC" or "BCE") end if adj == "circa" then fdate = "c. " .. fdate end return fdate end local function hijriFormat(qualifiers, dateformat, lang) if not qualifiers.P4241 then return; end local year, month, day local val local qhmonths = {["Q1952053"]=1,["Q489557"]=2, ["Q474167"] = 3, ["Q273815"] = 4, ["Q852002"] = 5, ["Q822218"] = 6, ["Q194210"] = 7, ["Q220914"] = 8, ["Q8867089"]=9, ["Q685440"]=10,["Q150853"]=11,["Q186022"]=12 } local hmonths = {"محرم","صفر","ربيع الأول","ربيع الآخر","جمادى الأولى","جمادى الآخرة","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة"} local hmonths_inv = {["محرم"] = 1, ["صفر"]=2, ["ربيع الأول"]=3, ["ربيع الآخر"]=4, ["جمادى الأولى"]=5, ["جمادى الآخرة"]=6, ["رجب"]=7, ["شعبان"]=8, ["رمضان"]=9, ["شوال"]=10, ["ذو القعدة"]=11, ["ذو الحجة"]=12} for _, item in ipairs(qualifiers.P4241) do local timeQ = item.datavalue and item.datavalue.value and item.datavalue.value.id local hastime = false if timeQ then local timeQt = mw.wikibase.getBestStatements(timeQ, "P361") for _,timeQsnak in pairs(timeQt) do local timeType = timeQsnak.mainsnak and timeQsnak.mainsnak.datavalue and timeQsnak.mainsnak.datavalue.value and timeQsnak.mainsnak.datavalue.value.id if timeType == "Q28892" then local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then year = mw.ustring.match(timeLableAr, "^(%d+) *هـ$") end if not year then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then year = mw.ustring.match(timeLableAr, "^(%d+) *AH$") end end hastime=true elseif qhmonths[timeType] then month = qhmonths[timeType] if month>0 and month<13 then month = hmonths[month] end local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end if not day then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end end hastime=true end end if not hastime then timeQt = mw.wikibase.getBestStatements(timeQ, "P31") if "Q125390868" == (timeQt[1].mainsnak and timeQt[1].mainsnak.datavalue and timeQt[1].mainsnak.datavalue.value and timeQt[1].mainsnak.datavalue.value.id ) then val = mw.wikibase.getLabelByLang(timeQ, "ar") month, year = mw.ustring.match(val, "^(%a[%a ]+%a) *(%d+) *هـ?$") end end end end if year then if dateformat == "y" then return year; elseif day and month then return day .. ' ' .. month .. ' ' .. year; elseif month then return month .. ' ' .. year; end end return nil; end local function sourced(claim) if claim.references then for kr, vr in pairs(claim.references) do local ref = mw.wikibase.renderSnaks(vr.snaks) if not ref:find("Wiki") then return true end end end end local function linkedItem(id, args) local lprefix = (args.linkprefix or ""):gsub('"', '') local lpostfix = (args.lpostfix or ""):gsub('"', '') local prefix = (args.prefix or ""):gsub('"', '') local postfix = (args.postfix or ""):gsub('"', '') local dtxt = args.dtxt local uselbl = parseParam( args.uselbl, true) local disp local sitelink = mw.wikibase.getSitelink(id, args.linksproject) local label, islabel if dtxt then label, islabel = dtxt, true else label, islabel = labelOrId(id, args.lang) end if sitelink then if not uselbl then local pos = sitelink:find(":") or 0 local slink = sitelink if pos > 0 then local pfx = sitelink:sub(1,pos-1) if mw.site.namespaces[pfx] then slink = sitelink:sub(pos+1) end end slink = slink:gsub("%s%(.+%)$", ""):gsub(",.+$", "") if label:find("^%u") then label = slink:gsub("^(%l)", string.upper) else label = slink:gsub("^(%u)", string.lower) end end disp = "[[" .. lprefix .. sitelink .. lpostfix .. "|" .. prefix .. label .. postfix .. "]]" elseif islabel then disp = prefix .. label .. postfix else disp = prefix .. label .. postfix .. i18n.missinginfocat end return disp end local function rendersnak(propval, args, linked, lpre, lpost, pre, post, uabbr, filter) lpre = lpre or "" lpost = lpost or "" pre = pre or "" post = post or "" args.lang = args.lang or findLang().code local snak = propval.mainsnak or propval local dtype = snak.datatype local dv = snak.datavalue dv = dv and dv.value local val, mlt local namedas; namedas = propval.qualifiers and propval.qualifiers.P1932 and propval.qualifiers.P1932[1].datavalue and propval.qualifiers.P1932[1].datavalue.value or nil args.dtxt = namedas if propval.rank and not args.reqranks[propval.rank] then return nil elseif snak.snaktype == "somevalue" then val = namedas or i18n["Unknown"] elseif snak.snaktype == "novalue" then -- return nothing elseif dtype == "wikibase-item" then local qnumber = dv.id if linked then val = linkedItem(qnumber, args) else if namedas then val = pre .. namedas .. post else local label, islabel = labelOrId(qnumber, args.lang) val = pre .. label .. post end end elseif dtype == "time" then if args.hijri then val = hijriFormat(propval.qualifiers, args.df, args.lang) else val = dateFormat(dv.time, dv.precision, args.df, args.bc, args.pd, propval.qualifiers, args.lang, "", dv.calendarmodel) end elseif dtype == "commonsMedia" or dtype == "external-id" or dtype == "string" or dtype == "url" then if (lpre == "" or lpre == ":") and lpost == "" then val = pre .. dv .. post elseif dtype == "external-id" then val = "[" .. lpre .. dv .. lpost .. " " .. pre .. dv .. post .. "]" else val = "[[" .. lpre .. dv .. lpost .. "|" .. pre .. dv .. post .. "]]" end elseif dtype == "quantity" then local amount = tonumber(dv.amount) or i18n["NaN"] local unit = "" local unitqid = string.match(dv.unit, "(Q%d+)") if filter and unitqid ~= filter then return nil end if unitqid then local uname = mw.wikibase.getLabelByLang(unitqid, args.lang) or "" if uname ~= "" then unit = " " .. uname end end val = tostring(amount) .. unit elseif dtype == "globe-coordinate" then local lat, long, prec = dv.latitude, dv.longitude, dv.precision local show = (args.show or ""):lower() if show == "lat" then val = decimalPrecision(lat, prec) elseif show == "lon" then val = decimalPrecision(long, prec) elseif show == "longlat" then val = decimalPrecision(long, prec) .. ", " .. decimalPrecision(lat, prec) else local ns = lat < 0 and "S" or "N" local ew = long < 0 and "W" or "E" if lat < 0 then lat = -lat end if long < 0 then long = -long end val = decimalPrecision(lat, prec) .. "°" .. ns .. " " .. decimalPrecision(long, prec) .. "°" .. ew end elseif dtype == "monolingualtext" then val = pre .. dv.text .. post mlt = dv.language else val = "unknown data type: " .. dtype end return val, mlt end local function assembleoutput(out, args, entityID, propertyID) local sorted = parseParam(args.sorted, false) local noic = parseParam(args.noicon, false) local list = args.list or "" local separator = args.sep or "" separator = string.gsub(separator, '"', '') if separator == "" then local rtl_lang = {ar = true, fa = true, ur = true, ku = true, he = true} separator = rtl_lang[args.lang] and i18n["list separator-ar"] or i18n["list separator"] end local strout if #out > 0 then if sorted then table.sort(out) end if list == "" then strout = table.concat(out, separator) elseif list:lower() == "prose" then strout = mw.text.listToText(out) else strout = mw.getCurrentFrame():expandTemplate{title = list, args = out} end else strout = nil end return strout end local function propertyvalueandquals(objproperty, args, qualID) -- needs this style of declaration because it's re-entrant -- onlysourced is a boolean passed to return only values sourced to other than Wikipedia -- if nothing or an empty string is passed set it true local onlysrc = parseParam(args.onlysourced, false) -- linked is a a boolean that enables the link to a local page via sitelink -- if nothing or an empty string is passed set it true local linked = parseParam(args.linked, true) -- prefix is a string that may be nil, empty (""), or a string of characters -- this is prefixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local prefix = (args.prefix or ""):gsub('"', '') -- postfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local postfix = (args.postfix or ""):gsub('"', '') -- linkprefix is a string that may be nil, empty (""), or a string of characters -- this creates a link and is then prefixed to each value -- useful when when multiple values are returned and indirect links are needed -- any double-quotes " are stripped out, so that spaces may be passed local lprefix = (args.linkprefix or ""):gsub('"', '') -- linkpostfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value when linking is enabled with lprefix -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local lpostfix = (args.linkpostfix or ""):gsub('"', '') -- wdlinks is a boolean passed to enable links to Wikidata when no article exists -- if nothing or an empty string is passed set it false local wdl = parseParam(args.wdl, false) -- unitabbr is a boolean passed to enable unit abbreviations for common units -- if nothing or an empty string is passed set it false local uabbr = parseParam(args.unitabbr, false) -- qualsonly is a boolean passed to return just the qualifiers -- if nothing or an empty string is passed set it false local qualsonly = parseParam(args.qualsonly, false) -- maxvals is a string that may be nil, empty (""), or a number -- this determines how many items may be returned when multiple values are available -- setting it = 1 is useful where the returned string is used within another call, e.g. image local maxvals = tonumber(args.maxvals) or 0 -- pd boolean -- to disable/enable "sourcing cirumstances" or use adjectival form for the plain date local pd = args.pd or false args.pd = pd -- allow qualifiers to have a different date format; default to year unless qualsonly is set args.qdf = args.qdf or (not qualsonly and "y") local lang = args.lang or (args.langs and args.langs[1]) or findLang().code -- qualID is a string list of wanted qualifiers or "ALL" qualID = qualID or "" -- capitalise list of wanted qualifiers and substitute "DATES" qualID = qualID:upper():gsub("DATES", "P580, P582") local allflag = (qualID == "ALL") -- create table of wanted qualifiers as key local qwanted = {} -- create sequence of wanted qualifiers local qorder = {} for q in mw.text.gsplit(qualID, "%p") do -- split at punctuation and iterate local qtrim = mw.text.trim(q) if qtrim ~= "" then qwanted[mw.text.trim(q)] = true qorder[#qorder+1] = qtrim end end -- qsep is the output separator for rendering qualifier list local qsep = (args.qsep or ""):gsub('"', '') -- qargs are the arguments to supply to assembleoutput() local qargs = { ["osd"] = "false", ["linked"] = tostring(linked), ["prefix"] = args.qprefix, ["postfix"] = args.qpostfix, ["linkprefix"] = args.qlinkprefix, ["linkpostfix"] = args.qlinkpostfix, ["wdl"] = "false", ["unitabbr"] = tostring(uabbr), ["maxvals"] = 0, ["sorted"] = tostring(args.qsorted), ["noicon"] = "true", ["list"] = args.qlist, ["sep"] = qsep, -- ["langobj"] = args.langobj, ["lang"] = args.lang or (args.langs and args.lang[1]), ["df"] = args.qdf, ["sn"] = parseParam(args.qsn, false), } -- all proper values of a Wikidata property will be the same type as the first -- qualifiers don't have a mainsnak, properties do --#Modified line local datatype = objproperty[1].datatype or (objproperty[1].mainsnak and objproperty[1].mainsnak.datatype) -- out[] holds the a list of returned values for this property -- mlt[] holds the language code if the datatype is monolingual text local out = {} local mlt = {} for k, v in ipairs(objproperty) do local hasvalue = true if (onlysrc and not sourced(v)) then -- no value: it isn't sourced when onlysourced=true hasvalue = false else local val, lcode = rendersnak(v, args, linked, lprefix, lpostfix, prefix, postfix, uabbr) if not val then hasvalue = false -- rank doesn't match elseif qualsonly and qualID then -- suppress value returned: only qualifiers are requested else out[#out+1], mlt[#out+1] = val, lcode end end -- See if qualifiers are to be returned: local snak = v.mainsnak or v if hasvalue and v.qualifiers and qualID ~= "" and snak.snaktype~="novalue" then -- collect all wanted qualifier values returned in qlist, indexed by propertyID local qlist = {} local timestart, timeend = "", "" -- loop through qualifiers for k1, v1 in pairs(v.qualifiers) do if allflag or qwanted[k1] then if k1 == "P1326" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before") elseif k1 == "P1319" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after") elseif k1 == "P580" then timestart = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one start time as valid elseif k1 == "P582" then timeend = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one end time as valid else local q = assembleoutput(propertyvalueandquals(v1, qargs), qargs) -- we already deal with circa via 'sourcing circumstances' if the datatype was time -- circa may be either linked or unlinked *** internationalise later *** if datatype ~= "time" or q ~= "circa" and not (type(q) == "string" and q:find("circa]]")) then qlist[k1] = q end end end -- of test for wanted end -- of loop through qualifiers -- set date separator local t = timestart .. timeend -- *** internationalise date separators later *** local dsep = "&ndash;" if t:find("%s") or t:find("&nbsp;") then dsep = " &ndash; " end -- set the order for the list of qualifiers returned; start time and end time go last if next(qlist) then local qlistout = {} if allflag then for k2, v2 in pairs(qlist) do qlistout[#qlistout+1] = v2 end else for i2, v2 in ipairs(qorder) do qlistout[#qlistout+1] = qlist[v2] end end if t ~= "" then qlistout[#qlistout+1] = timestart .. dsep .. timeend end local qstr = assembleoutput(qlistout, qargs) if qualsonly then out[#out+1] = qstr else out[#out] = out[#out] .. " (" .. qstr .. ")" end elseif t ~= "" then if qualsonly then if timestart == "" then out[#out+1] = timeend elseif timeend == "" then out[#out+1] = timestart else out[#out+1] = timestart .. dsep .. timeend end else out[#out] = out[#out] .. " (" .. timestart .. dsep .. timeend .. ")" end end end -- of test for qualifiers wanted if maxvals > 0 and #out >= maxvals then break end end -- of for each value loop -- we need to pick one value to return if the datatype was "monolingualtext" -- if there's only one value, use that -- otherwise look through the fallback languages for a match if datatype == "monolingualtext" and #out >1 then lang = mw.text.split( lang, '-', true )[1] local fbtbl = mw.language.getFallbacksFor( lang ) table.insert( fbtbl, 1, lang ) local bestval = "" local found = false for idx1, lang1 in ipairs(fbtbl) do for idx2, lang2 in ipairs(mlt) do if (lang1 == lang2) and not found then bestval = out[idx2] found = true break end end -- loop through values of property end -- loop through fallback languages if found then -- replace output table with a table containing the best value out = { bestval } else -- more than one value and none of them on the list of fallback languages -- sod it, just give them the first one out = { out[1] } end end return out end local function mergeOptions(defaults, overrides) overrides = overrides or {} defaults = defaults or {} local result = {} for k, v in pairs(defaults) do result[k] = v end for k, v in pairs(overrides) do result[k] = v if k == 'rank' then result.reqranks = setRanks(v) end end return result end local function filterbyqualifier(statements,qual,value) local filtered_statements = {} for _, statement in ipairs(statements) do if statement.qualifiers and statement.qualifiers[qual] then if '*' == value then table.insert(filtered_statements, statement) else for _, q in ipairs(statement.qualifiers[qual]) do if q.datavalue and (rawValue(q.datavalue) == value) then table.insert(filtered_statements, statement) break end end end end end return filtered_statements end local function orderbyrank(statements) local pref_count = 0 local sorted_statements = {} for k,v in ipairs(statements) do if v.rank == 'preferred' then pref_count = pref_count + 1 table.insert(sorted_statements, pref_count, v) else table.insert(sorted_statements, v) end end return sorted_statements end ------------------------------------------------------------------------------- -- helper class functions ------------------------------------------------------------------------------- local function class() local c = {} c.__index = c function c:new(...) local o = setmetatable({}, c) if o.init then o:init(...) end return o end return c end ------------------------------------------------------------------------------- -- Statement Class Definition ------------------------------------------------------------------------------- local WdStatement = class() function WdStatement:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statement = self._statement if not statement then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals({statement}, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatement:getRawValue() if not self._statement then return nil end if self._statement.mainsnak.snaktype == "value" then return rawValue(self._statement.mainsnak.datavalue) else return self._statement.mainsnak.snaktype end end function WdStatement:getRawQual(qualID) local ret = {} local s = self._statement if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(ret, rawValue(q.datavalue)) else table.insert(ret, q.snaktype) end end end return ret end ------------------------------------------------------------------------------- -- Statements Class Definition ------------------------------------------------------------------------------- local WdStatements = class() function WdStatements:getStatmentsTable() return self._statements end function WdStatements:count() return #self._statements end function WdStatements:getFilters() return self.filtered_by end function WdStatements:filter(filter_t) local statements = self._statements if #statements == 0 then return self; end local ret = WdStatements:new() ret.parent = self.parent ret.filtered_by = {} for _,v in ipairs(self.filtered_by) do table.insert(ret.filtered_by, v) end local filtered_statements = {} for k,v in pairs(filter_t) do filtered_statements = filterbyqualifier(statements, k, v) table.insert(ret.filtered_by, {[k] = v}) if #filtered_statements == 0 then break; else statements = filtered_statements end end ret._statements = filtered_statements return ret end function WdStatements:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getQual(qualID, opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getRawQual(qualID) local ret = {} for _,s in pairs(self._statements) do local qual_t = {} if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(qual_t, rawValue(q.datavalue)) else table.insert(qual_t, q.snaktype) end end end table.insert(ret,qual_t) end return ret end function WdStatements:getRawValue() local ret = {} for _,v in pairs(self._statements) do if v.mainsnak.snaktype=="value" then table.insert(ret, rawValue(v.mainsnak.datavalue)) else table.insert(ret, v.mainsnak.snaktype) end end return ret end function WdStatements:get(index) local ret = WdStatement:new() ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = self._statements[index] ret.pid = ret.pid return ret end function WdStatements:getBestOne() local orderd_statements = orderbyrank(self._statements) local ret = WdStatement:new() --setmetatable({}, WdStatement) ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = orderd_statements[1] ret.pid = ret.pid return ret end ------------------------------------------------------------------------------- -- WdItem Class Definition ------------------------------------------------------------------------------- local WdItem = class() function WdItem:__tostring() return "WdItem: " .. (self.qid or "no QID") end function WdItem:UpdateOptions(newOpts) for k, v in pairs(newOpts or {}) do local key = options_aliases[k] self.options[key] = v -- Set default options if key == 'langs' and #v > 0 then self.options.langobj = findLang(self.options.langs[1]) self.options.lang = self.options.langobj.code if not self.options.langobj then self.options.langobj = findLang(self.options.lang) self.options.lang = self.options.langobj.code end end if key == 'rank' then self.options.reqranks = setRanks(self.options.rank) end end if not self.options.reqranks then self.options.reqranks = setRanks('preferred normal') end end function WdItem:init(qid, options) if qid == "" then qid = nil end if not qid then qid = mw.wikibase.getEntityIdForCurrentPage() end self.qid = qid self.snak = nil self.options = options or {} self:UpdateOptions(options) return self end function WdItem:newFromSnaks(snakTable, options) local self = WdItem:new() self.qid = nil self.snak = snakTable or {} self.options = options or {} self:UpdateOptions(options) return self end function WdItem:setOptions(newOpts) self:UpdateOptions(newOpts) end function WdItem:getStatements(pid, opts) local mergedOpts = mergeOptions(self.options, opts or {}) local statements local ret = WdStatements:new() ret.parent = self ret.filtered_by = {} ret._statements = {} ret.pid = pid if self.snak and self.snak[pid] then statements = self.snak[pid] elseif not self.qid or not mw.wikibase then statements = {} elseif mergedOpts.reqranks and mergedOpts.reqranks.best then statements = mw.wikibase.getBestStatements(self.qid, pid) or {} else statements = mw.wikibase.getAllStatements(self.qid, pid) or {} local filtered_statements = {} if not (mergedOpts.reqranks.deprecated == true and mergedOpts.reqranks.preferred == true and mergedOpts.reqranks.normal == true) then for _,s in pairs(statements) do if mergedOpts.reqranks[s.rank] then table.insert(filtered_statements,s) end end end statements = filtered_statements end if #statements > 0 and mergedOpts.qualifiedaspossible and mergedOpts.qualifiedaspossible ~= {} then local filtered_statements = {} for q,qv in pairs(mergedOpts.qualifiedaspossible) do filtered_statements = filterbyqualifier(statements, q, qv) if #filtered_statements > 0 then table.insert(ret.filtered_by, {[q] = qv}) statements = filtered_statements end end end if #statements > 0 and mergedOpts.qualified and mergedOpts.qualified ~= {} then for q,qv in pairs(mergedOpts.qualified) do statements = filterbyqualifier(statements, q, qv) table.insert(ret.filtered_by, {[q] = qv}) if #statements == 0 then break; end end end ret._statements = statements return ret end function WdItem:getValue(pid, opts) local mergedOpts = mergeOptions(self.options, opts) local statements = self:getStatements(pid, mergedOpts):getStatmentsTable() if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.qid, pid) end function WdItem:getValueFromSnaks(pid, opts) if not self.snak or not self.snak[pid] then return nil end local mergedOpts = mergeOptions(self.options, opts) local props = self.snak[pid] local out = propertyvalueandquals(props, mergedOpts) return assembleoutput(out, mergedOpts, nil, pid) end function WdItem:getPropertyIDsTable(pid, opts) local mergedOpts = mergeOptions(self.options, opts) mergedOpts.noicon = tostring(parseParam(mergedOpts.noicon or "", true)) local statements = self:getStatements(pid, opts) if not statements or #statements == 0 then return {} end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local out = {} for i, v in ipairs(statements) do local snak = v.mainsnak if (snak.datatype == "wikibase-item") and (v.rank and mergedOpts.reqranks[v.rank:sub(1, 1)]) and (snak.snaktype == "value") and (sourced(v) or not onlysrc) then out[#out+1] = snak.datavalue.value.id end if maxvals > 0 and #out >= maxvals then break end end return out end function WdItem:getPropertyIDs(pid, opts) local out = WdItem:getPropertyIDsTable(pid, opts) if #out == 0 then return nil end return assembleoutput(out, mergeOptions(self.options, opts), self.qid, pid) end function WdItem:getPropOfProp(prop1, prop2, opts) local mergedOpts = mergeOptions(self.options, opts) if not self.qid then return nil end local statements1 = self:getStatements(prop1, opts) if not statements1 or #statements1 == 0 then return nil end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = {} for k, v in ipairs(statements1) do if not onlysrc or sourced(v) then local snak = v.mainsnak if snak.datatype == "wikibase-item" and snak.snaktype == "value" then local qid2 = snak.datavalue.value.id local item2 = WdItem.new(qid2, mergedOpts) local statements2 = item2:getStatements(prop2, opts) if statements2 and statements2[1] then local out2 = propertyvalueandquals(statements2, mergedOpts, qualID) out[#out+1] = assembleoutput(out2, mergedOpts, qid2, prop2) end end end if maxvals > 0 and #out >= maxvals then break end end return assembleoutput(out, mergedOpts, self.qid, prop1) end function WdItem:getLangOfProp(pid) if not pid or not self.qid then return {} end local out = {} local props = mw.wikibase.getAllStatements(self.qid, pid) for _, v in ipairs(props) do if v.mainsnak.datatype == "monolingualtext" and v.mainsnak.datavalue then out[#out + 1] = v.mainsnak.datavalue.value.language end end return out end function WdItem:followQid(props, all) all = parseParam(all, false) props = (props or ""):upper() if not self.qid then return nil end if props == "" then return self.qid end local out = {} for p in mw.text.gsplit(props, "%p") do p = mw.text.trim(p) for i, v in ipairs(mw.wikibase.getBestStatements(self.qid, p)) do local linkedid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id if linkedid then if all then out[#out+1] = linkedid else return linkedid end end end end if #out > 0 then return table.concat(out, " ") else return self.qid end end ------------------------------------------------------------------------------- -- Public API - WdItem Constructors ------------------------------------------------------------------------------- p.WdItem = WdItem function p.newItem(qid, opts) return WdItem:new(qid, opts) end function p.newSnakItem(snakTable, opts) return WdItem:newFromSnaks(snakTable, opts) end return p 5tx5vh5z8d6rzfnxktcvw567rbzvb39 1097284 1097238 2026-07-22T20:34:24Z حبيشان 31560 1097284 Scribunto text/plain -- Module: WdItem -- Object-oriented Wikidata access module for Lua -- Refactored from WikidataIB for direct Lua usage require("strict") local p = {} -- i18n configuration local i18n = { ["errors"] = { ["property-not-found"] = "الخاصية غير موجودة.", ["entity-not-found"] = "الكيان على ويكي بيانات غير موجود.", ["unknown-claim-type"] = "نوع الادعاء غير معروف.", ["local-article-not-found"] = "المعرف متاح على ويكي بيانات، ولكن المقال غير متاح على ويكيبيديا", }, ["months"] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, ["Unknown"] = "Unknown", ["NaN"] = "Not a number", ["missinginfocat"] = "[[تصنيف:Articles with missing Wikidata information]]", ["list separator"] = ", ", ["list separator-ar"] = "، ", } -- Date precision constants local dp = { [6] = "millennium", [7] = "century", [8] = "decade", [9] = "year", [10] = "month", [11] = "day", } local options_aliases = { ["osd"] = "onlysourced", ["wdlinks"] = "wdl", ["uabbr"] = "unitabbr", ["qo"] = "qualsonly", ["lp"] = "linkprefix", ["lprefix"] = "linkprefix", ["qlp"] = "qlinkprefix", ["sn"] = "shortname", ["uselabel"] = "uselbl", ["plaindate"] = "pd", ["qualifierdateformat"] = "qdf", ["df"] = "qdf", ["qshortname"] = "qsn" } setmetatable(options_aliases, { __index = function(t, k) return k end }) ------------------------------------------------------------------------------- -- Internal helper functions ------------------------------------------------------------------------------- local function findLang(langcode) local langobj langcode = mw.text.trim(langcode or "") if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langcode = mw.getCurrentFrame():callParserFunction('int', {'lang'}) if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langobj = mw.language.getContentLanguage() end end return langobj end local function parseParam(param, default) if param == nil then return default end return param end local function setRanks(rank) rank = (rank or ""):lower() local ranks = {} for w in string.gmatch(rank, "%a+") do if w == "best" or w == "preferred" or w == "normal" or w == "deprecated" then ranks[w] = true end end if ranks.best or not next(ranks) then ranks.preferred = true ranks.normal = true ranks.deprecated = false end return ranks end local function labelOrId(id, lang) if lang == "default" then lang = findLang().code end local label if lang then label = mw.wikibase.getLabelByLang(id, lang) end if not label then local trylang = {"ar","en","fr", "mul"} local triedlang = lang for _,lang in pairs(trylang) do if triedlang ~= lang then label = mw.wikibase.getLabelByLang(id, lang) if label ~= "" then break end end end end if label then return mw.text.nowiki(label), true else return id, false end end local function roundto(x, sf) if x == 0 then return 0 end local s = 1 if x < 0 then x = -x s = -1 end if sf < 1 then sf = 1 end local p = 10 ^ (math.floor(math.log10(x)) - sf + 1) x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end return x end local function decimalPrecision(x, p) local s = 1 if x < 0 then x = -x s = -1 end if not tonumber(p) then p = 1e-4 elseif p > 1 then p = 1 elseif p < 1e-6 then p = 1e-6 else p = 10 ^ math.floor(math.log10(p)) end x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end if math.abs(x) < 1e-4 then x = string.format("%f", x) end return x end local function decimalToDMS(x, p) if not tonumber(p) then p = 1e-4 end local d = math.floor(x) local ms = (x - d) * 60 if p > 0.5 then if ms > 30 then d = d + 1 end ms = 0 end local m = math.floor(ms) local s = (ms - m) * 60 if p > 0.008 then if s > 30 then m = m +1 end s = 0 elseif p > 0.00014 then s = math.floor(s + 0.5) elseif p > 0.000014 then s = math.floor(10 * s + 0.5) / 10 elseif p > 0.0000014 then s = math.floor(100 * s + 0.5) / 100 else s = math.floor(1000 * s + 0.5) / 1000 end return d, m, s end local function rawValue(dataValue) if dataValue.type == "string" then return dataValue.value elseif dataValue.type == "wikibase-entityid" then return dataValue.value and dataValue.value.id elseif dataValue.type == "monolingualtext" then return dataValue.value.text elseif dataValue.type == "quantity" then return tonumber(dataValue.value.amount) elseif dataValue.type == 'time' then return dataValue.value.time elseif dataValue.type == "globecoordinate" then return dataValue.value.latitude .. '/' .. dataValue.value.longitude end end local function compareValue(dataValue, strValue) return rawValue(dataValue) == strValue end local function dateFormat(timestamp, dprec, df, bcf, pd, qualifiers, lang, adj, model) df = (df or ""):lower() if df == "ymd" then if timestamp:sub(1,1) == "+" then return timestamp:sub(2,11) else local yr = tonumber(timestamp:sub(2,5)) - 1 yr = ("000" .. yr):sub(-4) if yr ~= "0000" then yr = "-" .. yr end return yr .. timestamp:sub(6,11) end end timestamp = timestamp:gsub("%-00%-00T", "-01-01T") dprec = dprec or 11 if df == "y" and dprec > 9 then dprec = 9 end dprec = dprec>11 and 11 or dprec dprec = dprec<6 and 6 or dprec bcf = (bcf or ""):upper() pd = (pd or ""):sub(1,1):lower() if pd == "" or pd == "n" or pd == "f" or pd == "0" then pd = false end lang = lang or findLang().code adj = adj or "" local bc = timestamp:sub(1, 1)=="-" and "BC" or "" local year, month, day = timestamp:match("[+-](%d*)-(%d*)-(%d*)T") local iso = tonumber(year) if dprec == 6 then iso = math.floor( (iso - 1) / 1000 ) + 1 end if dprec == 7 then iso = math.floor( (iso - 1) / 100 ) + 1 end if dprec == 8 then iso = math.floor( iso / 10 ) .. "0" end if dprec == 10 then iso = year .. "-" .. month end if dprec == 11 then iso = year .. "-" .. month .. "-" .. day end local sc = not pd and qualifiers and qualifiers.P1480 if sc then for k1, v1 in pairs(sc) do if v1.datavalue and v1.datavalue.value.id == "Q5727902" then adj = "circa" break end end end local calendarmodel = "" if tonumber(year) > 1582 and dprec > 8 and not pd and model == "http://www.wikidata.org/entity/Q1985786" then calendarmodel = "julian" end -- Simplified date formatting (complex date module not available) local fdate = tostring(iso) if bc ~= "" then fdate = fdate .. " " .. (bcf == "BC" and "BC" or "BCE") end if adj == "circa" then fdate = "c. " .. fdate end return fdate end local function hijriFormat(qualifiers, dateformat, lang) if not qualifiers.P4241 then return; end local year, month, day local val local qhmonths = {["Q1952053"]=1,["Q489557"]=2, ["Q474167"] = 3, ["Q273815"] = 4, ["Q852002"] = 5, ["Q822218"] = 6, ["Q194210"] = 7, ["Q220914"] = 8, ["Q8867089"]=9, ["Q685440"]=10,["Q150853"]=11,["Q186022"]=12 } local hmonths = {"محرم","صفر","ربيع الأول","ربيع الآخر","جمادى الأولى","جمادى الآخرة","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة"} local hmonths_inv = {["محرم"] = 1, ["صفر"]=2, ["ربيع الأول"]=3, ["ربيع الآخر"]=4, ["جمادى الأولى"]=5, ["جمادى الآخرة"]=6, ["رجب"]=7, ["شعبان"]=8, ["رمضان"]=9, ["شوال"]=10, ["ذو القعدة"]=11, ["ذو الحجة"]=12} for _, item in ipairs(qualifiers.P4241) do local timeQ = item.datavalue and item.datavalue.value and item.datavalue.value.id local hastime = false if timeQ then local timeQt = mw.wikibase.getBestStatements(timeQ, "P361") for _,timeQsnak in pairs(timeQt) do local timeType = timeQsnak.mainsnak and timeQsnak.mainsnak.datavalue and timeQsnak.mainsnak.datavalue.value and timeQsnak.mainsnak.datavalue.value.id if timeType == "Q28892" then local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then year = mw.ustring.match(timeLableAr, "^(%d+) *هـ$") end if not year then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then year = mw.ustring.match(timeLableAr, "^(%d+) *AH$") end end hastime=true elseif qhmonths[timeType] then month = qhmonths[timeType] if month>0 and month<13 then month = hmonths[month] end local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end if not day then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end end hastime=true end end if not hastime then timeQt = mw.wikibase.getBestStatements(timeQ, "P31") if "Q125390868" == (timeQt[1].mainsnak and timeQt[1].mainsnak.datavalue and timeQt[1].mainsnak.datavalue.value and timeQt[1].mainsnak.datavalue.value.id ) then val = mw.wikibase.getLabelByLang(timeQ, "ar") month, year = mw.ustring.match(val, "^(%a[%a ]+%a) *(%d+) *هـ?$") end end end end if year then if dateformat == "y" then return year; elseif day and month then return day .. ' ' .. month .. ' ' .. year; elseif month then return month .. ' ' .. year; end end return nil; end local function sourced(claim) if claim.references then for kr, vr in pairs(claim.references) do local ref = mw.wikibase.renderSnaks(vr.snaks) if not ref:find("Wiki") then return true end end end end local function linkedItem(id, args) local lprefix = (args.linkprefix or ""):gsub('"', '') local lpostfix = (args.lpostfix or ""):gsub('"', '') local prefix = (args.prefix or ""):gsub('"', '') local postfix = (args.postfix or ""):gsub('"', '') local dtxt = args.dtxt local uselbl = parseParam( args.uselbl, true) local disp local sitelink = mw.wikibase.getSitelink(id, args.linksproject) local label, islabel if dtxt then label, islabel = dtxt, true else label, islabel = labelOrId(id, args.lang) end if sitelink then if not uselbl then local pos = sitelink:find(":") or 0 local slink = sitelink if pos > 0 then local pfx = sitelink:sub(1,pos-1) if mw.site.namespaces[pfx] then slink = sitelink:sub(pos+1) end end slink = slink:gsub("%s%(.+%)$", ""):gsub(",.+$", "") if label:find("^%u") then label = slink:gsub("^(%l)", string.upper) else label = slink:gsub("^(%u)", string.lower) end end disp = "[[" .. lprefix .. sitelink .. lpostfix .. "|" .. prefix .. label .. postfix .. "]]" elseif islabel then disp = prefix .. label .. postfix else disp = prefix .. label .. postfix .. i18n.missinginfocat end return disp end local function rendersnak(propval, args, linked, lpre, lpost, pre, post, uabbr, filter) lpre = lpre or "" lpost = lpost or "" pre = pre or "" post = post or "" args.lang = args.lang or findLang().code local snak = propval.mainsnak or propval local dtype = snak.datatype local dv = snak.datavalue dv = dv and dv.value local val, mlt local namedas; namedas = propval.qualifiers and propval.qualifiers.P1932 and propval.qualifiers.P1932[1].datavalue and propval.qualifiers.P1932[1].datavalue.value or nil args.dtxt = namedas if propval.rank and not args.reqranks[propval.rank] then return nil elseif snak.snaktype == "somevalue" then val = namedas or i18n["Unknown"] elseif snak.snaktype == "novalue" then -- return nothing elseif dtype == "wikibase-item" then local qnumber = dv.id if linked then val = linkedItem(qnumber, args) else if namedas then val = pre .. namedas .. post else local label, islabel = labelOrId(qnumber, args.lang) val = pre .. label .. post end end elseif dtype == "time" then if args.hijri then val = hijriFormat(propval.qualifiers, args.df, args.lang) else val = dateFormat(dv.time, dv.precision, args.df, args.bc, args.pd, propval.qualifiers, args.lang, "", dv.calendarmodel) end elseif dtype == "commonsMedia" or dtype == "external-id" or dtype == "string" or dtype == "url" then if (lpre == "" or lpre == ":") and lpost == "" then val = pre .. dv .. post elseif dtype == "external-id" then val = "[" .. lpre .. dv .. lpost .. " " .. pre .. dv .. post .. "]" else val = "[[" .. lpre .. dv .. lpost .. "|" .. pre .. dv .. post .. "]]" end elseif dtype == "quantity" then local amount = tonumber(dv.amount) or i18n["NaN"] local unit = "" local unitqid = string.match(dv.unit, "(Q%d+)") if filter and unitqid ~= filter then return nil end if unitqid then local uname = mw.wikibase.getLabelByLang(unitqid, args.lang) or "" if uname ~= "" then unit = " " .. uname end end val = tostring(amount) .. unit elseif dtype == "globe-coordinate" then local lat, long, prec = dv.latitude, dv.longitude, dv.precision local show = (args.show or ""):lower() if show == "lat" then val = decimalPrecision(lat, prec) elseif show == "lon" then val = decimalPrecision(long, prec) elseif show == "longlat" then val = decimalPrecision(long, prec) .. ", " .. decimalPrecision(lat, prec) else local ns = lat < 0 and "S" or "N" local ew = long < 0 and "W" or "E" if lat < 0 then lat = -lat end if long < 0 then long = -long end val = decimalPrecision(lat, prec) .. "°" .. ns .. " " .. decimalPrecision(long, prec) .. "°" .. ew end elseif dtype == "monolingualtext" then val = pre .. dv.text .. post mlt = dv.language else val = "unknown data type: " .. dtype end return val, mlt end local function assembleoutput(out, args, entityID, propertyID) local sorted = parseParam(args.sorted, false) local noic = parseParam(args.noicon, false) local list = args.list or "" local separator = args.sep or "" separator = string.gsub(separator, '"', '') if separator == "" then local rtl_lang = {ar = true, fa = true, ur = true, ku = true, he = true} separator = rtl_lang[args.lang] and i18n["list separator-ar"] or i18n["list separator"] end local strout if #out > 0 then if sorted then table.sort(out) end if list == "" then strout = table.concat(out, separator) elseif list:lower() == "prose" then strout = mw.text.listToText(out) else strout = mw.getCurrentFrame():expandTemplate{title = list, args = out} end else strout = nil end return strout end local function propertyvalueandquals(objproperty, args, qualID) -- needs this style of declaration because it's re-entrant -- onlysourced is a boolean passed to return only values sourced to other than Wikipedia -- if nothing or an empty string is passed set it true local onlysrc = parseParam(args.onlysourced, false) -- linked is a a boolean that enables the link to a local page via sitelink -- if nothing or an empty string is passed set it true local linked = parseParam(args.linked, true) -- prefix is a string that may be nil, empty (""), or a string of characters -- this is prefixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local prefix = (args.prefix or ""):gsub('"', '') -- postfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local postfix = (args.postfix or ""):gsub('"', '') -- linkprefix is a string that may be nil, empty (""), or a string of characters -- this creates a link and is then prefixed to each value -- useful when when multiple values are returned and indirect links are needed -- any double-quotes " are stripped out, so that spaces may be passed local lprefix = (args.linkprefix or ""):gsub('"', '') -- linkpostfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value when linking is enabled with lprefix -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local lpostfix = (args.linkpostfix or ""):gsub('"', '') -- wdlinks is a boolean passed to enable links to Wikidata when no article exists -- if nothing or an empty string is passed set it false local wdl = parseParam(args.wdl, false) -- unitabbr is a boolean passed to enable unit abbreviations for common units -- if nothing or an empty string is passed set it false local uabbr = parseParam(args.unitabbr, false) -- qualsonly is a boolean passed to return just the qualifiers -- if nothing or an empty string is passed set it false local qualsonly = parseParam(args.qualsonly, false) -- maxvals is a string that may be nil, empty (""), or a number -- this determines how many items may be returned when multiple values are available -- setting it = 1 is useful where the returned string is used within another call, e.g. image local maxvals = tonumber(args.maxvals) or 0 -- pd boolean -- to disable/enable "sourcing cirumstances" or use adjectival form for the plain date local pd = args.pd or false args.pd = pd -- allow qualifiers to have a different date format; default to year unless qualsonly is set args.qdf = args.qdf or (not qualsonly and "y") local lang = args.lang or (args.langs and args.langs[1]) or findLang().code -- qualID is a string list of wanted qualifiers or "ALL" qualID = qualID or "" -- capitalise list of wanted qualifiers and substitute "DATES" qualID = qualID:upper():gsub("DATES", "P580, P582") local allflag = (qualID == "ALL") -- create table of wanted qualifiers as key local qwanted = {} -- create sequence of wanted qualifiers local qorder = {} for q in mw.text.gsplit(qualID, "%p") do -- split at punctuation and iterate local qtrim = mw.text.trim(q) if qtrim ~= "" then qwanted[mw.text.trim(q)] = true qorder[#qorder+1] = qtrim end end -- qsep is the output separator for rendering qualifier list local qsep = (args.qsep or ""):gsub('"', '') -- qargs are the arguments to supply to assembleoutput() local qargs = { ["osd"] = "false", ["linked"] = tostring(linked), ["prefix"] = args.qprefix, ["postfix"] = args.qpostfix, ["linkprefix"] = args.qlinkprefix, ["linkpostfix"] = args.qlinkpostfix, ["wdl"] = "false", ["unitabbr"] = tostring(uabbr), ["maxvals"] = 0, ["sorted"] = tostring(args.qsorted), ["noicon"] = "true", ["list"] = args.qlist, ["sep"] = qsep, -- ["langobj"] = args.langobj, ["lang"] = args.lang or (args.langs and args.lang[1]), ["df"] = args.qdf, ["sn"] = parseParam(args.qsn, false), } -- all proper values of a Wikidata property will be the same type as the first -- qualifiers don't have a mainsnak, properties do --#Modified line local datatype = objproperty[1].datatype or (objproperty[1].mainsnak and objproperty[1].mainsnak.datatype) -- out[] holds the a list of returned values for this property -- mlt[] holds the language code if the datatype is monolingual text local out = {} local mlt = {} for k, v in ipairs(objproperty) do local hasvalue = true if (onlysrc and not sourced(v)) then -- no value: it isn't sourced when onlysourced=true hasvalue = false else local val, lcode = rendersnak(v, args, linked, lprefix, lpostfix, prefix, postfix, uabbr) if not val then hasvalue = false -- rank doesn't match elseif qualsonly and qualID then -- suppress value returned: only qualifiers are requested else out[#out+1], mlt[#out+1] = val, lcode end end -- See if qualifiers are to be returned: local snak = v.mainsnak or v if hasvalue and v.qualifiers and qualID ~= "" and snak.snaktype~="novalue" then -- collect all wanted qualifier values returned in qlist, indexed by propertyID local qlist = {} local timestart, timeend = "", "" -- loop through qualifiers for k1, v1 in pairs(v.qualifiers) do if allflag or qwanted[k1] then if k1 == "P1326" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before") elseif k1 == "P1319" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after") elseif k1 == "P580" then timestart = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one start time as valid elseif k1 == "P582" then timeend = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one end time as valid else local q = assembleoutput(propertyvalueandquals(v1, qargs), qargs) -- we already deal with circa via 'sourcing circumstances' if the datatype was time -- circa may be either linked or unlinked *** internationalise later *** if datatype ~= "time" or q ~= "circa" and not (type(q) == "string" and q:find("circa]]")) then qlist[k1] = q end end end -- of test for wanted end -- of loop through qualifiers -- set date separator local t = timestart .. timeend -- *** internationalise date separators later *** local dsep = "&ndash;" if t:find("%s") or t:find("&nbsp;") then dsep = " &ndash; " end -- set the order for the list of qualifiers returned; start time and end time go last if next(qlist) then local qlistout = {} if allflag then for k2, v2 in pairs(qlist) do qlistout[#qlistout+1] = v2 end else for i2, v2 in ipairs(qorder) do qlistout[#qlistout+1] = qlist[v2] end end if t ~= "" then qlistout[#qlistout+1] = timestart .. dsep .. timeend end local qstr = assembleoutput(qlistout, qargs) if qualsonly then out[#out+1] = qstr else out[#out] = out[#out] .. " (" .. qstr .. ")" end elseif t ~= "" then if qualsonly then if timestart == "" then out[#out+1] = timeend elseif timeend == "" then out[#out+1] = timestart else out[#out+1] = timestart .. dsep .. timeend end else out[#out] = out[#out] .. " (" .. timestart .. dsep .. timeend .. ")" end end end -- of test for qualifiers wanted if maxvals > 0 and #out >= maxvals then break end end -- of for each value loop -- we need to pick one value to return if the datatype was "monolingualtext" -- if there's only one value, use that -- otherwise look through the fallback languages for a match if datatype == "monolingualtext" and #out >1 then lang = mw.text.split( lang, '-', true )[1] local fbtbl = mw.language.getFallbacksFor( lang ) table.insert( fbtbl, 1, lang ) local bestval = "" local found = false for idx1, lang1 in ipairs(fbtbl) do for idx2, lang2 in ipairs(mlt) do if (lang1 == lang2) and not found then bestval = out[idx2] found = true break end end -- loop through values of property end -- loop through fallback languages if found then -- replace output table with a table containing the best value out = { bestval } else -- more than one value and none of them on the list of fallback languages -- sod it, just give them the first one out = { out[1] } end end return out end local function mergeOptions(defaults, overrides) overrides = overrides or {} defaults = defaults or {} local result = {} for k, v in pairs(defaults) do result[k] = v end for k, v in pairs(overrides) do result[k] = v if k == 'rank' then result.reqranks = setRanks(v) end end return result end local function filterbyqualifier(statements,qual,value) local filtered_statements = {} for _, statement in ipairs(statements) do if statement.qualifiers and statement.qualifiers[qual] then if '*' == value then table.insert(filtered_statements, statement) else for _, q in ipairs(statement.qualifiers[qual]) do if q.datavalue and (rawValue(q.datavalue) == value) then table.insert(filtered_statements, statement) break end end end end end return filtered_statements end local function orderbyrank(statements) local pref_count = 0 local sorted_statements = {} for k,v in ipairs(statements) do if v.rank == 'preferred' then pref_count = pref_count + 1 table.insert(sorted_statements, pref_count, v) else table.insert(sorted_statements, v) end end return sorted_statements end ------------------------------------------------------------------------------- -- helper class functions ------------------------------------------------------------------------------- local function class() local c = {} c.__index = c function c:new(...) local o = setmetatable({}, c) if o.init then o:init(...) end return o end return c end ------------------------------------------------------------------------------- -- Statement Class Definition ------------------------------------------------------------------------------- local WdStatement = class() function WdStatement:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statement = self._statement if not statement then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals({statement}, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatement:getRawValue() if not self._statement then return nil end if self._statement.mainsnak.snaktype == "value" then return rawValue(self._statement.mainsnak.datavalue) else return self._statement.mainsnak.snaktype end end function WdStatement:getRawQual(qualID) local ret = {} local s = self._statement if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(ret, rawValue(q.datavalue)) else table.insert(ret, q.snaktype) end end end return ret end ------------------------------------------------------------------------------- -- Statements Class Definition ------------------------------------------------------------------------------- local WdStatements = class() function WdStatements:getStatmentsTable() return self._statements end function WdStatements:count() return #self._statements end function WdStatements:getFilters() return self.filtered_by end function WdStatements:filter(filter_t) local statements = self._statements if #statements == 0 then return self; end local ret = WdStatements:new() ret.parent = self.parent ret.filtered_by = {} for _,v in ipairs(self.filtered_by) do table.insert(ret.filtered_by, v) end local filtered_statements = {} for k,v in pairs(filter_t) do filtered_statements = filterbyqualifier(statements, k, v) table.insert(ret.filtered_by, {[k] = v}) if #filtered_statements == 0 then break; else statements = filtered_statements end end ret._statements = filtered_statements return ret end function WdStatements:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getQual(qualID, opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getRawQual(qualID) local ret = {} for _,s in pairs(self._statements) do local qual_t = {} if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(qual_t, rawValue(q.datavalue)) else table.insert(qual_t, q.snaktype) end end end table.insert(ret,qual_t) end return ret end function WdStatements:getRawValue() local ret = {} for _,v in pairs(self._statements) do if v.mainsnak.snaktype=="value" then table.insert(ret, rawValue(v.mainsnak.datavalue)) else table.insert(ret, v.mainsnak.snaktype) end end return ret end function WdStatements:get(index) local ret = WdStatement:new() ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = self._statements[index] ret.pid = ret.pid return ret end function WdStatements:getBestOne() local orderd_statements = orderbyrank(self._statements) local ret = WdStatement:new() --setmetatable({}, WdStatement) ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = orderd_statements[1] ret.pid = ret.pid return ret end ------------------------------------------------------------------------------- -- WdItem Class Definition ------------------------------------------------------------------------------- local WdItem = class() function WdItem:__tostring() return "WdItem: " .. (self.qid or "no QID") end function WdItem:UpdateOptions(newOpts) for k, v in pairs(newOpts or {}) do local key = options_aliases[k] self.options[key] = v -- Set default options if key == 'langs' and #v > 0 then self.options.langobj = findLang(self.options.langs[1]) self.options.lang = self.options.langobj.code if not self.options.langobj then self.options.langobj = findLang(self.options.lang) self.options.lang = self.options.langobj.code end end if key == 'rank' then self.options.reqranks = setRanks(self.options.rank) end end if not self.options.reqranks then self.options.reqranks = setRanks('preferred normal') end end function WdItem:init(qid, options,snak) if qid == "" then qid = nil; end self.qid = qid self.snak = snak self.options = options or {} self:UpdateOptions(options) return self end function WdItem:newFromSnaks(snakTable, options) local self = WdItem:new(nil, options or {}, snakTable) self:UpdateOptions(options) return self end function WdItem:setOptions(newOpts) self:UpdateOptions(newOpts) end function WdItem:getStatements(pid, opts) local mergedOpts = mergeOptions(self.options, opts or {}) local statements local ret = WdStatements:new() ret.parent = self ret.filtered_by = {} ret._statements = {} ret.pid = pid if self.snak and self.snak[pid] then statements = self.snak[pid] elseif not self.qid or not mw.wikibase then statements = {} elseif mergedOpts.reqranks and mergedOpts.reqranks.best then statements = mw.wikibase.getBestStatements(self.qid, pid) or {} else statements = mw.wikibase.getAllStatements(self.qid, pid) or {} local filtered_statements = {} if not (mergedOpts.reqranks.deprecated == true and mergedOpts.reqranks.preferred == true and mergedOpts.reqranks.normal == true) then for _,s in pairs(statements) do if mergedOpts.reqranks[s.rank] then table.insert(filtered_statements,s) end end end statements = filtered_statements end if #statements > 0 and mergedOpts.qualifiedaspossible and mergedOpts.qualifiedaspossible ~= {} then local filtered_statements = {} for q,qv in pairs(mergedOpts.qualifiedaspossible) do filtered_statements = filterbyqualifier(statements, q, qv) if #filtered_statements > 0 then table.insert(ret.filtered_by, {[q] = qv}) statements = filtered_statements end end end if #statements > 0 and mergedOpts.qualified and mergedOpts.qualified ~= {} then for q,qv in pairs(mergedOpts.qualified) do statements = filterbyqualifier(statements, q, qv) table.insert(ret.filtered_by, {[q] = qv}) if #statements == 0 then break; end end end ret._statements = statements return ret end function WdItem:getValue(pid, opts) local mergedOpts = mergeOptions(self.options, opts) local statements = self:getStatements(pid, mergedOpts):getStatmentsTable() if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.qid, pid) end function WdItem:getValueFromSnaks(pid, opts) if not self.snak or not self.snak[pid] then return nil end local mergedOpts = mergeOptions(self.options, opts) local props = self.snak[pid] local out = propertyvalueandquals(props, mergedOpts) return assembleoutput(out, mergedOpts, nil, pid) end function WdItem:getPropertyIDsTable(pid, opts) local mergedOpts = mergeOptions(self.options, opts) mergedOpts.noicon = tostring(parseParam(mergedOpts.noicon or "", true)) local statements = self:getStatements(pid, opts) if not statements or #statements == 0 then return {} end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local out = {} for i, v in ipairs(statements) do local snak = v.mainsnak if (snak.datatype == "wikibase-item") and (v.rank and mergedOpts.reqranks[v.rank:sub(1, 1)]) and (snak.snaktype == "value") and (sourced(v) or not onlysrc) then out[#out+1] = snak.datavalue.value.id end if maxvals > 0 and #out >= maxvals then break end end return out end function WdItem:getPropertyIDs(pid, opts) local out = WdItem:getPropertyIDsTable(pid, opts) if #out == 0 then return nil end return assembleoutput(out, mergeOptions(self.options, opts), self.qid, pid) end function WdItem:getPropOfProp(prop1, prop2, opts) local mergedOpts = mergeOptions(self.options, opts) if not self.qid then return nil end local statements1 = self:getStatements(prop1, opts) if not statements1 or #statements1 == 0 then return nil end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = {} for k, v in ipairs(statements1) do if not onlysrc or sourced(v) then local snak = v.mainsnak if snak.datatype == "wikibase-item" and snak.snaktype == "value" then local qid2 = snak.datavalue.value.id local item2 = WdItem.new(qid2, mergedOpts) local statements2 = item2:getStatements(prop2, opts) if statements2 and statements2[1] then local out2 = propertyvalueandquals(statements2, mergedOpts, qualID) out[#out+1] = assembleoutput(out2, mergedOpts, qid2, prop2) end end end if maxvals > 0 and #out >= maxvals then break end end return assembleoutput(out, mergedOpts, self.qid, prop1) end function WdItem:getLangOfProp(pid) if not pid then return {}; end local out = {} local props = self.snak and self.snak[pid] or mw.wikibase.getAllStatements(self.qid, pid) for _, v in ipairs(props) do if v.mainsnak.datatype == "monolingualtext" and v.mainsnak.datavalue then out[#out + 1] = v.mainsnak.datavalue.value.language end end return out end function WdItem:followQid(props, all) all = parseParam(all, false) props = (props or ""):upper() if not self.qid then return nil end if props == "" then return self.qid end local out = {} for p in mw.text.gsplit(props, "%p") do p = mw.text.trim(p) for i, v in ipairs(mw.wikibase.getBestStatements(self.qid, p)) do local linkedid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id if linkedid then if all then out[#out+1] = linkedid else return linkedid end end end end if #out > 0 then return table.concat(out, " ") else return self.qid end end ------------------------------------------------------------------------------- -- Public API - WdItem Constructors ------------------------------------------------------------------------------- p.WdItem = WdItem function p.newItem(qid, opts) return WdItem:new(qid, opts) end function p.newSnakItem(snakTable, opts) return WdItem:newFromSnaks(snakTable, opts) end return p snhr4ojyf5zilqa4guc1dl4l872nrix 1097285 1097284 2026-07-22T20:51:55Z حبيشان 31560 1097285 Scribunto text/plain -- Module: WdItem -- Object-oriented Wikidata access module for Lua -- Refactored from WikidataIB for direct Lua usage require("strict") local p = {} -- i18n configuration local i18n = { ["errors"] = { ["property-not-found"] = "الخاصية غير موجودة.", ["entity-not-found"] = "الكيان على ويكي بيانات غير موجود.", ["unknown-claim-type"] = "نوع الادعاء غير معروف.", ["local-article-not-found"] = "المعرف متاح على ويكي بيانات، ولكن المقال غير متاح على ويكيبيديا", }, ["months"] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, ["Unknown"] = "Unknown", ["NaN"] = "Not a number", ["missinginfocat"] = "[[تصنيف:Articles with missing Wikidata information]]", ["list separator"] = ", ", ["list separator-ar"] = "، ", } -- Date precision constants local dp = { [6] = "millennium", [7] = "century", [8] = "decade", [9] = "year", [10] = "month", [11] = "day", } local options_aliases = { ["osd"] = "onlysourced", ["wdlinks"] = "wdl", ["uabbr"] = "unitabbr", ["qo"] = "qualsonly", ["lp"] = "linkprefix", ["lprefix"] = "linkprefix", ["qlp"] = "qlinkprefix", ["sn"] = "shortname", ["uselabel"] = "uselbl", ["plaindate"] = "pd", ["qualifierdateformat"] = "qdf", ["df"] = "qdf", ["qshortname"] = "qsn" } setmetatable(options_aliases, { __index = function(t, k) return k end }) ------------------------------------------------------------------------------- -- Internal helper functions ------------------------------------------------------------------------------- local function findLang(langcode) local langobj langcode = mw.text.trim(langcode or "") if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langcode = mw.getCurrentFrame():callParserFunction('int', {'lang'}) if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langobj = mw.language.getContentLanguage() end end return langobj end local function parseParam(param, default) if param == nil then return default end return param end local function setRanks(rank) rank = (rank or ""):lower() local ranks = {} for w in string.gmatch(rank, "%a+") do if w == "best" or w == "preferred" or w == "normal" or w == "deprecated" then ranks[w] = true end end if ranks.best or not next(ranks) then ranks.preferred = true ranks.normal = true ranks.deprecated = false end return ranks end local function labelOrId(id, lang) if lang == "default" then lang = findLang().code end local label if lang then label = mw.wikibase.getLabelByLang(id, lang) end if not label then local trylang = {"ar","en","fr", "mul"} local triedlang = lang for _,lang in pairs(trylang) do if triedlang ~= lang then label = mw.wikibase.getLabelByLang(id, lang) if label ~= "" then break end end end end if label then return mw.text.nowiki(label), true else return id, false end end local function roundto(x, sf) if x == 0 then return 0 end local s = 1 if x < 0 then x = -x s = -1 end if sf < 1 then sf = 1 end local p = 10 ^ (math.floor(math.log10(x)) - sf + 1) x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end return x end local function decimalPrecision(x, p) local s = 1 if x < 0 then x = -x s = -1 end if not tonumber(p) then p = 1e-4 elseif p > 1 then p = 1 elseif p < 1e-6 then p = 1e-6 else p = 10 ^ math.floor(math.log10(p)) end x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end if math.abs(x) < 1e-4 then x = string.format("%f", x) end return x end local function decimalToDMS(x, p) if not tonumber(p) then p = 1e-4 end local d = math.floor(x) local ms = (x - d) * 60 if p > 0.5 then if ms > 30 then d = d + 1 end ms = 0 end local m = math.floor(ms) local s = (ms - m) * 60 if p > 0.008 then if s > 30 then m = m +1 end s = 0 elseif p > 0.00014 then s = math.floor(s + 0.5) elseif p > 0.000014 then s = math.floor(10 * s + 0.5) / 10 elseif p > 0.0000014 then s = math.floor(100 * s + 0.5) / 100 else s = math.floor(1000 * s + 0.5) / 1000 end return d, m, s end local function rawValue(dataValue) if dataValue.type == "string" then return dataValue.value elseif dataValue.type == "wikibase-entityid" then return dataValue.value and dataValue.value.id elseif dataValue.type == "monolingualtext" then return dataValue.value.text elseif dataValue.type == "quantity" then return tonumber(dataValue.value.amount) elseif dataValue.type == 'time' then return dataValue.value.time elseif dataValue.type == "globecoordinate" then return dataValue.value.latitude .. '/' .. dataValue.value.longitude end end local function compareValue(dataValue, strValue) return rawValue(dataValue) == strValue end local function dateFormat(timestamp, dprec, df, bcf, pd, qualifiers, lang, adj, model) df = (df or ""):lower() if df == "ymd" then if timestamp:sub(1,1) == "+" then return timestamp:sub(2,11) else local yr = tonumber(timestamp:sub(2,5)) - 1 yr = ("000" .. yr):sub(-4) if yr ~= "0000" then yr = "-" .. yr end return yr .. timestamp:sub(6,11) end end timestamp = timestamp:gsub("%-00%-00T", "-01-01T") dprec = dprec or 11 if df == "y" and dprec > 9 then dprec = 9 end dprec = dprec>11 and 11 or dprec dprec = dprec<6 and 6 or dprec bcf = (bcf or ""):upper() pd = (pd or ""):sub(1,1):lower() if pd == "" or pd == "n" or pd == "f" or pd == "0" then pd = false end lang = lang or findLang().code adj = adj or "" local bc = timestamp:sub(1, 1)=="-" and "BC" or "" local year, month, day = timestamp:match("[+-](%d*)-(%d*)-(%d*)T") local iso = tonumber(year) if dprec == 6 then iso = math.floor( (iso - 1) / 1000 ) + 1 end if dprec == 7 then iso = math.floor( (iso - 1) / 100 ) + 1 end if dprec == 8 then iso = math.floor( iso / 10 ) .. "0" end if dprec == 10 then iso = year .. "-" .. month end if dprec == 11 then iso = year .. "-" .. month .. "-" .. day end local sc = not pd and qualifiers and qualifiers.P1480 if sc then for k1, v1 in pairs(sc) do if v1.datavalue and v1.datavalue.value.id == "Q5727902" then adj = "circa" break end end end local calendarmodel = "" if tonumber(year) > 1582 and dprec > 8 and not pd and model == "http://www.wikidata.org/entity/Q1985786" then calendarmodel = "julian" end -- Simplified date formatting (complex date module not available) local fdate = tostring(iso) if bc ~= "" then fdate = fdate .. " " .. (bcf == "BC" and "BC" or "BCE") end if adj == "circa" then fdate = "c. " .. fdate end return fdate end local function hijriFormat(qualifiers, dateformat, lang) if not qualifiers.P4241 then return; end local year, month, day local val local qhmonths = {["Q1952053"]=1,["Q489557"]=2, ["Q474167"] = 3, ["Q273815"] = 4, ["Q852002"] = 5, ["Q822218"] = 6, ["Q194210"] = 7, ["Q220914"] = 8, ["Q8867089"]=9, ["Q685440"]=10,["Q150853"]=11,["Q186022"]=12 } local hmonths = {"محرم","صفر","ربيع الأول","ربيع الآخر","جمادى الأولى","جمادى الآخرة","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة"} local hmonths_inv = {["محرم"] = 1, ["صفر"]=2, ["ربيع الأول"]=3, ["ربيع الآخر"]=4, ["جمادى الأولى"]=5, ["جمادى الآخرة"]=6, ["رجب"]=7, ["شعبان"]=8, ["رمضان"]=9, ["شوال"]=10, ["ذو القعدة"]=11, ["ذو الحجة"]=12} for _, item in ipairs(qualifiers.P4241) do local timeQ = item.datavalue and item.datavalue.value and item.datavalue.value.id local hastime = false if timeQ then local timeQt = mw.wikibase.getBestStatements(timeQ, "P361") for _,timeQsnak in pairs(timeQt) do local timeType = timeQsnak.mainsnak and timeQsnak.mainsnak.datavalue and timeQsnak.mainsnak.datavalue.value and timeQsnak.mainsnak.datavalue.value.id if timeType == "Q28892" then local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then year = mw.ustring.match(timeLableAr, "^(%d+) *هـ$") end if not year then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then year = mw.ustring.match(timeLableAr, "^(%d+) *AH$") end end hastime=true elseif qhmonths[timeType] then month = qhmonths[timeType] if month>0 and month<13 then month = hmonths[month] end local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end if not day then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end end hastime=true end end if not hastime then timeQt = mw.wikibase.getBestStatements(timeQ, "P31") if "Q125390868" == (timeQt[1].mainsnak and timeQt[1].mainsnak.datavalue and timeQt[1].mainsnak.datavalue.value and timeQt[1].mainsnak.datavalue.value.id ) then val = mw.wikibase.getLabelByLang(timeQ, "ar") month, year = mw.ustring.match(val, "^(%a[%a ]+%a) *(%d+) *هـ?$") end end end end if year then if dateformat == "y" then return year; elseif day and month then return day .. ' ' .. month .. ' ' .. year; elseif month then return month .. ' ' .. year; end end return nil; end local function sourced(claim) if claim.references then for kr, vr in pairs(claim.references) do local ref = mw.wikibase.renderSnaks(vr.snaks) if not ref:find("Wiki") then return true end end end end local function linkedItem(id, args) local lprefix = (args.linkprefix or ""):gsub('"', '') local lpostfix = (args.lpostfix or ""):gsub('"', '') local prefix = (args.prefix or ""):gsub('"', '') local postfix = (args.postfix or ""):gsub('"', '') local dtxt = args.dtxt local uselbl = parseParam( args.uselbl, true) local disp local sitelink = mw.wikibase.getSitelink(id, args.linksproject) local label, islabel if dtxt then label, islabel = dtxt, true else label, islabel = labelOrId(id, args.lang) end if sitelink then if not uselbl then local pos = sitelink:find(":") or 0 local slink = sitelink if pos > 0 then local pfx = sitelink:sub(1,pos-1) if mw.site.namespaces[pfx] then slink = sitelink:sub(pos+1) end end slink = slink:gsub("%s%(.+%)$", ""):gsub(",.+$", "") if label:find("^%u") then label = slink:gsub("^(%l)", string.upper) else label = slink:gsub("^(%u)", string.lower) end end disp = "[[" .. lprefix .. sitelink .. lpostfix .. "|" .. prefix .. label .. postfix .. "]]" elseif islabel then disp = prefix .. label .. postfix else disp = prefix .. label .. postfix .. i18n.missinginfocat end return disp end local function rendersnak(propval, args, linked, lpre, lpost, pre, post, uabbr, filter) lpre = lpre or "" lpost = lpost or "" pre = pre or "" post = post or "" args.lang = args.lang or findLang().code local snak = propval.mainsnak or propval local dtype = snak.datatype local dv = snak.datavalue dv = dv and dv.value local val, mlt local namedas; namedas = propval.qualifiers and propval.qualifiers.P1932 and propval.qualifiers.P1932[1].datavalue and propval.qualifiers.P1932[1].datavalue.value or nil args.dtxt = namedas if propval.rank and not args.reqranks[propval.rank] then return nil elseif snak.snaktype == "somevalue" then val = namedas or i18n["Unknown"] elseif snak.snaktype == "novalue" then -- return nothing elseif dtype == "wikibase-item" then local qnumber = dv.id if linked then val = linkedItem(qnumber, args) else if namedas then val = pre .. namedas .. post else local label, islabel = labelOrId(qnumber, args.lang) val = pre .. label .. post end end elseif dtype == "time" then if args.hijri then val = hijriFormat(propval.qualifiers, args.df, args.lang) else val = dateFormat(dv.time, dv.precision, args.df, args.bc, args.pd, propval.qualifiers, args.lang, "", dv.calendarmodel) end elseif dtype == "commonsMedia" or dtype == "external-id" or dtype == "string" or dtype == "url" then if (lpre == "" or lpre == ":") and lpost == "" then val = pre .. dv .. post elseif dtype == "external-id" then val = "[" .. lpre .. dv .. lpost .. " " .. pre .. dv .. post .. "]" else val = "[[" .. lpre .. dv .. lpost .. "|" .. pre .. dv .. post .. "]]" end elseif dtype == "quantity" then local amount = tonumber(dv.amount) or i18n["NaN"] local unit = "" local unitqid = string.match(dv.unit, "(Q%d+)") if filter and unitqid ~= filter then return nil end if unitqid then local uname = mw.wikibase.getLabelByLang(unitqid, args.lang) or "" if uname ~= "" then unit = " " .. uname end end val = tostring(amount) .. unit elseif dtype == "globe-coordinate" then local lat, long, prec = dv.latitude, dv.longitude, dv.precision local show = (args.show or ""):lower() if show == "lat" then val = decimalPrecision(lat, prec) elseif show == "lon" then val = decimalPrecision(long, prec) elseif show == "longlat" then val = decimalPrecision(long, prec) .. ", " .. decimalPrecision(lat, prec) else local ns = lat < 0 and "S" or "N" local ew = long < 0 and "W" or "E" if lat < 0 then lat = -lat end if long < 0 then long = -long end val = decimalPrecision(lat, prec) .. "°" .. ns .. " " .. decimalPrecision(long, prec) .. "°" .. ew end elseif dtype == "monolingualtext" then val = pre .. dv.text .. post mlt = dv.language else val = "unknown data type: " .. dtype end return val, mlt end local function assembleoutput(out, args, entityID, propertyID) local sorted = parseParam(args.sorted, false) local noic = parseParam(args.noicon, false) local list = args.list or "" local separator = args.sep or "" separator = string.gsub(separator, '"', '') if separator == "" then local rtl_lang = {ar = true, fa = true, ur = true, ku = true, he = true} separator = rtl_lang[args.lang] and i18n["list separator-ar"] or i18n["list separator"] end local strout if #out > 0 then if sorted then table.sort(out) end if list == "" then strout = table.concat(out, separator) elseif list:lower() == "prose" then strout = mw.text.listToText(out) else strout = mw.getCurrentFrame():expandTemplate{title = list, args = out} end else strout = nil end return strout end local function propertyvalueandquals(objproperty, args, qualID) -- needs this style of declaration because it's re-entrant -- onlysourced is a boolean passed to return only values sourced to other than Wikipedia -- if nothing or an empty string is passed set it true local onlysrc = parseParam(args.onlysourced, false) -- linked is a a boolean that enables the link to a local page via sitelink -- if nothing or an empty string is passed set it true local linked = parseParam(args.linked, true) -- prefix is a string that may be nil, empty (""), or a string of characters -- this is prefixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local prefix = (args.prefix or ""):gsub('"', '') -- postfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local postfix = (args.postfix or ""):gsub('"', '') -- linkprefix is a string that may be nil, empty (""), or a string of characters -- this creates a link and is then prefixed to each value -- useful when when multiple values are returned and indirect links are needed -- any double-quotes " are stripped out, so that spaces may be passed local lprefix = (args.linkprefix or ""):gsub('"', '') -- linkpostfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value when linking is enabled with lprefix -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local lpostfix = (args.linkpostfix or ""):gsub('"', '') -- wdlinks is a boolean passed to enable links to Wikidata when no article exists -- if nothing or an empty string is passed set it false local wdl = parseParam(args.wdl, false) -- unitabbr is a boolean passed to enable unit abbreviations for common units -- if nothing or an empty string is passed set it false local uabbr = parseParam(args.unitabbr, false) -- qualsonly is a boolean passed to return just the qualifiers -- if nothing or an empty string is passed set it false local qualsonly = parseParam(args.qualsonly, false) -- maxvals is a string that may be nil, empty (""), or a number -- this determines how many items may be returned when multiple values are available -- setting it = 1 is useful where the returned string is used within another call, e.g. image local maxvals = tonumber(args.maxvals) or 0 -- pd boolean -- to disable/enable "sourcing cirumstances" or use adjectival form for the plain date local pd = args.pd or false args.pd = pd -- allow qualifiers to have a different date format; default to year unless qualsonly is set args.qdf = args.qdf or (not qualsonly and "y") local lang = args.lang or (args.langs and args.langs[1]) or findLang().code -- qualID is a string list of wanted qualifiers or "ALL" qualID = qualID or "" -- capitalise list of wanted qualifiers and substitute "DATES" qualID = qualID:upper():gsub("DATES", "P580, P582") local allflag = (qualID == "ALL") -- create table of wanted qualifiers as key local qwanted = {} -- create sequence of wanted qualifiers local qorder = {} for q in mw.text.gsplit(qualID, "%p") do -- split at punctuation and iterate local qtrim = mw.text.trim(q) if qtrim ~= "" then qwanted[mw.text.trim(q)] = true qorder[#qorder+1] = qtrim end end -- qsep is the output separator for rendering qualifier list local qsep = (args.qsep or ""):gsub('"', '') -- qargs are the arguments to supply to assembleoutput() local qargs = { ["osd"] = "false", ["linked"] = tostring(linked), ["prefix"] = args.qprefix, ["postfix"] = args.qpostfix, ["linkprefix"] = args.qlinkprefix, ["linkpostfix"] = args.qlinkpostfix, ["wdl"] = "false", ["unitabbr"] = tostring(uabbr), ["maxvals"] = 0, ["sorted"] = tostring(args.qsorted), ["noicon"] = "true", ["list"] = args.qlist, ["sep"] = qsep, -- ["langobj"] = args.langobj, ["lang"] = args.lang or (args.langs and args.lang[1]), ["df"] = args.qdf, ["sn"] = parseParam(args.qsn, false), } -- all proper values of a Wikidata property will be the same type as the first -- qualifiers don't have a mainsnak, properties do --#Modified line local datatype = objproperty[1].datatype or (objproperty[1].mainsnak and objproperty[1].mainsnak.datatype) -- out[] holds the a list of returned values for this property -- mlt[] holds the language code if the datatype is monolingual text local out = {} local mlt = {} for k, v in ipairs(objproperty) do local hasvalue = true if (onlysrc and not sourced(v)) then -- no value: it isn't sourced when onlysourced=true hasvalue = false else local val, lcode = rendersnak(v, args, linked, lprefix, lpostfix, prefix, postfix, uabbr) if not val then hasvalue = false -- rank doesn't match elseif qualsonly and qualID then -- suppress value returned: only qualifiers are requested else out[#out+1], mlt[#out+1] = val, lcode end end -- See if qualifiers are to be returned: local snak = v.mainsnak or v if hasvalue and v.qualifiers and qualID ~= "" and snak.snaktype~="novalue" then -- collect all wanted qualifier values returned in qlist, indexed by propertyID local qlist = {} local timestart, timeend = "", "" -- loop through qualifiers for k1, v1 in pairs(v.qualifiers) do if allflag or qwanted[k1] then if k1 == "P1326" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before") elseif k1 == "P1319" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after") elseif k1 == "P580" then timestart = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one start time as valid elseif k1 == "P582" then timeend = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one end time as valid else local q = assembleoutput(propertyvalueandquals(v1, qargs), qargs) -- we already deal with circa via 'sourcing circumstances' if the datatype was time -- circa may be either linked or unlinked *** internationalise later *** if datatype ~= "time" or q ~= "circa" and not (type(q) == "string" and q:find("circa]]")) then qlist[k1] = q end end end -- of test for wanted end -- of loop through qualifiers -- set date separator local t = timestart .. timeend -- *** internationalise date separators later *** local dsep = "&ndash;" if t:find("%s") or t:find("&nbsp;") then dsep = " &ndash; " end -- set the order for the list of qualifiers returned; start time and end time go last if next(qlist) then local qlistout = {} if allflag then for k2, v2 in pairs(qlist) do qlistout[#qlistout+1] = v2 end else for i2, v2 in ipairs(qorder) do qlistout[#qlistout+1] = qlist[v2] end end if t ~= "" then qlistout[#qlistout+1] = timestart .. dsep .. timeend end local qstr = assembleoutput(qlistout, qargs) if qualsonly then out[#out+1] = qstr else out[#out] = out[#out] .. " (" .. qstr .. ")" end elseif t ~= "" then if qualsonly then if timestart == "" then out[#out+1] = timeend elseif timeend == "" then out[#out+1] = timestart else out[#out+1] = timestart .. dsep .. timeend end else out[#out] = out[#out] .. " (" .. timestart .. dsep .. timeend .. ")" end end end -- of test for qualifiers wanted if maxvals > 0 and #out >= maxvals then break end end -- of for each value loop -- we need to pick one value to return if the datatype was "monolingualtext" -- if there's only one value, use that -- otherwise look through the fallback languages for a match if datatype == "monolingualtext" and #out >1 then lang = mw.text.split( lang, '-', true )[1] local fbtbl = mw.language.getFallbacksFor( lang ) table.insert( fbtbl, 1, lang ) local bestval = "" local found = false for idx1, lang1 in ipairs(fbtbl) do for idx2, lang2 in ipairs(mlt) do if (lang1 == lang2) and not found then bestval = out[idx2] found = true break end end -- loop through values of property end -- loop through fallback languages if found then -- replace output table with a table containing the best value out = { bestval } else -- more than one value and none of them on the list of fallback languages -- sod it, just give them the first one out = { out[1] } end end return out end local function mergeOptions(defaults, overrides) overrides = overrides or {} defaults = defaults or {} local result = {} for k, v in pairs(defaults) do result[k] = v end for k, v in pairs(overrides) do result[k] = v if k == 'rank' then result.reqranks = setRanks(v) end end return result end local function filterbyqualifier(statements,qual,value) local filtered_statements = {} for _, statement in ipairs(statements) do if statement.qualifiers and statement.qualifiers[qual] then if '*' == value then table.insert(filtered_statements, statement) else for _, q in ipairs(statement.qualifiers[qual]) do if q.datavalue and (rawValue(q.datavalue) == value) then table.insert(filtered_statements, statement) break end end end end end return filtered_statements end local function orderbyrank(statements) local pref_count = 0 local sorted_statements = {} for k,v in ipairs(statements) do if v.rank == 'preferred' then pref_count = pref_count + 1 table.insert(sorted_statements, pref_count, v) else table.insert(sorted_statements, v) end end return sorted_statements end ------------------------------------------------------------------------------- -- helper class functions ------------------------------------------------------------------------------- local function class() local c = {} c.__index = c function c:new(...) local o = setmetatable({}, c) if o.init then o:init(...) end return o end return c end ------------------------------------------------------------------------------- -- Statement Class Definition ------------------------------------------------------------------------------- local WdStatement = class() function WdStatement:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statement = self._statement if not statement then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals({statement}, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatement:getRawValue() if not self._statement then return nil end if self._statement.mainsnak.snaktype == "value" then return rawValue(self._statement.mainsnak.datavalue) else return self._statement.mainsnak.snaktype end end function WdStatement:getRawQual(qualID) local ret = {} local s = self._statement if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(ret, rawValue(q.datavalue)) else table.insert(ret, q.snaktype) end end end return ret end ------------------------------------------------------------------------------- -- Statements Class Definition ------------------------------------------------------------------------------- local WdStatements = class() function WdStatements:getStatmentsTable() return self._statements end function WdStatements:count() return #self._statements end function WdStatements:getFilters() return self.filtered_by end function WdStatements:filter(filter_t) local statements = self._statements if #statements == 0 then return self; end local ret = WdStatements:new() ret.parent = self.parent ret.filtered_by = {} for _,v in ipairs(self.filtered_by) do table.insert(ret.filtered_by, v) end local filtered_statements = {} for k,v in pairs(filter_t) do filtered_statements = filterbyqualifier(statements, k, v) table.insert(ret.filtered_by, {[k] = v}) if #filtered_statements == 0 then break; else statements = filtered_statements end end ret._statements = filtered_statements return ret end function WdStatements:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getQual(qualID, opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getRawQual(qualID) local ret = {} for _,s in pairs(self._statements) do local qual_t = {} if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(qual_t, rawValue(q.datavalue)) else table.insert(qual_t, q.snaktype) end end end table.insert(ret,qual_t) end return ret end function WdStatements:getRawValue() local ret = {} for _,v in pairs(self._statements) do if v.mainsnak.snaktype=="value" then table.insert(ret, rawValue(v.mainsnak.datavalue)) else table.insert(ret, v.mainsnak.snaktype) end end return ret end function WdStatements:get(index) local ret = WdStatement:new() ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = self._statements[index] ret.pid = ret.pid return ret end function WdStatements:getBestOne() local orderd_statements = orderbyrank(self._statements) local ret = WdStatement:new() --setmetatable({}, WdStatement) ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = orderd_statements[1] ret.pid = ret.pid return ret end ------------------------------------------------------------------------------- -- WdItem Class Definition ------------------------------------------------------------------------------- local WdItem = class() function WdItem:__tostring() return "WdItem: " .. (self.qid or "no QID") end function WdItem:UpdateOptions(newOpts) for k, v in pairs(newOpts or {}) do local key = options_aliases[k] self.options[key] = v -- Set default options if key == 'langs' and #v > 0 then self.options.langobj = findLang(self.options.langs[1]) self.options.lang = self.options.langobj.code if not self.options.langobj then self.options.langobj = findLang(self.options.lang) self.options.lang = self.options.langobj.code end end if key == 'rank' then self.options.reqranks = setRanks(self.options.rank) end end if not self.options.reqranks then self.options.reqranks = setRanks('preferred normal') end end function WdItem:init(qid, options,snak) if qid == "" then qid = nil; end self.qid = qid self.snak = snak self.options = options or {} self:UpdateOptions(options) return self end function WdItem:newFromSnaks(snakTable, options) local self = WdItem:new(nil, options or {}, snakTable) self:UpdateOptions(options) return self end function WdItem:setOptions(newOpts) self:UpdateOptions(newOpts) end function WdItem:getStatements(pid, opts) local mergedOpts = mergeOptions(self.options, opts or {}) local statements local ret = WdStatements:new() ret.parent = self ret.filtered_by = {} ret._statements = {} ret.pid = pid if self.snak and self.snak[pid] then statements = self.snak[pid] elseif not self.qid or not mw.wikibase then statements = {} elseif mergedOpts.reqranks and mergedOpts.reqranks.best then statements = mw.wikibase.getBestStatements(self.qid, pid) or {} else statements = mw.wikibase.getAllStatements(self.qid, pid) or {} local filtered_statements = {} if not (mergedOpts.reqranks.deprecated == true and mergedOpts.reqranks.preferred == true and mergedOpts.reqranks.normal == true) then for _,s in pairs(statements) do if mergedOpts.reqranks[s.rank] then table.insert(filtered_statements,s) end end end statements = filtered_statements end if #statements > 0 and mergedOpts.qualifiedaspossible and mergedOpts.qualifiedaspossible ~= {} then local filtered_statements = {} for q,qv in pairs(mergedOpts.qualifiedaspossible) do filtered_statements = filterbyqualifier(statements, q, qv) if #filtered_statements > 0 then table.insert(ret.filtered_by, {[q] = qv}) statements = filtered_statements end end end if #statements > 0 and mergedOpts.qualified and mergedOpts.qualified ~= {} then for q,qv in pairs(mergedOpts.qualified) do statements = filterbyqualifier(statements, q, qv) table.insert(ret.filtered_by, {[q] = qv}) if #statements == 0 then break; end end end ret._statements = statements return ret end function WdItem:getValue(pid, opts) local mergedOpts = mergeOptions(self.options, opts) local statements = self:getStatements(pid, mergedOpts):getStatmentsTable() if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.qid, pid) end function WdItem:getValueFromSnaks(pid, opts) if not self.snak or not self.snak[pid] then return nil end local mergedOpts = mergeOptions(self.options, opts) local props = self.snak[pid] local out = propertyvalueandquals(props, mergedOpts) return assembleoutput(out, mergedOpts, nil, pid) end function WdItem:getPropertyIDsTable(pid, opts) local mergedOpts = mergeOptions(self.options, opts) mergedOpts.noicon = tostring(parseParam(mergedOpts.noicon or "", true)) local statements = self:getStatements(pid, opts) if not statements or #statements == 0 then return {} end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local out = {} for i, v in ipairs(statements) do local snak = v.mainsnak if (snak.datatype == "wikibase-item") and (v.rank and mergedOpts.reqranks[v.rank:sub(1, 1)]) and (snak.snaktype == "value") and (sourced(v) or not onlysrc) then out[#out+1] = snak.datavalue.value.id end if maxvals > 0 and #out >= maxvals then break end end return out end function WdItem:getPropertyIDs(pid, opts) local out = WdItem:getPropertyIDsTable(pid, opts) if #out == 0 then return nil end return assembleoutput(out, mergeOptions(self.options, opts), self.qid, pid) end function WdItem:getPropOfProp(prop1, prop2, opts) local mergedOpts = mergeOptions(self.options, opts) if not self.qid then return nil end local statements1 = self:getStatements(prop1, opts) if not statements1 or #statements1 == 0 then return nil end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = {} for k, v in ipairs(statements1) do if not onlysrc or sourced(v) then local snak = v.mainsnak if snak.datatype == "wikibase-item" and snak.snaktype == "value" then local qid2 = snak.datavalue.value.id local item2 = WdItem.new(qid2, mergedOpts) local statements2 = item2:getStatements(prop2, opts) if statements2 and statements2[1] then local out2 = propertyvalueandquals(statements2, mergedOpts, qualID) out[#out+1] = assembleoutput(out2, mergedOpts, qid2, prop2) end end end if maxvals > 0 and #out >= maxvals then break end end return assembleoutput(out, mergedOpts, self.qid, prop1) end function WdItem:getLangOfProp(pid) if not pid then return {}; end local out = {} local props = self.snak and self.snak[pid] or (self.qid and mw.wikibase.getAllStatements(self.qid, pid)) or {} for _, v in ipairs(props) do if v.mainsnak.datatype == "monolingualtext" and v.mainsnak.datavalue then out[#out + 1] = v.mainsnak.datavalue.value.language end end return out end function WdItem:followQid(props, all) all = parseParam(all, false) props = (props or ""):upper() if not self.qid then return nil end if props == "" then return self.qid end local out = {} for p in mw.text.gsplit(props, "%p") do p = mw.text.trim(p) for i, v in ipairs(mw.wikibase.getBestStatements(self.qid, p)) do local linkedid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id if linkedid then if all then out[#out+1] = linkedid else return linkedid end end end end if #out > 0 then return table.concat(out, " ") else return self.qid end end ------------------------------------------------------------------------------- -- Public API - WdItem Constructors ------------------------------------------------------------------------------- p.WdItem = WdItem function p.newItem(qid, opts, snak ) return WdItem:new(qid, opts, snak) end function p.newSnakItem(snakTable, opts) return WdItem:newFromSnaks(snakTable, opts) end return p o0ek6595wqc98fa6xr0vg2ex4tn2plw 1097288 1097285 2026-07-22T21:27:48Z حبيشان 31560 1097288 Scribunto text/plain -- Module: WdItem -- Object-oriented Wikidata access module for Lua -- Refactored from WikidataIB for direct Lua usage require("strict") local p = {} -- i18n configuration local i18n = { ["errors"] = { ["property-not-found"] = "الخاصية غير موجودة.", ["entity-not-found"] = "الكيان على ويكي بيانات غير موجود.", ["unknown-claim-type"] = "نوع الادعاء غير معروف.", ["local-article-not-found"] = "المعرف متاح على ويكي بيانات، ولكن المقال غير متاح على ويكيبيديا", }, ["months"] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, ["Unknown"] = "Unknown", ["NaN"] = "Not a number", ["missinginfocat"] = "[[تصنيف:Articles with missing Wikidata information]]", ["list separator"] = ", ", ["list separator-ar"] = "، ", } -- Date precision constants local dp = { [6] = "millennium", [7] = "century", [8] = "decade", [9] = "year", [10] = "month", [11] = "day", } local options_aliases = { ["osd"] = "onlysourced", ["wdlinks"] = "wdl", ["uabbr"] = "unitabbr", ["qo"] = "qualsonly", ["lp"] = "linkprefix", ["lprefix"] = "linkprefix", ["qlp"] = "qlinkprefix", ["sn"] = "shortname", ["uselabel"] = "uselbl", ["plaindate"] = "pd", ["qualifierdateformat"] = "qdf", ["df"] = "qdf", ["qshortname"] = "qsn" } setmetatable(options_aliases, { __index = function(t, k) return k end }) ------------------------------------------------------------------------------- -- Internal helper functions ------------------------------------------------------------------------------- local function findLang(langcode) local langobj langcode = mw.text.trim(langcode or "") if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langcode = mw.getCurrentFrame():callParserFunction('int', {'lang'}) if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langobj = mw.language.getContentLanguage() end end return langobj end local function parseParam(param, default) if param == nil then return default end return param end local function setRanks(rank) rank = (rank or ""):lower() local ranks = {} for w in string.gmatch(rank, "%a+") do if w == "best" or w == "preferred" or w == "normal" or w == "deprecated" then ranks[w] = true end end if ranks.best or not next(ranks) then ranks.preferred = true ranks.normal = true ranks.deprecated = false end return ranks end local function labelOrId(id, lang) if lang == "default" then lang = findLang().code end local label if lang then label = mw.wikibase.getLabelByLang(id, lang) end if not label then local trylang = {"ar","en","fr", "mul"} local triedlang = lang for _,lang in pairs(trylang) do if triedlang ~= lang then label = mw.wikibase.getLabelByLang(id, lang) if label ~= "" then break end end end end if label then return mw.text.nowiki(label), true else return id, false end end local function roundto(x, sf) if x == 0 then return 0 end local s = 1 if x < 0 then x = -x s = -1 end if sf < 1 then sf = 1 end local p = 10 ^ (math.floor(math.log10(x)) - sf + 1) x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end return x end local function decimalPrecision(x, p) local s = 1 if x < 0 then x = -x s = -1 end if not tonumber(p) then p = 1e-4 elseif p > 1 then p = 1 elseif p < 1e-6 then p = 1e-6 else p = 10 ^ math.floor(math.log10(p)) end x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end if math.abs(x) < 1e-4 then x = string.format("%f", x) end return x end local function decimalToDMS(x, p) if not tonumber(p) then p = 1e-4 end local d = math.floor(x) local ms = (x - d) * 60 if p > 0.5 then if ms > 30 then d = d + 1 end ms = 0 end local m = math.floor(ms) local s = (ms - m) * 60 if p > 0.008 then if s > 30 then m = m +1 end s = 0 elseif p > 0.00014 then s = math.floor(s + 0.5) elseif p > 0.000014 then s = math.floor(10 * s + 0.5) / 10 elseif p > 0.0000014 then s = math.floor(100 * s + 0.5) / 100 else s = math.floor(1000 * s + 0.5) / 1000 end return d, m, s end local function rawValue(dataValue) if dataValue.type == "string" then return dataValue.value elseif dataValue.type == "wikibase-entityid" then return dataValue.value and dataValue.value.id elseif dataValue.type == "monolingualtext" then return dataValue.value.text elseif dataValue.type == "quantity" then return tonumber(dataValue.value.amount) elseif dataValue.type == 'time' then return dataValue.value.time elseif dataValue.type == "globecoordinate" then return dataValue.value.latitude .. '/' .. dataValue.value.longitude end end local function compareValue(dataValue, strValue) return rawValue(dataValue) == strValue end local function dateFormat(timestamp, dprec, df, bcf, pd, qualifiers, lang, adj, model) df = (df or ""):lower() if df == "ymd" then if timestamp:sub(1,1) == "+" then return timestamp:sub(2,11) else local yr = tonumber(timestamp:sub(2,5)) - 1 yr = ("000" .. yr):sub(-4) if yr ~= "0000" then yr = "-" .. yr end return yr .. timestamp:sub(6,11) end end timestamp = timestamp:gsub("%-00%-00T", "-01-01T") dprec = dprec or 11 if df == "y" and dprec > 9 then dprec = 9 end dprec = dprec>11 and 11 or dprec dprec = dprec<6 and 6 or dprec bcf = (bcf or ""):upper() pd = (pd or ""):sub(1,1):lower() if pd == "" or pd == "n" or pd == "f" or pd == "0" then pd = false end lang = lang or findLang().code adj = adj or "" local bc = timestamp:sub(1, 1)=="-" and "BC" or "" local year, month, day = timestamp:match("[+-](%d*)-(%d*)-(%d*)T") local iso = tonumber(year) if dprec == 6 then iso = math.floor( (iso - 1) / 1000 ) + 1 end if dprec == 7 then iso = math.floor( (iso - 1) / 100 ) + 1 end if dprec == 8 then iso = math.floor( iso / 10 ) .. "0" end if dprec == 10 then iso = year .. "-" .. month end if dprec == 11 then iso = year .. "-" .. month .. "-" .. day end local sc = not pd and qualifiers and qualifiers.P1480 if sc then for k1, v1 in pairs(sc) do if v1.datavalue and v1.datavalue.value.id == "Q5727902" then adj = "circa" break end end end local calendarmodel = "" if tonumber(year) > 1582 and dprec > 8 and not pd and model == "http://www.wikidata.org/entity/Q1985786" then calendarmodel = "julian" end -- Simplified date formatting (complex date module not available) local fdate = tostring(iso) if bc ~= "" then fdate = fdate .. " " .. (bcf == "BC" and "BC" or "BCE") end if adj == "circa" then fdate = "c. " .. fdate end return fdate end local function hijriFormat(qualifiers, dateformat, lang) if not qualifiers.P4241 then return; end local year, month, day local val local qhmonths = {["Q1952053"]=1,["Q489557"]=2, ["Q474167"] = 3, ["Q273815"] = 4, ["Q852002"] = 5, ["Q822218"] = 6, ["Q194210"] = 7, ["Q220914"] = 8, ["Q8867089"]=9, ["Q685440"]=10,["Q150853"]=11,["Q186022"]=12 } local hmonths = {"محرم","صفر","ربيع الأول","ربيع الآخر","جمادى الأولى","جمادى الآخرة","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة"} local hmonths_inv = {["محرم"] = 1, ["صفر"]=2, ["ربيع الأول"]=3, ["ربيع الآخر"]=4, ["جمادى الأولى"]=5, ["جمادى الآخرة"]=6, ["رجب"]=7, ["شعبان"]=8, ["رمضان"]=9, ["شوال"]=10, ["ذو القعدة"]=11, ["ذو الحجة"]=12} for _, item in ipairs(qualifiers.P4241) do local timeQ = item.datavalue and item.datavalue.value and item.datavalue.value.id local hastime = false if timeQ then local timeQt = mw.wikibase.getBestStatements(timeQ, "P361") for _,timeQsnak in pairs(timeQt) do local timeType = timeQsnak.mainsnak and timeQsnak.mainsnak.datavalue and timeQsnak.mainsnak.datavalue.value and timeQsnak.mainsnak.datavalue.value.id if timeType == "Q28892" then local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then year = mw.ustring.match(timeLableAr, "^(%d+) *هـ$") end if not year then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then year = mw.ustring.match(timeLableAr, "^(%d+) *AH$") end end hastime=true elseif qhmonths[timeType] then month = qhmonths[timeType] if month>0 and month<13 then month = hmonths[month] end local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end if not day then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end end hastime=true end end if not hastime then timeQt = mw.wikibase.getBestStatements(timeQ, "P31") if "Q125390868" == (timeQt[1].mainsnak and timeQt[1].mainsnak.datavalue and timeQt[1].mainsnak.datavalue.value and timeQt[1].mainsnak.datavalue.value.id ) then val = mw.wikibase.getLabelByLang(timeQ, "ar") month, year = mw.ustring.match(val, "^(%a[%a ]+%a) *(%d+) *هـ?$") end end end end if year then if dateformat == "y" then return year; elseif day and month then return day .. ' ' .. month .. ' ' .. year; elseif month then return month .. ' ' .. year; end end return nil; end local function sourced(claim) if claim.references then for kr, vr in pairs(claim.references) do local ref = mw.wikibase.renderSnaks(vr.snaks) if not ref:find("Wiki") then return true end end end end local function linkedItem(id, args) local lprefix = (args.linkprefix or ""):gsub('"', '') local lpostfix = (args.lpostfix or ""):gsub('"', '') local prefix = (args.prefix or ""):gsub('"', '') local postfix = (args.postfix or ""):gsub('"', '') local wikilinkprefix = (args.wikilinkprefix or ""):gsub('"', '') local dtxt = args.dtxt local uselbl = parseParam( args.uselbl, true) local disp local sitelink = mw.wikibase.getSitelink(id, args.linksproject) local label, islabel if dtxt then label, islabel = dtxt, true else label, islabel = labelOrId(id, args.lang) end if sitelink then if not uselbl then local pos = sitelink:find(":") or 0 local slink = sitelink if pos > 0 then local pfx = sitelink:sub(1,pos-1) if mw.site.namespaces[pfx] then slink = sitelink:sub(pos+1) end end slink = slink:gsub("%s%(.+%)$", ""):gsub(",.+$", "") if label:find("^%u") then label = slink:gsub("^(%l)", string.upper) else label = slink:gsub("^(%u)", string.lower) end end disp = "[[" .. wikilinkprefix .. sitelink .. lpostfix .. "|" .. prefix .. label .. postfix .. "]]" elseif islabel then disp = prefix .. label .. postfix else disp = prefix .. label .. postfix .. i18n.missinginfocat end return disp end local function rendersnak(propval, args, linked, lpre, lpost, pre, post, uabbr, filter) lpre = lpre or "" lpost = lpost or "" pre = pre or "" post = post or "" args.lang = args.lang or findLang().code local snak = propval.mainsnak or propval local dtype = snak.datatype local dv = snak.datavalue dv = dv and dv.value local val, mlt local namedas; namedas = propval.qualifiers and propval.qualifiers.P1932 and propval.qualifiers.P1932[1].datavalue and propval.qualifiers.P1932[1].datavalue.value or nil args.dtxt = namedas if propval.rank and not args.reqranks[propval.rank] then return nil elseif snak.snaktype == "somevalue" then val = namedas or i18n["Unknown"] elseif snak.snaktype == "novalue" then -- return nothing elseif dtype == "wikibase-item" then local qnumber = dv.id if linked then val = linkedItem(qnumber, args) else if namedas then val = pre .. namedas .. post else local label, islabel = labelOrId(qnumber, args.lang) val = pre .. label .. post end end elseif dtype == "time" then if args.hijri then val = hijriFormat(propval.qualifiers, args.df, args.lang) else val = dateFormat(dv.time, dv.precision, args.df, args.bc, args.pd, propval.qualifiers, args.lang, "", dv.calendarmodel) end elseif dtype == "commonsMedia" or dtype == "external-id" or dtype == "string" or dtype == "url" then if (lpre == "" or lpre == ":") and lpost == "" then val = pre .. dv .. post elseif dtype == "external-id" then val = "[" .. lpre .. dv .. lpost .. " " .. pre .. dv .. post .. "]" else val = "[[" .. lpre .. dv .. lpost .. "|" .. pre .. dv .. post .. "]]" end elseif dtype == "quantity" then local amount = tonumber(dv.amount) or i18n["NaN"] local unit = "" local unitqid = string.match(dv.unit, "(Q%d+)") if filter and unitqid ~= filter then return nil end if unitqid then local uname = mw.wikibase.getLabelByLang(unitqid, args.lang) or "" if uname ~= "" then unit = " " .. uname end end val = tostring(amount) .. unit elseif dtype == "globe-coordinate" then local lat, long, prec = dv.latitude, dv.longitude, dv.precision local show = (args.show or ""):lower() if show == "lat" then val = decimalPrecision(lat, prec) elseif show == "lon" then val = decimalPrecision(long, prec) elseif show == "longlat" then val = decimalPrecision(long, prec) .. ", " .. decimalPrecision(lat, prec) else local ns = lat < 0 and "S" or "N" local ew = long < 0 and "W" or "E" if lat < 0 then lat = -lat end if long < 0 then long = -long end val = decimalPrecision(lat, prec) .. "°" .. ns .. " " .. decimalPrecision(long, prec) .. "°" .. ew end elseif dtype == "monolingualtext" then val = pre .. dv.text .. post mlt = dv.language else val = "unknown data type: " .. dtype end return val, mlt end local function assembleoutput(out, args, entityID, propertyID) local sorted = parseParam(args.sorted, false) local noic = parseParam(args.noicon, false) local list = args.list or "" local separator = args.sep or "" separator = string.gsub(separator, '"', '') if separator == "" then local rtl_lang = {ar = true, fa = true, ur = true, ku = true, he = true} separator = rtl_lang[args.lang] and i18n["list separator-ar"] or i18n["list separator"] end local strout if #out > 0 then if sorted then table.sort(out) end if list == "" then strout = table.concat(out, separator) elseif list:lower() == "prose" then strout = mw.text.listToText(out) else strout = mw.getCurrentFrame():expandTemplate{title = list, args = out} end else strout = nil end return strout end local function propertyvalueandquals(objproperty, args, qualID) -- needs this style of declaration because it's re-entrant -- onlysourced is a boolean passed to return only values sourced to other than Wikipedia -- if nothing or an empty string is passed set it true local onlysrc = parseParam(args.onlysourced, false) -- linked is a a boolean that enables the link to a local page via sitelink -- if nothing or an empty string is passed set it true local linked = parseParam(args.linked, true) -- prefix is a string that may be nil, empty (""), or a string of characters -- this is prefixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local prefix = (args.prefix or ""):gsub('"', '') -- postfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local postfix = (args.postfix or ""):gsub('"', '') -- linkprefix is a string that may be nil, empty (""), or a string of characters -- this creates a link and is then prefixed to each value -- useful when when multiple values are returned and indirect links are needed -- any double-quotes " are stripped out, so that spaces may be passed local lprefix = (args.linkprefix or ""):gsub('"', '') -- linkpostfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value when linking is enabled with lprefix -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local lpostfix = (args.linkpostfix or ""):gsub('"', '') -- wdlinks is a boolean passed to enable links to Wikidata when no article exists -- if nothing or an empty string is passed set it false local wdl = parseParam(args.wdl, false) -- unitabbr is a boolean passed to enable unit abbreviations for common units -- if nothing or an empty string is passed set it false local uabbr = parseParam(args.unitabbr, false) -- qualsonly is a boolean passed to return just the qualifiers -- if nothing or an empty string is passed set it false local qualsonly = parseParam(args.qualsonly, false) -- maxvals is a string that may be nil, empty (""), or a number -- this determines how many items may be returned when multiple values are available -- setting it = 1 is useful where the returned string is used within another call, e.g. image local maxvals = tonumber(args.maxvals) or 0 -- pd boolean -- to disable/enable "sourcing cirumstances" or use adjectival form for the plain date local pd = args.pd or false args.pd = pd -- allow qualifiers to have a different date format; default to year unless qualsonly is set args.qdf = args.qdf or (not qualsonly and "y") local lang = args.lang or (args.langs and args.langs[1]) or findLang().code -- qualID is a string list of wanted qualifiers or "ALL" qualID = qualID or "" -- capitalise list of wanted qualifiers and substitute "DATES" qualID = qualID:upper():gsub("DATES", "P580, P582") local allflag = (qualID == "ALL") -- create table of wanted qualifiers as key local qwanted = {} -- create sequence of wanted qualifiers local qorder = {} for q in mw.text.gsplit(qualID, "%p") do -- split at punctuation and iterate local qtrim = mw.text.trim(q) if qtrim ~= "" then qwanted[mw.text.trim(q)] = true qorder[#qorder+1] = qtrim end end -- qsep is the output separator for rendering qualifier list local qsep = (args.qsep or ""):gsub('"', '') -- qargs are the arguments to supply to assembleoutput() local qargs = { ["osd"] = "false", ["linked"] = tostring(linked), ["prefix"] = args.qprefix, ["postfix"] = args.qpostfix, ["linkprefix"] = args.qlinkprefix, ["linkpostfix"] = args.qlinkpostfix, ["wdl"] = "false", ["unitabbr"] = tostring(uabbr), ["maxvals"] = 0, ["sorted"] = tostring(args.qsorted), ["noicon"] = "true", ["list"] = args.qlist, ["sep"] = qsep, -- ["langobj"] = args.langobj, ["lang"] = args.lang or (args.langs and args.lang[1]), ["df"] = args.qdf, ["sn"] = parseParam(args.qsn, false), } -- all proper values of a Wikidata property will be the same type as the first -- qualifiers don't have a mainsnak, properties do --#Modified line local datatype = objproperty[1].datatype or (objproperty[1].mainsnak and objproperty[1].mainsnak.datatype) -- out[] holds the a list of returned values for this property -- mlt[] holds the language code if the datatype is monolingual text local out = {} local mlt = {} for k, v in ipairs(objproperty) do local hasvalue = true if (onlysrc and not sourced(v)) then -- no value: it isn't sourced when onlysourced=true hasvalue = false else local val, lcode = rendersnak(v, args, linked, lprefix, lpostfix, prefix, postfix, uabbr) if not val then hasvalue = false -- rank doesn't match elseif qualsonly and qualID then -- suppress value returned: only qualifiers are requested else out[#out+1], mlt[#out+1] = val, lcode end end -- See if qualifiers are to be returned: local snak = v.mainsnak or v if hasvalue and v.qualifiers and qualID ~= "" and snak.snaktype~="novalue" then -- collect all wanted qualifier values returned in qlist, indexed by propertyID local qlist = {} local timestart, timeend = "", "" -- loop through qualifiers for k1, v1 in pairs(v.qualifiers) do if allflag or qwanted[k1] then if k1 == "P1326" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before") elseif k1 == "P1319" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after") elseif k1 == "P580" then timestart = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one start time as valid elseif k1 == "P582" then timeend = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one end time as valid else local q = assembleoutput(propertyvalueandquals(v1, qargs), qargs) -- we already deal with circa via 'sourcing circumstances' if the datatype was time -- circa may be either linked or unlinked *** internationalise later *** if datatype ~= "time" or q ~= "circa" and not (type(q) == "string" and q:find("circa]]")) then qlist[k1] = q end end end -- of test for wanted end -- of loop through qualifiers -- set date separator local t = timestart .. timeend -- *** internationalise date separators later *** local dsep = "&ndash;" if t:find("%s") or t:find("&nbsp;") then dsep = " &ndash; " end -- set the order for the list of qualifiers returned; start time and end time go last if next(qlist) then local qlistout = {} if allflag then for k2, v2 in pairs(qlist) do qlistout[#qlistout+1] = v2 end else for i2, v2 in ipairs(qorder) do qlistout[#qlistout+1] = qlist[v2] end end if t ~= "" then qlistout[#qlistout+1] = timestart .. dsep .. timeend end local qstr = assembleoutput(qlistout, qargs) if qualsonly then out[#out+1] = qstr else out[#out] = out[#out] .. " (" .. qstr .. ")" end elseif t ~= "" then if qualsonly then if timestart == "" then out[#out+1] = timeend elseif timeend == "" then out[#out+1] = timestart else out[#out+1] = timestart .. dsep .. timeend end else out[#out] = out[#out] .. " (" .. timestart .. dsep .. timeend .. ")" end end end -- of test for qualifiers wanted if maxvals > 0 and #out >= maxvals then break end end -- of for each value loop -- we need to pick one value to return if the datatype was "monolingualtext" -- if there's only one value, use that -- otherwise look through the fallback languages for a match if datatype == "monolingualtext" and #out >1 then lang = mw.text.split( lang, '-', true )[1] local fbtbl = mw.language.getFallbacksFor( lang ) table.insert( fbtbl, 1, lang ) local bestval = "" local found = false for idx1, lang1 in ipairs(fbtbl) do for idx2, lang2 in ipairs(mlt) do if (lang1 == lang2) and not found then bestval = out[idx2] found = true break end end -- loop through values of property end -- loop through fallback languages if found then -- replace output table with a table containing the best value out = { bestval } else -- more than one value and none of them on the list of fallback languages -- sod it, just give them the first one out = { out[1] } end end return out end local function mergeOptions(defaults, overrides) overrides = overrides or {} defaults = defaults or {} local result = {} for k, v in pairs(defaults) do result[k] = v end for k, v in pairs(overrides) do result[k] = v if k == 'rank' then result.reqranks = setRanks(v) end end return result end local function filterbyqualifier(statements,qual,value) local filtered_statements = {} for _, statement in ipairs(statements) do if statement.qualifiers and statement.qualifiers[qual] then if '*' == value then table.insert(filtered_statements, statement) else for _, q in ipairs(statement.qualifiers[qual]) do if q.datavalue and (rawValue(q.datavalue) == value) then table.insert(filtered_statements, statement) break end end end end end return filtered_statements end local function orderbyrank(statements) local pref_count = 0 local sorted_statements = {} for k,v in ipairs(statements) do if v.rank == 'preferred' then pref_count = pref_count + 1 table.insert(sorted_statements, pref_count, v) else table.insert(sorted_statements, v) end end return sorted_statements end ------------------------------------------------------------------------------- -- helper class functions ------------------------------------------------------------------------------- local function class() local c = {} c.__index = c function c:new(...) local o = setmetatable({}, c) if o.init then o:init(...) end return o end return c end ------------------------------------------------------------------------------- -- Statement Class Definition ------------------------------------------------------------------------------- local WdStatement = class() function WdStatement:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statement = self._statement if not statement then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals({statement}, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatement:getRawValue() if not self._statement then return nil end if self._statement.mainsnak.snaktype == "value" then return rawValue(self._statement.mainsnak.datavalue) else return self._statement.mainsnak.snaktype end end function WdStatement:getRawQual(qualID) local ret = {} local s = self._statement if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(ret, rawValue(q.datavalue)) else table.insert(ret, q.snaktype) end end end return ret end ------------------------------------------------------------------------------- -- Statements Class Definition ------------------------------------------------------------------------------- local WdStatements = class() function WdStatements:getStatmentsTable() return self._statements end function WdStatements:count() return #self._statements end function WdStatements:getFilters() return self.filtered_by end function WdStatements:filter(filter_t) local statements = self._statements if #statements == 0 then return self; end local ret = WdStatements:new() ret.parent = self.parent ret.filtered_by = {} for _,v in ipairs(self.filtered_by) do table.insert(ret.filtered_by, v) end local filtered_statements = {} for k,v in pairs(filter_t) do filtered_statements = filterbyqualifier(statements, k, v) table.insert(ret.filtered_by, {[k] = v}) if #filtered_statements == 0 then break; else statements = filtered_statements end end ret._statements = filtered_statements return ret end function WdStatements:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getQual(qualID, opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getRawQual(qualID) local ret = {} for _,s in pairs(self._statements) do local qual_t = {} if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(qual_t, rawValue(q.datavalue)) else table.insert(qual_t, q.snaktype) end end end table.insert(ret,qual_t) end return ret end function WdStatements:getRawValue() local ret = {} for _,v in pairs(self._statements) do if v.mainsnak.snaktype=="value" then table.insert(ret, rawValue(v.mainsnak.datavalue)) else table.insert(ret, v.mainsnak.snaktype) end end return ret end function WdStatements:get(index) local ret = WdStatement:new() ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = self._statements[index] ret.pid = ret.pid return ret end function WdStatements:getBestOne() local orderd_statements = orderbyrank(self._statements) local ret = WdStatement:new() --setmetatable({}, WdStatement) ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = orderd_statements[1] ret.pid = ret.pid return ret end ------------------------------------------------------------------------------- -- WdItem Class Definition ------------------------------------------------------------------------------- local WdItem = class() function WdItem:__tostring() return "WdItem: " .. (self.qid or "no QID") end function WdItem:UpdateOptions(newOpts) for k, v in pairs(newOpts or {}) do local key = options_aliases[k] self.options[key] = v -- Set default options if key == 'langs' and #v > 0 then self.options.langobj = findLang(self.options.langs[1]) self.options.lang = self.options.langobj.code if not self.options.langobj then self.options.langobj = findLang(self.options.lang) self.options.lang = self.options.langobj.code end end if key == 'rank' then self.options.reqranks = setRanks(self.options.rank) end end if not self.options.reqranks then self.options.reqranks = setRanks('preferred normal') end end function WdItem:init(qid, options,snak) if qid == "" then qid = nil; end self.qid = qid self.snak = snak self.options = options or {} self:UpdateOptions(options) return self end function WdItem:newFromSnaks(snakTable, options) local self = WdItem:new(nil, options or {}, snakTable) self:UpdateOptions(options) return self end function WdItem:setOptions(newOpts) self:UpdateOptions(newOpts) end function WdItem:getStatements(pid, opts) local mergedOpts = mergeOptions(self.options, opts or {}) local statements local ret = WdStatements:new() ret.parent = self ret.filtered_by = {} ret._statements = {} ret.pid = pid if self.snak and self.snak[pid] then statements = self.snak[pid] elseif not self.qid or not mw.wikibase then statements = {} elseif mergedOpts.reqranks and mergedOpts.reqranks.best then statements = mw.wikibase.getBestStatements(self.qid, pid) or {} else statements = mw.wikibase.getAllStatements(self.qid, pid) or {} local filtered_statements = {} if not (mergedOpts.reqranks.deprecated == true and mergedOpts.reqranks.preferred == true and mergedOpts.reqranks.normal == true) then for _,s in pairs(statements) do if mergedOpts.reqranks[s.rank] then table.insert(filtered_statements,s) end end end statements = filtered_statements end if #statements > 0 and mergedOpts.qualifiedaspossible and mergedOpts.qualifiedaspossible ~= {} then local filtered_statements = {} for q,qv in pairs(mergedOpts.qualifiedaspossible) do filtered_statements = filterbyqualifier(statements, q, qv) if #filtered_statements > 0 then table.insert(ret.filtered_by, {[q] = qv}) statements = filtered_statements end end end if #statements > 0 and mergedOpts.qualified and mergedOpts.qualified ~= {} then for q,qv in pairs(mergedOpts.qualified) do statements = filterbyqualifier(statements, q, qv) table.insert(ret.filtered_by, {[q] = qv}) if #statements == 0 then break; end end end ret._statements = statements return ret end function WdItem:getValue(pid, opts) local mergedOpts = mergeOptions(self.options, opts) local statements = self:getStatements(pid, mergedOpts):getStatmentsTable() if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.qid, pid) end function WdItem:getValueFromSnaks(pid, opts) if not self.snak or not self.snak[pid] then return nil end local mergedOpts = mergeOptions(self.options, opts) local props = self.snak[pid] local out = propertyvalueandquals(props, mergedOpts) return assembleoutput(out, mergedOpts, nil, pid) end function WdItem:getPropertyIDsTable(pid, opts) local mergedOpts = mergeOptions(self.options, opts) mergedOpts.noicon = tostring(parseParam(mergedOpts.noicon or "", true)) local statements = self:getStatements(pid, opts) if not statements or #statements == 0 then return {} end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local out = {} for i, v in ipairs(statements) do local snak = v.mainsnak if (snak.datatype == "wikibase-item") and (v.rank and mergedOpts.reqranks[v.rank:sub(1, 1)]) and (snak.snaktype == "value") and (sourced(v) or not onlysrc) then out[#out+1] = snak.datavalue.value.id end if maxvals > 0 and #out >= maxvals then break end end return out end function WdItem:getPropertyIDs(pid, opts) local out = WdItem:getPropertyIDsTable(pid, opts) if #out == 0 then return nil end return assembleoutput(out, mergeOptions(self.options, opts), self.qid, pid) end function WdItem:getPropOfProp(prop1, prop2, opts) local mergedOpts = mergeOptions(self.options, opts) if not self.qid then return nil end local statements1 = self:getStatements(prop1, opts) if not statements1 or #statements1 == 0 then return nil end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = {} for k, v in ipairs(statements1) do if not onlysrc or sourced(v) then local snak = v.mainsnak if snak.datatype == "wikibase-item" and snak.snaktype == "value" then local qid2 = snak.datavalue.value.id local item2 = WdItem.new(qid2, mergedOpts) local statements2 = item2:getStatements(prop2, opts) if statements2 and statements2[1] then local out2 = propertyvalueandquals(statements2, mergedOpts, qualID) out[#out+1] = assembleoutput(out2, mergedOpts, qid2, prop2) end end end if maxvals > 0 and #out >= maxvals then break end end return assembleoutput(out, mergedOpts, self.qid, prop1) end function WdItem:getLangOfProp(pid) if not pid then return {}; end local out = {} local props = self.snak and self.snak[pid] or (self.qid and mw.wikibase.getAllStatements(self.qid, pid)) or {} for _, v in ipairs(props) do if v.mainsnak.datatype == "monolingualtext" and v.mainsnak.datavalue then out[#out + 1] = v.mainsnak.datavalue.value.language end end return out end function WdItem:followQid(props, all) all = parseParam(all, false) props = (props or ""):upper() if not self.qid then return nil end if props == "" then return self.qid end local out = {} for p in mw.text.gsplit(props, "%p") do p = mw.text.trim(p) for i, v in ipairs(mw.wikibase.getBestStatements(self.qid, p)) do local linkedid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id if linkedid then if all then out[#out+1] = linkedid else return linkedid end end end end if #out > 0 then return table.concat(out, " ") else return self.qid end end ------------------------------------------------------------------------------- -- Public API - WdItem Constructors ------------------------------------------------------------------------------- p.WdItem = WdItem function p.newItem(qid, opts, snak ) return WdItem:new(qid, opts, snak) end function p.newSnakItem(snakTable, opts) return WdItem:newFromSnaks(snakTable, opts) end return p 3lq9n952vzwvwbqtam6xldkkr7fvete 1097319 1097288 2026-07-23T11:09:46Z حبيشان 31560 1097319 Scribunto text/plain -- Module: WdItem -- Object-oriented Wikidata access module for Lua -- Refactored from WikidataIB for direct Lua usage require("strict") local p = {} -- i18n configuration local i18n = { ["errors"] = { ["property-not-found"] = "الخاصية غير موجودة.", ["entity-not-found"] = "الكيان على ويكي بيانات غير موجود.", ["unknown-claim-type"] = "نوع الادعاء غير معروف.", ["local-article-not-found"] = "المعرف متاح على ويكي بيانات، ولكن المقال غير متاح على ويكيبيديا", }, ["months"] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, ["Unknown"] = "Unknown", ["NaN"] = "Not a number", ["missinginfocat"] = "[[تصنيف:Articles with missing Wikidata information]]", ["list separator"] = ", ", ["list separator-ar"] = "، ", } -- Date precision constants local dp = { [6] = "millennium", [7] = "century", [8] = "decade", [9] = "year", [10] = "month", [11] = "day", } local options_aliases = { ["osd"] = "onlysourced", ["wdlinks"] = "wdl", ["uabbr"] = "unitabbr", ["qo"] = "qualsonly", ["lp"] = "linkprefix", ["lprefix"] = "linkprefix", ["qlp"] = "qlinkprefix", ["sn"] = "shortname", ["uselabel"] = "uselbl", ["plaindate"] = "pd", ["qualifierdateformat"] = "qdf", ["df"] = "qdf", ["qshortname"] = "qsn" } setmetatable(options_aliases, { __index = function(t, k) return k end }) ------------------------------------------------------------------------------- -- Internal helper functions ------------------------------------------------------------------------------- local function findLang(langcode) local langobj langcode = mw.text.trim(langcode or "") if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langcode = mw.getCurrentFrame():callParserFunction('int', {'lang'}) if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langobj = mw.language.getContentLanguage() end end return langobj end local function parseParam(param, default) if param == nil then return default end return param end local function setRanks(rank) rank = (rank or ""):lower() local ranks = {} for w in string.gmatch(rank, "%a+") do if w == "best" or w == "preferred" or w == "normal" or w == "deprecated" then ranks[w] = true end end if ranks.best or not next(ranks) then ranks.preferred = true ranks.normal = true ranks.deprecated = false end return ranks end local function labelOrId(id, lang) if lang == "default" then lang = findLang().code end local label if lang then label = mw.wikibase.getLabelByLang(id, lang) end if not label then local trylang = {"ar","en","fr", "mul"} local triedlang = lang for _,lang in pairs(trylang) do if triedlang ~= lang then label = mw.wikibase.getLabelByLang(id, lang) if label ~= "" then break end end end end if label then return mw.text.nowiki(label), true else return id, false end end local function roundto(x, sf) if x == 0 then return 0 end local s = 1 if x < 0 then x = -x s = -1 end if sf < 1 then sf = 1 end local p = 10 ^ (math.floor(math.log10(x)) - sf + 1) x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end return x end local function decimalPrecision(x, p) local s = 1 if x < 0 then x = -x s = -1 end if not tonumber(p) then p = 1e-4 elseif p > 1 then p = 1 elseif p < 1e-6 then p = 1e-6 else p = 10 ^ math.floor(math.log10(p)) end x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end if math.abs(x) < 1e-4 then x = string.format("%f", x) end return x end local function decimalToDMS(x, p) if not tonumber(p) then p = 1e-4 end local d = math.floor(x) local ms = (x - d) * 60 if p > 0.5 then if ms > 30 then d = d + 1 end ms = 0 end local m = math.floor(ms) local s = (ms - m) * 60 if p > 0.008 then if s > 30 then m = m +1 end s = 0 elseif p > 0.00014 then s = math.floor(s + 0.5) elseif p > 0.000014 then s = math.floor(10 * s + 0.5) / 10 elseif p > 0.0000014 then s = math.floor(100 * s + 0.5) / 100 else s = math.floor(1000 * s + 0.5) / 1000 end return d, m, s end local function rawValue(dataValue) if dataValue.type == "string" then return dataValue.value elseif dataValue.type == "wikibase-entityid" then return dataValue.value and dataValue.value.id elseif dataValue.type == "monolingualtext" then return dataValue.value.text elseif dataValue.type == "quantity" then return tonumber(dataValue.value.amount) elseif dataValue.type == 'time' then return dataValue.value.time elseif dataValue.type == "globecoordinate" then return dataValue.value.latitude .. '/' .. dataValue.value.longitude end end local function compareValue(dataValue, strValue) return rawValue(dataValue) == strValue end local function dateFormat(timestamp, dprec, df, bcf, pd, qualifiers, lang, adj, model) df = (df or ""):lower() if df == "ymd" then if timestamp:sub(1,1) == "+" then return timestamp:sub(2,11) else local yr = tonumber(timestamp:sub(2,5)) - 1 yr = ("000" .. yr):sub(-4) if yr ~= "0000" then yr = "-" .. yr end return yr .. timestamp:sub(6,11) end end timestamp = timestamp:gsub("%-00%-00T", "-01-01T") dprec = dprec or 11 if df == "y" and dprec > 9 then dprec = 9 end dprec = dprec>11 and 11 or dprec dprec = dprec<6 and 6 or dprec bcf = (bcf or ""):upper() pd = (pd or ""):sub(1,1):lower() if pd == "" or pd == "n" or pd == "f" or pd == "0" then pd = false end lang = lang or findLang().code adj = adj or "" local bc = timestamp:sub(1, 1)=="-" and "BC" or "" local year, month, day = timestamp:match("[+-](%d*)-(%d*)-(%d*)T") local iso = tonumber(year) if dprec == 6 then iso = math.floor( (iso - 1) / 1000 ) + 1 end if dprec == 7 then iso = math.floor( (iso - 1) / 100 ) + 1 end if dprec == 8 then iso = math.floor( iso / 10 ) .. "0" end if dprec == 10 then iso = year .. "-" .. month end if dprec == 11 then iso = year .. "-" .. month .. "-" .. day end local sc = not pd and qualifiers and qualifiers.P1480 if sc then for k1, v1 in pairs(sc) do if v1.datavalue and v1.datavalue.value.id == "Q5727902" then adj = "circa" break end end end local calendarmodel = "" if tonumber(year) > 1582 and dprec > 8 and not pd and model == "http://www.wikidata.org/entity/Q1985786" then calendarmodel = "julian" end -- Simplified date formatting (complex date module not available) local fdate = tostring(iso) if bc ~= "" then fdate = fdate .. " " .. (bcf == "BC" and "BC" or "BCE") end if adj == "circa" then fdate = "c. " .. fdate end return fdate end local function hijriFormat(qualifiers, dateformat, lang) if not qualifiers.P4241 then return; end local year, month, day local val local qhmonths = {["Q1952053"]=1,["Q489557"]=2, ["Q474167"] = 3, ["Q273815"] = 4, ["Q852002"] = 5, ["Q822218"] = 6, ["Q194210"] = 7, ["Q220914"] = 8, ["Q8867089"]=9, ["Q685440"]=10,["Q150853"]=11,["Q186022"]=12 } local hmonths = {"محرم","صفر","ربيع الأول","ربيع الآخر","جمادى الأولى","جمادى الآخرة","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة"} local hmonths_inv = {["محرم"] = 1, ["صفر"]=2, ["ربيع الأول"]=3, ["ربيع الآخر"]=4, ["جمادى الأولى"]=5, ["جمادى الآخرة"]=6, ["رجب"]=7, ["شعبان"]=8, ["رمضان"]=9, ["شوال"]=10, ["ذو القعدة"]=11, ["ذو الحجة"]=12} for _, item in ipairs(qualifiers.P4241) do local timeQ = item.datavalue and item.datavalue.value and item.datavalue.value.id local hastime = false if timeQ then local timeQt = mw.wikibase.getBestStatements(timeQ, "P361") for _,timeQsnak in pairs(timeQt) do local timeType = timeQsnak.mainsnak and timeQsnak.mainsnak.datavalue and timeQsnak.mainsnak.datavalue.value and timeQsnak.mainsnak.datavalue.value.id if timeType == "Q28892" then local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then year = mw.ustring.match(timeLableAr, "^(%d+) *هـ$") end if not year then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then year = mw.ustring.match(timeLableAr, "^(%d+) *AH$") end end hastime=true elseif qhmonths[timeType] then month = qhmonths[timeType] if month>0 and month<13 then month = hmonths[month] end local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end if not day then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end end hastime=true end end if not hastime then timeQt = mw.wikibase.getBestStatements(timeQ, "P31") if "Q125390868" == (timeQt[1].mainsnak and timeQt[1].mainsnak.datavalue and timeQt[1].mainsnak.datavalue.value and timeQt[1].mainsnak.datavalue.value.id ) then val = mw.wikibase.getLabelByLang(timeQ, "ar") month, year = mw.ustring.match(val, "^(%a[%a ]+%a) *(%d+) *هـ?$") end end end end if year then if dateformat == "y" then return year; elseif day and month then return day .. ' ' .. month .. ' ' .. year; elseif month then return month .. ' ' .. year; end end return nil; end local function sourced(claim) if claim.references then for kr, vr in pairs(claim.references) do local ref = mw.wikibase.renderSnaks(vr.snaks) if not ref:find("Wiki") then return true end end end end local function linkedItem(id, args) local lprefix = (args.linkprefix or ""):gsub('"', '') local lpostfix = (args.lpostfix or ""):gsub('"', '') local prefix = (args.prefix or ""):gsub('"', '') local postfix = (args.postfix or ""):gsub('"', '') local wikilinkprefix = (args.wikilinkprefix or ""):gsub('"', '') local dtxt = args.dtxt local uselbl = parseParam( args.uselbl, true) local disp local sitelink = mw.wikibase.getSitelink(id, args.linksproject) local label, islabel if dtxt then label, islabel = dtxt, true else label, islabel = labelOrId(id, args.lang) end if sitelink then if not uselbl then local pos = sitelink:find(":") or 0 local slink = sitelink if pos > 0 then local pfx = sitelink:sub(1,pos-1) if mw.site.namespaces[pfx] then slink = sitelink:sub(pos+1) end end slink = slink:gsub("%s%(.+%)$", ""):gsub(",.+$", "") if label:find("^%u") then label = slink:gsub("^(%l)", string.upper) else label = slink:gsub("^(%u)", string.lower) end end disp = "[[" .. wikilinkprefix .. sitelink .. lpostfix .. "|" .. prefix .. label .. postfix .. "]]" elseif islabel then disp = prefix .. label .. postfix else disp = prefix .. label .. postfix .. i18n.missinginfocat end return disp end local function rendersnak(propval, args, linked, lpre, lpost, pre, post, uabbr, filter) lpre = lpre or "" lpost = lpost or "" pre = pre or "" post = post or "" args.lang = args.lang or findLang().code local snak = propval.mainsnak or propval local dtype = snak.datatype local dv = snak.datavalue dv = dv and dv.value local val, mlt local namedas; namedas = propval.qualifiers and propval.qualifiers.P1932 and propval.qualifiers.P1932[1].datavalue and propval.qualifiers.P1932[1].datavalue.value or nil args.dtxt = namedas if propval.rank and not args.reqranks[propval.rank] then return nil elseif snak.snaktype == "somevalue" then val = namedas or i18n["Unknown"] elseif snak.snaktype == "novalue" then -- return nothing elseif dtype == "wikibase-item" then local qnumber = dv.id if linked then val = linkedItem(qnumber, args) else if namedas then val = pre .. namedas .. post else local label, islabel = labelOrId(qnumber, args.lang) val = pre .. label .. post end end elseif dtype == "time" then if args.hijri then val = hijriFormat(propval.qualifiers, args.df, args.lang) else val = dateFormat(dv.time, dv.precision, args.df, args.bc, args.pd, propval.qualifiers, args.lang, "", dv.calendarmodel) end elseif dtype == "commonsMedia" or dtype == "external-id" or dtype == "string" or dtype == "url" then if (lpre == "" or lpre == ":") and lpost == "" then val = pre .. dv .. post elseif dtype == "external-id" then val = "[" .. lpre .. dv .. lpost .. " " .. pre .. dv .. post .. "]" else val = "[[" .. lpre .. dv .. lpost .. "|" .. pre .. dv .. post .. "]]" end elseif dtype == "quantity" then local amount = tonumber(dv.amount) or i18n["NaN"] local unit = "" local unitqid = string.match(dv.unit, "(Q%d+)") if filter and unitqid ~= filter then return nil end if unitqid then local uname = mw.wikibase.getLabelByLang(unitqid, args.lang) or "" if uname ~= "" then unit = " " .. uname end end val = tostring(amount) .. unit elseif dtype == "globe-coordinate" then local lat, long, prec = dv.latitude, dv.longitude, dv.precision local show = (args.show or ""):lower() if show == "lat" then val = decimalPrecision(lat, prec) elseif show == "lon" then val = decimalPrecision(long, prec) elseif show == "longlat" then val = decimalPrecision(long, prec) .. ", " .. decimalPrecision(lat, prec) else local ns = lat < 0 and "S" or "N" local ew = long < 0 and "W" or "E" if lat < 0 then lat = -lat end if long < 0 then long = -long end val = decimalPrecision(lat, prec) .. "°" .. ns .. " " .. decimalPrecision(long, prec) .. "°" .. ew end elseif dtype == "monolingualtext" then val = pre .. dv.text .. post mlt = dv.language else val = "unknown data type: " .. dtype end return val, mlt end local function assembleoutput(out, args, entityID, propertyID) local sorted = parseParam(args.sorted, false) local noic = parseParam(args.noicon, false) local list = args.list or "" local separator = args.sep or "" separator = string.gsub(separator, '"', '') if separator == "" then local rtl_lang = {ar = true, fa = true, ur = true, ku = true, he = true} separator = rtl_lang[args.lang] and i18n["list separator-ar"] or i18n["list separator"] end local strout if #out > 0 then if sorted then table.sort(out) end if list == "" then strout = table.concat(out, separator) elseif list:lower() == "prose" then strout = mw.text.listToText(out) else strout = mw.getCurrentFrame():expandTemplate{title = list, args = out} end else strout = nil end return strout end local function propertyvalueandquals(objproperty, args, qualID) -- needs this style of declaration because it's re-entrant -- onlysourced is a boolean passed to return only values sourced to other than Wikipedia -- if nothing or an empty string is passed set it true local onlysrc = parseParam(args.onlysourced, false) -- linked is a a boolean that enables the link to a local page via sitelink -- if nothing or an empty string is passed set it true local linked = parseParam(args.linked, true) -- prefix is a string that may be nil, empty (""), or a string of characters -- this is prefixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local prefix = (args.prefix or ""):gsub('"', '') -- postfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local postfix = (args.postfix or ""):gsub('"', '') -- linkprefix is a string that may be nil, empty (""), or a string of characters -- this creates a link and is then prefixed to each value -- useful when when multiple values are returned and indirect links are needed -- any double-quotes " are stripped out, so that spaces may be passed local lprefix = (args.linkprefix or ""):gsub('"', '') -- linkpostfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value when linking is enabled with lprefix -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local lpostfix = (args.linkpostfix or ""):gsub('"', '') -- wdlinks is a boolean passed to enable links to Wikidata when no article exists -- if nothing or an empty string is passed set it false local wdl = parseParam(args.wdl, false) -- unitabbr is a boolean passed to enable unit abbreviations for common units -- if nothing or an empty string is passed set it false local uabbr = parseParam(args.unitabbr, false) -- qualsonly is a boolean passed to return just the qualifiers -- if nothing or an empty string is passed set it false local qualsonly = parseParam(args.qualsonly, false) -- maxvals is a string that may be nil, empty (""), or a number -- this determines how many items may be returned when multiple values are available -- setting it = 1 is useful where the returned string is used within another call, e.g. image local maxvals = tonumber(args.maxvals) or 0 -- pd boolean -- to disable/enable "sourcing cirumstances" or use adjectival form for the plain date local pd = args.pd or false args.pd = pd -- allow qualifiers to have a different date format; default to year unless qualsonly is set args.qdf = args.qdf or (not qualsonly and "y") local lang = args.lang or (args.langs and args.langs[1]) or findLang().code -- qualID is a string list of wanted qualifiers or "ALL" qualID = qualID or "" -- capitalise list of wanted qualifiers and substitute "DATES" qualID = qualID:upper():gsub("DATES", "P580, P582") local allflag = (qualID == "ALL") -- create table of wanted qualifiers as key local qwanted = {} -- create sequence of wanted qualifiers local qorder = {} for q in mw.text.gsplit(qualID, "%p") do -- split at punctuation and iterate local qtrim = mw.text.trim(q) if qtrim ~= "" then qwanted[mw.text.trim(q)] = true qorder[#qorder+1] = qtrim end end -- qsep is the output separator for rendering qualifier list local qsep = (args.qsep or ""):gsub('"', '') -- qargs are the arguments to supply to assembleoutput() local qargs = { ["osd"] = "false", ["linked"] = tostring(linked), ["prefix"] = args.qprefix, ["postfix"] = args.qpostfix, ["linkprefix"] = args.qlinkprefix, ["linkpostfix"] = args.qlinkpostfix, ["wdl"] = "false", ["unitabbr"] = tostring(uabbr), ["maxvals"] = 0, ["sorted"] = tostring(args.qsorted), ["noicon"] = "true", ["list"] = args.qlist, ["sep"] = qsep, -- ["langobj"] = args.langobj, ["lang"] = args.lang or (args.langs and args.lang[1]), ["df"] = args.qdf, ["sn"] = parseParam(args.qsn, false), } -- all proper values of a Wikidata property will be the same type as the first -- qualifiers don't have a mainsnak, properties do --#Modified line local datatype = objproperty[1].datatype or (objproperty[1].mainsnak and objproperty[1].mainsnak.datatype) -- out[] holds the a list of returned values for this property -- mlt[] holds the language code if the datatype is monolingual text local out = {} local mlt = {} for k, v in ipairs(objproperty) do local hasvalue = true if (onlysrc and not sourced(v)) then -- no value: it isn't sourced when onlysourced=true hasvalue = false else local val, lcode = rendersnak(v, args, linked, lprefix, lpostfix, prefix, postfix, uabbr) if not val then hasvalue = false -- rank doesn't match elseif qualsonly and qualID then -- suppress value returned: only qualifiers are requested else out[#out+1], mlt[#out+1] = val, lcode end end -- See if qualifiers are to be returned: local snak = v.mainsnak or v if hasvalue and v.qualifiers and qualID ~= "" and snak.snaktype~="novalue" then -- collect all wanted qualifier values returned in qlist, indexed by propertyID local qlist = {} local timestart, timeend = "", "" -- loop through qualifiers for k1, v1 in pairs(v.qualifiers) do if allflag or qwanted[k1] then if k1 == "P1326" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before") elseif k1 == "P1319" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after") elseif k1 == "P580" then timestart = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one start time as valid elseif k1 == "P582" then timeend = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one end time as valid else local q = assembleoutput(propertyvalueandquals(v1, qargs), qargs) -- we already deal with circa via 'sourcing circumstances' if the datatype was time -- circa may be either linked or unlinked *** internationalise later *** if datatype ~= "time" or q ~= "circa" and not (type(q) == "string" and q:find("circa]]")) then qlist[k1] = q end end end -- of test for wanted end -- of loop through qualifiers -- set date separator local t = timestart .. timeend -- *** internationalise date separators later *** local dsep = "&ndash;" if t:find("%s") or t:find("&nbsp;") then dsep = " &ndash; " end -- set the order for the list of qualifiers returned; start time and end time go last if next(qlist) then local qlistout = {} if allflag then for k2, v2 in pairs(qlist) do qlistout[#qlistout+1] = v2 end else for i2, v2 in ipairs(qorder) do qlistout[#qlistout+1] = qlist[v2] end end if t ~= "" then qlistout[#qlistout+1] = timestart .. dsep .. timeend end local qstr = assembleoutput(qlistout, qargs) if qualsonly then out[#out+1] = qstr else out[#out] = out[#out] .. " (" .. qstr .. ")" end elseif t ~= "" then if qualsonly then if timestart == "" then out[#out+1] = timeend elseif timeend == "" then out[#out+1] = timestart else out[#out+1] = timestart .. dsep .. timeend end else out[#out] = out[#out] .. " (" .. timestart .. dsep .. timeend .. ")" end end end -- of test for qualifiers wanted if maxvals > 0 and #out >= maxvals then break end end -- of for each value loop -- we need to pick one value to return if the datatype was "monolingualtext" -- if there's only one value, use that -- otherwise look through the fallback languages for a match if datatype == "monolingualtext" and #out >1 then lang = mw.text.split( lang, '-', true )[1] local fbtbl = mw.language.getFallbacksFor( lang ) table.insert( fbtbl, 1, lang ) local bestval = "" local found = false for idx1, lang1 in ipairs(fbtbl) do for idx2, lang2 in ipairs(mlt) do if (lang1 == lang2) and not found then bestval = out[idx2] found = true break end end -- loop through values of property end -- loop through fallback languages if found then -- replace output table with a table containing the best value out = { bestval } else -- more than one value and none of them on the list of fallback languages -- sod it, just give them the first one out = { out[1] } end end return out end local function mergeOptions(defaults, overrides) overrides = overrides or {} defaults = defaults or {} local result = {} for k, v in pairs(defaults) do result[k] = v end for k, v in pairs(overrides) do result[k] = v if k == 'rank' then result.reqranks = setRanks(v) end end return result end local function filterbyqualifier(statements,qual,value) local filtered_statements = {} for _, statement in ipairs(statements) do if statement.qualifiers and statement.qualifiers[qual] then if '*' == value then table.insert(filtered_statements, statement) else for _, q in ipairs(statement.qualifiers[qual]) do if q.datavalue and (rawValue(q.datavalue) == value) then table.insert(filtered_statements, statement) break end end end end end return filtered_statements end local function orderbyrank(statements) local pref_count = 0 local sorted_statements = {} for k,v in ipairs(statements) do if v.rank == 'preferred' then pref_count = pref_count + 1 table.insert(sorted_statements, pref_count, v) else table.insert(sorted_statements, v) end end return sorted_statements end ------------------------------------------------------------------------------- -- helper class functions ------------------------------------------------------------------------------- local function class() local c = {} c.__index = c function c:new(...) local o = setmetatable({}, c) if o.init then o:init(...) end return o end return c end ------------------------------------------------------------------------------- -- Statement Class Definition ------------------------------------------------------------------------------- local WdStatement = class() function WdStatement:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statement = self._statement if not statement then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals({statement}, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatement:getRawValue() if not self._statement then return nil end if self._statement.mainsnak.snaktype == "value" then return rawValue(self._statement.mainsnak.datavalue) else return self._statement.mainsnak.snaktype end end function WdStatement:getRawQual(qualID) local ret = {} local s = self._statement if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(ret, rawValue(q.datavalue)) else table.insert(ret, q.snaktype) end end end return ret end ------------------------------------------------------------------------------- -- Statements Class Definition ------------------------------------------------------------------------------- local WdStatements = class() function WdStatements:getStatmentsTable() return self._statements end function WdStatements:count() return #self._statements end function WdStatements:getFilters() return self.filtered_by end function WdStatements:filter(filter_t) local statements = self._statements if #statements == 0 then return self; end local ret = WdStatements:new() ret.parent = self.parent ret.filtered_by = {} for _,v in ipairs(self.filtered_by) do table.insert(ret.filtered_by, v) end local filtered_statements = {} for k,v in pairs(filter_t) do filtered_statements = filterbyqualifier(statements, k, v) table.insert(ret.filtered_by, {[k] = v}) if #filtered_statements == 0 then break; else statements = filtered_statements end end ret._statements = filtered_statements return ret end function WdStatements:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getQual(qualID, opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getRawQual(qualID) local ret = {} for _,s in pairs(self._statements) do local qual_t = {} if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(qual_t, rawValue(q.datavalue)) else table.insert(qual_t, q.snaktype) end end end table.insert(ret,qual_t) end return ret end function WdStatements:getRawValue() local ret = {} for _,v in pairs(self._statements) do if v.mainsnak.snaktype=="value" then table.insert(ret, rawValue(v.mainsnak.datavalue)) else table.insert(ret, v.mainsnak.snaktype) end end return ret end function WdStatements:get(index) local ret = WdStatement:new() ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = self._statements[index] ret.pid = ret.pid return ret end function WdStatements:iter() local i = 0 local n = self._statements and #self._statements or 0 return function() i = i + 1 if i <= n then return i, self:get(i) end end end function WdStatements:getBestOne() local orderd_statements = orderbyrank(self._statements) local ret = WdStatement:new() --setmetatable({}, WdStatement) ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = orderd_statements[1] ret.pid = ret.pid return ret end ------------------------------------------------------------------------------- -- WdItem Class Definition ------------------------------------------------------------------------------- local WdItem = class() function WdItem:__tostring() return "WdItem: " .. (self.qid or "no QID") end function WdItem:UpdateOptions(newOpts) for k, v in pairs(newOpts or {}) do local key = options_aliases[k] self.options[key] = v -- Set default options if key == 'langs' and #v > 0 then self.options.langobj = findLang(self.options.langs[1]) self.options.lang = self.options.langobj.code if not self.options.langobj then self.options.langobj = findLang(self.options.lang) self.options.lang = self.options.langobj.code end end if key == 'rank' then self.options.reqranks = setRanks(self.options.rank) end end if not self.options.reqranks then self.options.reqranks = setRanks('preferred normal') end end function WdItem:init(qid, options,snak) if qid == "" then qid = nil; end self.qid = qid self.snak = snak self.options = options or {} self:UpdateOptions(options) return self end function WdItem:newFromSnaks(snakTable, options) local self = WdItem:new(nil, options or {}, snakTable) self:UpdateOptions(options) return self end function WdItem:setOptions(newOpts) self:UpdateOptions(newOpts) end function WdItem:getStatements(pid, opts) local mergedOpts = mergeOptions(self.options, opts or {}) local statements local ret = WdStatements:new() ret.parent = self ret.filtered_by = {} ret._statements = {} ret.pid = pid if self.snak and self.snak[pid] then statements = self.snak[pid] elseif not self.qid or not mw.wikibase then statements = {} elseif mergedOpts.reqranks and mergedOpts.reqranks.best then statements = mw.wikibase.getBestStatements(self.qid, pid) or {} else statements = mw.wikibase.getAllStatements(self.qid, pid) or {} local filtered_statements = {} if not (mergedOpts.reqranks.deprecated == true and mergedOpts.reqranks.preferred == true and mergedOpts.reqranks.normal == true) then for _,s in pairs(statements) do if mergedOpts.reqranks[s.rank] then table.insert(filtered_statements,s) end end end statements = filtered_statements end if #statements > 0 and mergedOpts.qualifiedaspossible and mergedOpts.qualifiedaspossible ~= {} then local filtered_statements = {} for q,qv in pairs(mergedOpts.qualifiedaspossible) do filtered_statements = filterbyqualifier(statements, q, qv) if #filtered_statements > 0 then table.insert(ret.filtered_by, {[q] = qv}) statements = filtered_statements end end end if #statements > 0 and mergedOpts.qualified and mergedOpts.qualified ~= {} then for q,qv in pairs(mergedOpts.qualified) do statements = filterbyqualifier(statements, q, qv) table.insert(ret.filtered_by, {[q] = qv}) if #statements == 0 then break; end end end ret._statements = statements return ret end function WdItem:getValue(pid, opts) local mergedOpts = mergeOptions(self.options, opts) local statements = self:getStatements(pid, mergedOpts):getStatmentsTable() if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.qid, pid) end function WdItem:getValueFromSnaks(pid, opts) if not self.snak or not self.snak[pid] then return nil end local mergedOpts = mergeOptions(self.options, opts) local props = self.snak[pid] local out = propertyvalueandquals(props, mergedOpts) return assembleoutput(out, mergedOpts, nil, pid) end function WdItem:getPropertyIDsTable(pid, opts) local mergedOpts = mergeOptions(self.options, opts) mergedOpts.noicon = tostring(parseParam(mergedOpts.noicon or "", true)) local statements = self:getStatements(pid, opts) if not statements or #statements == 0 then return {} end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local out = {} for i, v in ipairs(statements) do local snak = v.mainsnak if (snak.datatype == "wikibase-item") and (v.rank and mergedOpts.reqranks[v.rank:sub(1, 1)]) and (snak.snaktype == "value") and (sourced(v) or not onlysrc) then out[#out+1] = snak.datavalue.value.id end if maxvals > 0 and #out >= maxvals then break end end return out end function WdItem:getPropertyIDs(pid, opts) local out = WdItem:getPropertyIDsTable(pid, opts) if #out == 0 then return nil end return assembleoutput(out, mergeOptions(self.options, opts), self.qid, pid) end function WdItem:getPropOfProp(prop1, prop2, opts) local mergedOpts = mergeOptions(self.options, opts) if not self.qid then return nil end local statements1 = self:getStatements(prop1, opts) if not statements1 or #statements1 == 0 then return nil end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = {} for k, v in ipairs(statements1) do if not onlysrc or sourced(v) then local snak = v.mainsnak if snak.datatype == "wikibase-item" and snak.snaktype == "value" then local qid2 = snak.datavalue.value.id local item2 = WdItem.new(qid2, mergedOpts) local statements2 = item2:getStatements(prop2, opts) if statements2 and statements2[1] then local out2 = propertyvalueandquals(statements2, mergedOpts, qualID) out[#out+1] = assembleoutput(out2, mergedOpts, qid2, prop2) end end end if maxvals > 0 and #out >= maxvals then break end end return assembleoutput(out, mergedOpts, self.qid, prop1) end function WdItem:getLangOfProp(pid) if not pid then return {}; end local out = {} local props = self.snak and self.snak[pid] or (self.qid and mw.wikibase.getAllStatements(self.qid, pid)) or {} for _, v in ipairs(props) do if v.mainsnak.datatype == "monolingualtext" and v.mainsnak.datavalue then out[#out + 1] = v.mainsnak.datavalue.value.language end end return out end function WdItem:followQid(props, all) all = parseParam(all, false) props = (props or ""):upper() if not self.qid then return nil end if props == "" then return self.qid end local out = {} for p in mw.text.gsplit(props, "%p") do p = mw.text.trim(p) for i, v in ipairs(mw.wikibase.getBestStatements(self.qid, p)) do local linkedid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id if linkedid then if all then out[#out+1] = linkedid else return linkedid end end end end if #out > 0 then return table.concat(out, " ") else return self.qid end end ------------------------------------------------------------------------------- -- Public API - WdItem Constructors ------------------------------------------------------------------------------- p.WdItem = WdItem function p.newItem(qid, opts, snak ) return WdItem:new(qid, opts, snak) end function p.newSnakItem(snakTable, opts) return WdItem:newFromSnaks(snakTable, opts) end return p g3s161umbzsgizm9f15fa4yodj2inep 1097320 1097319 2026-07-23T11:21:07Z حبيشان 31560 1097320 Scribunto text/plain -- Module: WdItem -- Object-oriented Wikidata access module for Lua -- Refactored from WikidataIB for direct Lua usage require("strict") local p = {} -- i18n configuration local i18n = { ["errors"] = { ["property-not-found"] = "الخاصية غير موجودة.", ["entity-not-found"] = "الكيان على ويكي بيانات غير موجود.", ["unknown-claim-type"] = "نوع الادعاء غير معروف.", ["local-article-not-found"] = "المعرف متاح على ويكي بيانات، ولكن المقال غير متاح على ويكيبيديا", }, ["months"] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, ["Unknown"] = "Unknown", ["NaN"] = "Not a number", ["missinginfocat"] = "[[تصنيف:Articles with missing Wikidata information]]", ["list separator"] = ", ", ["list separator-ar"] = "، ", } -- Date precision constants local dp = { [6] = "millennium", [7] = "century", [8] = "decade", [9] = "year", [10] = "month", [11] = "day", } local options_aliases = { ["osd"] = "onlysourced", ["wdlinks"] = "wdl", ["uabbr"] = "unitabbr", ["qo"] = "qualsonly", ["lp"] = "linkprefix", ["lprefix"] = "linkprefix", ["qlp"] = "qlinkprefix", ["sn"] = "shortname", ["uselabel"] = "uselbl", ["plaindate"] = "pd", ["qualifierdateformat"] = "qdf", ["df"] = "qdf", ["qshortname"] = "qsn" } setmetatable(options_aliases, { __index = function(t, k) return k end }) ------------------------------------------------------------------------------- -- Internal helper functions ------------------------------------------------------------------------------- local function findLang(langcode) local langobj langcode = mw.text.trim(langcode or "") if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langcode = mw.getCurrentFrame():callParserFunction('int', {'lang'}) if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langobj = mw.language.getContentLanguage() end end return langobj end local function parseParam(param, default) if param == nil then return default end return param end local function setRanks(rank) rank = (rank or ""):lower() local ranks = {} for w in string.gmatch(rank, "%a+") do if w == "best" or w == "preferred" or w == "normal" or w == "deprecated" then ranks[w] = true end end if ranks.best or not next(ranks) then ranks.preferred = true ranks.normal = true ranks.deprecated = false end return ranks end local function labelOrId(id, lang) if lang == "default" then lang = findLang().code end local label if lang then label = mw.wikibase.getLabelByLang(id, lang) end if not label then local trylang = {"ar","en","fr", "mul"} local triedlang = lang for _,lang in pairs(trylang) do if triedlang ~= lang then label = mw.wikibase.getLabelByLang(id, lang) if label ~= "" then break end end end end if label then return mw.text.nowiki(label), true else return id, false end end local function roundto(x, sf) if x == 0 then return 0 end local s = 1 if x < 0 then x = -x s = -1 end if sf < 1 then sf = 1 end local p = 10 ^ (math.floor(math.log10(x)) - sf + 1) x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end return x end local function decimalPrecision(x, p) local s = 1 if x < 0 then x = -x s = -1 end if not tonumber(p) then p = 1e-4 elseif p > 1 then p = 1 elseif p < 1e-6 then p = 1e-6 else p = 10 ^ math.floor(math.log10(p)) end x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end if math.abs(x) < 1e-4 then x = string.format("%f", x) end return x end local function decimalToDMS(x, p) if not tonumber(p) then p = 1e-4 end local d = math.floor(x) local ms = (x - d) * 60 if p > 0.5 then if ms > 30 then d = d + 1 end ms = 0 end local m = math.floor(ms) local s = (ms - m) * 60 if p > 0.008 then if s > 30 then m = m +1 end s = 0 elseif p > 0.00014 then s = math.floor(s + 0.5) elseif p > 0.000014 then s = math.floor(10 * s + 0.5) / 10 elseif p > 0.0000014 then s = math.floor(100 * s + 0.5) / 100 else s = math.floor(1000 * s + 0.5) / 1000 end return d, m, s end local function rawValue(dataValue) if dataValue.type == "string" then return dataValue.value elseif dataValue.type == "wikibase-entityid" then return dataValue.value and dataValue.value.id elseif dataValue.type == "monolingualtext" then return dataValue.value.text elseif dataValue.type == "quantity" then return tonumber(dataValue.value.amount) elseif dataValue.type == 'time' then return dataValue.value.time elseif dataValue.type == "globecoordinate" then return dataValue.value.latitude .. '/' .. dataValue.value.longitude end end local function compareValue(dataValue, strValue) return rawValue(dataValue) == strValue end local function dateFormat(timestamp, dprec, df, bcf, pd, qualifiers, lang, adj, model) df = (df or ""):lower() if df == "ymd" then if timestamp:sub(1,1) == "+" then return timestamp:sub(2,11) else local yr = tonumber(timestamp:sub(2,5)) - 1 yr = ("000" .. yr):sub(-4) if yr ~= "0000" then yr = "-" .. yr end return yr .. timestamp:sub(6,11) end end timestamp = timestamp:gsub("%-00%-00T", "-01-01T") dprec = dprec or 11 if df == "y" and dprec > 9 then dprec = 9 end dprec = dprec>11 and 11 or dprec dprec = dprec<6 and 6 or dprec bcf = (bcf or ""):upper() pd = (pd or ""):sub(1,1):lower() if pd == "" or pd == "n" or pd == "f" or pd == "0" then pd = false end lang = lang or findLang().code adj = adj or "" local bc = timestamp:sub(1, 1)=="-" and "BC" or "" local year, month, day = timestamp:match("[+-](%d*)-(%d*)-(%d*)T") local iso = tonumber(year) if dprec == 6 then iso = math.floor( (iso - 1) / 1000 ) + 1 end if dprec == 7 then iso = math.floor( (iso - 1) / 100 ) + 1 end if dprec == 8 then iso = math.floor( iso / 10 ) .. "0" end if dprec == 10 then iso = year .. "-" .. month end if dprec == 11 then iso = year .. "-" .. month .. "-" .. day end local sc = not pd and qualifiers and qualifiers.P1480 if sc then for k1, v1 in pairs(sc) do if v1.datavalue and v1.datavalue.value.id == "Q5727902" then adj = "circa" break end end end local calendarmodel = "" if tonumber(year) > 1582 and dprec > 8 and not pd and model == "http://www.wikidata.org/entity/Q1985786" then calendarmodel = "julian" end -- Simplified date formatting (complex date module not available) local fdate = tostring(iso) if bc ~= "" then fdate = fdate .. " " .. (bcf == "BC" and "BC" or "BCE") end if adj == "circa" then fdate = "c. " .. fdate end return fdate end local function hijriFormat(qualifiers, dateformat, lang) if not qualifiers.P4241 then return; end local year, month, day local val local qhmonths = {["Q1952053"]=1,["Q489557"]=2, ["Q474167"] = 3, ["Q273815"] = 4, ["Q852002"] = 5, ["Q822218"] = 6, ["Q194210"] = 7, ["Q220914"] = 8, ["Q8867089"]=9, ["Q685440"]=10,["Q150853"]=11,["Q186022"]=12 } local hmonths = {"محرم","صفر","ربيع الأول","ربيع الآخر","جمادى الأولى","جمادى الآخرة","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة"} local hmonths_inv = {["محرم"] = 1, ["صفر"]=2, ["ربيع الأول"]=3, ["ربيع الآخر"]=4, ["جمادى الأولى"]=5, ["جمادى الآخرة"]=6, ["رجب"]=7, ["شعبان"]=8, ["رمضان"]=9, ["شوال"]=10, ["ذو القعدة"]=11, ["ذو الحجة"]=12} for _, item in ipairs(qualifiers.P4241) do local timeQ = item.datavalue and item.datavalue.value and item.datavalue.value.id local hastime = false if timeQ then local timeQt = mw.wikibase.getBestStatements(timeQ, "P361") for _,timeQsnak in pairs(timeQt) do local timeType = timeQsnak.mainsnak and timeQsnak.mainsnak.datavalue and timeQsnak.mainsnak.datavalue.value and timeQsnak.mainsnak.datavalue.value.id if timeType == "Q28892" then local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then year = mw.ustring.match(timeLableAr, "^(%d+) *هـ$") end if not year then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then year = mw.ustring.match(timeLableAr, "^(%d+) *AH$") end end hastime=true elseif qhmonths[timeType] then month = qhmonths[timeType] if month>0 and month<13 then month = hmonths[month] end local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end if not day then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end end hastime=true end end if not hastime then timeQt = mw.wikibase.getBestStatements(timeQ, "P31") if "Q125390868" == (timeQt[1].mainsnak and timeQt[1].mainsnak.datavalue and timeQt[1].mainsnak.datavalue.value and timeQt[1].mainsnak.datavalue.value.id ) then val = mw.wikibase.getLabelByLang(timeQ, "ar") month, year = mw.ustring.match(val, "^(%a[%a ]+%a) *(%d+) *هـ?$") end end end end if year then if dateformat == "y" then return year; elseif day and month then return day .. ' ' .. month .. ' ' .. year; elseif month then return month .. ' ' .. year; end end return nil; end local function sourced(claim) if claim.references then for kr, vr in pairs(claim.references) do local ref = mw.wikibase.renderSnaks(vr.snaks) if not ref:find("Wiki") then return true end end end end local function linkedItem(id, args) local lprefix = (args.linkprefix or ""):gsub('"', '') local lpostfix = (args.lpostfix or ""):gsub('"', '') local prefix = (args.prefix or ""):gsub('"', '') local postfix = (args.postfix or ""):gsub('"', '') local wikilinkprefix = (args.wikilinkprefix or ""):gsub('"', '') local dtxt = args.dtxt local uselbl = parseParam( args.uselbl, true) local disp local sitelink = mw.wikibase.getSitelink(id, args.linksproject) local label, islabel if dtxt then label, islabel = dtxt, true else label, islabel = labelOrId(id, args.lang) end if sitelink then if not uselbl then local pos = sitelink:find(":") or 0 local slink = sitelink if pos > 0 then local pfx = sitelink:sub(1,pos-1) if mw.site.namespaces[pfx] then slink = sitelink:sub(pos+1) end end slink = slink:gsub("%s%(.+%)$", ""):gsub(",.+$", "") if label:find("^%u") then label = slink:gsub("^(%l)", string.upper) else label = slink:gsub("^(%u)", string.lower) end end disp = "[[" .. wikilinkprefix .. sitelink .. lpostfix .. "|" .. prefix .. label .. postfix .. "]]" elseif islabel then disp = prefix .. label .. postfix else disp = prefix .. label .. postfix .. i18n.missinginfocat end return disp end local function rendersnak(propval, args, linked, lpre, lpost, pre, post, uabbr, filter) lpre = lpre or "" lpost = lpost or "" pre = pre or "" post = post or "" args.lang = args.lang or findLang().code local snak = propval.mainsnak or propval local dtype = snak.datatype local dv = snak.datavalue dv = dv and dv.value local val, mlt local namedas; namedas = propval.qualifiers and propval.qualifiers.P1932 and propval.qualifiers.P1932[1].datavalue and propval.qualifiers.P1932[1].datavalue.value or nil args.dtxt = namedas if propval.rank and not args.reqranks[propval.rank] then return nil elseif snak.snaktype == "somevalue" then val = namedas or i18n["Unknown"] elseif snak.snaktype == "novalue" then -- return nothing elseif dtype == "wikibase-item" then local qnumber = dv.id if linked then val = linkedItem(qnumber, args) else if namedas then val = pre .. namedas .. post else local label, islabel = labelOrId(qnumber, args.lang) val = pre .. label .. post end end elseif dtype == "time" then if args.hijri then val = hijriFormat(propval.qualifiers, args.df, args.lang) else val = dateFormat(dv.time, dv.precision, args.df, args.bc, args.pd, propval.qualifiers, args.lang, "", dv.calendarmodel) end elseif dtype == "commonsMedia" or dtype == "external-id" or dtype == "string" or dtype == "url" then if (lpre == "" or lpre == ":") and lpost == "" then val = pre .. dv .. post elseif dtype == "external-id" then val = "[" .. lpre .. dv .. lpost .. " " .. pre .. dv .. post .. "]" else val = "[[" .. lpre .. dv .. lpost .. "|" .. pre .. dv .. post .. "]]" end elseif dtype == "quantity" then local amount = tonumber(dv.amount) or i18n["NaN"] local unit = "" local unitqid = string.match(dv.unit, "(Q%d+)") if filter and unitqid ~= filter then return nil end if unitqid then local uname = mw.wikibase.getLabelByLang(unitqid, args.lang) or "" if uname ~= "" then unit = " " .. uname end end val = tostring(amount) .. unit elseif dtype == "globe-coordinate" then local lat, long, prec = dv.latitude, dv.longitude, dv.precision local show = (args.show or ""):lower() if show == "lat" then val = decimalPrecision(lat, prec) elseif show == "lon" then val = decimalPrecision(long, prec) elseif show == "longlat" then val = decimalPrecision(long, prec) .. ", " .. decimalPrecision(lat, prec) else local ns = lat < 0 and "S" or "N" local ew = long < 0 and "W" or "E" if lat < 0 then lat = -lat end if long < 0 then long = -long end val = decimalPrecision(lat, prec) .. "°" .. ns .. " " .. decimalPrecision(long, prec) .. "°" .. ew end elseif dtype == "monolingualtext" then val = pre .. dv.text .. post mlt = dv.language else val = "unknown data type: " .. dtype end return val, mlt end local function assembleoutput(out, args, entityID, propertyID) local sorted = parseParam(args.sorted, false) local noic = parseParam(args.noicon, false) local list = args.list or "" local separator = args.sep or "" separator = string.gsub(separator, '"', '') if separator == "" then local rtl_lang = {ar = true, fa = true, ur = true, ku = true, he = true} separator = rtl_lang[args.lang] and i18n["list separator-ar"] or i18n["list separator"] end local strout if #out > 0 then if sorted then table.sort(out) end if list == "" then strout = table.concat(out, separator) elseif list:lower() == "prose" then strout = mw.text.listToText(out) else strout = mw.getCurrentFrame():expandTemplate{title = list, args = out} end else strout = nil end return strout end local function propertyvalueandquals(objproperty, args, qualID) -- needs this style of declaration because it's re-entrant -- onlysourced is a boolean passed to return only values sourced to other than Wikipedia -- if nothing or an empty string is passed set it true local onlysrc = parseParam(args.onlysourced, false) -- linked is a a boolean that enables the link to a local page via sitelink -- if nothing or an empty string is passed set it true local linked = parseParam(args.linked, true) -- prefix is a string that may be nil, empty (""), or a string of characters -- this is prefixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local prefix = (args.prefix or ""):gsub('"', '') -- postfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local postfix = (args.postfix or ""):gsub('"', '') -- linkprefix is a string that may be nil, empty (""), or a string of characters -- this creates a link and is then prefixed to each value -- useful when when multiple values are returned and indirect links are needed -- any double-quotes " are stripped out, so that spaces may be passed local lprefix = (args.linkprefix or ""):gsub('"', '') -- linkpostfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value when linking is enabled with lprefix -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local lpostfix = (args.linkpostfix or ""):gsub('"', '') -- wdlinks is a boolean passed to enable links to Wikidata when no article exists -- if nothing or an empty string is passed set it false local wdl = parseParam(args.wdl, false) -- unitabbr is a boolean passed to enable unit abbreviations for common units -- if nothing or an empty string is passed set it false local uabbr = parseParam(args.unitabbr, false) -- qualsonly is a boolean passed to return just the qualifiers -- if nothing or an empty string is passed set it false local qualsonly = parseParam(args.qualsonly, false) -- maxvals is a string that may be nil, empty (""), or a number -- this determines how many items may be returned when multiple values are available -- setting it = 1 is useful where the returned string is used within another call, e.g. image local maxvals = tonumber(args.maxvals) or 0 -- pd boolean -- to disable/enable "sourcing cirumstances" or use adjectival form for the plain date local pd = args.pd or false args.pd = pd -- allow qualifiers to have a different date format; default to year unless qualsonly is set args.qdf = args.qdf or (not qualsonly and "y") local lang = args.lang or (args.langs and args.langs[1]) or findLang().code -- qualID is a string list of wanted qualifiers or "ALL" qualID = qualID or "" -- capitalise list of wanted qualifiers and substitute "DATES" qualID = qualID:upper():gsub("DATES", "P580, P582") local allflag = (qualID == "ALL") -- create table of wanted qualifiers as key local qwanted = {} -- create sequence of wanted qualifiers local qorder = {} for q in mw.text.gsplit(qualID, "%p") do -- split at punctuation and iterate local qtrim = mw.text.trim(q) if qtrim ~= "" then qwanted[mw.text.trim(q)] = true qorder[#qorder+1] = qtrim end end -- qsep is the output separator for rendering qualifier list local qsep = (args.qsep or ""):gsub('"', '') -- qargs are the arguments to supply to assembleoutput() local qargs = { ["osd"] = "false", ["linked"] = tostring(linked), ["prefix"] = args.qprefix, ["postfix"] = args.qpostfix, ["linkprefix"] = args.qlinkprefix, ["linkpostfix"] = args.qlinkpostfix, ["wdl"] = "false", ["unitabbr"] = tostring(uabbr), ["maxvals"] = 0, ["sorted"] = tostring(args.qsorted), ["noicon"] = "true", ["list"] = args.qlist, ["sep"] = qsep, -- ["langobj"] = args.langobj, ["lang"] = args.lang or (args.langs and args.lang[1]), ["df"] = args.qdf, ["sn"] = parseParam(args.qsn, false), } -- all proper values of a Wikidata property will be the same type as the first -- qualifiers don't have a mainsnak, properties do --#Modified line local datatype = objproperty[1].datatype or (objproperty[1].mainsnak and objproperty[1].mainsnak.datatype) -- out[] holds the a list of returned values for this property -- mlt[] holds the language code if the datatype is monolingual text local out = {} local mlt = {} for k, v in ipairs(objproperty) do local hasvalue = true if (onlysrc and not sourced(v)) then -- no value: it isn't sourced when onlysourced=true hasvalue = false else local val, lcode = rendersnak(v, args, linked, lprefix, lpostfix, prefix, postfix, uabbr) if not val then hasvalue = false -- rank doesn't match elseif qualsonly and qualID then -- suppress value returned: only qualifiers are requested else out[#out+1], mlt[#out+1] = val, lcode end end -- See if qualifiers are to be returned: local snak = v.mainsnak or v if hasvalue and v.qualifiers and qualID ~= "" and snak.snaktype~="novalue" then -- collect all wanted qualifier values returned in qlist, indexed by propertyID local qlist = {} local timestart, timeend = "", "" -- loop through qualifiers for k1, v1 in pairs(v.qualifiers) do if allflag or qwanted[k1] then if k1 == "P1326" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before") elseif k1 == "P1319" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after") elseif k1 == "P580" then timestart = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one start time as valid elseif k1 == "P582" then timeend = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one end time as valid else local q = assembleoutput(propertyvalueandquals(v1, qargs), qargs) -- we already deal with circa via 'sourcing circumstances' if the datatype was time -- circa may be either linked or unlinked *** internationalise later *** if datatype ~= "time" or q ~= "circa" and not (type(q) == "string" and q:find("circa]]")) then qlist[k1] = q end end end -- of test for wanted end -- of loop through qualifiers -- set date separator local t = timestart .. timeend -- *** internationalise date separators later *** local dsep = "&ndash;" if t:find("%s") or t:find("&nbsp;") then dsep = " &ndash; " end -- set the order for the list of qualifiers returned; start time and end time go last if next(qlist) then local qlistout = {} if allflag then for k2, v2 in pairs(qlist) do qlistout[#qlistout+1] = v2 end else for i2, v2 in ipairs(qorder) do qlistout[#qlistout+1] = qlist[v2] end end if t ~= "" then qlistout[#qlistout+1] = timestart .. dsep .. timeend end local qstr = assembleoutput(qlistout, qargs) if qualsonly then out[#out+1] = qstr else out[#out] = out[#out] .. " (" .. qstr .. ")" end elseif t ~= "" then if qualsonly then if timestart == "" then out[#out+1] = timeend elseif timeend == "" then out[#out+1] = timestart else out[#out+1] = timestart .. dsep .. timeend end else out[#out] = out[#out] .. " (" .. timestart .. dsep .. timeend .. ")" end end end -- of test for qualifiers wanted if maxvals > 0 and #out >= maxvals then break end end -- of for each value loop -- we need to pick one value to return if the datatype was "monolingualtext" -- if there's only one value, use that -- otherwise look through the fallback languages for a match if datatype == "monolingualtext" and #out >1 then lang = mw.text.split( lang, '-', true )[1] local fbtbl = mw.language.getFallbacksFor( lang ) table.insert( fbtbl, 1, lang ) local bestval = "" local found = false for idx1, lang1 in ipairs(fbtbl) do for idx2, lang2 in ipairs(mlt) do if (lang1 == lang2) and not found then bestval = out[idx2] found = true break end end -- loop through values of property end -- loop through fallback languages if found then -- replace output table with a table containing the best value out = { bestval } else -- more than one value and none of them on the list of fallback languages -- sod it, just give them the first one out = { out[1] } end end return out end local function mergeOptions(defaults, overrides) overrides = overrides or {} defaults = defaults or {} local result = {} for k, v in pairs(defaults) do result[k] = v end for k, v in pairs(overrides) do result[k] = v if k == 'rank' then result.reqranks = setRanks(v) end end return result end local function filterbyqualifier(statements,qual,value) local filtered_statements = {} for _, statement in ipairs(statements) do if statement.qualifiers and statement.qualifiers[qual] then if '*' == value then table.insert(filtered_statements, statement) else for _, q in ipairs(statement.qualifiers[qual]) do if q.datavalue and (rawValue(q.datavalue) == value) then table.insert(filtered_statements, statement) break end end end end end return filtered_statements end local function orderbyrank(statements) local pref_count = 0 local sorted_statements = {} for k,v in ipairs(statements) do if v.rank == 'preferred' then pref_count = pref_count + 1 table.insert(sorted_statements, pref_count, v) else table.insert(sorted_statements, v) end end return sorted_statements end ------------------------------------------------------------------------------- -- helper class functions ------------------------------------------------------------------------------- local function class() local c = {} c.__index = c function c:new(...) local o = setmetatable({}, c) if o.init then o:init(...) end return o end return c end ------------------------------------------------------------------------------- -- Statement Class Definition ------------------------------------------------------------------------------- local WdStatement = class() function WdStatement:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statement = self._statement if not statement then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals({statement}, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatement:getRawValue() if not self._statement then return nil end if self._statement.mainsnak.snaktype == "value" then return rawValue(self._statement.mainsnak.datavalue) else return self._statement.mainsnak.snaktype end end function WdStatement:getRawQual(qualID) local ret = {} local s = self._statement if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(ret, rawValue(q.datavalue)) else table.insert(ret, q.snaktype) end end end return ret end ------------------------------------------------------------------------------- -- Statements Class Definition ------------------------------------------------------------------------------- local WdStatements = class() function WdStatements:getStatmentsTable() return self._statements end function WdStatements:count() return #self._statements end function WdStatements:getFilters() return self.filtered_by end function WdStatements:filter(filter_t) local statements = self._statements if #statements == 0 then return self; end local ret = WdStatements:new() ret.parent = self.parent ret.filtered_by = {} for _,v in ipairs(self.filtered_by) do table.insert(ret.filtered_by, v) end local filtered_statements = {} for k,v in pairs(filter_t) do filtered_statements = filterbyqualifier(statements, k, v) table.insert(ret.filtered_by, {[k] = v}) if #filtered_statements == 0 then break; else statements = filtered_statements end end ret._statements = filtered_statements return ret end function WdStatements:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getQual(qualID, opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getRawQual(qualID) local ret = {} for _,s in pairs(self._statements) do local qual_t = {} if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(qual_t, rawValue(q.datavalue)) else table.insert(qual_t, q.snaktype) end end end table.insert(ret,qual_t) end return ret end function WdStatements:getRawValue() local ret = {} for _,v in pairs(self._statements) do if v.mainsnak.snaktype=="value" then table.insert(ret, rawValue(v.mainsnak.datavalue)) else table.insert(ret, v.mainsnak.snaktype) end end return ret end function WdStatements:get(index) local ret = WdStatement:new() ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = self._statements[index] ret.pid = ret.pid return ret end function WdStatements:iter() local i = 0 local n = self._statements and #self._statements or 0 return function() i = i + 1 if i <= n then return i, self:get(i) end end end function WdStatements:ipairs() return self:iter() end function WdStatements:getBestOne() local orderd_statements = orderbyrank(self._statements) local ret = WdStatement:new() --setmetatable({}, WdStatement) ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = orderd_statements[1] ret.pid = ret.pid return ret end ------------------------------------------------------------------------------- -- WdItem Class Definition ------------------------------------------------------------------------------- local WdItem = class() function WdItem:__tostring() return "WdItem: " .. (self.qid or "no QID") end function WdItem:UpdateOptions(newOpts) for k, v in pairs(newOpts or {}) do local key = options_aliases[k] self.options[key] = v -- Set default options if key == 'langs' and #v > 0 then self.options.langobj = findLang(self.options.langs[1]) self.options.lang = self.options.langobj.code if not self.options.langobj then self.options.langobj = findLang(self.options.lang) self.options.lang = self.options.langobj.code end end if key == 'rank' then self.options.reqranks = setRanks(self.options.rank) end end if not self.options.reqranks then self.options.reqranks = setRanks('preferred normal') end end function WdItem:init(qid, options,snak) if qid == "" then qid = nil; end self.qid = qid self.snak = snak self.options = options or {} self:UpdateOptions(options) return self end function WdItem:newFromSnaks(snakTable, options) local self = WdItem:new(nil, options or {}, snakTable) self:UpdateOptions(options) return self end function WdItem:setOptions(newOpts) self:UpdateOptions(newOpts) end function WdItem:getStatements(pid, opts) local mergedOpts = mergeOptions(self.options, opts or {}) local statements local ret = WdStatements:new() ret.parent = self ret.filtered_by = {} ret._statements = {} ret.pid = pid if self.snak and self.snak[pid] then statements = self.snak[pid] elseif not self.qid or not mw.wikibase then statements = {} elseif mergedOpts.reqranks and mergedOpts.reqranks.best then statements = mw.wikibase.getBestStatements(self.qid, pid) or {} else statements = mw.wikibase.getAllStatements(self.qid, pid) or {} local filtered_statements = {} if not (mergedOpts.reqranks.deprecated == true and mergedOpts.reqranks.preferred == true and mergedOpts.reqranks.normal == true) then for _,s in pairs(statements) do if mergedOpts.reqranks[s.rank] then table.insert(filtered_statements,s) end end end statements = filtered_statements end if #statements > 0 and mergedOpts.qualifiedaspossible and mergedOpts.qualifiedaspossible ~= {} then local filtered_statements = {} for q,qv in pairs(mergedOpts.qualifiedaspossible) do filtered_statements = filterbyqualifier(statements, q, qv) if #filtered_statements > 0 then table.insert(ret.filtered_by, {[q] = qv}) statements = filtered_statements end end end if #statements > 0 and mergedOpts.qualified and mergedOpts.qualified ~= {} then for q,qv in pairs(mergedOpts.qualified) do statements = filterbyqualifier(statements, q, qv) table.insert(ret.filtered_by, {[q] = qv}) if #statements == 0 then break; end end end ret._statements = statements return ret end function WdItem:getValue(pid, opts) local mergedOpts = mergeOptions(self.options, opts) local statements = self:getStatements(pid, mergedOpts):getStatmentsTable() if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.qid, pid) end function WdItem:getValueFromSnaks(pid, opts) if not self.snak or not self.snak[pid] then return nil end local mergedOpts = mergeOptions(self.options, opts) local props = self.snak[pid] local out = propertyvalueandquals(props, mergedOpts) return assembleoutput(out, mergedOpts, nil, pid) end function WdItem:getPropertyIDsTable(pid, opts) local mergedOpts = mergeOptions(self.options, opts) mergedOpts.noicon = tostring(parseParam(mergedOpts.noicon or "", true)) local statements = self:getStatements(pid, opts) if not statements or #statements == 0 then return {} end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local out = {} for i, v in ipairs(statements) do local snak = v.mainsnak if (snak.datatype == "wikibase-item") and (v.rank and mergedOpts.reqranks[v.rank:sub(1, 1)]) and (snak.snaktype == "value") and (sourced(v) or not onlysrc) then out[#out+1] = snak.datavalue.value.id end if maxvals > 0 and #out >= maxvals then break end end return out end function WdItem:getPropertyIDs(pid, opts) local out = WdItem:getPropertyIDsTable(pid, opts) if #out == 0 then return nil end return assembleoutput(out, mergeOptions(self.options, opts), self.qid, pid) end function WdItem:getPropOfProp(prop1, prop2, opts) local mergedOpts = mergeOptions(self.options, opts) if not self.qid then return nil end local statements1 = self:getStatements(prop1, opts) if not statements1 or #statements1 == 0 then return nil end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = {} for k, v in ipairs(statements1) do if not onlysrc or sourced(v) then local snak = v.mainsnak if snak.datatype == "wikibase-item" and snak.snaktype == "value" then local qid2 = snak.datavalue.value.id local item2 = WdItem.new(qid2, mergedOpts) local statements2 = item2:getStatements(prop2, opts) if statements2 and statements2[1] then local out2 = propertyvalueandquals(statements2, mergedOpts, qualID) out[#out+1] = assembleoutput(out2, mergedOpts, qid2, prop2) end end end if maxvals > 0 and #out >= maxvals then break end end return assembleoutput(out, mergedOpts, self.qid, prop1) end function WdItem:getLangOfProp(pid) if not pid then return {}; end local out = {} local props = self.snak and self.snak[pid] or (self.qid and mw.wikibase.getAllStatements(self.qid, pid)) or {} for _, v in ipairs(props) do if v.mainsnak.datatype == "monolingualtext" and v.mainsnak.datavalue then out[#out + 1] = v.mainsnak.datavalue.value.language end end return out end function WdItem:followQid(props, all) all = parseParam(all, false) props = (props or ""):upper() if not self.qid then return nil end if props == "" then return self.qid end local out = {} for p in mw.text.gsplit(props, "%p") do p = mw.text.trim(p) for i, v in ipairs(mw.wikibase.getBestStatements(self.qid, p)) do local linkedid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id if linkedid then if all then out[#out+1] = linkedid else return linkedid end end end end if #out > 0 then return table.concat(out, " ") else return self.qid end end ------------------------------------------------------------------------------- -- Public API - WdItem Constructors ------------------------------------------------------------------------------- p.WdItem = WdItem function p.newItem(qid, opts, snak ) return WdItem:new(qid, opts, snak) end function p.newSnakItem(snakTable, opts) return WdItem:newFromSnaks(snakTable, opts) end return p i1i400465y4qj7zr77x6mpyh1o1dml3 وحدة:Cite Q/config 828 235800 1097061 1096567 2026-07-21T19:40:42Z حبيشان 31560 1097061 Scribunto text/plain local config_t = { linksproject = "", wikilinkprefix = "" } local aliases_t = { ['accessdate'] = {'تاريخ-الوصول','تاريخ الوصول', 'تاريخ وصول', 'access-date', 'accessdate'}, ['agency'] = {'وكالة', 'agency'}, ['archivedate'] = {'تاريخ-الأرشيف', 'تاريخ أرشيف', 'تاريخ الأرشيف', 'archive-date', 'archivedate'}, ['archive-format'] = {'صيغة-الأرشيف', 'صيغة الأرشيف', 'archive-format'}, ['archive-url'] = {'مسار-الأرشيف', 'مسار أرشيف', 'مسار الأرشيف', 'archive-url', 'archiveurl'}, ['article-number'] = {'رقم-المقالة', 'article-number'}, ['asin-tld'] = 'asin-tld', ['at'] = {'في', 'at'}, --##TOREVISE ['authors'] = {'المؤلفون', 'المؤلفين', 'authors', 'people', 'host', 'credits', 'أشخاص'}, ['book-title'] = {'عنوان الكتاب', 'book-title', 'booktitle', 'عنوان المؤتمر'}, ['cartography'] = 'cartography', ['chapter'] = {'الفصل', 'chapter', 'contribution', 'entry', 'article', 'section'}, ['chapter-format'] = {'صيغة-الفصل', 'صيغة الفصل', 'تنسيق الفصل', 'chapter-format', 'contribution-format', 'entry-format', 'article-format', 'section-format'}, ['chapter-url'] = {'مسار-الفصل', 'مسار الفصل', 'chapter-url', 'contribution-url', 'entry-url', 'article-url', 'section-url'}, -- Used by InternetArchiveBot ['chapter-url-access'] = {'chapter-url-access', 'contribution-url-access', 'entry-url-access', 'article-url-access', 'section-url-access'}, -- Used by InternetArchiveBot ['class'] = {'صنف', 'class'}, -- cite arxiv and arxiv identifier ['collaboration'] = 'collaboration', ['conference'] = {'اسم-المؤتمر', 'اسم المؤتمر', 'conference'}, ['conference-format'] = 'conference-format', ['conference-url'] = {'مسار-المؤتمر', 'مسار المؤتمر', 'conference-url'}, -- Used by InternetArchiveBot ['date'] = {'تاريخ', 'التاريخ', 'date', 'air-date', 'airdate'}, ['degree'] = {'الدرجة', 'degree'}, ['df'] = 'df', ['display-authors'] = {'إظهار-المؤلفين', 'إظهار المؤلفين', 'display-authors', 'display-subjects'}, ['display-contributors'] = 'display-contributors', ['display-editors'] = {'إظهار-المحررين', 'إظهار المحررين', 'display-editors'}, ['display-interviewers'] = 'display-interviewers', ['display-translators'] = 'display-translators', ['docket'] = 'docket', ['doi-broken-date'] = 'doi-broken-date', ['edition'] = {'طبعة', 'الإصدار', 'الاصدار', 'إصدار', 'اصدار', 'الطبعة', 'رقم الطبعة', 'edition'}, ['pmc-embargo-date'] = 'pmc-embargo-date', ['encyclopedia'] = {'موسوعة', 'encyclopedia', 'encyclopaedia', 'اسم المعجم', 'dictionary', 'اسم الموسوعة'}, -- cite encyclopedia only ['episode'] = {'الحلقة', 'episode'}, -- cite serial only TODO: make available to cite episode? ['format'] = {'صيغة', 'التنسيق', 'format', 'تنسيق', 'الصيغة'}, ['id'] = {'id', 'ID', 'المعرف'}, ['inset'] = {'inset', 'مجموعة'}, ['issue'] = {'العدد', 'issue', 'number'}, ['language'] = {'لغة', 'اللغة', 'language', 'lang'}, ['mailing-list'] = {'القائمة البريدية', 'mailing-list'}, -- cite mailing list only ['map'] = {'الخريطة', 'map'}, -- cite map only ['map-format'] = {'صيغة الخريطة', 'map-format'}, -- cite map only ['map-url'] = {'مسار الخريطة', 'map-url'}, -- cite map only -- Used by InternetArchiveBot ['map-url-access'] = 'map-url-access', -- cite map only -- Used by InternetArchiveBot ['minutes'] = {'دقيقة', 'minutes'}, ['mode'] = 'mode', ['name-list-style'] = 'name-list-style', ['network'] = {'الشبكة', 'network'}, ['newsgroup'] = {'اسم المجموعة', 'newsgroup'}, -- cite newsgroup only ['nopp'] = {'no-pp', 'nopp'}, ['no-tracking'] = {'no-tracking', 'template-doc-demo'}, ['number'] = 'number', -- this case only for cite techreport ['orig-date'] = {'orig-date', 'orig-year', 'origyear', 'سنة النشر الأصلية'}, ['others'] = {'آخرون','others', 'المحاور', 'المحاورون', 'المحقق'}, ['page'] = {'صفحة', 'p', 'الصفحة', 'page', 'الصفحة', 'رقم الصفحة', 'رقم صفحة','ص'}, -- Used by InternetArchiveBot ['pages'] = {'صفحات', 'الصفحات', 'pp', 'أرقام الصفحات', 'أرقم صفحات', 'pages'}, -- Used by InternetArchiveBot ['journal'] = { 'صحيفة', 'journal', 'دورية محكمة', 'مجلة', 'magazine', 'اسم المجلة', 'newspaper', 'جريدة', 'اسم الصحيفة', 'دورية', 'periodical', 'موقع', 'website', 'الموقع', 'عمل', 'work', 'العمل', 'من عمل', }, ['place'] = { 'مكان', 'place', 'المكان', 'مقر', 'المقر', 'location'}, ['postscript'] = 'postscript', ['publication-date'] = {'تاريخ-النشر', 'تاريخ النشر', 'publication-date'}, ['publication-place'] = {'مكان-النشر', 'مكان النشر', 'publication-place'}, ['publisher'] = {'ناشر', 'publisher', 'الناشر', 'institution', 'مصدر', 'الموزع', 'المصدر', 'المؤسسة'}, ['quote'] = {'اقتباس', 'quote', 'quotation'}, ['quote-page'] = 'quote-page', ['quote-pages'] = 'quote-pages', ['ref'] = {'مرجع', 'ref'}, ['scale'] = {'المقياس', 'scale'}, ['script-chapter'] = {'script-chapter', 'script-contribution', 'script-entry', 'script-article', 'script-section'}, ['script-encyclopedia'] = {'script-encyclopedia', 'script-encyclopaedia'}, -- cite encyclopedia only ['script-map'] = 'script-map', ['script-journal'] = {'script-journal', 'script-magazine', 'script-newspaper', 'script-periodical', 'script-website', 'script-work'}, ['script-quote'] = 'script-quote', ['script-title'] = 'script-title', -- Used by InternetArchiveBot ['season'] = {'الموسم', 'season'}, ['sections'] = {'الأقسام', 'sections'}, -- cite map only ['series'] = {'سلسلة', 'series', 'version'}, ['series-link'] = {'وصلة-سلسلة', 'وصلة سلسلة', 'series-link', 'مسار المسلسل'}, ['series-number'] = {'رقم-سلسلة', 'رقم سلسلة', 'series-number', 'series-no'}, ['sheet'] = {'ورقة', 'sheet'}, -- cite map only ['sheets'] = {'أوراق', 'sheets'}, -- cite map only ['station'] = {'محطة', 'station'}, ['time'] = {'الوقت', 'time'}, ['time-caption'] = 'time-caption', ['title'] = {'عنوان', 'title', 'العنوان'}, ['title-link'] = {'وصلة-العنوان', 'وصلة العنوان', 'title-link', 'episode-link', 'وصلة الحلقة'}, ['title-note'] = {'title-note', 'department'}, ['type'] = {'النوع', 'type', 'medium'}, ['trans-chapter'] = {'trans-article', 'trans-chapter', 'trans-contribution', 'trans-entry', 'trans-section'}, ['transcript'] = 'transcript', ['transcript-format'] = 'transcript-format', ['transcript-url'] = 'transcript-url', -- Used by InternetArchiveBot ['trans-encyclopedia'] = {'trans-encyclopedia', 'trans-encyclopaedia'}, -- cite encyclopedia only ['trans-map'] = 'trans-map', -- cite map only ['trans-journal'] = {'trans-journal', 'trans-magazine', 'trans-newspaper', 'trans-periodical', 'trans-website', 'trans-work'}, ['trans-quote'] = 'trans-quote', ['trans-title'] = {'عنوان مترجم', 'العنوان بالعربي', 'العنوان الأجنبي', 'عنوان أجنبي', 'trans-title', 'العنوان المترجم'}, -- Used by InternetArchiveBot ['url'] = {'مسار', 'المسار','وصلة', 'url', 'URL'}, -- Used by InternetArchiveBot ['url-access'] = {'url-access', 'التسجيل'}, -- Used by InternetArchiveBot ['url-status'] = {'url-status','حالة المسار'}, -- Used by InternetArchiveBot ['vauthors'] = {'vauthors', 'عدة مؤلفين'}, ['veditors'] = {'veditors', 'عدة محررين' }, ['via'] = {'عبر', 'via'}, ['volume'] = {'المجلد', 'volume', 'الجزء', 'ج'}, ['wikidatacite'] = 'wikidatacite', ['year'] = {'سنة', 'year', 'السنة'}, } local i18n_t = { ["ar"] = { illustrator = "رسم", composer = "تلحين", animator = "رسم الرسوم المتحركة", director = "إخراج", screenwriter = "سيناريو", signatory = "توقيع", presenter = "تقديم", performer = "أداء", annotator = "تحقيق", reviewer = "مراجعة", unknown = "مجهول", supervisor = "إشراف", ["unknown-publication-date"] = '<abbr class="abbr" title="دون تاريخ">د.ت.</abbr>', ["unknown-publisher"] = '<abbr class="abbr" title="دون ناشر">د.ن.</abbr>', wikidata = "ويكي بيانات" }, ["cite_q"] = "{{استشهاد بويكي بيانات|", ["erratum"] = "(erratum)", ["unknown-author"] = { ar = "غير معروف", en = "Anonymous", fr = "Aanonyme", de = "Anonymus", es = "Anónimo" }, ["wdq"] = "[[ويكي بيانات|QID]]", -- go through "WDQ (identifier)" redirect to reduce clutter in "What links here" and improve reverse lookup. Keep in sync with {{QID}}. ["wikisource"] = "arwikisource", ["errors"] = { ["local-article-not-found"] = "المقال المحلي غير موجود.", ["no-label-or-title"] = "لا عنون أو تسمية: ", }, -- Next Line Edited ["unknown-author-trackingcat"] = "", -- [[تصنيف:Cite Q - author unknown]] ["months"] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, ["ordinal"] = { [1] = "st", [2] = "nd", [3] = "rd", ["default"] = "th" }, ["trackingcats"] = { ["erratum"] = "[[تصنيف:استشهاد بويكي بيانات:الاستشهاد يعمل مع خطأ]]", ["missing-wikidata"] = "[[تصنيف:مقالات مع بيانات ويكي بيانات نقاصة]]", -- TODO: point to a {{cite q}}-specific category; this one is specific to Module:WikidataIB ['no-label-or-title'] = '[[تصنيف:استشهاد بويكي بيانات:يفتقر إلى عنوان أو تسمية]]', ["retracted"] = "[[تصنيف:الاستشهاد بويكي بيانات: الاستشهاد بعمل مسحوب]]<!-- retracted -->", ["replaced"] = "[[تصنيف:الاستشهاد بويكي بيانات: الاستشهاد بعمل مستبدل]]<!-- replaced -->", ["unknown-author"] = "", -- [[Category:Cite Q - author unknown]] removed as misplaced; someone is welcome to restore it if it is placed outside of the template parameter value ["unknown-template"] = "[[تصنيف:الاستشهاد بويكي بيانات:قالب مجهول]]", }, } local rejected_t = { sources = { Q465 = true, Q15241312 = true, Q52 = true }, properties = { "P1800", "P1566", "P21"}, instances = { Q5 = true, -- Human is not a direct reference Q184188 = true, Q1250464 = true, -- inatance of refference DBs Q8513 = true, Q17152639 = true, Q7094076 = true, Q5535082 = true, Q856638= true, Q1982918 = true, Q36524 = true, Q36218176 = true, Q526334 = true, Q5227411 = true } } -- Table of simple properties that can be fetched in roughly the same way: -- id = PXXX -- maxvals = maximum number of multiple values (0 for all) -- linked = "no" suppresses linking -- populate_from_journal = true/false determines whether to look in a journal where the source is published -- rank = "best", "preferred", normal, etc. determines how Wikidata ranks are treated -- others = true - the value for the property goes to "others" section local simple_properties_t = { -- Next Line Edited publisher = {id = "P123", maxvals = 3}, oclc = {id = "P243", maxvals = 1}, ['publication-place'] = {id = "P291", maxvals = 0, linked = false}, -- publication place (don't put into |place=; is treated specially in {{citation}} if both are given) doi = {id = "P356", maxvals = 1}, -- take care of |doi-broken-date= (WD "reason for deprecation"/"stated as") and |doi-access= (WD "access status")? issue = {id = "P433", maxvals = 0, populate_from_journal = true}, -- distinguish from |number= ("P1545"?) if both are given (still blocked by {{citation}}, but will be supported in the future) pmid = {id = "P698", maxvals = 1}, -- gbooks = {id = "P675", maxvals = 1}, -- to be added to {{citation}} -- ia = {id = "P724", maxvals = 1}, -- to be added to {{citation}} arxiv = {id = "P818", maxvals = 1}, bibcode = {id = "P819", maxvals = 1}, -- take care of |bibcode-access=? jstor = {id = "P888", maxvals = 1}, -- take care of |jstor-access=? mr = {id = "P889", maxvals = 1}, rfc = {id = "P892", maxvals = 1}, zbl = {id = "P894", maxvals = 1}, ssrn = {id = "P893", maxvals = 1}, place = {id = "P1071", maxvals = 0, linked = false}, -- written-at place -- ['total-pages'] = {id = "P1104", maxvals = 0, linked = 'no'}, -- to be added to {{citation}} / COinS &rft.tpages= -- coden = {id = "P1159", maxvals = 1}, -- to be added to {{citation}} / COinS &rft.coden= s2cid = {id = "P8299", maxvals = 1}, -- take care of |s2cid-access=? pmc = {id = "P932", maxvals = 1}, -- take care of |pmc-embargo-date= (WD "reason for deprecation")? lccn = {id = "P1144", maxvals = 1}, hdl = {id = "P1184", maxvals = 1}, -- take care of |hdl-access=? ismn = {id = "P1208", maxvals = 1}, journal = {id = "P1433", maxvals = 1}, citeseerx = {id = "P3784", maxvals = 1}, osti = {id = "P3894", maxvals = 1}, -- take care of |osti-access=? biorxiv = {id = "P3951", maxvals = 1}, asin = {id = "P5749", maxvals = 1}, -- What about |asin-tld=? (WD examples resolve to .com at present, but may change) -- ['catalog-number'] = {id = "P528", maxvals = 0}, -- to be added to {{citation}} / COinS &rft.artnum= isbn = {id = "P212", maxvals = 1, populate_from_journal = true}, -- ISBN 13 issn = {id = "P236", maxvals = 1, populate_from_journal = true}, -- distinguish from |eissn= for electronic issues? -- jfm = {id = "P?", maxvals = 1}, -- Jahrbuch über die Fortschritte der Mathematik (not Zbl) -- sbn = {id = "P?", maxvals = 1}, -- Standard Book Number (predecessor of ISBN, not ICCU) -- message-id = {id = "P?", maxvals = 1}, -- Usenet message ID chapter = {id = "P792", maxvals = 1, no_vol_qual=true}, ['publication-date'] = {id = "P577", maxvals = 1, populate_from_journal = true}, -- publication date (don't use |date=; is treated specially in {{citation}} if both are given.) series = {id = "P179", maxvals = 1, populate_from_journal = true, qual = "P1545"}, version = {id = "P348", maxvals = 0}, edition = {id = "P393", maxvals = 0}, volume = {id = "P478", maxvals = 0, populate_from_journal = true, no_vol_qual=true}, -- part = {id = "P1545"?, maxvals = 0}, -- to be added to {{citation}} / COinS &rft.part= title = {id = "P1476", rank="p n"}, -- url = {id = "P953", maxvals = 1}, -- deal with this along with archive-url pages = {id = "P304", maxvals = 0, populate_from_journal = true, no_vol_qual=true}, at = {id = "P958", maxvals = 0, populate_from_journal = true, no_vol_qual=true}, -- also incorporate lines (P7421) and columns (P3903) into this (cite map also supports |section=) -- sheets = {id = "P7416", maxvals = 0, populate_from_journal = true}, -- interviewer = {id = "P?", maxvals = 0}, -- does **not** go to "others" section! Multiple interviewers should be n-enumerated illustrator = {id = "P110", maxvals = 10, others = true}, -- goes to "others" section -- foreword and afterword, when contributions to another author's work, are contributions so belong in |contribution=; -- the writer's name goes in |contributor=; requires |title= and |author= -- However, this might need to add support for multiple contributors and their roles to {{citation}}, see Help_talk:Citation_Style_1#Others -- foreword = {id = "P2679", maxvals = 10, others = true}, -- goes to "others" section -- afterword = {id = "P2680", maxvals = 10, others = true}, -- goes to "others" section composer = {id = "P86", maxvals = 10, others = true}, -- goes to "others" section animator = {id = "P6942", maxvals = 10, others = true}, -- goes to "others" section director = {id = "P57", maxvals = 10, others = true}, -- goes to "others" section screenwriter = {id = "P58", maxvals = 10, others = true}, -- goes to "others" section signatory = {id = "P1891", maxvals = 10, others = true}, -- goes to "others" section presenter = {id = "P371", maxvals = 10, others = true}, -- goes to "others" section performer = {id = "P175", maxvals = 10, others = true}, -- goes to "others" section -- next 2 lines added for Arabic Wikipedia annotator = {id ="P11105", maxvals = 10, others = true}, -- goes to "others" section reviewer = {id ="P4032", maxvals = 10, others = true}, -- goes to "others" section supervisor = {id ="P7604", maxvals = 3, others = true}, -- goes to "others" section } local used_args_t = {accessdate=true, language=true, mode=true, ol=true, other=true, ['display-authors']=true, ['display-editors']=true, ['archive-url']=true, ['archive-date']=true, url=true, title=true} -- all_used_properties local used_properties_t = { P1071 = {arg= "place", maxvals = 0, linked = false}, -- written-at place P110 = {arg= "illustrator", maxvals = 10, others = true}, -- goes to "others" section P11105 = {arg= "annotator", maxvals = 10, others = true}, -- goes to "others" section P1144 = {arg= "lccn", maxvals = 1}, P1184 = {arg= "hdl", maxvals = 1}, -- take care of |hdl-access=? P1208 = {arg= "ismn", maxvals = 1}, P123 = {arg= "publisher", maxvals = 3}, P1433 = {arg= "journal", maxvals = 1}, P1476 = {arg= "title", rank="p n"}, P1680 = true, P175 = {arg= "performer", maxvals = 10, others = true}, -- goes to "others" section P179 = {arg= "series", maxvals = 1, populate_from_journal = true}, P1891 = {arg= "signatory", maxvals = 10, others = true}, -- goes to "others" section P1932 = true, P2093 = true, -- author string P212 = {arg= "isbn", maxvals = 1, populate_from_journal = true}, -- ISBN 13 P236 = {arg= "issn", maxvals = 1, populate_from_journal = true}, -- distinguish from |eissn= for electronic issues? P243 = {arg= "oclc", maxvals = 1}, P2699 = true, P291 = {arg= "publication-place", maxvals = 0, linked = false}, -- publication place (don't put into |place=; is treated specially in {{citation}} if both are given) P304 = {arg= "pages", maxvals = 0, populate_from_journal = true}, P348 = {arg= "version", maxvals = 0}, P356 = {arg= "doi", maxvals = 1}, -- take care of |doi-broken-date= (WD "reason for deprecation"/"stated as") and |doi-access= (WD "access status")? P371 = {arg= "presenter", maxvals = 10, others = true}, -- goes to "others" section P3784 = {arg= "citeseerx", maxvals = 1}, P3894 = {arg= "osti", maxvals = 1}, -- take care of |osti-access=? P393 = {arg= "edition", maxvals = 0}, P3951 = {arg= "biorxiv", maxvals = 1}, P4032 = {arg= "reviewer", maxvals = 10, others = true}, -- goes to "others" section P407 = true, P433 = {arg= "issue", maxvals = 0, populate_from_journal = true}, -- distinguish from |number= ("P1545"?) if both are given (still blocked by {{citation}}, but will be supported in the future) P478 = {arg= "volume", maxvals = 0, populate_from_journal = true}, P50 = true, -- author P57 = {arg= "director", maxvals = 10, others = true}, -- goes to "others" section P5749 = {arg= "asin", maxvals = 1}, -- What about |asin-tld=? (WD examples resolve to .com at present, but may change) P5769 = true, --editor P577 = {arg= "publication-date", maxvals = 1, populate_from_journal = true}, -- publication date (don't use |date=; is treated specially in {{citation}} if both are given.) P58 = {arg= "screenwriter", maxvals = 10, others = true}, -- goes to "others" section P655 = true, P6942 = {arg= "animator", maxvals = 10, others = true}, -- goes to "others" section P698 = {arg= "pmid", maxvals = 1}, P7604 = {arg ="supervisor", maxvals = 3, others = true}, -- goes to "others" section P792 = {arg= "chapter", maxvals = 1}, P818 = {arg= "arxiv", maxvals = 1}, P819 = {arg= "bibcode", maxvals = 1}, -- take care of |bibcode-access=? P8299 = {arg= "s2cid", maxvals = 1}, -- take care of |s2cid-access=? P856 = true, P86 = {arg= "composer", maxvals = 10, others = true}, -- goes to "others" section P888 = {arg= "jstor", maxvals = 1}, -- take care of |jstor-access=? P889 = {arg= "mr", maxvals = 1}, P892 = {arg= "rfc", maxvals = 1}, P893 = {arg= "ssrn", maxvals = 1}, P894 = {arg= "zbl", maxvals = 1}, P932 = {arg= "pmc", maxvals = 1}, -- take care of |pmc-embargo-date= (WD "reason for deprecation")? P953 = true, P958 = {arg= "at", maxvals = 0, populate_from_journal = true}, -- also incorporate lines (P7421) and columns (P3903) into this (cite map also supports |section=) P98 = true, P854 = true, } return { aliases_t = aliases_t, i18n_t = i18n_t, rejected_t = rejected_t, simple_properties_t = simple_properties_t, used_args_t = used_args_t, used_properties_t = used_properties_t, config_t = config_t } k6btb6fafyxnxmkyglbnabepvl55y5v 1097253 1097061 2026-07-22T15:51:51Z حبيشان 31560 إصلاح 1097253 Scribunto text/plain local config_t = { linksproject = "", wikilinkprefix = "" } local aliases_t = { ['accessdate'] = {'تاريخ-الوصول','تاريخ الوصول', 'تاريخ وصول', 'access-date', 'accessdate'}, ['agency'] = {'وكالة', 'agency'}, ['archivedate'] = {'تاريخ-الأرشيف', 'تاريخ أرشيف', 'تاريخ الأرشيف', 'archive-date', 'archivedate'}, ['archive-format'] = {'صيغة-الأرشيف', 'صيغة الأرشيف', 'archive-format'}, ['archive-url'] = {'مسار-الأرشيف', 'مسار أرشيف', 'مسار الأرشيف', 'archive-url', 'archiveurl'}, ['article-number'] = {'رقم-المقالة', 'article-number'}, ['asin-tld'] = 'asin-tld', ['at'] = {'في', 'at'}, --##TOREVISE ['authors'] = {'المؤلفون', 'المؤلفين', 'authors', 'people', 'host', 'credits', 'أشخاص'}, ['book-title'] = {'عنوان الكتاب', 'book-title', 'booktitle', 'عنوان المؤتمر'}, ['cartography'] = 'cartography', ['chapter'] = {'الفصل', 'chapter', 'contribution', 'entry', 'article', 'section'}, ['chapter-format'] = {'صيغة-الفصل', 'صيغة الفصل', 'تنسيق الفصل', 'chapter-format', 'contribution-format', 'entry-format', 'article-format', 'section-format'}, ['chapter-url'] = {'مسار-الفصل', 'مسار الفصل', 'chapter-url', 'contribution-url', 'entry-url', 'article-url', 'section-url'}, -- Used by InternetArchiveBot ['chapter-url-access'] = {'chapter-url-access', 'contribution-url-access', 'entry-url-access', 'article-url-access', 'section-url-access'}, -- Used by InternetArchiveBot ['class'] = {'صنف', 'class'}, -- cite arxiv and arxiv identifier ['collaboration'] = 'collaboration', ['conference'] = {'اسم-المؤتمر', 'اسم المؤتمر', 'conference'}, ['conference-format'] = 'conference-format', ['conference-url'] = {'مسار-المؤتمر', 'مسار المؤتمر', 'conference-url'}, -- Used by InternetArchiveBot ['date'] = {'تاريخ', 'التاريخ', 'date', 'air-date', 'airdate'}, ['degree'] = {'الدرجة', 'degree'}, ['df'] = 'df', ['display-authors'] = {'إظهار-المؤلفين', 'إظهار المؤلفين', 'display-authors', 'display-subjects'}, ['display-contributors'] = 'display-contributors', ['display-editors'] = {'إظهار-المحررين', 'إظهار المحررين', 'display-editors'}, ['display-interviewers'] = 'display-interviewers', ['display-translators'] = 'display-translators', ['docket'] = 'docket', ['doi-broken-date'] = 'doi-broken-date', ['edition'] = {'طبعة', 'الإصدار', 'الاصدار', 'إصدار', 'اصدار', 'الطبعة', 'رقم الطبعة', 'edition'}, ['pmc-embargo-date'] = 'pmc-embargo-date', ['encyclopedia'] = {'موسوعة', 'encyclopedia', 'encyclopaedia', 'اسم المعجم', 'dictionary', 'اسم الموسوعة'}, -- cite encyclopedia only ['episode'] = {'الحلقة', 'episode'}, -- cite serial only TODO: make available to cite episode? ['format'] = {'صيغة', 'التنسيق', 'format', 'تنسيق', 'الصيغة'}, ['id'] = {'id', 'ID', 'المعرف'}, ['inset'] = {'inset', 'مجموعة'}, ['issue'] = {'العدد', 'issue', 'number'}, ['language'] = {'لغة', 'اللغة', 'language', 'lang'}, ['mailing-list'] = {'القائمة البريدية', 'mailing-list'}, -- cite mailing list only ['map'] = {'الخريطة', 'map'}, -- cite map only ['map-format'] = {'صيغة الخريطة', 'map-format'}, -- cite map only ['map-url'] = {'مسار الخريطة', 'map-url'}, -- cite map only -- Used by InternetArchiveBot ['map-url-access'] = 'map-url-access', -- cite map only -- Used by InternetArchiveBot ['minutes'] = {'دقيقة', 'minutes'}, ['mode'] = 'mode', ['name-list-style'] = 'name-list-style', ['network'] = {'الشبكة', 'network'}, ['newsgroup'] = {'اسم المجموعة', 'newsgroup'}, -- cite newsgroup only ['nopp'] = {'no-pp', 'nopp'}, ['no-tracking'] = {'no-tracking', 'template-doc-demo'}, ['number'] = 'number', -- this case only for cite techreport ['orig-date'] = {'orig-date', 'orig-year', 'origyear', 'سنة النشر الأصلية'}, ['others'] = {'آخرون','others', 'المحاور', 'المحاورون', 'المحقق'}, ['page'] = {'صفحة', 'p', 'الصفحة', 'page', 'الصفحة', 'رقم الصفحة', 'رقم صفحة','ص'}, -- Used by InternetArchiveBot ['pages'] = {'صفحات', 'الصفحات', 'pp', 'أرقام الصفحات', 'أرقم صفحات', 'pages'}, -- Used by InternetArchiveBot ['journal'] = { 'صحيفة', 'journal', 'دورية محكمة', 'مجلة', 'magazine', 'اسم المجلة', 'newspaper', 'جريدة', 'اسم الصحيفة', 'دورية', 'periodical', 'موقع', 'website', 'الموقع', 'عمل', 'work', 'العمل', 'من عمل', }, ['place'] = { 'مكان', 'place', 'المكان', 'مقر', 'المقر', 'location'}, ['postscript'] = 'postscript', ['publication-date'] = {'تاريخ-النشر', 'تاريخ النشر', 'publication-date'}, ['publication-place'] = {'مكان-النشر', 'مكان النشر', 'publication-place'}, ['publisher'] = {'ناشر', 'publisher', 'الناشر', 'institution', 'مصدر', 'الموزع', 'المصدر', 'المؤسسة'}, ['quote'] = {'اقتباس', 'quote', 'quotation'}, ['quote-page'] = 'quote-page', ['quote-pages'] = 'quote-pages', ['ref'] = {'مرجع', 'ref'}, ['scale'] = {'المقياس', 'scale'}, ['script-chapter'] = {'script-chapter', 'script-contribution', 'script-entry', 'script-article', 'script-section'}, ['script-encyclopedia'] = {'script-encyclopedia', 'script-encyclopaedia'}, -- cite encyclopedia only ['script-map'] = 'script-map', ['script-journal'] = {'script-journal', 'script-magazine', 'script-newspaper', 'script-periodical', 'script-website', 'script-work'}, ['script-quote'] = 'script-quote', ['script-title'] = 'script-title', -- Used by InternetArchiveBot ['season'] = {'الموسم', 'season'}, ['sections'] = {'الأقسام', 'sections'}, -- cite map only ['series'] = {'سلسلة', 'series', 'version'}, ['series-link'] = {'وصلة-سلسلة', 'وصلة سلسلة', 'series-link', 'مسار المسلسل'}, ['series-number'] = {'رقم-سلسلة', 'رقم سلسلة', 'series-number', 'series-no'}, ['sheet'] = {'ورقة', 'sheet'}, -- cite map only ['sheets'] = {'أوراق', 'sheets'}, -- cite map only ['station'] = {'محطة', 'station'}, ['time'] = {'الوقت', 'time'}, ['time-caption'] = 'time-caption', ['title'] = {'عنوان', 'title', 'العنوان'}, ['title-link'] = {'وصلة-العنوان', 'وصلة العنوان', 'title-link', 'episode-link', 'وصلة الحلقة'}, ['title-note'] = {'title-note', 'department'}, ['type'] = {'النوع', 'type', 'medium'}, ['trans-chapter'] = {'trans-article', 'trans-chapter', 'trans-contribution', 'trans-entry', 'trans-section'}, ['transcript'] = 'transcript', ['transcript-format'] = 'transcript-format', ['transcript-url'] = 'transcript-url', -- Used by InternetArchiveBot ['trans-encyclopedia'] = {'trans-encyclopedia', 'trans-encyclopaedia'}, -- cite encyclopedia only ['trans-map'] = 'trans-map', -- cite map only ['trans-journal'] = {'trans-journal', 'trans-magazine', 'trans-newspaper', 'trans-periodical', 'trans-website', 'trans-work'}, ['trans-quote'] = 'trans-quote', ['trans-title'] = {'عنوان مترجم', 'العنوان بالعربي', 'العنوان الأجنبي', 'عنوان أجنبي', 'trans-title', 'العنوان المترجم'}, -- Used by InternetArchiveBot ['url'] = {'مسار', 'المسار','وصلة', 'url', 'URL'}, -- Used by InternetArchiveBot ['url-access'] = {'url-access', 'التسجيل'}, -- Used by InternetArchiveBot ['url-status'] = {'url-status','حالة المسار'}, -- Used by InternetArchiveBot ['vauthors'] = {'vauthors', 'عدة مؤلفين'}, ['veditors'] = {'veditors', 'عدة محررين' }, ['via'] = {'عبر', 'via'}, ['volume'] = {'المجلد', 'volume', 'الجزء', 'ج'}, ['wikidatacite'] = 'wikidatacite', ['year'] = {'سنة', 'year', 'السنة'}, } local i18n_t = { ["ar"] = { illustrator = "رسم", composer = "تلحين", animator = "رسم الرسوم المتحركة", director = "إخراج", screenwriter = "سيناريو", signatory = "توقيع", presenter = "تقديم", performer = "أداء", annotator = "تحقيق", reviewer = "مراجعة", unknown = "مجهول", supervisor = "إشراف", ["unknown-publication-date"] = '<abbr class="abbr" title="دون تاريخ">د.ت.</abbr>', ["unknown-publisher"] = '<abbr class="abbr" title="دون ناشر">د.ن.</abbr>', wikidata = "ويكي بيانات" }, ["cite_q"] = "{{استشهاد بويكي بيانات|", ["erratum"] = "(erratum)", ["unknown-author"] = { ar = "غير معروف", en = "Anonymous", fr = "Aanonyme", de = "Anonymus", es = "Anónimo" }, ["wdq"] = "[[ويكي بيانات|QID]]", -- go through "WDQ (identifier)" redirect to reduce clutter in "What links here" and improve reverse lookup. Keep in sync with {{QID}}. ["wikisource"] = "arwikisource", ["errors"] = { ["local-article-not-found"] = "المقال المحلي غير موجود.", ["no-label-or-title"] = "لا عنون أو تسمية: ", }, -- Next Line Edited ["unknown-author-trackingcat"] = "", -- [[تصنيف:Cite Q - author unknown]] ["months"] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, ["ordinal"] = { [1] = "st", [2] = "nd", [3] = "rd", ["default"] = "th" }, ["trackingcats"] = { ["erratum"] = "[[تصنيف:استشهاد بويكي بيانات:الاستشهاد يعمل مع خطأ]]", ["missing-wikidata"] = "[[تصنيف:مقالات مع بيانات ويكي بيانات نقاصة]]", -- TODO: point to a {{cite q}}-specific category; this one is specific to Module:WikidataIB ['no-label-or-title'] = '[[تصنيف:استشهاد بويكي بيانات:يفتقر إلى عنوان أو تسمية]]', ["retracted"] = "[[تصنيف:الاستشهاد بويكي بيانات: الاستشهاد بعمل مسحوب]]<!-- retracted -->", ["replaced"] = "[[تصنيف:الاستشهاد بويكي بيانات: الاستشهاد بعمل مستبدل]]<!-- replaced -->", ["unknown-author"] = "", -- [[Category:Cite Q - author unknown]] removed as misplaced; someone is welcome to restore it if it is placed outside of the template parameter value ["unknown-template"] = "[[تصنيف:الاستشهاد بويكي بيانات:قالب مجهول]]", }, } local rejected_t = { sources = { Q465 = true, Q15241312 = true, Q52 = true }, properties = { "P1800", "P1566", "P21"}, instances = { Q5 = true, -- Human is not a direct reference Q184188 = true, Q1250464 = true, -- inatance of refference DBs Q8513 = true, Q17152639 = true, Q7094076 = true, Q5535082 = true, Q856638= true, Q1982918 = true, Q36524 = true, Q36218176 = true, Q526334 = true, Q5227411 = true } } -- Table of simple properties that can be fetched in roughly the same way: -- id = PXXX -- maxvals = maximum number of multiple values (0 for all) -- linked = "no" suppresses linking -- populate_from_journal = true/false determines whether to look in a journal where the source is published -- rank = "best", "preferred", normal, etc. determines how Wikidata ranks are treated -- others = true - the value for the property goes to "others" section local simple_properties_t = { -- Next Line Edited publisher = {id = "P123", maxvals = 3}, oclc = {id = "P243", maxvals = 1}, ['publication-place'] = {id = "P291", maxvals = 0, linked = false}, -- publication place (don't put into |place=; is treated specially in {{citation}} if both are given) doi = {id = "P356", maxvals = 1}, -- take care of |doi-broken-date= (WD "reason for deprecation"/"stated as") and |doi-access= (WD "access status")? issue = {id = "P433", maxvals = 0, populate_from_journal = true}, -- distinguish from |number= ("P1545"?) if both are given (still blocked by {{citation}}, but will be supported in the future) pmid = {id = "P698", maxvals = 1}, -- gbooks = {id = "P675", maxvals = 1}, -- to be added to {{citation}} -- ia = {id = "P724", maxvals = 1}, -- to be added to {{citation}} arxiv = {id = "P818", maxvals = 1}, bibcode = {id = "P819", maxvals = 1}, -- take care of |bibcode-access=? jstor = {id = "P888", maxvals = 1}, -- take care of |jstor-access=? mr = {id = "P889", maxvals = 1}, rfc = {id = "P892", maxvals = 1}, zbl = {id = "P894", maxvals = 1}, ssrn = {id = "P893", maxvals = 1}, place = {id = "P1071", maxvals = 0, linked = false}, -- written-at place -- ['total-pages'] = {id = "P1104", maxvals = 0, linked = 'no'}, -- to be added to {{citation}} / COinS &rft.tpages= -- coden = {id = "P1159", maxvals = 1}, -- to be added to {{citation}} / COinS &rft.coden= s2cid = {id = "P8299", maxvals = 1}, -- take care of |s2cid-access=? pmc = {id = "P932", maxvals = 1}, -- take care of |pmc-embargo-date= (WD "reason for deprecation")? lccn = {id = "P1144", maxvals = 1}, hdl = {id = "P1184", maxvals = 1}, -- take care of |hdl-access=? ismn = {id = "P1208", maxvals = 1}, journal = {id = "P1433", maxvals = 1}, citeseerx = {id = "P3784", maxvals = 1}, osti = {id = "P3894", maxvals = 1}, -- take care of |osti-access=? biorxiv = {id = "P3951", maxvals = 1}, asin = {id = "P5749", maxvals = 1}, -- What about |asin-tld=? (WD examples resolve to .com at present, but may change) -- ['catalog-number'] = {id = "P528", maxvals = 0}, -- to be added to {{citation}} / COinS &rft.artnum= isbn = {id = "P212", maxvals = 1, populate_from_journal = true}, -- ISBN 13 issn = {id = "P236", maxvals = 1, populate_from_journal = true}, -- distinguish from |eissn= for electronic issues? -- jfm = {id = "P?", maxvals = 1}, -- Jahrbuch über die Fortschritte der Mathematik (not Zbl) -- sbn = {id = "P?", maxvals = 1}, -- Standard Book Number (predecessor of ISBN, not ICCU) -- message-id = {id = "P?", maxvals = 1}, -- Usenet message ID chapter = {id = "P792", maxvals = 1, no_vol_qual=true}, ['publication-date'] = {id = "P577", maxvals = 1, populate_from_journal = true}, -- publication date (don't use |date=; is treated specially in {{citation}} if both are given.) series = {id = "P179", maxvals = 1, populate_from_journal = true, qual = "P1545"}, version = {id = "P348", maxvals = 0}, edition = {id = "P393", maxvals = 0}, volume = {id = "P478", maxvals = 0, populate_from_journal = true, no_vol_qual=true}, -- part = {id = "P1545"?, maxvals = 0}, -- to be added to {{citation}} / COinS &rft.part= title = {id = "P1476", rank="p n"}, -- url = {id = "P953", maxvals = 1}, -- deal with this along with archive-url pages = {id = "P304", maxvals = 0, populate_from_journal = true, no_vol_qual=true}, at = {id = "P958", maxvals = 0, populate_from_journal = true, no_vol_qual=true}, -- also incorporate lines (P7421) and columns (P3903) into this (cite map also supports |section=) -- sheets = {id = "P7416", maxvals = 0, populate_from_journal = true}, -- interviewer = {id = "P?", maxvals = 0}, -- does **not** go to "others" section! Multiple interviewers should be n-enumerated illustrator = {id = "P110", maxvals = 10, others = true}, -- goes to "others" section -- foreword and afterword, when contributions to another author's work, are contributions so belong in |contribution=; -- the writer's name goes in |contributor=; requires |title= and |author= -- However, this might need to add support for multiple contributors and their roles to {{citation}}, see Help_talk:Citation_Style_1#Others -- foreword = {id = "P2679", maxvals = 10, others = true}, -- goes to "others" section -- afterword = {id = "P2680", maxvals = 10, others = true}, -- goes to "others" section composer = {id = "P86", maxvals = 10, others = true}, -- goes to "others" section animator = {id = "P6942", maxvals = 10, others = true}, -- goes to "others" section director = {id = "P57", maxvals = 10, others = true}, -- goes to "others" section screenwriter = {id = "P58", maxvals = 10, others = true}, -- goes to "others" section signatory = {id = "P1891", maxvals = 10, others = true}, -- goes to "others" section presenter = {id = "P371", maxvals = 10, others = true}, -- goes to "others" section performer = {id = "P175", maxvals = 10, others = true}, -- goes to "others" section -- next 2 lines added for Arabic Wikipedia annotator = {id ="P11105", maxvals = 10, others = true}, -- goes to "others" section reviewer = {id ="P4032", maxvals = 10, others = true}, -- goes to "others" section supervisor = {id ="P7604", maxvals = 3, others = true}, -- goes to "others" section } local used_args_t = {accessdate=true, language=true, mode=true, ol=true, other=true, ['display-authors']=true, ['display-editors']=true, ['archive-url']=true, ['archive-date']=true, url=true, title=true, page=true, pages = true, volume=true} -- all_used_properties local used_properties_t = { P1071 = {arg= "place", maxvals = 0, linked = false}, -- written-at place P110 = {arg= "illustrator", maxvals = 10, others = true}, -- goes to "others" section P11105 = {arg= "annotator", maxvals = 10, others = true}, -- goes to "others" section P1144 = {arg= "lccn", maxvals = 1}, P1184 = {arg= "hdl", maxvals = 1}, -- take care of |hdl-access=? P1208 = {arg= "ismn", maxvals = 1}, P123 = {arg= "publisher", maxvals = 3}, P1433 = {arg= "journal", maxvals = 1}, P1476 = {arg= "title", rank="p n"}, P1680 = true, P175 = {arg= "performer", maxvals = 10, others = true}, -- goes to "others" section P179 = {arg= "series", maxvals = 1, populate_from_journal = true}, P1891 = {arg= "signatory", maxvals = 10, others = true}, -- goes to "others" section P1932 = true, P2093 = true, -- author string P212 = {arg= "isbn", maxvals = 1, populate_from_journal = true}, -- ISBN 13 P236 = {arg= "issn", maxvals = 1, populate_from_journal = true}, -- distinguish from |eissn= for electronic issues? P243 = {arg= "oclc", maxvals = 1}, P2699 = true, P291 = {arg= "publication-place", maxvals = 0, linked = false}, -- publication place (don't put into |place=; is treated specially in {{citation}} if both are given) P304 = {arg= "pages", maxvals = 0, populate_from_journal = true}, P348 = {arg= "version", maxvals = 0}, P356 = {arg= "doi", maxvals = 1}, -- take care of |doi-broken-date= (WD "reason for deprecation"/"stated as") and |doi-access= (WD "access status")? P371 = {arg= "presenter", maxvals = 10, others = true}, -- goes to "others" section P3784 = {arg= "citeseerx", maxvals = 1}, P3894 = {arg= "osti", maxvals = 1}, -- take care of |osti-access=? P393 = {arg= "edition", maxvals = 0}, P3951 = {arg= "biorxiv", maxvals = 1}, P4032 = {arg= "reviewer", maxvals = 10, others = true}, -- goes to "others" section P407 = true, P433 = {arg= "issue", maxvals = 0, populate_from_journal = true}, -- distinguish from |number= ("P1545"?) if both are given (still blocked by {{citation}}, but will be supported in the future) P478 = {arg= "volume", maxvals = 0, populate_from_journal = true}, P50 = true, -- author P57 = {arg= "director", maxvals = 10, others = true}, -- goes to "others" section P5749 = {arg= "asin", maxvals = 1}, -- What about |asin-tld=? (WD examples resolve to .com at present, but may change) P5769 = true, --editor P577 = {arg= "publication-date", maxvals = 1, populate_from_journal = true}, -- publication date (don't use |date=; is treated specially in {{citation}} if both are given.) P58 = {arg= "screenwriter", maxvals = 10, others = true}, -- goes to "others" section P655 = true, P6942 = {arg= "animator", maxvals = 10, others = true}, -- goes to "others" section P698 = {arg= "pmid", maxvals = 1}, P7604 = {arg ="supervisor", maxvals = 3, others = true}, -- goes to "others" section P792 = {arg= "chapter", maxvals = 1}, P818 = {arg= "arxiv", maxvals = 1}, P819 = {arg= "bibcode", maxvals = 1}, -- take care of |bibcode-access=? P8299 = {arg= "s2cid", maxvals = 1}, -- take care of |s2cid-access=? P856 = true, P86 = {arg= "composer", maxvals = 10, others = true}, -- goes to "others" section P888 = {arg= "jstor", maxvals = 1}, -- take care of |jstor-access=? P889 = {arg= "mr", maxvals = 1}, P892 = {arg= "rfc", maxvals = 1}, P893 = {arg= "ssrn", maxvals = 1}, P894 = {arg= "zbl", maxvals = 1}, P932 = {arg= "pmc", maxvals = 1}, -- take care of |pmc-embargo-date= (WD "reason for deprecation")? P953 = true, P958 = {arg= "at", maxvals = 0, populate_from_journal = true}, -- also incorporate lines (P7421) and columns (P3903) into this (cite map also supports |section=) P98 = true, P854 = true, } return { aliases_t = aliases_t, i18n_t = i18n_t, rejected_t = rejected_t, simple_properties_t = simple_properties_t, used_args_t = used_args_t, used_properties_t = used_properties_t, config_t = config_t } k36sn5bwe2o6q1ui3s5jrjkx7azlmms 1097286 1097253 2026-07-22T21:14:32Z حبيشان 31560 1097286 Scribunto text/plain local config_t = { linksproject = "arwiki", wikilinkprefix = ":w:" } local aliases_t = { ['accessdate'] = {'تاريخ-الوصول','تاريخ الوصول', 'تاريخ وصول', 'access-date', 'accessdate'}, ['agency'] = {'وكالة', 'agency'}, ['archivedate'] = {'تاريخ-الأرشيف', 'تاريخ أرشيف', 'تاريخ الأرشيف', 'archive-date', 'archivedate'}, ['archive-format'] = {'صيغة-الأرشيف', 'صيغة الأرشيف', 'archive-format'}, ['archive-url'] = {'مسار-الأرشيف', 'مسار أرشيف', 'مسار الأرشيف', 'archive-url', 'archiveurl'}, ['article-number'] = {'رقم-المقالة', 'article-number'}, ['asin-tld'] = 'asin-tld', ['at'] = {'في', 'at'}, --##TOREVISE ['authors'] = {'المؤلفون', 'المؤلفين', 'authors', 'people', 'host', 'credits', 'أشخاص'}, ['book-title'] = {'عنوان الكتاب', 'book-title', 'booktitle', 'عنوان المؤتمر'}, ['cartography'] = 'cartography', ['chapter'] = {'الفصل', 'chapter', 'contribution', 'entry', 'article', 'section'}, ['chapter-format'] = {'صيغة-الفصل', 'صيغة الفصل', 'تنسيق الفصل', 'chapter-format', 'contribution-format', 'entry-format', 'article-format', 'section-format'}, ['chapter-url'] = {'مسار-الفصل', 'مسار الفصل', 'chapter-url', 'contribution-url', 'entry-url', 'article-url', 'section-url'}, -- Used by InternetArchiveBot ['chapter-url-access'] = {'chapter-url-access', 'contribution-url-access', 'entry-url-access', 'article-url-access', 'section-url-access'}, -- Used by InternetArchiveBot ['class'] = {'صنف', 'class'}, -- cite arxiv and arxiv identifier ['collaboration'] = 'collaboration', ['conference'] = {'اسم-المؤتمر', 'اسم المؤتمر', 'conference'}, ['conference-format'] = 'conference-format', ['conference-url'] = {'مسار-المؤتمر', 'مسار المؤتمر', 'conference-url'}, -- Used by InternetArchiveBot ['date'] = {'تاريخ', 'التاريخ', 'date', 'air-date', 'airdate'}, ['degree'] = {'الدرجة', 'degree'}, ['df'] = 'df', ['display-authors'] = {'إظهار-المؤلفين', 'إظهار المؤلفين', 'display-authors', 'display-subjects'}, ['display-contributors'] = 'display-contributors', ['display-editors'] = {'إظهار-المحررين', 'إظهار المحررين', 'display-editors'}, ['display-interviewers'] = 'display-interviewers', ['display-translators'] = 'display-translators', ['docket'] = 'docket', ['doi-broken-date'] = 'doi-broken-date', ['edition'] = {'طبعة', 'الإصدار', 'الاصدار', 'إصدار', 'اصدار', 'الطبعة', 'رقم الطبعة', 'edition'}, ['pmc-embargo-date'] = 'pmc-embargo-date', ['encyclopedia'] = {'موسوعة', 'encyclopedia', 'encyclopaedia', 'اسم المعجم', 'dictionary', 'اسم الموسوعة'}, -- cite encyclopedia only ['episode'] = {'الحلقة', 'episode'}, -- cite serial only TODO: make available to cite episode? ['format'] = {'صيغة', 'التنسيق', 'format', 'تنسيق', 'الصيغة'}, ['id'] = {'id', 'ID', 'المعرف'}, ['inset'] = {'inset', 'مجموعة'}, ['issue'] = {'العدد', 'issue', 'number'}, ['language'] = {'لغة', 'اللغة', 'language', 'lang'}, ['mailing-list'] = {'القائمة البريدية', 'mailing-list'}, -- cite mailing list only ['map'] = {'الخريطة', 'map'}, -- cite map only ['map-format'] = {'صيغة الخريطة', 'map-format'}, -- cite map only ['map-url'] = {'مسار الخريطة', 'map-url'}, -- cite map only -- Used by InternetArchiveBot ['map-url-access'] = 'map-url-access', -- cite map only -- Used by InternetArchiveBot ['minutes'] = {'دقيقة', 'minutes'}, ['mode'] = 'mode', ['name-list-style'] = 'name-list-style', ['network'] = {'الشبكة', 'network'}, ['newsgroup'] = {'اسم المجموعة', 'newsgroup'}, -- cite newsgroup only ['nopp'] = {'no-pp', 'nopp'}, ['no-tracking'] = {'no-tracking', 'template-doc-demo'}, ['number'] = 'number', -- this case only for cite techreport ['orig-date'] = {'orig-date', 'orig-year', 'origyear', 'سنة النشر الأصلية'}, ['others'] = {'آخرون','others', 'المحاور', 'المحاورون', 'المحقق'}, ['page'] = {'صفحة', 'p', 'الصفحة', 'page', 'الصفحة', 'رقم الصفحة', 'رقم صفحة','ص'}, -- Used by InternetArchiveBot ['pages'] = {'صفحات', 'الصفحات', 'pp', 'أرقام الصفحات', 'أرقم صفحات', 'pages'}, -- Used by InternetArchiveBot ['journal'] = { 'صحيفة', 'journal', 'دورية محكمة', 'مجلة', 'magazine', 'اسم المجلة', 'newspaper', 'جريدة', 'اسم الصحيفة', 'دورية', 'periodical', 'موقع', 'website', 'الموقع', 'عمل', 'work', 'العمل', 'من عمل', }, ['place'] = { 'مكان', 'place', 'المكان', 'مقر', 'المقر', 'location'}, ['postscript'] = 'postscript', ['publication-date'] = {'تاريخ-النشر', 'تاريخ النشر', 'publication-date'}, ['publication-place'] = {'مكان-النشر', 'مكان النشر', 'publication-place'}, ['publisher'] = {'ناشر', 'publisher', 'الناشر', 'institution', 'مصدر', 'الموزع', 'المصدر', 'المؤسسة'}, ['quote'] = {'اقتباس', 'quote', 'quotation'}, ['quote-page'] = 'quote-page', ['quote-pages'] = 'quote-pages', ['ref'] = {'مرجع', 'ref'}, ['scale'] = {'المقياس', 'scale'}, ['script-chapter'] = {'script-chapter', 'script-contribution', 'script-entry', 'script-article', 'script-section'}, ['script-encyclopedia'] = {'script-encyclopedia', 'script-encyclopaedia'}, -- cite encyclopedia only ['script-map'] = 'script-map', ['script-journal'] = {'script-journal', 'script-magazine', 'script-newspaper', 'script-periodical', 'script-website', 'script-work'}, ['script-quote'] = 'script-quote', ['script-title'] = 'script-title', -- Used by InternetArchiveBot ['season'] = {'الموسم', 'season'}, ['sections'] = {'الأقسام', 'sections'}, -- cite map only ['series'] = {'سلسلة', 'series', 'version'}, ['series-link'] = {'وصلة-سلسلة', 'وصلة سلسلة', 'series-link', 'مسار المسلسل'}, ['series-number'] = {'رقم-سلسلة', 'رقم سلسلة', 'series-number', 'series-no'}, ['sheet'] = {'ورقة', 'sheet'}, -- cite map only ['sheets'] = {'أوراق', 'sheets'}, -- cite map only ['station'] = {'محطة', 'station'}, ['time'] = {'الوقت', 'time'}, ['time-caption'] = 'time-caption', ['title'] = {'عنوان', 'title', 'العنوان'}, ['title-link'] = {'وصلة-العنوان', 'وصلة العنوان', 'title-link', 'episode-link', 'وصلة الحلقة'}, ['title-note'] = {'title-note', 'department'}, ['type'] = {'النوع', 'type', 'medium'}, ['trans-chapter'] = {'trans-article', 'trans-chapter', 'trans-contribution', 'trans-entry', 'trans-section'}, ['transcript'] = 'transcript', ['transcript-format'] = 'transcript-format', ['transcript-url'] = 'transcript-url', -- Used by InternetArchiveBot ['trans-encyclopedia'] = {'trans-encyclopedia', 'trans-encyclopaedia'}, -- cite encyclopedia only ['trans-map'] = 'trans-map', -- cite map only ['trans-journal'] = {'trans-journal', 'trans-magazine', 'trans-newspaper', 'trans-periodical', 'trans-website', 'trans-work'}, ['trans-quote'] = 'trans-quote', ['trans-title'] = {'عنوان مترجم', 'العنوان بالعربي', 'العنوان الأجنبي', 'عنوان أجنبي', 'trans-title', 'العنوان المترجم'}, -- Used by InternetArchiveBot ['url'] = {'مسار', 'المسار','وصلة', 'url', 'URL'}, -- Used by InternetArchiveBot ['url-access'] = {'url-access', 'التسجيل'}, -- Used by InternetArchiveBot ['url-status'] = {'url-status','حالة المسار'}, -- Used by InternetArchiveBot ['vauthors'] = {'vauthors', 'عدة مؤلفين'}, ['veditors'] = {'veditors', 'عدة محررين' }, ['via'] = {'عبر', 'via'}, ['volume'] = {'المجلد', 'volume', 'الجزء', 'ج'}, ['wikidatacite'] = 'wikidatacite', ['year'] = {'سنة', 'year', 'السنة'}, } local i18n_t = { ["ar"] = { illustrator = "رسم", composer = "تلحين", animator = "رسم الرسوم المتحركة", director = "إخراج", screenwriter = "سيناريو", signatory = "توقيع", presenter = "تقديم", performer = "أداء", annotator = "تحقيق", reviewer = "مراجعة", unknown = "مجهول", supervisor = "إشراف", ["unknown-publication-date"] = '<abbr class="abbr" title="دون تاريخ">د.ت.</abbr>', ["unknown-publisher"] = '<abbr class="abbr" title="دون ناشر">د.ن.</abbr>', wikidata = "ويكي بيانات" }, ["cite_q"] = "{{استشهاد بويكي بيانات|", ["erratum"] = "(erratum)", ["unknown-author"] = { ar = "غير معروف", en = "Anonymous", fr = "Aanonyme", de = "Anonymus", es = "Anónimo" }, ["wdq"] = "[[ويكي بيانات|QID]]", -- go through "WDQ (identifier)" redirect to reduce clutter in "What links here" and improve reverse lookup. Keep in sync with {{QID}}. ["wikisource"] = "arwikisource", ["errors"] = { ["local-article-not-found"] = "المقال المحلي غير موجود.", ["no-label-or-title"] = "لا عنون أو تسمية: ", }, -- Next Line Edited ["unknown-author-trackingcat"] = "", -- [[تصنيف:Cite Q - author unknown]] ["months"] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, ["ordinal"] = { [1] = "st", [2] = "nd", [3] = "rd", ["default"] = "th" }, ["trackingcats"] = { ["erratum"] = "[[تصنيف:استشهاد بويكي بيانات:الاستشهاد يعمل مع خطأ]]", ["missing-wikidata"] = "[[تصنيف:مقالات مع بيانات ويكي بيانات نقاصة]]", -- TODO: point to a {{cite q}}-specific category; this one is specific to Module:WikidataIB ['no-label-or-title'] = '[[تصنيف:استشهاد بويكي بيانات:يفتقر إلى عنوان أو تسمية]]', ["retracted"] = "[[تصنيف:الاستشهاد بويكي بيانات: الاستشهاد بعمل مسحوب]]<!-- retracted -->", ["replaced"] = "[[تصنيف:الاستشهاد بويكي بيانات: الاستشهاد بعمل مستبدل]]<!-- replaced -->", ["unknown-author"] = "", -- [[Category:Cite Q - author unknown]] removed as misplaced; someone is welcome to restore it if it is placed outside of the template parameter value ["unknown-template"] = "[[تصنيف:الاستشهاد بويكي بيانات:قالب مجهول]]", }, } local rejected_t = { sources = { Q465 = true, Q15241312 = true, Q52 = true }, properties = { "P1800", "P1566", "P21"}, instances = { Q5 = true, -- Human is not a direct reference Q184188 = true, Q1250464 = true, -- inatance of refference DBs Q8513 = true, Q17152639 = true, Q7094076 = true, Q5535082 = true, Q856638= true, Q1982918 = true, Q36524 = true, Q36218176 = true, Q526334 = true, Q5227411 = true } } -- Table of simple properties that can be fetched in roughly the same way: -- id = PXXX -- maxvals = maximum number of multiple values (0 for all) -- linked = "no" suppresses linking -- populate_from_journal = true/false determines whether to look in a journal where the source is published -- rank = "best", "preferred", normal, etc. determines how Wikidata ranks are treated -- others = true - the value for the property goes to "others" section local simple_properties_t = { -- Next Line Edited publisher = {id = "P123", maxvals = 3}, oclc = {id = "P243", maxvals = 1}, ['publication-place'] = {id = "P291", maxvals = 0, linked = false}, -- publication place (don't put into |place=; is treated specially in {{citation}} if both are given) doi = {id = "P356", maxvals = 1}, -- take care of |doi-broken-date= (WD "reason for deprecation"/"stated as") and |doi-access= (WD "access status")? issue = {id = "P433", maxvals = 0, populate_from_journal = true}, -- distinguish from |number= ("P1545"?) if both are given (still blocked by {{citation}}, but will be supported in the future) pmid = {id = "P698", maxvals = 1}, -- gbooks = {id = "P675", maxvals = 1}, -- to be added to {{citation}} -- ia = {id = "P724", maxvals = 1}, -- to be added to {{citation}} arxiv = {id = "P818", maxvals = 1}, bibcode = {id = "P819", maxvals = 1}, -- take care of |bibcode-access=? jstor = {id = "P888", maxvals = 1}, -- take care of |jstor-access=? mr = {id = "P889", maxvals = 1}, rfc = {id = "P892", maxvals = 1}, zbl = {id = "P894", maxvals = 1}, ssrn = {id = "P893", maxvals = 1}, place = {id = "P1071", maxvals = 0, linked = false}, -- written-at place -- ['total-pages'] = {id = "P1104", maxvals = 0, linked = 'no'}, -- to be added to {{citation}} / COinS &rft.tpages= -- coden = {id = "P1159", maxvals = 1}, -- to be added to {{citation}} / COinS &rft.coden= s2cid = {id = "P8299", maxvals = 1}, -- take care of |s2cid-access=? pmc = {id = "P932", maxvals = 1}, -- take care of |pmc-embargo-date= (WD "reason for deprecation")? lccn = {id = "P1144", maxvals = 1}, hdl = {id = "P1184", maxvals = 1}, -- take care of |hdl-access=? ismn = {id = "P1208", maxvals = 1}, journal = {id = "P1433", maxvals = 1}, citeseerx = {id = "P3784", maxvals = 1}, osti = {id = "P3894", maxvals = 1}, -- take care of |osti-access=? biorxiv = {id = "P3951", maxvals = 1}, asin = {id = "P5749", maxvals = 1}, -- What about |asin-tld=? (WD examples resolve to .com at present, but may change) -- ['catalog-number'] = {id = "P528", maxvals = 0}, -- to be added to {{citation}} / COinS &rft.artnum= isbn = {id = "P212", maxvals = 1, populate_from_journal = true}, -- ISBN 13 issn = {id = "P236", maxvals = 1, populate_from_journal = true}, -- distinguish from |eissn= for electronic issues? -- jfm = {id = "P?", maxvals = 1}, -- Jahrbuch über die Fortschritte der Mathematik (not Zbl) -- sbn = {id = "P?", maxvals = 1}, -- Standard Book Number (predecessor of ISBN, not ICCU) -- message-id = {id = "P?", maxvals = 1}, -- Usenet message ID chapter = {id = "P792", maxvals = 1, no_vol_qual=true}, ['publication-date'] = {id = "P577", maxvals = 1, populate_from_journal = true}, -- publication date (don't use |date=; is treated specially in {{citation}} if both are given.) series = {id = "P179", maxvals = 1, populate_from_journal = true, qual = "P1545"}, version = {id = "P348", maxvals = 0}, edition = {id = "P393", maxvals = 0}, volume = {id = "P478", maxvals = 0, populate_from_journal = true, no_vol_qual=true}, -- part = {id = "P1545"?, maxvals = 0}, -- to be added to {{citation}} / COinS &rft.part= title = {id = "P1476", rank="p n"}, -- url = {id = "P953", maxvals = 1}, -- deal with this along with archive-url pages = {id = "P304", maxvals = 0, populate_from_journal = true, no_vol_qual=true}, at = {id = "P958", maxvals = 0, populate_from_journal = true, no_vol_qual=true}, -- also incorporate lines (P7421) and columns (P3903) into this (cite map also supports |section=) -- sheets = {id = "P7416", maxvals = 0, populate_from_journal = true}, -- interviewer = {id = "P?", maxvals = 0}, -- does **not** go to "others" section! Multiple interviewers should be n-enumerated illustrator = {id = "P110", maxvals = 10, others = true}, -- goes to "others" section -- foreword and afterword, when contributions to another author's work, are contributions so belong in |contribution=; -- the writer's name goes in |contributor=; requires |title= and |author= -- However, this might need to add support for multiple contributors and their roles to {{citation}}, see Help_talk:Citation_Style_1#Others -- foreword = {id = "P2679", maxvals = 10, others = true}, -- goes to "others" section -- afterword = {id = "P2680", maxvals = 10, others = true}, -- goes to "others" section composer = {id = "P86", maxvals = 10, others = true}, -- goes to "others" section animator = {id = "P6942", maxvals = 10, others = true}, -- goes to "others" section director = {id = "P57", maxvals = 10, others = true}, -- goes to "others" section screenwriter = {id = "P58", maxvals = 10, others = true}, -- goes to "others" section signatory = {id = "P1891", maxvals = 10, others = true}, -- goes to "others" section presenter = {id = "P371", maxvals = 10, others = true}, -- goes to "others" section performer = {id = "P175", maxvals = 10, others = true}, -- goes to "others" section -- next 2 lines added for Arabic Wikipedia annotator = {id ="P11105", maxvals = 10, others = true}, -- goes to "others" section reviewer = {id ="P4032", maxvals = 10, others = true}, -- goes to "others" section supervisor = {id ="P7604", maxvals = 3, others = true}, -- goes to "others" section } local used_args_t = {accessdate=true, language=true, mode=true, ol=true, other=true, ['display-authors']=true, ['display-editors']=true, ['archive-url']=true, ['archive-date']=true, url=true, title=true, page=true, pages = true, volume=true} -- all_used_properties local used_properties_t = { P1071 = {arg= "place", maxvals = 0, linked = false}, -- written-at place P110 = {arg= "illustrator", maxvals = 10, others = true}, -- goes to "others" section P11105 = {arg= "annotator", maxvals = 10, others = true}, -- goes to "others" section P1144 = {arg= "lccn", maxvals = 1}, P1184 = {arg= "hdl", maxvals = 1}, -- take care of |hdl-access=? P1208 = {arg= "ismn", maxvals = 1}, P123 = {arg= "publisher", maxvals = 3}, P1433 = {arg= "journal", maxvals = 1}, P1476 = {arg= "title", rank="p n"}, P1680 = true, P175 = {arg= "performer", maxvals = 10, others = true}, -- goes to "others" section P179 = {arg= "series", maxvals = 1, populate_from_journal = true}, P1891 = {arg= "signatory", maxvals = 10, others = true}, -- goes to "others" section P1932 = true, P2093 = true, -- author string P212 = {arg= "isbn", maxvals = 1, populate_from_journal = true}, -- ISBN 13 P236 = {arg= "issn", maxvals = 1, populate_from_journal = true}, -- distinguish from |eissn= for electronic issues? P243 = {arg= "oclc", maxvals = 1}, P2699 = true, P291 = {arg= "publication-place", maxvals = 0, linked = false}, -- publication place (don't put into |place=; is treated specially in {{citation}} if both are given) P304 = {arg= "pages", maxvals = 0, populate_from_journal = true}, P348 = {arg= "version", maxvals = 0}, P356 = {arg= "doi", maxvals = 1}, -- take care of |doi-broken-date= (WD "reason for deprecation"/"stated as") and |doi-access= (WD "access status")? P371 = {arg= "presenter", maxvals = 10, others = true}, -- goes to "others" section P3784 = {arg= "citeseerx", maxvals = 1}, P3894 = {arg= "osti", maxvals = 1}, -- take care of |osti-access=? P393 = {arg= "edition", maxvals = 0}, P3951 = {arg= "biorxiv", maxvals = 1}, P4032 = {arg= "reviewer", maxvals = 10, others = true}, -- goes to "others" section P407 = true, P433 = {arg= "issue", maxvals = 0, populate_from_journal = true}, -- distinguish from |number= ("P1545"?) if both are given (still blocked by {{citation}}, but will be supported in the future) P478 = {arg= "volume", maxvals = 0, populate_from_journal = true}, P50 = true, -- author P57 = {arg= "director", maxvals = 10, others = true}, -- goes to "others" section P5749 = {arg= "asin", maxvals = 1}, -- What about |asin-tld=? (WD examples resolve to .com at present, but may change) P5769 = true, --editor P577 = {arg= "publication-date", maxvals = 1, populate_from_journal = true}, -- publication date (don't use |date=; is treated specially in {{citation}} if both are given.) P58 = {arg= "screenwriter", maxvals = 10, others = true}, -- goes to "others" section P655 = true, P6942 = {arg= "animator", maxvals = 10, others = true}, -- goes to "others" section P698 = {arg= "pmid", maxvals = 1}, P7604 = {arg ="supervisor", maxvals = 3, others = true}, -- goes to "others" section P792 = {arg= "chapter", maxvals = 1}, P818 = {arg= "arxiv", maxvals = 1}, P819 = {arg= "bibcode", maxvals = 1}, -- take care of |bibcode-access=? P8299 = {arg= "s2cid", maxvals = 1}, -- take care of |s2cid-access=? P856 = true, P86 = {arg= "composer", maxvals = 10, others = true}, -- goes to "others" section P888 = {arg= "jstor", maxvals = 1}, -- take care of |jstor-access=? P889 = {arg= "mr", maxvals = 1}, P892 = {arg= "rfc", maxvals = 1}, P893 = {arg= "ssrn", maxvals = 1}, P894 = {arg= "zbl", maxvals = 1}, P932 = {arg= "pmc", maxvals = 1}, -- take care of |pmc-embargo-date= (WD "reason for deprecation")? P953 = true, P958 = {arg= "at", maxvals = 0, populate_from_journal = true}, -- also incorporate lines (P7421) and columns (P3903) into this (cite map also supports |section=) P98 = true, P854 = true, } return { aliases_t = aliases_t, i18n_t = i18n_t, rejected_t = rejected_t, simple_properties_t = simple_properties_t, used_args_t = used_args_t, used_properties_t = used_properties_t, config_t = config_t } l8ms9bejwokc2aihkf23kn2dzt6b3gc أَذَاخَ 0 238496 1096915 1095245 2026-07-20T15:11:44Z ForzaGreen 28665 نقل ForzaGreen صفحة [[أَذْيَخَ]] إلى [[أَذَاخَ]]: تصحيح صيغة أفعل من الأجوف اليائي 1095245 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535795}} === المعاني === '''أَذْيَخَ''' {{أفعل}} {{معجمية|L1535795|معاني}} === النطق === * {{أصد-عر|أَذْيَخَ}} {{-}} === التصريفات === {{تصريف|جذر=ذيخ|وزن=أفعل}} === المراجع === {{مراجع}} 2cs9u3ujw20oaxpokb17587jisg96pi 1096917 1096915 2026-07-20T15:11:54Z ForzaGreen 28665 تصحيح صيغة أفعل من الأجوف اليائي 1096917 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535795}} === المعاني === '''أَذَاخَ''' {{أفعل}} {{معجمية|L1535795|معاني}} === النطق === * {{أصد-عر|أَذَاخَ}} {{-}} === التصريفات === {{تصريف|جذر=ذيخ|وزن=أفعل}} === المراجع === {{مراجع}} r907xmw9nn7wq6xr8hvs96mxqcgoucj أَرَارَ 0 238563 1096918 1095320 2026-07-20T15:12:04Z ForzaGreen 28665 نقل ForzaGreen صفحة [[أَرْيَرَ]] إلى [[أَرَارَ]]: تصحيح صيغة أفعل من الأجوف اليائي 1095320 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536365}} === المعاني === '''أَرْيَرَ''' {{أفعل}} {{معجمية|L1536365|معاني}} === النطق === * {{أصد-عر|أَرْيَرَ}} {{-}} === التصريفات === {{تصريف|جذر=رير|وزن=أفعل}} === المراجع === {{مراجع}} k1ds63kc5gcwuavyxvhni1taa0vn98v 1096921 1096918 2026-07-20T15:12:14Z ForzaGreen 28665 تصحيح صيغة أفعل من الأجوف اليائي 1096921 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536365}} === المعاني === '''أَرَارَ''' {{أفعل}} {{معجمية|L1536365|معاني}} === النطق === * {{أصد-عر|أَرَارَ}} {{-}} === التصريفات === {{تصريف|جذر=رير|وزن=أفعل}} === المراجع === {{مراجع}} alfionnu142iqnhprqxz31yw62ujj9t أَدَانَ 0 238664 1096922 1095428 2026-07-20T15:12:24Z ForzaGreen 28665 نقل ForzaGreen صفحة [[أَدْيَنَ]] إلى [[أَدَانَ]]: تصحيح صيغة أفعل من الأجوف اليائي 1095428 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1477261}} === المعاني === '''أَدْيَنَ''' {{أفعل}} {{معجمية|L1477261|معاني}} === النطق === * {{أصد-عر|أَدْيَنَ}} {{-}} === التصريفات === {{تصريف|جذر=دين|وزن=أفعل}} === المراجع === {{مراجع}} pudojbo28qssrepwaiyywsyz555k48w 1096924 1096922 2026-07-20T15:12:34Z ForzaGreen 28665 تصحيح صيغة أفعل من الأجوف اليائي 1096924 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1477261}} === المعاني === '''أَدَانَ''' {{أفعل}} {{معجمية|L1477261|معاني}} === النطق === * {{أصد-عر|أَدَانَ}} {{-}} === التصريفات === {{تصريف|جذر=دين|وزن=أفعل}} === المراجع === {{مراجع}} 3l9ej1fmldl2mgbspha6hsxdagf6vvp أَذَالَ 0 239259 1096925 1096075 2026-07-20T15:12:44Z ForzaGreen 28665 نقل ForzaGreen صفحة [[أَذْيَلَ]] إلى [[أَذَالَ]]: تصحيح صيغة أفعل من الأجوف اليائي 1096075 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1487116}} === المعاني === '''أَذْيَلَ''' {{أفعل}} {{معجمية|L1487116|معاني}} === النطق === * {{أصد-عر|أَذْيَلَ}} {{-}} === التصريفات === {{تصريف|جذر=ذيل|وزن=أفعل}} === المراجع === {{مراجع}} elb7391zrljak2jge877g2vz9xr5ud2 1096928 1096925 2026-07-20T15:12:54Z ForzaGreen 28665 تصحيح صيغة أفعل من الأجوف اليائي 1096928 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1487116}} === المعاني === '''أَذَالَ''' {{أفعل}} {{معجمية|L1487116|معاني}} === النطق === * {{أصد-عر|أَذَالَ}} {{-}} === التصريفات === {{تصريف|جذر=ذيل|وزن=أفعل}} === المراجع === {{مراجع}} 50zyeg5c381qv0ld0lwu4by5wlunssj أَتَاكَ 0 239893 1096929 1096745 2026-07-20T15:13:04Z ForzaGreen 28665 نقل ForzaGreen صفحة [[أَتْيَكَ]] إلى [[أَتَاكَ]]: تصحيح صيغة أفعل من الأجوف اليائي 1096745 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533512}} === المعاني === '''أَتْيَكَ''' {{أفعل}} {{معجمية|L1533512|معاني}} === النطق === * {{أصد-عر|أَتْيَكَ}} {{-}} === التصريفات === {{تصريف|جذر=تيك|وزن=أفعل}} === المراجع === {{مراجع}} 2q0owdxsz3g8h6xj1ffagzw0t8k6gm9 1096932 1096929 2026-07-20T15:13:14Z ForzaGreen 28665 تصحيح صيغة أفعل من الأجوف اليائي 1096932 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533512}} === المعاني === '''أَتَاكَ''' {{أفعل}} {{معجمية|L1533512|معاني}} === النطق === * {{أصد-عر|أَتَاكَ}} {{-}} === التصريفات === {{تصريف|جذر=تيك|وزن=أفعل}} === المراجع === {{مراجع}} ozc0tg60g41qhryq2wv764b6pgcoj4c أَتَامَ 0 239894 1096933 1096746 2026-07-20T15:13:24Z ForzaGreen 28665 نقل ForzaGreen صفحة [[أَتْيَمَ]] إلى [[أَتَامَ]]: تصحيح صيغة أفعل من الأجوف اليائي 1096746 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533513}} === المعاني === '''أَتْيَمَ''' {{أفعل}} {{معجمية|L1533513|معاني}} === النطق === * {{أصد-عر|أَتْيَمَ}} {{-}} === التصريفات === {{تصريف|جذر=تيم|وزن=أفعل}} === المراجع === {{مراجع}} edyxp354955f2qp5dao1m9j5gqjzxay 1096935 1096933 2026-07-20T15:13:34Z ForzaGreen 28665 تصحيح صيغة أفعل من الأجوف اليائي 1096935 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533513}} === المعاني === '''أَتَامَ''' {{أفعل}} {{معجمية|L1533513|معاني}} === النطق === * {{أصد-عر|أَتَامَ}} {{-}} === التصريفات === {{تصريف|جذر=تيم|وزن=أفعل}} === المراجع === {{مراجع}} s3njec4yl5rftgnnvxelt4evx8lubva اِسْتَذَابَ 0 240003 1096878 2026-07-20T14:14:14Z إسلام 12622 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096878 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535781}} === المعاني === '''اِسْتَذَابَ''' {{استفعل}} {{معجمية|L1535781|معاني}} === النطق === * {{أصد-عر|اِسْتَذَابَ}} {{-}} === التصريفات === {{تصريف|جذر=ذوب|وزن=استفعل}} === المراجع === {{مراجع}} s5blbspgs4ykku1o8zmr508imxq6tcl ذَوَّبَ 0 240004 1096879 2026-07-20T14:15:33Z إسلام 12622 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096879 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1495188}} === المعاني === '''ذَوَّبَ''' {{فعّل}} {{معجمية|L1495188|معاني}} === النطق === * {{أصد-عر|ذَوَّبَ}} {{-}} === التصريفات === {{تصريف|جذر=ذوب|وزن=فعّل}} === المراجع === {{مراجع}} f30y7agl00xjxxwi1kswkxdjf9h6byv أَذَادَ 0 240005 1096880 2026-07-20T14:17:41Z إسلام 12622 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096880 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535783}} === المعاني === '''أَذَادَ''' {{أفعل}} {{معجمية|L1535783|معاني}} === النطق === * {{أصد-عر|أَذَادَ}} {{-}} === التصريفات === {{تصريف|جذر=ذود|وزن=أفعل}} === المراجع === {{مراجع}} 3l4oqbwmgxouenysxmacfkouyhja8ea اِسْتَذْهَنَ 0 240006 1096881 2026-07-20T14:19:15Z إسلام 12622 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096881 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1480822}} === المعاني === '''اِسْتَذْهَنَ''' {{استفعل}} {{معجمية|L1480822|معاني}} === النطق === * {{أصد-عر|اِسْتَذْهَنَ}} {{-}} === التصريفات === {{تصريف|جذر=ذهن|وزن=استفعل}} === المراجع === {{مراجع}} olqqabdi7hppk1ld8rrs0vav1bxp4tn ذَهِرَ 0 240007 1096882 2026-07-20T14:20:51Z إسلام 12622 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096882 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1543758}} === المعاني === '''ذَهِرَ''' {{سمع}} {{معجمية|L1543758|معاني}} === النطق === * {{أصد-عر|ذَهِرَ}} {{-}} === التصريفات === {{تصريف|جذر=ذهر|وزن=فعِل يفعَل}} === المراجع === {{مراجع}} imlv6sowu7b6ammi3jhrhyap29736b0 تَذَانَبَ 0 240008 1096883 2026-07-20T14:21:45Z إسلام 12622 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096883 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535775}} === المعاني === '''تَذَانَبَ''' {{تفاعل}} {{معجمية|L1535775|معاني}} === النطق === * {{أصد-عر|تَذَانَبَ}} {{-}} === التصريفات === {{تصريف|جذر=ذنب|وزن=تفاعل}} === المراجع === {{مراجع}} 6nw071lme30h7wh04be80ogjfpwi1k2 اِسْتَذْمَى 0 240009 1096884 2026-07-20T14:24:07Z إسلام 12622 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096884 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1487603}} === المعاني === '''اِسْتَذْمَى''' {{استفعل}} {{معجمية|L1487603|معاني}} === النطق === * {{أصد-عر|اِسْتَذْمَى}} {{-}} === التصريفات === {{تصريف|جذر=ذمي|وزن=استفعل}} === المراجع === {{مراجع}} i8rdk0lye0zgngd2gtk8nskrzkv4sti أَذْمَى 0 240010 1096885 2026-07-20T14:29:59Z إسلام 12622 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096885 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535774}} === المعاني === '''أَذْمَى''' {{أفعل}} {{معجمية|L1535774|معاني}} === النطق === * {{أصد-عر|أَذْمَى}} {{-}} === التصريفات === {{تصريف|جذر=ذمي|وزن=أفعل}} === المراجع === {{مراجع}} 76yhi6zyo9zfj1h6owv3srl8nhme2pa تَذَلَّلَ 0 240011 1096886 2026-07-20T14:30:56Z إسلام 12622 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096886 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535760}} === المعاني === '''تَذَلَّلَ''' {{تفعّل}} {{معجمية|L1535760|معاني}} === النطق === * {{أصد-عر|تَذَلَّلَ}} {{-}} === التصريفات === {{تصريف|جذر=ذلل|وزن=تفعّل}} === المراجع === {{مراجع}} pu6raaqj41zi8m0gph6lrbeqcz9jtr8 اِسْتَذَمَّ 0 240012 1096887 2026-07-20T14:37:12Z إسلام 12622 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096887 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1483705}} === المعاني === '''اِسْتَذَمَّ''' {{استفعل}} {{معجمية|L1483705|معاني}} === النطق === * {{أصد-عر|اِسْتَذَمَّ}} {{-}} === التصريفات === {{تصريف|جذر=ذمم|وزن=استفعل}} === المراجع === {{مراجع}} 1no2brjuxu4cpfqpz3n0haslctp475b تَذَمَّرَ 0 240013 1096888 2026-07-20T14:39:25Z إسلام 12622 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096888 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1486291}} === المعاني === '''تَذَمَّرَ''' {{تفعّل}} {{معجمية|L1486291|معاني}} === النطق === * {{أصد-عر|تَذَمَّرَ}} {{-}} === التصريفات === {{تصريف|جذر=ذمر|وزن=تفعّل}} === المراجع === {{مراجع}} 134ln9ag00nbyspt4w2s2yjxfgtlo98 اِسْتَذْكَرَ 0 240014 1096889 2026-07-20T14:43:53Z إسلام 12622 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096889 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1485395}} === المعاني === '''اِسْتَذْكَرَ''' {{استفعل}} {{معجمية|L1485395|معاني}} === النطق === * {{أصد-عر|اِسْتَذْكَرَ}} {{-}} === التصريفات === {{تصريف|جذر=ذكر|وزن=استفعل}} === المراجع === {{مراجع}} to80gifakey1ze7jwtj2xc5h67s35lh اِسْتَذْكَى 0 240015 1096890 2026-07-20T14:46:46Z إسلام 12622 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096890 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535751}} === المعاني === '''اِسْتَذْكَى''' {{استفعل}} {{معجمية|L1535751|معاني}} === النطق === * {{أصد-عر|اِسْتَذْكَى}} {{-}} === التصريفات === {{تصريف|جذر=ذكو|وزن=استفعل}} === المراجع === {{مراجع}} mckds2hpfrypr9g5ku1vzhwnl0lpig6 ذَمَطَ 0 240016 1096891 2026-07-20T14:47:49Z إسلام 12622 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096891 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1544817}} === المعاني === '''ذَمَطَ''' {{ضرب}} {{معجمية|L1544817|معاني}} === النطق === * {{أصد-عر|ذَمَطَ}} {{-}} === التصريفات === {{تصريف|جذر=ذمط|وزن=فعَل يفعِل}} === المراجع === {{مراجع}} j3bo1cfslhnyp3k189jj5fvkwwsvq6h ذَلَى 0 240017 1096892 2026-07-20T14:49:16Z إسلام 12622 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096892 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1497908}} === المعاني === '''ذَلَى''' {{فتح}} {{معجمية|L1497908|معاني}} === النطق === * {{أصد-عر|ذَلَى}} {{-}} === التصريفات === {{تصريف|جذر=ذلي|وزن=فعَل يفعَل}} === المراجع === {{مراجع}} f09dj6wg45r88i26u6skw1s0cgroym1 تَذَلَّى 0 240018 1096893 2026-07-20T14:50:28Z إسلام 12622 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096893 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535763}} === المعاني === '''تَذَلَّى''' {{تفعّل}} {{معجمية|L1535763|معاني}} === النطق === * {{أصد-عر|تَذَلَّى}} {{-}} === التصريفات === {{تصريف|جذر=ذلي|وزن=تفعّل}} === المراجع === {{مراجع}} rmfmqu7u7k14w1fhuwi4597ygsozev7 اِنْذَلَى 0 240019 1096894 2026-07-20T14:51:20Z إسلام 12622 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096894 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535762}} === المعاني === '''اِنْذَلَى''' {{انفعل}} {{معجمية|L1535762|معاني}} === النطق === * {{أصد-عر|اِنْذَلَى}} {{-}} === التصريفات === {{تصريف|جذر=ذلي|وزن=انفعل}} === المراجع === {{مراجع}} 40y293yxppm3j5fgkg1yuw830qj40s7 تَخَنْذَذَ 0 240020 1096895 2026-07-20T14:55:03Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096895 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535171}} === المعاني === '''تَخَنْذَذَ''' {{تفعلل}} {{معجمية|L1535171|معاني}} === النطق === * {{أصد-عر|تَخَنْذَذَ}} {{-}} === التصريفات === {{تصريف|جذر=خنذذ|وزن=تفعلل}} === المراجع === {{مراجع}} fyqo94k0o3wmh4kll8nbk3fu8cfk12b جَأْلَلَ 0 240021 1096896 2026-07-20T14:55:42Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096896 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533698}} === المعاني === '''جَأْلَلَ''' {{فعلل}} {{معجمية|L1533698|معاني}} === النطق === * {{أصد-عر|جَأْلَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جألل|وزن=فعلل}} === المراجع === {{مراجع}} 1qpurpe9vlzv2gi6s1olab2ceha92en تَبَاهَشَ 0 240022 1096897 2026-07-20T14:56:27Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096897 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533286}} === المعاني === '''تَبَاهَشَ''' {{تفاعل}} {{معجمية|L1533286|معاني}} === النطق === * {{أصد-عر|تَبَاهَشَ}} {{-}} === التصريفات === {{تصريف|جذر=بهش|وزن=تفاعل}} === المراجع === {{مراجع}} fukj9susk0odlfkwk72n7wgu60g3de5 اِزْيَأَنَّ 0 240023 1096898 2026-07-20T14:56:54Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096898 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536710}} === المعاني === '''اِزْيَأَنَّ''' {{افعللّ}} {{معجمية|L1536710|معاني}} === النطق === * {{أصد-عر|اِزْيَأَنَّ}} {{-}} === التصريفات === {{تصريف|جذر=زيأن|وزن=افعللّ}} === المراجع === {{مراجع}} 8jh2drfij1ndgofeti0rbucnxwxyrgn تَخَرَّبَ 0 240024 1096899 2026-07-20T14:57:32Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096899 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534894}} === المعاني === '''تَخَرَّبَ''' {{تفعّل}} {{معجمية|L1534894|معاني}} === النطق === * {{أصد-عر|تَخَرَّبَ}} {{-}} === التصريفات === {{تصريف|جذر=خرب|وزن=تفعّل}} === المراجع === {{مراجع}} 129co1xokfnfpy2lpa2p27nxsj0ybn7 بَلَتَ 0 240025 1096900 2026-07-20T14:58:48Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096900 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1502498}} === المعاني === '''بَلَتَ''' {{نصر}} {{معجمية|L1502498|معاني}} === النطق === * {{أصد-عر|بَلَتَ}} {{-}} === التصريفات === {{تصريف|جذر=بلت|وزن=فعَل يفعُل}} === المراجع === {{مراجع}} 6sh07fvkwr5rvy1d05ydnvsb59awrzg زَرِكَ 0 240026 1096901 2026-07-20T14:59:20Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096901 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1544461}} === المعاني === '''زَرِكَ''' {{سمع}} {{معجمية|L1544461|معاني}} === النطق === * {{أصد-عر|زَرِكَ}} {{-}} === التصريفات === {{تصريف|جذر=زرك|وزن=فعِل يفعَل}} === المراجع === {{مراجع}} ky2adrsx77u0wr6qi0i44n80d3s9g6v اِجْأَوَّى 0 240027 1096902 2026-07-20T14:59:37Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096902 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533700}} === المعاني === '''اِجْأَوَّى''' {{افعوّل}} {{معجمية|L1533700|معاني}} === النطق === * {{أصد-عر|اِجْأَوَّى}} {{-}} === التصريفات === {{تصريف|جذر=جأي|وزن=افعوّل}} === المراجع === {{مراجع}} lojnksnmqu58mluvvbka0tvnajc2tnn اِسْتَحْنَذَ 0 240028 1096903 2026-07-20T15:01:00Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096903 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534665}} === المعاني === '''اِسْتَحْنَذَ''' {{استفعل}} {{معجمية|L1534665|معاني}} === النطق === * {{أصد-عر|اِسْتَحْنَذَ}} {{-}} === التصريفات === {{تصريف|جذر=حنذ|وزن=استفعل}} === المراجع === {{مراجع}} 1malzf8y7u4oxvu9zpzcf5tuxnvaqkz جَئِيَ 0 240029 1096904 2026-07-20T15:02:16Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096904 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1544597}} === المعاني === '''جَئِيَ''' {{سمع}} {{معجمية|L1544597|معاني}} === النطق === * {{أصد-عر|جَئِيَ}} {{-}} === التصريفات === {{تصريف|جذر=جأي|وزن=فعِل يفعَل}} === المراجع === {{مراجع}} 6g7yqkvpc0rrh5rt1uhzhfcjfpf647i تَحَبَّسَ 0 240030 1096905 2026-07-20T15:02:21Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096905 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534176}} === المعاني === '''تَحَبَّسَ''' {{تفعّل}} {{معجمية|L1534176|معاني}} === النطق === * {{أصد-عر|تَحَبَّسَ}} {{-}} === التصريفات === {{تصريف|جذر=حبس|وزن=تفعّل}} === المراجع === {{مراجع}} 9b2bth0wikye9t0mvr8c9hgkvgfadaj زَكَّمَ 0 240031 1096906 2026-07-20T15:03:10Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096906 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536563}} === المعاني === '''زَكَّمَ''' {{فعّل}} {{معجمية|L1536563|معاني}} === النطق === * {{أصد-عر|زَكَّمَ}} {{-}} === التصريفات === {{تصريف|جذر=زكم|وزن=فعّل}} === المراجع === {{مراجع}} 1vxkl0pseehf7aq1qku25mksgxguvsz تَجَدَّفَ 0 240032 1096907 2026-07-20T15:03:19Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096907 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533790}} === المعاني === '''تَجَدَّفَ''' {{تفعّل}} {{معجمية|L1533790|معاني}} === النطق === * {{أصد-عر|تَجَدَّفَ}} {{-}} === التصريفات === {{تصريف|جذر=جدف|وزن=تفعّل}} === المراجع === {{مراجع}} m5971hk0o4xs96ivdmkx578av7yanb0 أَبْشَغَ 0 240033 1096908 2026-07-20T15:03:39Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096908 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533036}} === المعاني === '''أَبْشَغَ''' {{أفعل}} {{معجمية|L1533036|معاني}} === النطق === * {{أصد-عر|أَبْشَغَ}} {{-}} === التصريفات === {{تصريف|جذر=بشغ|وزن=أفعل}} === المراجع === {{مراجع}} s41x902x1w7mklg95g1gj5v1gfpp6tj اِسْتَحَاطَ 0 240034 1096909 2026-07-20T15:04:24Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096909 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534733}} === المعاني === '''اِسْتَحَاطَ''' {{استفعل}} {{معجمية|L1534733|معاني}} === النطق === * {{أصد-عر|اِسْتَحَاطَ}} {{-}} === التصريفات === {{تصريف|جذر=حوط|وزن=استفعل}} === المراجع === {{مراجع}} anuq4ify537ydqoktch21va550q2j5d اِرْمَأَزَّ 0 240035 1096910 2026-07-20T15:07:20Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096910 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536234}} === المعاني === '''اِرْمَأَزَّ''' {{افعللّ}} {{معجمية|L1536234|معاني}} === النطق === * {{أصد-عر|اِرْمَأَزَّ}} {{-}} === التصريفات === {{تصريف|جذر=رمأز|وزن=افعللّ}} === المراجع === {{مراجع}} p6u3wqooinsxydwqvi4zv60nb3ddwn0 اِنْجَدَلَ 0 240036 1096911 2026-07-20T15:08:27Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096911 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533793}} === المعاني === '''اِنْجَدَلَ''' {{انفعل}} {{معجمية|L1533793|معاني}} === النطق === * {{أصد-عر|اِنْجَدَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جدل|وزن=انفعل}} === المراجع === {{مراجع}} 5g1mkrdp4u68k61gpiz2n4eucw6tcx2 تَجَادَلَ 0 240037 1096912 2026-07-20T15:09:32Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096912 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1484978}} === المعاني === '''تَجَادَلَ''' {{تفاعل}} {{معجمية|L1484978|معاني}} === النطق === * {{أصد-عر|تَجَادَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جدل|وزن=تفاعل}} === المراجع === {{مراجع}} 2kxmua2yawicx3tl9xg29o9t10cysk0 رَادَفَ 0 240038 1096913 2026-07-20T15:09:35Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096913 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1482000}} === المعاني === '''رَادَفَ''' {{فاعل}} {{معجمية|L1482000|معاني}} === النطق === * {{أصد-عر|رَادَفَ}} {{-}} === التصريفات === {{تصريف|جذر=ردف|وزن=فاعل}} === المراجع === {{مراجع}} 76vgx8jc7g2xf54vnbotnal5bmoe2p3 تَجَدَّلَ 0 240039 1096914 2026-07-20T15:11:28Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096914 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533794}} === المعاني === '''تَجَدَّلَ''' {{تفعّل}} {{معجمية|L1533794|معاني}} === النطق === * {{أصد-عر|تَجَدَّلَ}} {{-}} === التصريفات === {{تصريف|جذر=جدل|وزن=تفعّل}} === المراجع === {{مراجع}} 39iwggwpinh6arsxx0os4s7fnenchur أَذْيَخَ 0 240040 1096916 2026-07-20T15:11:45Z ForzaGreen 28665 نقل ForzaGreen صفحة [[أَذْيَخَ]] إلى [[أَذَاخَ]]: تصحيح صيغة أفعل من الأجوف اليائي 1096916 wikitext text/x-wiki #تحويل [[أَذَاخَ]] 5j4bh4d9cdq8nhxjlkwklpn99q732ce أَرْيَرَ 0 240041 1096919 2026-07-20T15:12:05Z ForzaGreen 28665 نقل ForzaGreen صفحة [[أَرْيَرَ]] إلى [[أَرَارَ]]: تصحيح صيغة أفعل من الأجوف اليائي 1096919 wikitext text/x-wiki #تحويل [[أَرَارَ]] 4ytpq6t3bt8seiocnq4zc0fwigq1xsu اِسْتَحَقَّ 0 240042 1096920 2026-07-20T15:12:11Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096920 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1483848}} === المعاني === '''اِسْتَحَقَّ''' {{استفعل}} {{معجمية|L1483848|معاني}} === النطق === * {{أصد-عر|اِسْتَحَقَّ}} {{-}} === التصريفات === {{تصريف|جذر=حقق|وزن=استفعل}} === المراجع === {{مراجع}} 4nkwj82kdoi7x975g97k56g8c3qpjku أَدْيَنَ 0 240043 1096923 2026-07-20T15:12:28Z ForzaGreen 28665 نقل ForzaGreen صفحة [[أَدْيَنَ]] إلى [[أَدَانَ]]: تصحيح صيغة أفعل من الأجوف اليائي 1096923 wikitext text/x-wiki #تحويل [[أَدَانَ]] hamrwlnvkrtv96gm6w33lbn5fte4t4o أَذْيَلَ 0 240044 1096926 2026-07-20T15:12:46Z ForzaGreen 28665 نقل ForzaGreen صفحة [[أَذْيَلَ]] إلى [[أَذَالَ]]: تصحيح صيغة أفعل من الأجوف اليائي 1096926 wikitext text/x-wiki #تحويل [[أَذَالَ]] ro5udnuq1k66l5kqilzko63t0qsyelo زَامَلَ 0 240045 1096927 2026-07-20T15:12:49Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096927 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1487502}} === المعاني === '''زَامَلَ''' {{فاعل}} {{معجمية|L1487502|معاني}} === النطق === * {{أصد-عر|زَامَلَ}} {{-}} === التصريفات === {{تصريف|جذر=زمل|وزن=فاعل}} === المراجع === {{مراجع}} 82tygxm1n1gn73myma08owdj4vrovf5 أَتْيَكَ 0 240046 1096930 2026-07-20T15:13:04Z ForzaGreen 28665 نقل ForzaGreen صفحة [[أَتْيَكَ]] إلى [[أَتَاكَ]]: تصحيح صيغة أفعل من الأجوف اليائي 1096930 wikitext text/x-wiki #تحويل [[أَتَاكَ]] d4bnd1xunigbqle7y32ac9of9ehl33m جَدَمَ 0 240047 1096931 2026-07-20T15:13:06Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096931 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1502515}} === المعاني === '''جَدَمَ''' {{نصر}} {{معجمية|L1502515|معاني}} === النطق === * {{أصد-عر|جَدَمَ}} {{-}} === التصريفات === {{تصريف|جذر=جدم|وزن=فعَل يفعُل}} === المراجع === {{مراجع}} 2qvdheoh2c8g3harep34btx1xv07qod أَتْيَمَ 0 240048 1096934 2026-07-20T15:13:24Z ForzaGreen 28665 نقل ForzaGreen صفحة [[أَتْيَمَ]] إلى [[أَتَامَ]]: تصحيح صيغة أفعل من الأجوف اليائي 1096934 wikitext text/x-wiki #تحويل [[أَتَامَ]] g3wzmivx12v27967wmi43ude2r3rmc8 بَيَّحَ 0 240049 1096936 2026-07-20T15:14:02Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096936 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533348}} === المعاني === '''بَيَّحَ''' {{فعّل}} {{معجمية|L1533348|معاني}} === النطق === * {{أصد-عر|بَيَّحَ}} {{-}} === التصريفات === {{تصريف|جذر=بيح|وزن=فعّل}} === المراجع === {{مراجع}} 7crza3zpcqcwaozkzewhvjql4aiug0q اِحْتَبَكَ 0 240050 1096937 2026-07-20T15:15:22Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096937 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534188}} === المعاني === '''اِحْتَبَكَ''' {{افتعل}} {{معجمية|L1534188|معاني}} === النطق === * {{أصد-عر|اِحْتَبَكَ}} {{-}} === التصريفات === {{تصريف|جذر=حبك|وزن=افتعل}} === المراجع === {{مراجع}} 0zv15rjcscsvg5ehje1vfqujxg55c9b زَغْلَلَ 0 240051 1096938 2026-07-20T15:16:01Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096938 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536529}} === المعاني === '''زَغْلَلَ''' {{فعلل}} {{معجمية|L1536529|معاني}} === النطق === * {{أصد-عر|زَغْلَلَ}} {{-}} === التصريفات === {{تصريف|جذر=زغلل|وزن=فعلل}} === المراجع === {{مراجع}} 7rqutxkdhrki1f2g8jkbwmpy7g6sxc8 تَجَيَّشَ 0 240052 1096939 2026-07-20T15:17:00Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096939 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534158}} === المعاني === '''تَجَيَّشَ''' {{تفعّل}} {{معجمية|L1534158|معاني}} === النطق === * {{أصد-عر|تَجَيَّشَ}} {{-}} === التصريفات === {{تصريف|جذر=جيش|وزن=تفعّل}} === المراجع === {{مراجع}} 7xuevk2utxfnk96kinztb1lc65jaqvk أَجْدَنَ 0 240053 1096940 2026-07-20T15:17:34Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096940 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533797}} === المعاني === '''أَجْدَنَ''' {{أفعل}} {{معجمية|L1533797|معاني}} === النطق === * {{أصد-عر|أَجْدَنَ}} {{-}} === التصريفات === {{تصريف|جذر=جدن|وزن=أفعل}} === المراجع === {{مراجع}} owtnilxwyf9dh37ds2rdilij5h7aeru تَرَمَّقَ 0 240054 1096941 2026-07-20T15:17:57Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096941 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536264}} === المعاني === '''تَرَمَّقَ''' {{تفعّل}} {{معجمية|L1536264|معاني}} === النطق === * {{أصد-عر|تَرَمَّقَ}} {{-}} === التصريفات === {{تصريف|جذر=رمق|وزن=تفعّل}} === المراجع === {{مراجع}} npp8ngghau741nk0xkjvexohfwmbj8r اِجْتَدَى 0 240055 1096942 2026-07-20T15:19:27Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096942 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533798}} === المعاني === '''اِجْتَدَى''' {{افتعل}} {{معجمية|L1533798|معاني}} === النطق === * {{أصد-عر|اِجْتَدَى}} {{-}} === التصريفات === {{تصريف|جذر=جدو|وزن=افتعل}} === المراجع === {{مراجع}} 4rb2uc0m1se1zn27hgl2g05ah1t7ibk تَجَاذَبَ 0 240056 1096943 2026-07-20T15:26:42Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096943 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1496850}} === المعاني === '''تَجَاذَبَ''' {{تفاعل}} {{معجمية|L1496850|معاني}} === النطق === * {{أصد-عر|تَجَاذَبَ}} {{-}} === التصريفات === {{تصريف|جذر=جذب|وزن=تفاعل}} === المراجع === {{مراجع}} 7m2v191ygtfsrnuef11fdt9yayb4nsg اِنْجَذَرَ 0 240057 1096944 2026-07-20T15:36:15Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096944 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1485127}} === المعاني === '''اِنْجَذَرَ''' {{انفعل}} {{معجمية|L1485127|معاني}} === النطق === * {{أصد-عر|اِنْجَذَرَ}} {{-}} === التصريفات === {{تصريف|جذر=جذر|وزن=انفعل}} === المراجع === {{مراجع}} 5p0d2yghw4tg7lhh3deiotyz1lacyfq اِنْجَذَفَ 0 240058 1096945 2026-07-20T16:01:42Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096945 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533810}} === المعاني === '''اِنْجَذَفَ''' {{انفعل}} {{معجمية|L1533810|معاني}} === النطق === * {{أصد-عر|اِنْجَذَفَ}} {{-}} === التصريفات === {{تصريف|جذر=جذف|وزن=انفعل}} === المراجع === {{مراجع}} pzebxnol25eyfbv51podwpr3q3c0mwc اِجْتَذَلَ 0 240059 1096946 2026-07-20T16:07:26Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096946 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533812}} === المعاني === '''اِجْتَذَلَ''' {{افتعل}} {{معجمية|L1533812|معاني}} === النطق === * {{أصد-عر|اِجْتَذَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جذل|وزن=افتعل}} === المراجع === {{مراجع}} qyntt8bqkeb8a7550w98gxx720u0t77 اِسْتَجْذَلَ 0 240060 1096947 2026-07-20T16:12:02Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096947 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533811}} === المعاني === '''اِسْتَجْذَلَ''' {{استفعل}} {{معجمية|L1533811|معاني}} === النطق === * {{أصد-عر|اِسْتَجْذَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جذل|وزن=استفعل}} === المراجع === {{مراجع}} i4a9ctzl9z7y80yml6s0sc0hyszxspb تَجَاذَلَ 0 240061 1096948 2026-07-20T16:19:47Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096948 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533813}} === المعاني === '''تَجَاذَلَ''' {{تفاعل}} {{معجمية|L1533813|معاني}} === النطق === * {{أصد-عر|تَجَاذَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جذل|وزن=تفاعل}} === المراجع === {{مراجع}} lodokc8nalqt4c37n42cu72wn7574ih جَاذَى 0 240062 1096949 2026-07-20T16:24:30Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096949 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533822}} === المعاني === '''جَاذَى''' {{فاعل}} {{معجمية|L1533822|معاني}} === النطق === * {{أصد-عر|جَاذَى}} {{-}} === التصريفات === {{تصريف|جذر=جذو|وزن=فاعل}} === المراجع === {{مراجع}} dzxhufotzdinkanz5r6z9swzsr5pzqs اِجْتَرَأَ 0 240063 1096950 2026-07-20T16:28:16Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096950 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1497853}} === المعاني === '''اِجْتَرَأَ''' {{افتعل}} {{معجمية|L1497853|معاني}} === النطق === * {{أصد-عر|اِجْتَرَأَ}} {{-}} === التصريفات === {{تصريف|جذر=جرأ|وزن=افتعل}} === المراجع === {{مراجع}} nbgw2ig6exfcxaao4ns391o6b091910 تَجَرَّأَ 0 240064 1096951 2026-07-20T16:34:48Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096951 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533827}} === المعاني === '''تَجَرَّأَ''' {{تفعّل}} {{معجمية|L1533827|معاني}} === النطق === * {{أصد-عر|تَجَرَّأَ}} {{-}} === التصريفات === {{تصريف|جذر=جرأ|وزن=تفعّل}} === المراجع === {{مراجع}} 7lfxcwgw4tmwa3wbo2t4gvgq3szqx1d جَرْثَلَ 0 240065 1096952 2026-07-20T16:37:52Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096952 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533836}} === المعاني === '''جَرْثَلَ''' {{فعلل}} {{معجمية|L1533836|معاني}} === النطق === * {{أصد-عر|جَرْثَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جرثل|وزن=فعلل}} === المراجع === {{مراجع}} mpmc8druoz3l009kk6thzphr3ng1lqs جَرْدَحَ 0 240066 1096953 2026-07-20T16:41:55Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096953 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533849}} === المعاني === '''جَرْدَحَ''' {{فعلل}} {{معجمية|L1533849|معاني}} === النطق === * {{أصد-عر|جَرْدَحَ}} {{-}} === التصريفات === {{تصريف|جذر=جردح|وزن=فعلل}} === المراجع === {{مراجع}} chcq9cnfm28a8kyejd5hmtt6p272uuy جَرْدَلَ 0 240067 1096954 2026-07-20T16:43:52Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096954 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533850}} === المعاني === '''جَرْدَلَ''' {{فعلل}} {{معجمية|L1533850|معاني}} === النطق === * {{أصد-عر|جَرْدَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جردل|وزن=فعلل}} === المراجع === {{مراجع}} 83aoalgc63iogkuzqumzvm014m25snj جَرْذَمَ 0 240068 1096955 2026-07-20T16:45:16Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096955 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533854}} === المعاني === '''جَرْذَمَ''' {{فعلل}} {{معجمية|L1533854|معاني}} === النطق === * {{أصد-عر|جَرْذَمَ}} {{-}} === التصريفات === {{تصريف|جذر=جرذم|وزن=فعلل}} === المراجع === {{مراجع}} b601bi64j5uuf4bs86e2vt34b2lrw20 اِنْجَرَسَ 0 240069 1096956 2026-07-20T16:51:14Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096956 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533861}} === المعاني === '''اِنْجَرَسَ''' {{انفعل}} {{معجمية|L1533861|معاني}} === النطق === * {{أصد-عر|اِنْجَرَسَ}} {{-}} === التصريفات === {{تصريف|جذر=جرس|وزن=انفعل}} === المراجع === {{مراجع}} p8qxdnbrl7ko7fjn01f62kzdrxackr7 اِجْتَرَسَ 0 240070 1096957 2026-07-20T16:53:45Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096957 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533860}} === المعاني === '''اِجْتَرَسَ''' {{افتعل}} {{معجمية|L1533860|معاني}} === النطق === * {{أصد-عر|اِجْتَرَسَ}} {{-}} === التصريفات === {{تصريف|جذر=جرس|وزن=افتعل}} === المراجع === {{مراجع}} 8xiyjkvnopify5grskqwe6b4rcd0vq5 جَرْسَمَ 0 240071 1096958 2026-07-20T16:55:18Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096958 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533864}} === المعاني === '''جَرْسَمَ''' {{فعلل}} {{معجمية|L1533864|معاني}} === النطق === * {{أصد-عر|جَرْسَمَ}} {{-}} === التصريفات === {{تصريف|جذر=جرسم|وزن=فعلل}} === المراجع === {{مراجع}} 4wxt67vl0k84wyknrt47jsgn837dd4b اِجْرَنْشَمَ 0 240072 1096959 2026-07-20T16:57:18Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096959 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533870}} === المعاني === '''اِجْرَنْشَمَ''' {{افعنلل}} {{معجمية|L1533870|معاني}} === النطق === * {{أصد-عر|اِجْرَنْشَمَ}} {{-}} === التصريفات === {{تصريف|جذر=جرشم|وزن=افعنلل}} === المراجع === {{مراجع}} myqyi58n2f326wmubr4ipeq48s8fzn6 اِجْرَوَّطَ 0 240073 1096960 2026-07-20T16:58:31Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096960 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533872}} === المعاني === '''اِجْرَوَّطَ''' {{افعوّل}} {{معجمية|L1533872|معاني}} === النطق === * {{أصد-عر|اِجْرَوَّطَ}} {{-}} === التصريفات === {{تصريف|جذر=جرط|وزن=افعوّل}} === المراجع === {{مراجع}} ipxzrhykk6e2nfrggdu2yb5ljnks23r جَرِطَ 0 240074 1096961 2026-07-20T17:00:31Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096961 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1544078}} === المعاني === '''جَرِطَ''' {{سمع}} {{معجمية|L1544078|معاني}} === النطق === * {{أصد-عر|جَرِطَ}} {{-}} === التصريفات === {{تصريف|جذر=جرط|وزن=فعِل يفعَل}} === المراجع === {{مراجع}} 6u7rofaq2qktra4azt7w80tc3ja4hdj اِجْرَعَبَّ 0 240075 1096962 2026-07-20T17:15:15Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096962 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533875}} === المعاني === '''اِجْرَعَبَّ''' {{افعللّ}} {{معجمية|L1533875|معاني}} === النطق === * {{أصد-عر|اِجْرَعَبَّ}} {{-}} === التصريفات === {{تصريف|جذر=جرعب|وزن=افعللّ}} === المراجع === {{مراجع}} oa0d9fuwbyq4q0ggwy51qsa1rkemf3c جَرْعَبَ 0 240076 1096963 2026-07-20T17:16:19Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096963 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533874}} === المعاني === '''جَرْعَبَ''' {{فعلل}} {{معجمية|L1533874|معاني}} === النطق === * {{أصد-عر|جَرْعَبَ}} {{-}} === التصريفات === {{تصريف|جذر=جرعب|وزن=فعلل}} === المراجع === {{مراجع}} 28xlcefl2wz0pq6w3xxhws6z9zrquy7 اِنْجَرَفَ 0 240077 1096964 2026-07-20T17:17:36Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096964 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1475907}} === المعاني === '''اِنْجَرَفَ''' {{انفعل}} {{معجمية|L1475907|معاني}} === النطق === * {{أصد-عر|اِنْجَرَفَ}} {{-}} === التصريفات === {{تصريف|جذر=جرف|وزن=انفعل}} === المراجع === {{مراجع}} 940p00veos36s17fz2ejqgp8ydnounx جَرْفَخَ 0 240078 1096965 2026-07-20T17:19:05Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096965 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533878}} === المعاني === '''جَرْفَخَ''' {{فعلل}} {{معجمية|L1533878|معاني}} === النطق === * {{أصد-عر|جَرْفَخَ}} {{-}} === التصريفات === {{تصريف|جذر=جرفخ|وزن=فعلل}} === المراجع === {{مراجع}} nlj3mzfgqatsyap5046n9ch18ffvjr9 أَجْرَلَ 0 240079 1096966 2026-07-20T17:20:22Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096966 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533880}} === المعاني === '''أَجْرَلَ''' {{أفعل}} {{معجمية|L1533880|معاني}} === النطق === * {{أصد-عر|أَجْرَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جرل|وزن=أفعل}} === المراجع === {{مراجع}} tnekuqkh87gxurzg8lg8es9hxxedxnq تَجَرَّهَ 0 240080 1096967 2026-07-20T17:23:20Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096967 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533887}} === المعاني === '''تَجَرَّهَ''' {{تفعّل}} {{معجمية|L1533887|معاني}} === النطق === * {{أصد-عر|تَجَرَّهَ}} {{-}} === التصريفات === {{تصريف|جذر=جره|وزن=تفعّل}} === المراجع === {{مراجع}} kyi02zy187qvlomfaluazfe19myxanj جَرَّهَ 0 240081 1096968 2026-07-20T17:24:35Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096968 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533888}} === المعاني === '''جَرَّهَ''' {{فعّل}} {{معجمية|L1533888|معاني}} === النطق === * {{أصد-عر|جَرَّهَ}} {{-}} === التصريفات === {{تصريف|جذر=جره|وزن=فعّل}} === المراجع === {{مراجع}} 8lrln7ao6n463ktpogxf0a2laex08pf اِجْتَزَأَ 0 240082 1096969 2026-07-20T17:28:26Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096969 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533892}} === المعاني === '''اِجْتَزَأَ''' {{افتعل}} {{معجمية|L1533892|معاني}} === النطق === * {{أصد-عر|اِجْتَزَأَ}} {{-}} === التصريفات === {{تصريف|جذر=جزأ|وزن=افتعل}} === المراجع === {{مراجع}} hqs8pqn85gln9aauzogy2tdfk7z9ew0 اِجْتَزَفَ 0 240083 1096971 2026-07-21T09:23:35Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096971 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533905}} === المعاني === '''اِجْتَزَفَ''' {{افتعل}} {{معجمية|L1533905|معاني}} === النطق === * {{أصد-عر|اِجْتَزَفَ}} {{-}} === التصريفات === {{تصريف|جذر=جزف|وزن=افتعل}} === المراجع === {{مراجع}} mbp4xzeio6d6zxvun9moo216w3lo2kn تَجَزَّفَ 0 240084 1096972 2026-07-21T09:25:30Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096972 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533906}} === المعاني === '''تَجَزَّفَ''' {{تفعّل}} {{معجمية|L1533906|معاني}} === النطق === * {{أصد-عر|تَجَزَّفَ}} {{-}} === التصريفات === {{تصريف|جذر=جزف|وزن=تفعّل}} === المراجع === {{مراجع}} 7b52zqf0t9xmib70jtrqtgmcbp6ngca اِسْتَجْزَلَ 0 240085 1096973 2026-07-21T09:28:24Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096973 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533907}} === المعاني === '''اِسْتَجْزَلَ''' {{استفعل}} {{معجمية|L1533907|معاني}} === النطق === * {{أصد-عر|اِسْتَجْزَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جزل|وزن=استفعل}} === المراجع === {{مراجع}} 1wt3t1grkh29fzz3w819jhd5rr72vwd جَزْمَرَ 0 240086 1096974 2026-07-21T09:33:37Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096974 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533911}} === المعاني === '''جَزْمَرَ''' {{فعلل}} {{معجمية|L1533911|معاني}} === النطق === * {{أصد-عر|جَزْمَرَ}} {{-}} === التصريفات === {{تصريف|جذر=جزمر|وزن=فعلل}} === المراجع === {{مراجع}} mym5nwemymuoo5n54au0blbxex3zi3g اِجْتَزَى 0 240087 1096975 2026-07-21T09:35:34Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096975 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533912}} === المعاني === '''اِجْتَزَى''' {{افتعل}} {{معجمية|L1533912|معاني}} === النطق === * {{أصد-عر|اِجْتَزَى}} {{-}} === التصريفات === {{تصريف|جذر=جزي|وزن=افتعل}} === المراجع === {{مراجع}} qefjwfm49v41ineqyrixlwf712dobo5 تَجَازَى 0 240088 1096976 2026-07-21T09:39:59Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096976 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533913}} === المعاني === '''تَجَازَى''' {{تفاعل}} {{معجمية|L1533913|معاني}} === النطق === * {{أصد-عر|تَجَازَى}} {{-}} === التصريفات === {{تصريف|جذر=جزي|وزن=تفاعل}} === المراجع === {{مراجع}} mtcqldj86l2t77hvnvukj1ia166lpmz اِجْسَأَنَّ 0 240089 1096977 2026-07-21T09:42:13Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096977 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533914}} === المعاني === '''اِجْسَأَنَّ''' {{افعللّ}} {{معجمية|L1533914|معاني}} === النطق === * {{أصد-عر|اِجْسَأَنَّ}} {{-}} === التصريفات === {{تصريف|جذر=جسأن|وزن=افعللّ}} === المراجع === {{مراجع}} l4mhyw49ohcwxei3u6ytyb0yg7lcbpe أَجْسَرَ 0 240090 1096978 2026-07-21T09:42:57Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096978 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533915}} === المعاني === '''أَجْسَرَ''' {{أفعل}} {{معجمية|L1533915|معاني}} === النطق === * {{أصد-عر|أَجْسَرَ}} {{-}} === التصريفات === {{تصريف|جذر=جسر|وزن=أفعل}} === المراجع === {{مراجع}} m90i185wbd086bjh6c4laqtmf0ei122 اِجْتَسَّ 0 240091 1096979 2026-07-21T09:45:06Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096979 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533918}} === المعاني === '''اِجْتَسَّ''' {{افتعل}} {{معجمية|L1533918|معاني}} === النطق === * {{أصد-عر|اِجْتَسَّ}} {{-}} === التصريفات === {{تصريف|جذر=جسس|وزن=افتعل}} === المراجع === {{مراجع}} 9vtdwb8yx4cv93zq90053g1vatvujav جَاسَى 0 240092 1096980 2026-07-21T09:46:13Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096980 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533920}} === المعاني === '''جَاسَى''' {{فاعل}} {{معجمية|L1533920|معاني}} === النطق === * {{أصد-عر|جَاسَى}} {{-}} === التصريفات === {{تصريف|جذر=جسو|وزن=فاعل}} === المراجع === {{مراجع}} 026401b0p7bdo9evr9z01f8wo5gvowh اِجْتَشَأَ 0 240093 1096981 2026-07-21T09:49:51Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096981 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1496203}} === المعاني === '''اِجْتَشَأَ''' {{افتعل}} {{معجمية|L1496203|معاني}} === النطق === * {{أصد-عر|اِجْتَشَأَ}} {{-}} === التصريفات === {{تصريف|جذر=جشأ|وزن=افتعل}} === المراجع === {{مراجع}} gk92qn0jmdq6bs9e6w46swzfn3jpwyg جَشْجَشَ 0 240094 1096982 2026-07-21T09:50:46Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096982 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533923}} === المعاني === '''جَشْجَشَ''' {{فعلل}} {{معجمية|L1533923|معاني}} === النطق === * {{أصد-عر|جَشْجَشَ}} {{-}} === التصريفات === {{تصريف|جذر=جشجش|وزن=فعلل}} === المراجع === {{مراجع}} 5i80pb0erbyjtetfw5hg4dgw9vey39w تَجَاشَعَ 0 240095 1096983 2026-07-21T09:55:22Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096983 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533928}} === المعاني === '''تَجَاشَعَ''' {{تفاعل}} {{معجمية|L1533928|معاني}} === النطق === * {{أصد-عر|تَجَاشَعَ}} {{-}} === التصريفات === {{تصريف|جذر=جشع|وزن=تفاعل}} === المراجع === {{مراجع}} 76g0b52s5nmq919rw4wubava3w0ybhb اِجْتَشَى 0 240096 1096984 2026-07-21T09:56:18Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096984 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533931}} === المعاني === '''اِجْتَشَى''' {{افتعل}} {{معجمية|L1533931|معاني}} === النطق === * {{أصد-عر|اِجْتَشَى}} {{-}} === التصريفات === {{تصريف|جذر=جشو|وزن=افتعل}} === المراجع === {{مراجع}} pvn71q8g6ph5cxqypu9iinf5d0xub18 اِجْتَصَّ 0 240097 1096985 2026-07-21T09:57:39Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096985 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1483862}} === المعاني === '''اِجْتَصَّ''' {{افتعل}} {{معجمية|L1483862|معاني}} === النطق === * {{أصد-عر|اِجْتَصَّ}} {{-}} === التصريفات === {{تصريف|جذر=جصص|وزن=افتعل}} === المراجع === {{مراجع}} 6r16b6dy3pdtciv6j7u4b5fqte33exk تَجَاصَّ 0 240098 1096986 2026-07-21T09:58:52Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096986 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533932}} === المعاني === '''تَجَاصَّ''' {{تفاعل}} {{معجمية|L1533932|معاني}} === النطق === * {{أصد-عر|تَجَاصَّ}} {{-}} === التصريفات === {{تصريف|جذر=جصص|وزن=تفاعل}} === المراجع === {{مراجع}} k5clubu80olff7kb3p0yw0l5jl6p0uv اِسْتَجْرَأَ 0 240099 1096987 2026-07-21T10:16:28Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096987 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533826}} === المعاني === '''اِسْتَجْرَأَ''' {{استفعل}} {{معجمية|L1533826|معاني}} === النطق === * {{أصد-عر|اِسْتَجْرَأَ}} {{-}} === التصريفات === {{تصريف|جذر=جرأ|وزن=استفعل}} === المراجع === {{مراجع}} ekbrhref6y49z2g37lleoblhgnppa9y تَجَضَّمَ 0 240100 1096988 2026-07-21T10:19:04Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096988 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533935}} === المعاني === '''تَجَضَّمَ''' {{تفعّل}} {{معجمية|L1533935|معاني}} === النطق === * {{أصد-عر|تَجَضَّمَ}} {{-}} === التصريفات === {{تصريف|جذر=جضم|وزن=تفعّل}} === المراجع === {{مراجع}} jdvkvaspt5fkyc4jg2owpg40en5toh6 جَعْبَلَ 0 240101 1096989 2026-07-21T10:19:40Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096989 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533941}} === المعاني === '''جَعْبَلَ''' {{فعلل}} {{معجمية|L1533941|معاني}} === النطق === * {{أصد-عر|جَعْبَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جعبل|وزن=فعلل}} === المراجع === {{مراجع}} 9a8eu30pxap5mdxjcus1tt69f0vyl73 جَعْبَى 0 240102 1096990 2026-07-21T10:25:32Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096990 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533942}} === المعاني === '''جَعْبَى''' {{فعلل}} {{معجمية|L1533942|معاني}} === النطق === * {{أصد-عر|جَعْبَى}} {{-}} === التصريفات === {{تصريف|جذر=جعبي|وزن=فعلل}} === المراجع === {{مراجع}} lmizodp7t7w65lj6fryqjdbxvwai105 جَعْثَرَ 0 240103 1096991 2026-07-21T10:29:47Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096991 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533944}} === المعاني === '''جَعْثَرَ''' {{فعلل}} {{معجمية|L1533944|معاني}} === النطق === * {{أصد-عر|جَعْثَرَ}} {{-}} === التصريفات === {{تصريف|جذر=جعثر|وزن=فعلل}} === المراجع === {{مراجع}} 1xwyec2jh8nihz1ytkxbqjnirvbc7ne تَجَعْثَمَ 0 240104 1096992 2026-07-21T10:30:56Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096992 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533945}} === المعاني === '''تَجَعْثَمَ''' {{تفعلل}} {{معجمية|L1533945|معاني}} === النطق === * {{أصد-عر|تَجَعْثَمَ}} {{-}} === التصريفات === {{تصريف|جذر=جعثم|وزن=تفعلل}} === المراجع === {{مراجع}} sx735qeyldxoy4rnmpah1jmxsgrnep4 تَجَعْثَنَ 0 240105 1096993 2026-07-21T11:16:14Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096993 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533946}} === المعاني === '''تَجَعْثَنَ''' {{تفعلل}} {{معجمية|L1533946|معاني}} === النطق === * {{أصد-عر|تَجَعْثَنَ}} {{-}} === التصريفات === {{تصريف|جذر=جعثن|وزن=تفعلل}} === المراجع === {{مراجع}} 1vjinxsnwp4mb74d5zrbhwcrfqjuft7 اِنْجَعَرَ 0 240106 1096994 2026-07-21T11:19:24Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096994 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533949}} === المعاني === '''اِنْجَعَرَ''' {{انفعل}} {{معجمية|L1533949|معاني}} === النطق === * {{أصد-عر|اِنْجَعَرَ}} {{-}} === التصريفات === {{تصريف|جذر=جعر|وزن=انفعل}} === المراجع === {{مراجع}} rmkt0tmqona4lsuqd5rs1cybycn4nuc تَجَعَّرَ 0 240107 1096995 2026-07-21T11:23:33Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096995 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533950}} === المعاني === '''تَجَعَّرَ''' {{تفعّل}} {{معجمية|L1533950|معاني}} === النطق === * {{أصد-عر|تَجَعَّرَ}} {{-}} === التصريفات === {{تصريف|جذر=جعر|وزن=تفعّل}} === المراجع === {{مراجع}} 29z3dm2v0h0aw996d0c31kws6c3z7w7 جَعْضَرَ 0 240108 1096996 2026-07-21T11:25:15Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096996 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533952}} === المعاني === '''جَعْضَرَ''' {{فعلل}} {{معجمية|L1533952|معاني}} === النطق === * {{أصد-عر|جَعْضَرَ}} {{-}} === التصريفات === {{تصريف|جذر=جعضر|وزن=فعلل}} === المراجع === {{مراجع}} pnvfg5yv55751natd0qf5jstw7rbgya اِجْتَعَفَ 0 240109 1096997 2026-07-21T11:27:48Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096997 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533956}} === المعاني === '''اِجْتَعَفَ''' {{افتعل}} {{معجمية|L1533956|معاني}} === النطق === * {{أصد-عر|اِجْتَعَفَ}} {{-}} === التصريفات === {{تصريف|جذر=جعف|وزن=افتعل}} === المراجع === {{مراجع}} 8q1z79ih2vpdf0rvk4hu3y5s6h1ojpm جَعْفَدَ 0 240110 1096998 2026-07-21T11:29:24Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096998 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533958}} === المعاني === '''جَعْفَدَ''' {{فعلل}} {{معجمية|L1533958|معاني}} === النطق === * {{أصد-عر|جَعْفَدَ}} {{-}} === التصريفات === {{تصريف|جذر=جعفد|وزن=فعلل}} === المراجع === {{مراجع}} tb7loelbi61xlsnef42iwwksmlty8bp جَعْفَقَ 0 240111 1096999 2026-07-21T11:31:41Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1096999 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533959}} === المعاني === '''جَعْفَقَ''' {{فعلل}} {{معجمية|L1533959|معاني}} === النطق === * {{أصد-عر|جَعْفَقَ}} {{-}} === التصريفات === {{تصريف|جذر=جعفق|وزن=فعلل}} === المراجع === {{مراجع}} gg8m0wb8icbi1yrpbu89wb4oivoidwt جَعْفَلَ 0 240112 1097000 2026-07-21T11:37:55Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097000 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533960}} === المعاني === '''جَعْفَلَ''' {{فعلل}} {{معجمية|L1533960|معاني}} === النطق === * {{أصد-عر|جَعْفَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جعفل|وزن=فعلل}} === المراجع === {{مراجع}} grs5gtjqjo4yqjcpo1rif1x79jenybp اِسْتَجْعَلَ 0 240113 1097001 2026-07-21T11:40:08Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097001 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533962}} === المعاني === '''اِسْتَجْعَلَ''' {{استفعل}} {{معجمية|L1533962|معاني}} === النطق === * {{أصد-عر|اِسْتَجْعَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جعل|وزن=استفعل}} === المراجع === {{مراجع}} 1143u19dm16j7f7vm1md8fel88nptic تَجَاعَلَ 0 240114 1097002 2026-07-21T11:44:05Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097002 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533964}} === المعاني === '''تَجَاعَلَ''' {{تفاعل}} {{معجمية|L1533964|معاني}} === النطق === * {{أصد-عر|تَجَاعَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جعل|وزن=تفاعل}} === المراجع === {{مراجع}} 98fq24u4prvlqr1qeungy2ybwbs8zbm تَجَعَّمَ 0 240115 1097003 2026-07-21T11:49:45Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097003 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533967}} === المعاني === '''تَجَعَّمَ''' {{تفعّل}} {{معجمية|L1533967|معاني}} === النطق === * {{أصد-عر|تَجَعَّمَ}} {{-}} === التصريفات === {{تصريف|جذر=جعم|وزن=تفعّل}} === المراجع === {{مراجع}} kc0ha3io30p6pw0do83u3zhwqic105a اِجْتَعَلَ 0 240116 1097004 2026-07-21T12:02:19Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097004 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533963}} === المعاني === '''اِجْتَعَلَ''' {{افتعل}} {{معجمية|L1533963|معاني}} === النطق === * {{أصد-عر|اِجْتَعَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جعل|وزن=افتعل}} === المراجع === {{مراجع}} lc2y5nlf0lot9wuvralf5ptseeqv9yz جَعْمَرَ 0 240117 1097005 2026-07-21T12:04:01Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097005 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533968}} === المعاني === '''جَعْمَرَ''' {{فعلل}} {{معجمية|L1533968|معاني}} === النطق === * {{أصد-عر|جَعْمَرَ}} {{-}} === التصريفات === {{تصريف|جذر=جعمر|وزن=فعلل}} === المراجع === {{مراجع}} 1u3g6ifmybeowlpbcw7uy6jovhb5vqv أَجْعَنَ 0 240118 1097006 2026-07-21T12:06:30Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097006 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533969}} === المعاني === '''أَجْعَنَ''' {{أفعل}} {{معجمية|L1533969|معاني}} === النطق === * {{أصد-عر|أَجْعَنَ}} {{-}} === التصريفات === {{تصريف|جذر=جعن|وزن=أفعل}} === المراجع === {{مراجع}} dbt19jb33cni9omai5w2sa1qr7l0xcn اِجْفَاظَّ 0 240119 1097007 2026-07-21T12:14:13Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097007 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533985}} === المعاني === '''اِجْفَاظَّ''' {{افعالّ}} {{معجمية|L1533985|معاني}} === النطق === * {{أصد-عر|اِجْفَاظَّ}} {{-}} === التصريفات === {{تصريف|جذر=جفظ|وزن=افعالّ}} === المراجع === {{مراجع}} f96fzv4hkdg2n1wuoaa1qpxvgtbqsck اِجْتَفَّ 0 240120 1097008 2026-07-21T12:17:36Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097008 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533986}} === المعاني === '''اِجْتَفَّ''' {{افتعل}} {{معجمية|L1533986|معاني}} === النطق === * {{أصد-عر|اِجْتَفَّ}} {{-}} === التصريفات === {{تصريف|جذر=جفف|وزن=افتعل}} === المراجع === {{مراجع}} 7bjfwcgl5oyxlkvwypc670ooex7c4cn أَجْفَنَ 0 240121 1097009 2026-07-21T12:23:22Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097009 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533990}} === المعاني === '''أَجْفَنَ''' {{أفعل}} {{معجمية|L1533990|معاني}} === النطق === * {{أصد-عر|أَجْفَنَ}} {{-}} === التصريفات === {{تصريف|جذر=جفن|وزن=أفعل}} === المراجع === {{مراجع}} 0tgshzg9ysbdwf6m5d1sb8t7ukit4hl اِجْتَفَى 0 240122 1097010 2026-07-21T12:24:33Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097010 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533995}} === المعاني === '''اِجْتَفَى''' {{افتعل}} {{معجمية|L1533995|معاني}} === النطق === * {{أصد-عر|اِجْتَفَى}} {{-}} === التصريفات === {{تصريف|جذر=جفو|وزن=افتعل}} === المراجع === {{مراجع}} deqa6ftlzgxej7illsxk0nv61g5cg1d تَجَافَى 0 240123 1097011 2026-07-21T12:27:40Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097011 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1488388}} === المعاني === '''تَجَافَى''' {{تفاعل}} {{معجمية|L1488388|معاني}} === النطق === * {{أصد-عر|تَجَافَى}} {{-}} === التصريفات === {{تصريف|جذر=جفو|وزن=تفاعل}} === المراجع === {{مراجع}} p5wjqjbrf9kck6psnsdevn48wq5dzax اِنْجَلَبَ 0 240124 1097012 2026-07-21T12:31:37Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097012 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1486822}} === المعاني === '''اِنْجَلَبَ''' {{انفعل}} {{معجمية|L1486822|معاني}} === النطق === * {{أصد-عر|اِنْجَلَبَ}} {{-}} === التصريفات === {{تصريف|جذر=جلب|وزن=انفعل}} === المراجع === {{مراجع}} r0eqj05qjz0dl5gpoxf4ve7ekn3vtqw تَجَلَّبَ 0 240125 1097013 2026-07-21T12:36:40Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097013 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533998}} === المعاني === '''تَجَلَّبَ''' {{تفعّل}} {{معجمية|L1533998|معاني}} === النطق === * {{أصد-عر|تَجَلَّبَ}} {{-}} === التصريفات === {{تصريف|جذر=جلب|وزن=تفعّل}} === المراجع === {{مراجع}} ne820ndaf7g1jva2inl1qu9uvtzckg2 تَجَلْبَبَ 0 240126 1097014 2026-07-21T12:41:15Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097014 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1486799}} === المعاني === '''تَجَلْبَبَ''' {{تفعلل}} {{معجمية|L1486799|معاني}} === النطق === * {{أصد-عر|تَجَلْبَبَ}} {{-}} === التصريفات === {{تصريف|جذر=جلبب|وزن=تفعلل}} === المراجع === {{مراجع}} 30ujjrk4vk4y15bq3kwqwhux3ax88qd جَلْبَبَ 0 240127 1097015 2026-07-21T12:43:22Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097015 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1486987}} === المعاني === '''جَلْبَبَ''' {{فعلل}} {{معجمية|L1486987|معاني}} === النطق === * {{أصد-عر|جَلْبَبَ}} {{-}} === التصريفات === {{تصريف|جذر=جلبب|وزن=فعلل}} === المراجع === {{مراجع}} jb0adp8ighh3gdycuokim9zblvusccc اِجْلَخَبَّ 0 240128 1097016 2026-07-21T12:46:28Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097016 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534009}} === المعاني === '''اِجْلَخَبَّ''' {{افعللّ}} {{معجمية|L1534009|معاني}} === النطق === * {{أصد-عر|اِجْلَخَبَّ}} {{-}} === التصريفات === {{تصريف|جذر=جلخب|وزن=افعللّ}} === المراجع === {{مراجع}} jmo7s53dtdlsgpud7vd7tsv8a8innjl تَجَلَّدَ 0 240129 1097017 2026-07-21T12:52:38Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097017 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1484256}} === المعاني === '''تَجَلَّدَ''' {{تفعّل}} {{معجمية|L1484256|معاني}} === النطق === * {{أصد-عر|تَجَلَّدَ}} {{-}} === التصريفات === {{تصريف|جذر=جلد|وزن=تفعّل}} === المراجع === {{مراجع}} g9d24ywhebyolqfsexhhbzhabvaksdy اِسْتَجْلَسَ 0 240130 1097018 2026-07-21T12:53:44Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097018 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534016}} === المعاني === '''اِسْتَجْلَسَ''' {{استفعل}} {{معجمية|L1534016|معاني}} === النطق === * {{أصد-عر|اِسْتَجْلَسَ}} {{-}} === التصريفات === {{تصريف|جذر=جلس|وزن=استفعل}} === المراجع === {{مراجع}} pvbrtssd0wy03jfskhapkfvrazqsv2p تَجَالَسَ 0 240131 1097019 2026-07-21T12:56:43Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097019 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1484744}} === المعاني === '''تَجَالَسَ''' {{تفاعل}} {{معجمية|L1484744|معاني}} === النطق === * {{أصد-عر|تَجَالَسَ}} {{-}} === التصريفات === {{تصريف|جذر=جلس|وزن=تفاعل}} === المراجع === {{مراجع}} 9w130r2w740j1ormbly92h1wh296wj4 تَجَلَّطَ 0 240132 1097020 2026-07-21T12:57:32Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097020 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1486154}} === المعاني === '''تَجَلَّطَ''' {{تفعّل}} {{معجمية|L1486154|معاني}} === النطق === * {{أصد-عر|تَجَلَّطَ}} {{-}} === التصريفات === {{تصريف|جذر=جلط|وزن=تفعّل}} === المراجع === {{مراجع}} cik35u6iv8wzrs0l52hmbha5xg4vu2p اِجْلَوَّظَ 0 240133 1097021 2026-07-21T12:58:05Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097021 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534024}} === المعاني === '''اِجْلَوَّظَ''' {{افعوّل}} {{معجمية|L1534024|معاني}} === النطق === * {{أصد-عر|اِجْلَوَّظَ}} {{-}} === التصريفات === {{تصريف|جذر=جلظ|وزن=افعوّل}} === المراجع === {{مراجع}} 1lp13tziyahsdqim4fn99h973mefd2y اِنْجَلَعَ 0 240134 1097022 2026-07-21T13:05:03Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097022 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534027}} === المعاني === '''اِنْجَلَعَ''' {{انفعل}} {{معجمية|L1534027|معاني}} === النطق === * {{أصد-عر|اِنْجَلَعَ}} {{-}} === التصريفات === {{تصريف|جذر=جلع|وزن=انفعل}} === المراجع === {{مراجع}} kbi90yvs502oekruaqjvko4vxrywksb اِجْلَنْظَى 0 240135 1097023 2026-07-21T13:29:04Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097023 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534026}} === المعاني === '''اِجْلَنْظَى''' {{افعنلل}} {{معجمية|L1534026|معاني}} === النطق === * {{أصد-عر|اِجْلَنْظَى}} {{-}} === التصريفات === {{تصريف|جذر=جلظي|وزن=افعنلل}} === المراجع === {{مراجع}} f8e8y7a0af71xspibzaq4hp2pa69ph2 اِجْلَوَّذَ 0 240136 1097024 2026-07-21T15:22:32Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097024 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534013}} === المعاني === '''اِجْلَوَّذَ''' {{افعوّل}} {{معجمية|L1534013|معاني}} === النطق === * {{أصد-عر|اِجْلَوَّذَ}} {{-}} === التصريفات === {{تصريف|جذر=جلذ|وزن=افعوّل}} === المراجع === {{مراجع}} n1y6n4jmea9k9iq7p9gmsolli5kawn6 سَقَّدَ 0 240137 1097025 2026-07-21T16:56:18Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097025 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536982}} === المعاني === '''سَقَّدَ''' {{فعّل}} {{معجمية|L1536982|معاني}} === النطق === * {{أصد-عر|سَقَّدَ}} {{-}} === التصريفات === {{تصريف|جذر=سقد|وزن=فعّل}} === المراجع === {{مراجع}} cig7eicwsn8d7ornzely5qf8boalp6p اِسْتَأْشَرَ 0 240138 1097026 2026-07-21T16:57:10Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097026 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532651}} === المعاني === '''اِسْتَأْشَرَ''' {{استفعل}} {{معجمية|L1532651|معاني}} === النطق === * {{أصد-عر|اِسْتَأْشَرَ}} {{-}} === التصريفات === {{تصريف|جذر=أشر|وزن=استفعل}} === المراجع === {{مراجع}} qi1dkea1a0hk40dt1jp65n6zsxnc8cr جَذْجَذَ 0 240139 1097027 2026-07-21T16:58:45Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097027 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533802}} === المعاني === '''جَذْجَذَ''' {{فعلل}} {{معجمية|L1533802|معاني}} === النطق === * {{أصد-عر|جَذْجَذَ}} {{-}} === التصريفات === {{تصريف|جذر=جذجذ|وزن=فعلل}} === المراجع === {{مراجع}} i9zi66ywtdkgohr7d3xocmoh6kzwycs اِنْسَبَأَ 0 240140 1097028 2026-07-21T17:02:06Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097028 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536745}} === المعاني === '''اِنْسَبَأَ''' {{انفعل}} {{معجمية|L1536745|معاني}} === النطق === * {{أصد-عر|اِنْسَبَأَ}} {{-}} === التصريفات === {{تصريف|جذر=سبأ|وزن=انفعل}} === المراجع === {{مراجع}} fy0hufj2l2k7msbdshhf0kb7sftvl4i اِسْبَكَرَّ 0 240141 1097029 2026-07-21T17:03:34Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097029 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1483740}} === المعاني === '''اِسْبَكَرَّ''' {{افعللّ}} {{معجمية|L1483740|معاني}} === النطق === * {{أصد-عر|اِسْبَكَرَّ}} {{-}} === التصريفات === {{تصريف|جذر=سبكر|وزن=افعللّ}} === المراجع === {{مراجع}} a0kvvejry1sel5zasdrcqd90r3b2uir اِسْجَهَرَّ 0 240142 1097030 2026-07-21T17:04:52Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097030 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536800}} === المعاني === '''اِسْجَهَرَّ''' {{افعللّ}} {{معجمية|L1536800|معاني}} === النطق === * {{أصد-عر|اِسْجَهَرَّ}} {{-}} === التصريفات === {{تصريف|جذر=سجهر|وزن=افعللّ}} === المراجع === {{مراجع}} jnded5wogrnly3alf7548gnv6xm7sq2 اِنْسَجَلَ 0 240143 1097031 2026-07-21T17:05:40Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097031 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536795}} === المعاني === '''اِنْسَجَلَ''' {{انفعل}} {{معجمية|L1536795|معاني}} === النطق === * {{أصد-عر|اِنْسَجَلَ}} {{-}} === التصريفات === {{تصريف|جذر=سجل|وزن=انفعل}} === المراجع === {{مراجع}} iet1frbvv90o3hatdglwsn39gx0l25j سَجَّى 0 240144 1097032 2026-07-21T17:06:47Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097032 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536803}} === المعاني === '''سَجَّى''' {{فعّل}} {{معجمية|L1536803|معاني}} === النطق === * {{أصد-عر|سَجَّى}} {{-}} === التصريفات === {{تصريف|جذر=سجو|وزن=فعّل}} === المراجع === {{مراجع}} is7dz34v2w2kwnk3m1wlpgzj00hntwx اِسْحَنْفَرَ 0 240145 1097033 2026-07-21T17:09:14Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097033 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536822}} === المعاني === '''اِسْحَنْفَرَ''' {{افعنلل}} {{معجمية|L1536822|معاني}} === النطق === * {{أصد-عر|اِسْحَنْفَرَ}} {{-}} === التصريفات === {{تصريف|جذر=سحفر|وزن=افعنلل}} === المراجع === {{مراجع}} acb8vxp2ro835o79fsun1net64i0fde تَسَحَّحَ 0 240146 1097034 2026-07-21T17:11:47Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097034 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536814}} === المعاني === '''تَسَحَّحَ''' {{تفعّل}} {{معجمية|L1536814|معاني}} === النطق === * {{أصد-عر|تَسَحَّحَ}} {{-}} === التصريفات === {{تصريف|جذر=سحح|وزن=تفعّل}} === المراجع === {{مراجع}} p75v3xyyzkj8m50pzo9b8s5wmr6igtc اِسْتَحَى 0 240147 1097035 2026-07-21T17:12:40Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097035 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1480966}} === المعاني === '''اِسْتَحَى''' {{افتعل}} {{معجمية|L1480966|معاني}} === النطق === * {{أصد-عر|اِسْتَحَى}} {{-}} === التصريفات === {{تصريف|جذر=سحي|وزن=افتعل}} === المراجع === {{مراجع}} 6f3lt6aq2ox7zi3mlz06mdg8kplcz67 أَشَرَ 0 240148 1097036 2026-07-21T17:21:38Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097036 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1485950}} === المعاني === '''أَشَرَ''' {{نصر}} {{معجمية|L1485950|معاني}} === النطق === * {{أصد-عر|أَشَرَ}} {{-}} === التصريفات === {{تصريف|جذر=أشر|وزن=فعَل يفعُل}} === المراجع === {{مراجع}} 5ze5w3fhdnkapxryq2lqtx3t3nmmx7i أَصَّ 0 240149 1097037 2026-07-21T17:23:44Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097037 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1498065}} === المعاني === '''أَصَّ''' {{نصر}} {{معجمية|L1498065|معاني}} === النطق === * {{أصد-عر|أَصَّ}} {{-}} === التصريفات === {{تصريف|جذر=أصص|وزن=فعَل يفعُل}} === المراجع === {{مراجع}} evfcnkvi1l22lku3bfngng8acpnkih5 آطَمَ 0 240150 1097038 2026-07-21T17:24:16Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097038 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532669}} === المعاني === '''آطَمَ''' {{أفعل}} {{معجمية|L1532669|معاني}} === النطق === * {{أصد-عر|آطَمَ}} {{-}} === التصريفات === {{تصريف|جذر=أطم|وزن=أفعل}} === المراجع === {{مراجع}} s435tgnwfal02umaia2agmjtjr48dia تَأَفَّنَ 0 240151 1097039 2026-07-21T17:25:20Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097039 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532685}} === المعاني === '''تَأَفَّنَ''' {{تفعّل}} {{معجمية|L1532685|معاني}} === النطق === * {{أصد-عر|تَأَفَّنَ}} {{-}} === التصريفات === {{تصريف|جذر=أفن|وزن=تفعّل}} === المراجع === {{مراجع}} a0jn2kqvxrw5vf91c2ooahb7cf8181t أَلَّى 0 240152 1097040 2026-07-21T17:26:32Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097040 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532713}} === المعاني === '''أَلَّى''' {{فعّل}} {{معجمية|L1532713|معاني}} === النطق === * {{أصد-عر|أَلَّى}} {{-}} === التصريفات === {{تصريف|جذر=ألو|وزن=فعّل}} === المراجع === {{مراجع}} n1rw3vq4f7bqg54f5velgdlt9z2a2f8 آنَفَ 0 240153 1097041 2026-07-21T17:28:06Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097041 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1484444}} === المعاني === '''آنَفَ''' {{أفعل}} {{معجمية|L1484444|معاني}} === النطق === * {{أصد-عر|آنَفَ}} {{-}} === التصريفات === {{تصريف|جذر=أنف|وزن=أفعل}} === المراجع === {{مراجع}} cgf8z1gzy96sa56ys02zm5x9owap9wt اِئْتَفَظَ 0 240154 1097042 2026-07-21T17:30:40Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097042 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532676}} === المعاني === '''اِئْتَفَظَ''' {{افتعل}} {{معجمية|L1532676|معاني}} === النطق === * {{أصد-عر|اِئْتَفَظَ}} {{-}} === التصريفات === {{تصريف|جذر=أفظ|وزن=افتعل}} === المراجع === {{مراجع}} khy6b4i7plouzwiksqkoxfa8nt0oo6g أَكَأَ 0 240155 1097043 2026-07-21T17:31:30Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097043 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1545455}} === المعاني === '''أَكَأَ''' {{فتح}} {{معجمية|L1545455|معاني}} === النطق === * {{أصد-عر|أَكَأَ}} {{-}} === التصريفات === {{تصريف|جذر=أكأ|وزن=فعَل يفعَل}} === المراجع === {{مراجع}} 262ypiwxnpxfrz6wmm36io561djwmzf أَكَرَ 0 240156 1097044 2026-07-21T17:32:34Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097044 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1481135}} === المعاني === '''أَكَرَ''' {{نصر}} {{معجمية|L1481135|معاني}} === النطق === * {{أصد-عر|أَكَرَ}} {{-}} === التصريفات === {{تصريف|جذر=أكر|وزن=فعَل يفعُل}} === المراجع === {{مراجع}} tddef4w0cv42vkk86c0fmymxv46nwms آكَرَ 0 240157 1097045 2026-07-21T17:33:24Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097045 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532692}} === المعاني === '''آكَرَ''' {{فاعل}} {{معجمية|L1532692|معاني}} === النطق === * {{أصد-عر|آكَرَ}} {{-}} === التصريفات === {{تصريف|جذر=أكر|وزن=فاعل}} === المراجع === {{مراجع}} sn0nruu4j5r1b5ddiyslt4bsderjl3e أَكَّمَ 0 240158 1097046 2026-07-21T17:33:46Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097046 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532698}} === المعاني === '''أَكَّمَ''' {{فعّل}} {{معجمية|L1532698|معاني}} === النطق === * {{أصد-عر|أَكَّمَ}} {{-}} === التصريفات === {{تصريف|جذر=أكم|وزن=فعّل}} === المراجع === {{مراجع}} q5v7kdsk35mzccq8r86148ofm82xl4n أَمَتَ 0 240159 1097047 2026-07-21T17:35:03Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097047 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1498059}} === المعاني === '''أَمَتَ''' {{ضرب}} {{معجمية|L1498059|معاني}} === النطق === * {{أصد-عر|أَمَتَ}} {{-}} === التصريفات === {{تصريف|جذر=أمت|وزن=فعَل يفعِل}} === المراجع === {{مراجع}} e569fw6wuved52wtg45gpbc1k2bwpzs تَأَنَّنَ 0 240160 1097048 2026-07-21T17:35:39Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097048 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532726}} === المعاني === '''تَأَنَّنَ''' {{تفعّل}} {{معجمية|L1532726|معاني}} === النطق === * {{أصد-عر|تَأَنَّنَ}} {{-}} === التصريفات === {{تصريف|جذر=أنن|وزن=تفعّل}} === المراجع === {{مراجع}} h4y580kx35eodcfd3avawg0lxrm4pk4 آهَلَ 0 240161 1097049 2026-07-21T17:36:57Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097049 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532729}} === المعاني === '''آهَلَ''' {{أفعل}} {{معجمية|L1532729|معاني}} === النطق === * {{أصد-عر|آهَلَ}} {{-}} === التصريفات === {{تصريف|جذر=أهل|وزن=أفعل}} === المراجع === {{مراجع}} icxulb8j0zuoyk4jrxwpa0zp2rmx284 اِسْتَأْهَلَ 0 240162 1097050 2026-07-21T17:38:22Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097050 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1482030}} === المعاني === '''اِسْتَأْهَلَ''' {{استفعل}} {{معجمية|L1482030|معاني}} === النطق === * {{أصد-عر|اِسْتَأْهَلَ}} {{-}} === التصريفات === {{تصريف|جذر=أهل|وزن=استفعل}} === المراجع === {{مراجع}} 0idvqhb9kqfkekz493qa1f374ibmiu1 تَأَهَّلَ 0 240163 1097051 2026-07-21T17:39:07Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097051 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1480723}} === المعاني === '''تَأَهَّلَ''' {{تفعّل}} {{معجمية|L1480723|معاني}} === النطق === * {{أصد-عر|تَأَهَّلَ}} {{-}} === التصريفات === {{تصريف|جذر=أهل|وزن=تفعّل}} === المراجع === {{مراجع}} 3lu95y5iqffzgbsbhuf17qed80xahry تَآوَبَ 0 240164 1097052 2026-07-21T17:39:30Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097052 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532734}} === المعاني === '''تَآوَبَ''' {{تفاعل}} {{معجمية|L1532734|معاني}} === النطق === * {{أصد-عر|تَآوَبَ}} {{-}} === التصريفات === {{تصريف|جذر=أوب|وزن=تفاعل}} === المراجع === {{مراجع}} hhigo6rk8g1uxprco3o80xbhdovovwi اِخْتَبَّ 0 240165 1097053 2026-07-21T19:17:17Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097053 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534776}} === المعاني === '''اِخْتَبَّ''' {{افتعل}} {{معجمية|L1534776|معاني}} === النطق === * {{أصد-عر|اِخْتَبَّ}} {{-}} === التصريفات === {{تصريف|جذر=خبب|وزن=افتعل}} === المراجع === {{مراجع}} 0g2vpzz7zytsjenp8tgs83gpdxv12i2 خَثْعَجَ 0 240166 1097054 2026-07-21T19:20:17Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097054 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534833}} === المعاني === '''خَثْعَجَ''' {{فعلل}} {{معجمية|L1534833|معاني}} === النطق === * {{أصد-عر|خَثْعَجَ}} {{-}} === التصريفات === {{تصريف|جذر=خثعج|وزن=فعلل}} === المراجع === {{مراجع}} cg518rcgth61fe1qy30m5bsgeg6npah أَخْجَى 0 240167 1097055 2026-07-21T19:21:58Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097055 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534845}} === المعاني === '''أَخْجَى''' {{أفعل}} {{معجمية|L1534845|معاني}} === النطق === * {{أصد-عر|أَخْجَى}} {{-}} === التصريفات === {{تصريف|جذر=خجي|وزن=أفعل}} === المراجع === {{مراجع}} gf8pemuc6g031c45ktzf2jqsws25lxt خَجَّى 0 240168 1097056 2026-07-21T19:25:48Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097056 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534846}} === المعاني === '''خَجَّى''' {{فعّل}} {{معجمية|L1534846|معاني}} === النطق === * {{أصد-عر|خَجَّى}} {{-}} === التصريفات === {{تصريف|جذر=خجي|وزن=فعّل}} === المراجع === {{مراجع}} lnyver2tbx2chze8piz2izzbbd2oaou خَجِيَ 0 240169 1097057 2026-07-21T19:28:01Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097057 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1544086}} === المعاني === '''خَجِيَ''' {{سمع}} {{معجمية|L1544086|معاني}} === النطق === * {{أصد-عر|خَجِيَ}} {{-}} === التصريفات === {{تصريف|جذر=خجي|وزن=فعِل يفعَل}} === المراجع === {{مراجع}} ej7rte1eaj8yice8xvfsmsvb1u909bi تَخَادَّ 0 240170 1097058 2026-07-21T19:30:04Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097058 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534850}} === المعاني === '''تَخَادَّ''' {{تفاعل}} {{معجمية|L1534850|معاني}} === النطق === * {{أصد-عر|تَخَادَّ}} {{-}} === التصريفات === {{تصريف|جذر=خدد|وزن=تفاعل}} === المراجع === {{مراجع}} qpfkcsejhyfqht8k82wmw8l29rf4p7p خَادَشَ 0 240171 1097059 2026-07-21T19:33:22Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097059 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534856}} === المعاني === '''خَادَشَ''' {{فاعل}} {{معجمية|L1534856|معاني}} === النطق === * {{أصد-عر|خَادَشَ}} {{-}} === التصريفات === {{تصريف|جذر=خدش|وزن=فاعل}} === المراجع === {{مراجع}} 5sqpn3l5rbr0hizrqxyp3t8bkgwjyv8 اِخْتَدَعَ 0 240172 1097060 2026-07-21T19:40:03Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097060 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534857}} === المعاني === '''اِخْتَدَعَ''' {{افتعل}} {{معجمية|L1534857|معاني}} === النطق === * {{أصد-عر|اِخْتَدَعَ}} {{-}} === التصريفات === {{تصريف|جذر=خدع|وزن=افتعل}} === المراجع === {{مراجع}} 87qv3ox9bgzt5fpv0jppizuhd93as5d اِدْلَسَّ 0 240173 1097063 2026-07-21T19:48:56Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097063 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535507}} === المعاني === '''اِدْلَسَّ''' {{افعلّ}} {{معجمية|L1535507|معاني}} === النطق === * {{أصد-عر|اِدْلَسَّ}} {{-}} === التصريفات === {{تصريف|جذر=دلس|وزن=افعلّ}} === المراجع === {{مراجع}} qn9p7vwitll0s5p3wcq8dknckoky8lh أَضَّ 0 240174 1097065 2026-07-21T19:51:28Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097065 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1497590}} === المعاني === '''أَضَّ''' {{نصر}} {{معجمية|L1497590|معاني}} === النطق === * {{أصد-عر|أَضَّ}} {{-}} === التصريفات === {{تصريف|جذر=أضض|وزن=فعَل يفعُل}} === المراجع === {{مراجع}} b6i77gq7st5ud1056nlq39cb0lx29bn تَأَنَّقَ 0 240175 1097066 2026-07-21T19:53:17Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097066 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1486626}} === المعاني === '''تَأَنَّقَ''' {{تفعّل}} {{معجمية|L1486626|معاني}} === النطق === * {{أصد-عر|تَأَنَّقَ}} {{-}} === التصريفات === {{تصريف|جذر=أنق|وزن=تفعّل}} === المراجع === {{مراجع}} gvkm1a62nreo521f00ukhclgvt40nkn آمَ 0 240176 1097067 2026-07-21T19:55:10Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097067 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1485295}} === المعاني === '''آمَ''' {{نصر}} {{معجمية|L1485295|معاني}} === النطق === * {{أصد-عر|آمَ}} {{-}} === التصريفات === {{تصريف|جذر=أوم|وزن=فعَل يفعُل}} === المراجع === {{مراجع}} i23nzkma150d2ctzjbso3rs7ihuhya1 اِسْتَآرَ 0 240177 1097068 2026-07-21T19:56:27Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097068 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532741}} === المعاني === '''اِسْتَآرَ''' {{استفعل}} {{معجمية|L1532741|معاني}} === النطق === * {{أصد-عر|اِسْتَآرَ}} {{-}} === التصريفات === {{تصريف|جذر=أور|وزن=استفعل}} === المراجع === {{مراجع}} l1xipi3k9hz466kn6shepr47m2155cc اِنْسَحَقَ 0 240178 1097069 2026-07-21T19:58:29Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097069 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1485337}} === المعاني === '''اِنْسَحَقَ''' {{انفعل}} {{معجمية|L1485337|معاني}} === النطق === * {{أصد-عر|اِنْسَحَقَ}} {{-}} === التصريفات === {{تصريف|جذر=سحق|وزن=انفعل}} === المراجع === {{مراجع}} ni1v1ruux7nxu9s51caokxoffoxdwyu تَسَعْسَعَ 0 240179 1097070 2026-07-21T20:00:51Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097070 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536927}} === المعاني === '''تَسَعْسَعَ''' {{تفعلل}} {{معجمية|L1536927|معاني}} === النطق === * {{أصد-عر|تَسَعْسَعَ}} {{-}} === التصريفات === {{تصريف|جذر=سعسع|وزن=تفعلل}} === المراجع === {{مراجع}} oubgiv8dkpkvdv02futykb9uan18t6w سَعْسَعَ 0 240180 1097071 2026-07-21T20:02:22Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097071 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536926}} === المعاني === '''سَعْسَعَ''' {{فعلل}} {{معجمية|L1536926|معاني}} === النطق === * {{أصد-عر|سَعْسَعَ}} {{-}} === التصريفات === {{تصريف|جذر=سعسع|وزن=فعلل}} === المراجع === {{مراجع}} ag925fe5ec0g3rd093fwnk0bh8nlaqj سَأَى 0 240181 1097072 2026-07-21T20:09:12Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097072 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1544466}} === المعاني === '''سَأَى''' {{فتح}} {{معجمية|L1544466|معاني}} === النطق === * {{أصد-عر|سَأَى}} {{-}} === التصريفات === {{تصريف|جذر=سأي|وزن=فعَل يفعَل}} === المراجع === {{مراجع}} 5io4s7sd6zgxykmthhsxyb388qq9ohl زَأَفَ 0 240182 1097073 2026-07-21T20:10:05Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097073 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1545702}} === المعاني === '''زَأَفَ''' {{فتح}} {{معجمية|L1545702|معاني}} === النطق === * {{أصد-عر|زَأَفَ}} {{-}} === التصريفات === {{تصريف|جذر=زأف|وزن=فعَل يفعَل}} === المراجع === {{مراجع}} pre165fi5luk8f73wq7sypqhi624dsp تَزَاءَكَ 0 240183 1097074 2026-07-21T20:10:23Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097074 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536391}} === المعاني === '''تَزَاءَكَ''' {{تفاعل}} {{معجمية|L1536391|معاني}} === النطق === * {{أصد-عر|تَزَاءَكَ}} {{-}} === التصريفات === {{تصريف|جذر=زأك|وزن=تفاعل}} === المراجع === {{مراجع}} 9s4bl8tevx79ogoqifqzx1bs3aan6so اِزْدَأَمَ 0 240184 1097075 2026-07-21T20:10:55Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097075 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536392}} === المعاني === '''اِزْدَأَمَ''' {{افتعل}} {{معجمية|L1536392|معاني}} === النطق === * {{أصد-عر|اِزْدَأَمَ}} {{-}} === التصريفات === {{تصريف|جذر=زأم|وزن=افتعل}} === المراجع === {{مراجع}} ncul0ik2rtkd2d2fmnu3td62aenwrvm تَزَبْتَرَ 0 240185 1097076 2026-07-21T20:11:17Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097076 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536399}} === المعاني === '''تَزَبْتَرَ''' {{تفعلل}} {{معجمية|L1536399|معاني}} === النطق === * {{أصد-عر|تَزَبْتَرَ}} {{-}} === التصريفات === {{تصريف|جذر=زبتر|وزن=تفعلل}} === المراجع === {{مراجع}} 1bsj5ujj1n631j47xbtsqa6etl70cpm اِزْدَبَدَ 0 240186 1097077 2026-07-21T20:11:38Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097077 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536400}} === المعاني === '''اِزْدَبَدَ''' {{افتعل}} {{معجمية|L1536400|معاني}} === النطق === * {{أصد-عر|اِزْدَبَدَ}} {{-}} === التصريفات === {{تصريف|جذر=زبد|وزن=افتعل}} === المراجع === {{مراجع}} bsy4c3m2y8oz2z4chscg03jpkebrc78 زَابَدَ 0 240187 1097078 2026-07-21T20:12:02Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097078 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536402}} === المعاني === '''زَابَدَ''' {{فاعل}} {{معجمية|L1536402|معاني}} === النطق === * {{أصد-عر|زَابَدَ}} {{-}} === التصريفات === {{تصريف|جذر=زبد|وزن=فاعل}} === المراجع === {{مراجع}} h5ck5cw5g93vdbpfeiqgann33bhr0vv زَبُرَ 0 240188 1097079 2026-07-21T20:12:33Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097079 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1545149}} === المعاني === '''زَبُرَ''' {{كرم}} {{معجمية|L1545149|معاني}} === النطق === * {{أصد-عر|زَبُرَ}} {{-}} === التصريفات === {{تصريف|جذر=زبر|وزن=فعُل يفعُل}} === المراجع === {{مراجع}} ah19nskrjze48kpz5ow0dtps70tt535 زَبْرَجَ 0 240189 1097080 2026-07-21T20:13:07Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097080 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1492023}} === المعاني === '''زَبْرَجَ''' {{فعلل}} {{معجمية|L1492023|معاني}} === النطق === * {{أصد-عر|زَبْرَجَ}} {{-}} === التصريفات === {{تصريف|جذر=زبرج|وزن=فعلل}} === المراجع === {{مراجع}} 3twvot4r1scwhnzrddde4uh5kb23xua زَبَطَ 0 240190 1097081 2026-07-21T20:13:59Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097081 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1483974}} === المعاني === '''زَبَطَ''' {{ضرب}} {{معجمية|L1483974|معاني}} === النطق === * {{أصد-عر|زَبَطَ}} {{-}} === التصريفات === {{تصريف|جذر=زبط|وزن=فعَل يفعِل}} === المراجع === {{مراجع}} 6sshcifmd5fllt8anmmf94409sg7gov اِنْزَبَنَ 0 240191 1097082 2026-07-21T20:14:31Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097082 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536414}} === المعاني === '''اِنْزَبَنَ''' {{انفعل}} {{معجمية|L1536414|معاني}} === النطق === * {{أصد-عر|اِنْزَبَنَ}} {{-}} === التصريفات === {{تصريف|جذر=زبن|وزن=انفعل}} === المراجع === {{مراجع}} mp9ynzxtvw9gxxqkg3n4kyg3ts2i8cw زَتَّتَ 0 240192 1097083 2026-07-21T20:15:04Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097083 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536424}} === المعاني === '''زَتَّتَ''' {{فعّل}} {{معجمية|L1536424|معاني}} === النطق === * {{أصد-عر|زَتَّتَ}} {{-}} === التصريفات === {{تصريف|جذر=زتت|وزن=فعّل}} === المراجع === {{مراجع}} 00pb0bxf0i2le711gspe39tw6ng3ev8 أَزْجَى 0 240193 1097084 2026-07-21T20:15:30Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097084 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1486969}} === المعاني === '''أَزْجَى''' {{أفعل}} {{معجمية|L1486969|معاني}} === النطق === * {{أصد-عر|أَزْجَى}} {{-}} === التصريفات === {{تصريف|جذر=زجو|وزن=أفعل}} === المراجع === {{مراجع}} 0x3lxrpepkmjtvyztz1cam621s5l3h7 اِزْدَجَى 0 240194 1097085 2026-07-21T20:15:52Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097085 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536430}} === المعاني === '''اِزْدَجَى''' {{افتعل}} {{معجمية|L1536430|معاني}} === النطق === * {{أصد-عر|اِزْدَجَى}} {{-}} === التصريفات === {{تصريف|جذر=زجو|وزن=افتعل}} === المراجع === {{مراجع}} dmva7lgx5m7snuyrf5mw1ymzjftgcsl زَاحَرَ 0 240195 1097086 2026-07-21T20:16:22Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097086 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536434}} === المعاني === '''زَاحَرَ''' {{فاعل}} {{معجمية|L1536434|معاني}} === النطق === * {{أصد-عر|زَاحَرَ}} {{-}} === التصريفات === {{تصريف|جذر=زحر|وزن=فاعل}} === المراجع === {{مراجع}} b09p409arqw6jn51rwv0vfas83v6akj اِسْحَنْكَكَ 0 240196 1097087 2026-07-21T20:17:06Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097087 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536825}} === المعاني === '''اِسْحَنْكَكَ''' {{افعنلل}} {{معجمية|L1536825|معاني}} === النطق === * {{أصد-عر|اِسْحَنْكَكَ}} {{-}} === التصريفات === {{تصريف|جذر=سحكك|وزن=افعنلل}} === المراجع === {{مراجع}} pnksk0knv3st8d66wwtlgok6diqto9i سَخَأَ 0 240197 1097088 2026-07-21T20:18:10Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097088 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1545157}} === المعاني === '''سَخَأَ''' {{فتح}} {{معجمية|L1545157|معاني}} === النطق === * {{أصد-عر|سَخَأَ}} {{-}} === التصريفات === {{تصريف|جذر=سخأ|وزن=فعَل يفعَل}} === المراجع === {{مراجع}} 5ny423h3uro677e4snr9m48qd4ncdh2 تَسَخَّى 0 240198 1097089 2026-07-21T20:18:38Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097089 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536846}} === المعاني === '''تَسَخَّى''' {{تفعّل}} {{معجمية|L1536846|معاني}} === النطق === * {{أصد-عر|تَسَخَّى}} {{-}} === التصريفات === {{تصريف|جذر=سخو|وزن=تفعّل}} === المراجع === {{مراجع}} n44lubr70d2sdls6og15spf0rhsxztw اِنْسَدَجَ 0 240199 1097090 2026-07-21T20:19:00Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097090 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536847}} === المعاني === '''اِنْسَدَجَ''' {{انفعل}} {{معجمية|L1536847|معاني}} === النطق === * {{أصد-عر|اِنْسَدَجَ}} {{-}} === التصريفات === {{تصريف|جذر=سدج|وزن=انفعل}} === المراجع === {{مراجع}} pptshh1n3zdfs45vs2cfimv2ihw37k6 اِنْسَدَحَ 0 240200 1097092 2026-07-21T20:20:01Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097092 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536849}} === المعاني === '''اِنْسَدَحَ''' {{انفعل}} {{معجمية|L1536849|معاني}} === النطق === * {{أصد-عر|اِنْسَدَحَ}} {{-}} === التصريفات === {{تصريف|جذر=سدح|وزن=انفعل}} === المراجع === {{مراجع}} 7ecpc8wvevezfh8jaeg23saco18abfa تَسَرْبَلَ 0 240201 1097093 2026-07-21T20:20:37Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097093 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1497127}} === المعاني === '''تَسَرْبَلَ''' {{تفعلل}} {{معجمية|L1497127|معاني}} === النطق === * {{أصد-عر|تَسَرْبَلَ}} {{-}} === التصريفات === {{تصريف|جذر=سربل|وزن=تفعلل}} === المراجع === {{مراجع}} 81s7r8arzt3w3ctk2yptlj40bki2ovt سَرْدَجَ 0 240202 1097094 2026-07-21T20:21:13Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097094 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536875}} === المعاني === '''سَرْدَجَ''' {{فعلل}} {{معجمية|L1536875|معاني}} === النطق === * {{أصد-عر|سَرْدَجَ}} {{-}} === التصريفات === {{تصريف|جذر=سردج|وزن=فعلل}} === المراجع === {{مراجع}} 84hodnfzqi11avdvkrcwhjo7a12pzue تَسَرْدَكَ 0 240203 1097095 2026-07-21T20:21:39Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097095 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536878}} === المعاني === '''تَسَرْدَكَ''' {{تفعلل}} {{معجمية|L1536878|معاني}} === النطق === * {{أصد-عر|تَسَرْدَكَ}} {{-}} === التصريفات === {{تصريف|جذر=سردك|وزن=تفعلل}} === المراجع === {{مراجع}} g37mvr28h4piz3ys4r58wccwqs9324x سَرْسَرَ 0 240204 1097096 2026-07-21T20:22:06Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097096 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536882}} === المعاني === '''سَرْسَرَ''' {{فعلل}} {{معجمية|L1536882|معاني}} === النطق === * {{أصد-عر|سَرْسَرَ}} {{-}} === التصريفات === {{تصريف|جذر=سرسر|وزن=فعلل}} === المراجع === {{مراجع}} rrv8k8ilgrofq30km3svsrojzv4dn0t اِجْتَأَفَ 0 240205 1097097 2026-07-21T20:22:30Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097097 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533695}} === المعاني === '''اِجْتَأَفَ''' {{افتعل}} {{معجمية|L1533695|معاني}} === النطق === * {{أصد-عر|اِجْتَأَفَ}} {{-}} === التصريفات === {{تصريف|جذر=جأف|وزن=افتعل}} === المراجع === {{مراجع}} hsfuaroaf7r2jj3bd4ydihlfrgwc0a0 اِجْتَرَدَ 0 240206 1097098 2026-07-21T20:22:51Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097098 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533847}} === المعاني === '''اِجْتَرَدَ''' {{افتعل}} {{معجمية|L1533847|معاني}} === النطق === * {{أصد-عر|اِجْتَرَدَ}} {{-}} === التصريفات === {{تصريف|جذر=جرد|وزن=افتعل}} === المراجع === {{مراجع}} 73lbhysj3vv9v0vyelj3p1s2n70dzu8 اِجْتَفَتَ 0 240207 1097099 2026-07-21T20:23:26Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097099 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533975}} === المعاني === '''اِجْتَفَتَ''' {{افتعل}} {{معجمية|L1533975|معاني}} === النطق === * {{أصد-عر|اِجْتَفَتَ}} {{-}} === التصريفات === {{تصريف|جذر=جفت|وزن=افتعل}} === المراجع === {{مراجع}} m7ru2qmmnlkz9vbx7trdwvv5w6sj7on تَجَالَعَ 0 240208 1097100 2026-07-21T20:23:58Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097100 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534028}} === المعاني === '''تَجَالَعَ''' {{تفاعل}} {{معجمية|L1534028|معاني}} === النطق === * {{أصد-عر|تَجَالَعَ}} {{-}} === التصريفات === {{تصريف|جذر=جلع|وزن=تفاعل}} === المراجع === {{مراجع}} f0lhnys26geojz8a11vmn8a15h1ua0r اِجْلَعَدَّ 0 240209 1097101 2026-07-21T20:24:29Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097101 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1483797}} === المعاني === '''اِجْلَعَدَّ''' {{افعللّ}} {{معجمية|L1483797|معاني}} === النطق === * {{أصد-عر|اِجْلَعَدَّ}} {{-}} === التصريفات === {{تصريف|جذر=جلعد|وزن=افعللّ}} === المراجع === {{مراجع}} q06yc84lc63rm7fq1275n4wsgwpvthf جَلْفَنَ 0 240210 1097102 2026-07-21T20:24:49Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097102 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534038}} === المعاني === '''جَلْفَنَ''' {{فعلل}} {{معجمية|L1534038|معاني}} === النطق === * {{أصد-عر|جَلْفَنَ}} {{-}} === التصريفات === {{تصريف|جذر=جلفن|وزن=فعلل}} === المراجع === {{مراجع}} j2swek3q1dj5bocb3yqtwy1n8l6afqo جَلْمَقَ 0 240211 1097103 2026-07-21T20:25:21Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097103 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534046}} === المعاني === '''جَلْمَقَ''' {{فعلل}} {{معجمية|L1534046|معاني}} === النطق === * {{أصد-عر|جَلْمَقَ}} {{-}} === التصريفات === {{تصريف|جذر=جلمق|وزن=فعلل}} === المراجع === {{مراجع}} 6azkhj1bltbiko1shqt00b0gk4q3do5 جَلْوَزَ 0 240212 1097104 2026-07-21T20:25:56Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097104 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534051}} === المعاني === '''جَلْوَزَ''' {{فعلل}} {{معجمية|L1534051|معاني}} === النطق === * {{أصد-عر|جَلْوَزَ}} {{-}} === التصريفات === {{تصريف|جذر=جلوز|وزن=فعلل}} === المراجع === {{مراجع}} jce0b0fgmjzblozhhr580c4gh2rqaqu جَمُدَ 0 240213 1097105 2026-07-21T20:26:30Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097105 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1545476}} === المعاني === '''جَمُدَ''' {{كرم}} {{معجمية|L1545476|معاني}} === النطق === * {{أصد-عر|جَمُدَ}} {{-}} === التصريفات === {{تصريف|جذر=جمد|وزن=فعُل يفعُل}} === المراجع === {{مراجع}} cfoyape604q0zepdaohwvmcfn5n76lt جَمْرَكَ 0 240214 1097106 2026-07-21T20:26:50Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097106 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534062}} === المعاني === '''جَمْرَكَ''' {{فعلل}} {{معجمية|L1534062|معاني}} === النطق === * {{أصد-عر|جَمْرَكَ}} {{-}} === التصريفات === {{تصريف|جذر=جمرك|وزن=فعلل}} === المراجع === {{مراجع}} h1mfbknj89owt7nf2hih8ydknjoum5j جَلَّى 0 240215 1097107 2026-07-21T20:29:06Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097107 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1495160}} === المعاني === '''جَلَّى''' {{فعّل}} {{معجمية|L1495160|معاني}} === النطق === * {{أصد-عر|جَلَّى}} {{-}} === التصريفات === {{تصريف|جذر=جلي|وزن=فعّل}} === المراجع === {{مراجع}} owowe4khou7f79enzoapjua4b6bkeig جَلَغَ 0 240216 1097109 2026-07-21T20:56:38Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097109 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1502479}} === المعاني === '''جَلَغَ''' {{فتح}} {{معجمية|L1502479|معاني}} === النطق === * {{أصد-عر|جَلَغَ}} {{-}} === التصريفات === {{تصريف|جذر=جلغ|وزن=فعَل يفعَل}} === المراجع === {{مراجع}} nehvf521zkpmkh4esrtuzlitng23nqv جَلْفَطَ 0 240217 1097110 2026-07-21T21:00:30Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097110 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534036}} === المعاني === '''جَلْفَطَ''' {{فعلل}} {{معجمية|L1534036|معاني}} === النطق === * {{أصد-عر|جَلْفَطَ}} {{-}} === التصريفات === {{تصريف|جذر=جلفط|وزن=فعلل}} === المراجع === {{مراجع}} 62jr9ng3jocdxl33t2yn004q0sjxkq4 اِجْلَنْفَعَ 0 240218 1097111 2026-07-21T21:02:17Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097111 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1485720}} === المعاني === '''اِجْلَنْفَعَ''' {{افعنلل}} {{معجمية|L1485720|معاني}} === النطق === * {{أصد-عر|اِجْلَنْفَعَ}} {{-}} === التصريفات === {{تصريف|جذر=جلفع|وزن=افعنلل}} === المراجع === {{مراجع}} tr81c9r4c3opk65v84k8ggs40rftead جَلْهَزَ 0 240219 1097112 2026-07-21T21:05:00Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097112 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534047}} === المعاني === '''جَلْهَزَ''' {{فعلل}} {{معجمية|L1534047|معاني}} === النطق === * {{أصد-عر|جَلْهَزَ}} {{-}} === التصريفات === {{تصريف|جذر=جلهز|وزن=فعلل}} === المراجع === {{مراجع}} em2rnpdm0buzrlgkbqu9jm31icr8ayh جَلْفَظَ 0 240220 1097113 2026-07-21T21:06:13Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097113 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534037}} === المعاني === '''جَلْفَظَ''' {{فعلل}} {{معجمية|L1534037|معاني}} === النطق === * {{أصد-عر|جَلْفَظَ}} {{-}} === التصريفات === {{تصريف|جذر=جلفظ|وزن=فعلل}} === المراجع === {{مراجع}} loxjpnl9cz96acmfrmukgw2fbz3vnwi جَلْهَقَ 0 240221 1097114 2026-07-21T21:09:35Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097114 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534048}} === المعاني === '''جَلْهَقَ''' {{فعلل}} {{معجمية|L1534048|معاني}} === النطق === * {{أصد-عر|جَلْهَقَ}} {{-}} === التصريفات === {{تصريف|جذر=جلهق|وزن=فعلل}} === المراجع === {{مراجع}} 3h1rmbefeebc978lkmme69l217q2v7h تَجَمْجَمَ 0 240222 1097115 2026-07-21T21:16:44Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097115 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534053}} === المعاني === '''تَجَمْجَمَ''' {{تفعلل}} {{معجمية|L1534053|معاني}} === النطق === * {{أصد-عر|تَجَمْجَمَ}} {{-}} === التصريفات === {{تصريف|جذر=جمجم|وزن=تفعلل}} === المراجع === {{مراجع}} 3ufibuwjyrdv92yp3nv12kxfmr41fjy اِنْجَمَخَ 0 240223 1097116 2026-07-21T21:22:09Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097116 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534055}} === المعاني === '''اِنْجَمَخَ''' {{انفعل}} {{معجمية|L1534055|معاني}} === النطق === * {{أصد-عر|اِنْجَمَخَ}} {{-}} === التصريفات === {{تصريف|جذر=جمخ|وزن=انفعل}} === المراجع === {{مراجع}} h6rhw7uflyxwve5c07i5k2uugxnbwgk اِجْتَمَرَ 0 240224 1097117 2026-07-21T21:23:31Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097117 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1476635}} === المعاني === '''اِجْتَمَرَ''' {{افتعل}} {{معجمية|L1476635|معاني}} === النطق === * {{أصد-عر|اِجْتَمَرَ}} {{-}} === التصريفات === {{تصريف|جذر=جمر|وزن=افتعل}} === المراجع === {{مراجع}} 3l20sxyu6fud7bl8v08mlcikvvwvpbm جَمْعَلَ 0 240225 1097118 2026-07-21T21:30:29Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097118 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534067}} === المعاني === '''جَمْعَلَ''' {{فعلل}} {{معجمية|L1534067|معاني}} === النطق === * {{أصد-عر|جَمْعَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جمعل|وزن=فعلل}} === المراجع === {{مراجع}} hn3ropd59rr2qs6pa5acz731h3a95ok اِجْتَنَأَ 0 240226 1097119 2026-07-21T21:32:19Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097119 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534074}} === المعاني === '''اِجْتَنَأَ''' {{افتعل}} {{معجمية|L1534074|معاني}} === النطق === * {{أصد-عر|اِجْتَنَأَ}} {{-}} === التصريفات === {{تصريف|جذر=جنأ|وزن=افتعل}} === المراجع === {{مراجع}} 4ri6yrz52ult589ffjddz6jbeoe160s تَجَانَأَ 0 240227 1097120 2026-07-21T21:36:42Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097120 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534075}} === المعاني === '''تَجَانَأَ''' {{تفاعل}} {{معجمية|L1534075|معاني}} === النطق === * {{أصد-عر|تَجَانَأَ}} {{-}} === التصريفات === {{تصريف|جذر=جنأ|وزن=تفاعل}} === المراجع === {{مراجع}} 44t24th2moox7udqnztcf3vjyubj1vb اِسْتَأْلَهَ 0 240228 1097121 2026-07-21T21:39:04Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097121 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532710}} === المعاني === '''اِسْتَأْلَهَ''' {{استفعل}} {{معجمية|L1532710|معاني}} === النطق === * {{أصد-عر|اِسْتَأْلَهَ}} {{-}} === التصريفات === {{تصريف|جذر=أله|وزن=استفعل}} === المراجع === {{مراجع}} jwjx6e045ompz7z8ehhp6nek3sjg1fp أَمُوَ 0 240229 1097122 2026-07-21T21:39:25Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097122 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1487312}} === المعاني === '''أَمُوَ''' {{كرم}} {{معجمية|L1487312|معاني}} === النطق === * {{أصد-عر|أَمُوَ}} {{-}} === التصريفات === {{تصريف|جذر=أمو|وزن=فعُل يفعُل}} === المراجع === {{مراجع}} qmtic6i7btttandbekrhaoomfk9he64 اِبْثَأَجَّ 0 240230 1097123 2026-07-21T21:39:50Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097123 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532784}} === المعاني === '''اِبْثَأَجَّ''' {{افعللّ}} {{معجمية|L1532784|معاني}} === النطق === * {{أصد-عر|اِبْثَأَجَّ}} {{-}} === التصريفات === {{تصريف|جذر=بثأج|وزن=افعللّ}} === المراجع === {{مراجع}} b88579cx96q7bmfv8i0ukjusx37bag2 بَثَا 0 240231 1097124 2026-07-21T21:40:23Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097124 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1544406}} === المعاني === '''بَثَا''' {{نصر}} {{معجمية|L1544406|معاني}} === النطق === * {{أصد-عر|بَثَا}} {{-}} === التصريفات === {{تصريف|جذر=بثو|وزن=فعَل يفعُل}} === المراجع === {{مراجع}} e4dt9uy8wjgklji07nzn8tkmbd452yy اِبْتَحَّ 0 240232 1097125 2026-07-21T21:40:48Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097125 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532822}} === المعاني === '''اِبْتَحَّ''' {{افتعل}} {{معجمية|L1532822|معاني}} === النطق === * {{أصد-عر|اِبْتَحَّ}} {{-}} === التصريفات === {{تصريف|جذر=بحح|وزن=افتعل}} === المراجع === {{مراجع}} 9ij7m0wzbllvtplvsnjrhl4h0xtm0rp جَانَأَ 0 240233 1097126 2026-07-21T21:41:07Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097126 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534076}} === المعاني === '''جَانَأَ''' {{فاعل}} {{معجمية|L1534076|معاني}} === النطق === * {{أصد-عر|جَانَأَ}} {{-}} === التصريفات === {{تصريف|جذر=جنأ|وزن=فاعل}} === المراجع === {{مراجع}} 3y8esw1a94bn3ol37y9ev1x6jbnvy19 بَخَّتَ 0 240234 1097127 2026-07-21T21:41:24Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097127 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532830}} === المعاني === '''بَخَّتَ''' {{فعّل}} {{معجمية|L1532830|معاني}} === النطق === * {{أصد-عر|بَخَّتَ}} {{-}} === التصريفات === {{تصريف|جذر=بخت|وزن=فعّل}} === المراجع === {{مراجع}} srw73s6c0xqmx9ulw6apa3d2ei8iy92 بَخْنَقَ 0 240235 1097128 2026-07-21T21:41:53Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097128 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532851}} === المعاني === '''بَخْنَقَ''' {{فعلل}} {{معجمية|L1532851|معاني}} === النطق === * {{أصد-عر|بَخْنَقَ}} {{-}} === التصريفات === {{تصريف|جذر=بخنق|وزن=فعلل}} === المراجع === {{مراجع}} 532bx8cl1j7y47mu17kg9uoakr141bs بَدَسَ 0 240236 1097129 2026-07-21T21:42:14Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097129 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1502504}} === المعاني === '''بَدَسَ''' {{نصر}} {{معجمية|L1502504|معاني}} === النطق === * {{أصد-عر|بَدَسَ}} {{-}} === التصريفات === {{تصريف|جذر=بدس|وزن=فعَل يفعُل}} === المراجع === {{مراجع}} d9hgs9r2vlw2qs5p2skr3r8o25p58n7 أَبْخَى 0 240237 1097130 2026-07-21T21:42:34Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097130 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532853}} === المعاني === '''أَبْخَى''' {{أفعل}} {{معجمية|L1532853|معاني}} === النطق === * {{أصد-عر|أَبْخَى}} {{-}} === التصريفات === {{تصريف|جذر=بخو|وزن=أفعل}} === المراجع === {{مراجع}} ll530756yuk4nq3cjiw8wfcjkjvgxqa أَبْذَأَ 0 240238 1097131 2026-07-21T21:43:11Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097131 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1497559}} === المعاني === '''أَبْذَأَ''' {{أفعل}} {{معجمية|L1497559|معاني}} === النطق === * {{أصد-عر|أَبْذَأَ}} {{-}} === التصريفات === {{تصريف|جذر=بذأ|وزن=أفعل}} === المراجع === {{مراجع}} n0g4hu47v27gga7ezczarm40q0qrcta اِسْتَجْنَبَ 0 240239 1097132 2026-07-21T21:44:05Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097132 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534078}} === المعاني === '''اِسْتَجْنَبَ''' {{استفعل}} {{معجمية|L1534078|معاني}} === النطق === * {{أصد-عر|اِسْتَجْنَبَ}} {{-}} === التصريفات === {{تصريف|جذر=جنب|وزن=استفعل}} === المراجع === {{مراجع}} bevuor55ll2anav7eqkzn0sp7vlrvkw سَعَى 0 240240 1097133 2026-07-21T21:46:58Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097133 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1488761}} === المعاني === '''سَعَى''' {{فتح}} {{معجمية|L1488761|معاني}} === النطق === * {{أصد-عر|سَعَى}} {{-}} === التصريفات === {{تصريف|جذر=سعي|وزن=فعَل يفعَل}} === المراجع === {{مراجع}} ha694r9xdqbrr7uhyhgjmfldsoz1jfc تَسَاعَى 0 240241 1097134 2026-07-21T21:47:30Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097134 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536937}} === المعاني === '''تَسَاعَى''' {{تفاعل}} {{معجمية|L1536937|معاني}} === النطق === * {{أصد-عر|تَسَاعَى}} {{-}} === التصريفات === {{تصريف|جذر=سعي|وزن=تفاعل}} === المراجع === {{مراجع}} f1btbaivl7775s9f9lvytpeftiinffx اِسْتَفَتَ 0 240242 1097135 2026-07-21T21:48:09Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097135 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536945}} === المعاني === '''اِسْتَفَتَ''' {{افتعل}} {{معجمية|L1536945|معاني}} === النطق === * {{أصد-عر|اِسْتَفَتَ}} {{-}} === التصريفات === {{تصريف|جذر=سفت|وزن=افتعل}} === المراجع === {{مراجع}} 0eu44w626b2dwpu4ayquaoonn16kw37 سَفْتَجَ 0 240243 1097136 2026-07-21T21:48:46Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097136 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536946}} === المعاني === '''سَفْتَجَ''' {{فعلل}} {{معجمية|L1536946|معاني}} === النطق === * {{أصد-عر|سَفْتَجَ}} {{-}} === التصريفات === {{تصريف|جذر=سفتج|وزن=فعلل}} === المراجع === {{مراجع}} bzogmei9d5m2qxhmbb6plxit2dkiimf سَفْسَطَ 0 240244 1097137 2026-07-21T21:49:19Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097137 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1492061}} === المعاني === '''سَفْسَطَ''' {{فعلل}} {{معجمية|L1492061|معاني}} === النطق === * {{أصد-عر|سَفْسَطَ}} {{-}} === التصريفات === {{تصريف|جذر=سفسط|وزن=فعلل}} === المراجع === {{مراجع}} krebjnuubhcpdrlp44f1u0wrrsp9hli سَغْسَغَ 0 240245 1097138 2026-07-21T21:51:10Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097138 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536941}} === المعاني === '''سَغْسَغَ''' {{فعلل}} {{معجمية|L1536941|معاني}} === النطق === * {{أصد-عر|سَغْسَغَ}} {{-}} === التصريفات === {{تصريف|جذر=سغسغ|وزن=فعلل}} === المراجع === {{مراجع}} 8hny8dqt1zldjuzpjgl9i3jcmz3oa80 سَاكَتَ 0 240246 1097139 2026-07-21T21:51:44Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097139 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536997}} === المعاني === '''سَاكَتَ''' {{فاعل}} {{معجمية|L1536997|معاني}} === النطق === * {{أصد-عر|سَاكَتَ}} {{-}} === التصريفات === {{تصريف|جذر=سكت|وزن=فاعل}} === المراجع === {{مراجع}} crd8xtq0fisl9onz52ztlnrvnguqdb7 سَكْبَجَ 0 240247 1097140 2026-07-21T21:52:08Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097140 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536995}} === المعاني === '''سَكْبَجَ''' {{فعلل}} {{معجمية|L1536995|معاني}} === النطق === * {{أصد-عر|سَكْبَجَ}} {{-}} === التصريفات === {{تصريف|جذر=سكبج|وزن=فعلل}} === المراجع === {{مراجع}} m9pio255q8zxp3wzmtxobotr7d9hl15 سَقَى 0 240248 1097141 2026-07-21T21:55:41Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097141 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1157102}} === المعاني === '''سَقَى''' {{ضرب}} {{معجمية|L1157102|معاني}} === النطق === * {{أصد-عر|سَقَى}} {{-}} === التصريفات === {{تصريف|جذر=سقي|وزن=فعَل يفعِل}} === المراجع === {{مراجع}} 9xwq81huuwwq42mu4tskwl6ukayeqph أَسْقَى 0 240249 1097142 2026-07-21T21:57:52Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097142 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1476963}} === المعاني === '''أَسْقَى''' {{أفعل}} {{معجمية|L1476963|معاني}} === النطق === * {{أصد-عر|أَسْقَى}} {{-}} === التصريفات === {{تصريف|جذر=سقي|وزن=أفعل}} === المراجع === {{مراجع}} 0aixu9bpwfpmwv3yuc51ig3yjcd51pt أَسْفَى 0 240250 1097143 2026-07-21T22:00:43Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097143 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536976}} === المعاني === '''أَسْفَى''' {{أفعل}} {{معجمية|L1536976|معاني}} === النطق === * {{أصد-عر|أَسْفَى}} {{-}} === التصريفات === {{تصريف|جذر=سفي|وزن=أفعل}} === المراجع === {{مراجع}} p2r4b9f35cca9f4pdghrxdgwqzv25nw تَسَفَّرَ 0 240251 1097144 2026-07-21T22:02:48Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097144 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536955}} === المعاني === '''تَسَفَّرَ''' {{تفعّل}} {{معجمية|L1536955|معاني}} === النطق === * {{أصد-عر|تَسَفَّرَ}} {{-}} === التصريفات === {{تصريف|جذر=سفر|وزن=تفعّل}} === المراجع === {{مراجع}} a3trremk5tce82j5rjptpxsx50qhcji تَسَغْبَلَ 0 240252 1097145 2026-07-21T22:03:50Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097145 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536940}} === المعاني === '''تَسَغْبَلَ''' {{تفعلل}} {{معجمية|L1536940|معاني}} === النطق === * {{أصد-عر|تَسَغْبَلَ}} {{-}} === التصريفات === {{تصريف|جذر=سغبل|وزن=تفعلل}} === المراجع === {{مراجع}} 58lv1tmhpcb1r2km2uozescs9x4ibgc تَسَفَّدَ 0 240253 1097146 2026-07-21T22:04:22Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097146 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1497593}} === المعاني === '''تَسَفَّدَ''' {{تفعّل}} {{معجمية|L1497593|معاني}} === النطق === * {{أصد-عر|تَسَفَّدَ}} {{-}} === التصريفات === {{تصريف|جذر=سفد|وزن=تفعّل}} === المراجع === {{مراجع}} 6avz8qrrawya42rlg965rf19ya9exnb تَسَفْسَفَ 0 240254 1097147 2026-07-21T22:04:41Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097147 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536956}} === المعاني === '''تَسَفْسَفَ''' {{تفعلل}} {{معجمية|L1536956|معاني}} === النطق === * {{أصد-عر|تَسَفْسَفَ}} {{-}} === التصريفات === {{تصريف|جذر=سفسف|وزن=تفعلل}} === المراجع === {{مراجع}} sy7rhxcqocl628cmdftwth036cgq2bj آلَسَ 0 240255 1097148 2026-07-21T22:55:31Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097148 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532704}} === المعاني === '''آلَسَ''' {{فاعل}} {{معجمية|L1532704|معاني}} === النطق === * {{أصد-عر|آلَسَ}} {{-}} === التصريفات === {{تصريف|جذر=ألس|وزن=فاعل}} === المراجع === {{مراجع}} bl1z3ubhdemira7j9i6ir7hg434ldk3 تَبَاثَّ 0 240256 1097149 2026-07-21T22:55:56Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097149 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532788}} === المعاني === '''تَبَاثَّ''' {{تفاعل}} {{معجمية|L1532788|معاني}} === النطق === * {{أصد-عر|تَبَاثَّ}} {{-}} === التصريفات === {{تصريف|جذر=بثث|وزن=تفاعل}} === المراجع === {{مراجع}} styc8tww09dt3u2tkuwzu2exbyikd46 تَبَحْثَرَ 0 240257 1097150 2026-07-21T22:56:26Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097150 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1484702}} === المعاني === '''تَبَحْثَرَ''' {{تفعلل}} {{معجمية|L1484702|معاني}} === النطق === * {{أصد-عر|تَبَحْثَرَ}} {{-}} === التصريفات === {{تصريف|جذر=بحثر|وزن=تفعلل}} === المراجع === {{مراجع}} dp4uo0m5xinoub55j4gmeg381rvlok7 بَحَّحَ 0 240258 1097151 2026-07-21T22:56:46Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097151 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532823}} === المعاني === '''بَحَّحَ''' {{فعّل}} {{معجمية|L1532823|معاني}} === النطق === * {{أصد-عر|بَحَّحَ}} {{-}} === التصريفات === {{تصريف|جذر=بحح|وزن=فعّل}} === المراجع === {{مراجع}} 16yea9rmq2zsimh56bxsyyamoj1jvkg تَبَخْضَلَ 0 240259 1097152 2026-07-21T22:57:07Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097152 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532841}} === المعاني === '''تَبَخْضَلَ''' {{تفعلل}} {{معجمية|L1532841|معاني}} === النطق === * {{أصد-عر|تَبَخْضَلَ}} {{-}} === التصريفات === {{تصريف|جذر=بخضل|وزن=تفعلل}} === المراجع === {{مراجع}} rm787ax4h204pb4e5ciypujwq00g8q7 اِبْتَدَهَ 0 240260 1097153 2026-07-21T22:57:25Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097153 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532868}} === المعاني === '''اِبْتَدَهَ''' {{افتعل}} {{معجمية|L1532868|معاني}} === النطق === * {{أصد-عر|اِبْتَدَهَ}} {{-}} === التصريفات === {{تصريف|جذر=بده|وزن=افتعل}} === المراجع === {{مراجع}} hpfwtgmt9kcilbeb53ngutzl9o3cihn تَبَخْنَقَ 0 240261 1097154 2026-07-21T22:57:46Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097154 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532852}} === المعاني === '''تَبَخْنَقَ''' {{تفعلل}} {{معجمية|L1532852|معاني}} === النطق === * {{أصد-عر|تَبَخْنَقَ}} {{-}} === التصريفات === {{تصريف|جذر=بخنق|وزن=تفعلل}} === المراجع === {{مراجع}} f6dkew3m5y2ibekow9nqc32ft17ts8u بَدَّى 0 240262 1097155 2026-07-21T22:58:05Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097155 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532873}} === المعاني === '''بَدَّى''' {{فعّل}} {{معجمية|L1532873|معاني}} === النطق === * {{أصد-عر|بَدَّى}} {{-}} === التصريفات === {{تصريف|جذر=بدو|وزن=فعّل}} === المراجع === {{مراجع}} lk12dsp4oh7ky9m5c3wxurjbbubtwn3 بَاذَأَ 0 240263 1097156 2026-07-21T22:58:46Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097156 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532875}} === المعاني === '''بَاذَأَ''' {{فاعل}} {{معجمية|L1532875|معاني}} === النطق === * {{أصد-عر|بَاذَأَ}} {{-}} === التصريفات === {{تصريف|جذر=بذأ|وزن=فاعل}} === المراجع === {{مراجع}} 4ztocsif4ekkdpv49w0n422x98evoul اِسْتَبْذَرَ 0 240264 1097157 2026-07-21T22:59:02Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097157 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532883}} === المعاني === '''اِسْتَبْذَرَ''' {{استفعل}} {{معجمية|L1532883|معاني}} === النطق === * {{أصد-عر|اِسْتَبْذَرَ}} {{-}} === التصريفات === {{تصريف|جذر=بذر|وزن=استفعل}} === المراجع === {{مراجع}} 53drmmbft9vy6lwbkv01f3ataf4gagd اِنْبَذَرَ 0 240265 1097158 2026-07-21T22:59:20Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097158 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532884}} === المعاني === '''اِنْبَذَرَ''' {{انفعل}} {{معجمية|L1532884|معاني}} === النطق === * {{أصد-عر|اِنْبَذَرَ}} {{-}} === التصريفات === {{تصريف|جذر=بذر|وزن=انفعل}} === المراجع === {{مراجع}} 6qzylsa4w3j3wdxmx8gq9y9ydz5j4yb أَبْذَعَ 0 240266 1097159 2026-07-21T22:59:50Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097159 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532888}} === المعاني === '''أَبْذَعَ''' {{أفعل}} {{معجمية|L1532888|معاني}} === النطق === * {{أصد-عر|أَبْذَعَ}} {{-}} === التصريفات === {{تصريف|جذر=بذع|وزن=أفعل}} === المراجع === {{مراجع}} ekel3mggwjm5fmlt4s5uy307mfcfm3d بَذْلَخَ 0 240267 1097160 2026-07-21T23:00:16Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097160 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532895}} === المعاني === '''بَذْلَخَ''' {{فعلل}} {{معجمية|L1532895|معاني}} === النطق === * {{أصد-عر|بَذْلَخَ}} {{-}} === التصريفات === {{تصريف|جذر=بذلخ|وزن=فعلل}} === المراجع === {{مراجع}} 0vx2qciq68fjzs4j30dcs3jia1rck59 أَبْذَمَ 0 240268 1097161 2026-07-21T23:00:47Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097161 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532896}} === المعاني === '''أَبْذَمَ''' {{أفعل}} {{معجمية|L1532896|معاني}} === النطق === * {{أصد-عر|أَبْذَمَ}} {{-}} === التصريفات === {{تصريف|جذر=بذم|وزن=أفعل}} === المراجع === {{مراجع}} nztu0yqg54yi82b7dwcp7sjts8owlca تَبَارَأَ 0 240269 1097162 2026-07-21T23:01:25Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097162 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532899}} === المعاني === '''تَبَارَأَ''' {{تفاعل}} {{معجمية|L1532899|معاني}} === النطق === * {{أصد-عر|تَبَارَأَ}} {{-}} === التصريفات === {{تصريف|جذر=برأ|وزن=تفاعل}} === المراجع === {{مراجع}} a0kyxbjk3lkmk3d5ja4g74f0b30ze4w تَبَرَّأَ 0 240270 1097163 2026-07-21T23:01:54Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097163 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L305151}} === المعاني === '''تَبَرَّأَ''' {{تفعّل}} {{معجمية|L305151|معاني}} === النطق === * {{أصد-عر|تَبَرَّأَ}} {{-}} === التصريفات === {{تصريف|جذر=برأ|وزن=تفعّل}} === المراجع === {{مراجع}} 203j37x7mn0acn4xi1cw53p50mqer3n تَبَرْبَرَ 0 240271 1097164 2026-07-21T23:02:09Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097164 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532904}} === المعاني === '''تَبَرْبَرَ''' {{تفعلل}} {{معجمية|L1532904|معاني}} === النطق === * {{أصد-عر|تَبَرْبَرَ}} {{-}} === التصريفات === {{تصريف|جذر=بربر|وزن=تفعلل}} === المراجع === {{مراجع}} i0vsroxwmh5h2bexmlagy5dtpdy6ukg بَرْبَسَ 0 240272 1097165 2026-07-21T23:02:31Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097165 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532905}} === المعاني === '''بَرْبَسَ''' {{فعلل}} {{معجمية|L1532905|معاني}} === النطق === * {{أصد-عر|بَرْبَسَ}} {{-}} === التصريفات === {{تصريف|جذر=بربس|وزن=فعلل}} === المراجع === {{مراجع}} 1ligp3qebdmzmbboef6nm1fpnqhwzii بَرْبَصَ 0 240273 1097166 2026-07-21T23:03:03Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097166 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532907}} === المعاني === '''بَرْبَصَ''' {{فعلل}} {{معجمية|L1532907|معاني}} === النطق === * {{أصد-عر|بَرْبَصَ}} {{-}} === التصريفات === {{تصريف|جذر=بربص|وزن=فعلل}} === المراجع === {{مراجع}} 41z9buoibs6k5s6t1rouzko2zwwre50 أَبْرَتَ 0 240274 1097167 2026-07-21T23:03:39Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097167 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532908}} === المعاني === '''أَبْرَتَ''' {{أفعل}} {{معجمية|L1532908|معاني}} === النطق === * {{أصد-عر|أَبْرَتَ}} {{-}} === التصريفات === {{تصريف|جذر=برت|وزن=أفعل}} === المراجع === {{مراجع}} hnyw2zo8nkij7wi4b2iub0a57wajt5g بَرِتَ 0 240275 1097168 2026-07-21T23:04:06Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097168 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1543519}} === المعاني === '''بَرِتَ''' {{سمع}} {{معجمية|L1543519|معاني}} === النطق === * {{أصد-عر|بَرِتَ}} {{-}} === التصريفات === {{تصريف|جذر=برت|وزن=فعِل يفعَل}} === المراجع === {{مراجع}} d7ol7ry9dxdncfdvd6m7jidmebopoqf بَرْتَكَ 0 240276 1097169 2026-07-21T23:04:49Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097169 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532909}} === المعاني === '''بَرْتَكَ''' {{فعلل}} {{معجمية|L1532909|معاني}} === النطق === * {{أصد-عر|بَرْتَكَ}} {{-}} === التصريفات === {{تصريف|جذر=برتك|وزن=فعلل}} === المراجع === {{مراجع}} jia0wc1m25ke6gfdd488vhuejwdkyz7 بَرْجَمَ 0 240277 1097170 2026-07-21T23:05:12Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097170 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532914}} === المعاني === '''بَرْجَمَ''' {{فعلل}} {{معجمية|L1532914|معاني}} === النطق === * {{أصد-عر|بَرْجَمَ}} {{-}} === التصريفات === {{تصريف|جذر=برجم|وزن=فعلل}} === المراجع === {{مراجع}} 7vhfoa2e49u749vluoqh7x8u23jnd97 تَبَارَدَ 0 240278 1097171 2026-07-21T23:05:30Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097171 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532920}} === المعاني === '''تَبَارَدَ''' {{تفاعل}} {{معجمية|L1532920|معاني}} === النطق === * {{أصد-عر|تَبَارَدَ}} {{-}} === التصريفات === {{تصريف|جذر=برد|وزن=تفاعل}} === المراجع === {{مراجع}} p71b55thq1feim4aoe6blke9fj1hgwi اِبْرَنْدَعَ 0 240279 1097172 2026-07-21T23:05:53Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097172 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532922}} === المعاني === '''اِبْرَنْدَعَ''' {{افعنلل}} {{معجمية|L1532922|معاني}} === النطق === * {{أصد-عر|اِبْرَنْدَعَ}} {{-}} === التصريفات === {{تصريف|جذر=بردع|وزن=افعنلل}} === المراجع === {{مراجع}} oua5ii0jffky344f1hv2b2r6qzp1neg تَبَارَّ 0 240280 1097173 2026-07-21T23:06:14Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097173 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532926}} === المعاني === '''تَبَارَّ''' {{تفاعل}} {{معجمية|L1532926|معاني}} === النطق === * {{أصد-عر|تَبَارَّ}} {{-}} === التصريفات === {{تصريف|جذر=برر|وزن=تفاعل}} === المراجع === {{مراجع}} rsar5ej3swvhrv1g5pklz077xn6xl7l بَرِزَ 0 240281 1097174 2026-07-21T23:06:35Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097174 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1544937}} === المعاني === '''بَرِزَ''' {{سمع}} {{معجمية|L1544937|معاني}} === النطق === * {{أصد-عر|بَرِزَ}} {{-}} === التصريفات === {{تصريف|جذر=برز|وزن=فعِل يفعَل}} === المراجع === {{مراجع}} mwwu7tpkknhb8mfn5ea78r5vh2h4jx3 بَرْشَطَ 0 240282 1097175 2026-07-21T23:07:11Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097175 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532933}} === المعاني === '''بَرْشَطَ''' {{فعلل}} {{معجمية|L1532933|معاني}} === النطق === * {{أصد-عر|بَرْشَطَ}} {{-}} === التصريفات === {{تصريف|جذر=برشط|وزن=فعلل}} === المراجع === {{مراجع}} 78wkcf4flrzjfo2o9pyurlx2zi5o3i2 تَبَرَّصَ 0 240283 1097176 2026-07-21T23:07:51Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097176 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532938}} === المعاني === '''تَبَرَّصَ''' {{تفعّل}} {{معجمية|L1532938|معاني}} === النطق === * {{أصد-عر|تَبَرَّصَ}} {{-}} === التصريفات === {{تصريف|جذر=برص|وزن=تفعّل}} === المراجع === {{مراجع}} o7qctr4b1rpl1q4kx7l2fv9v7ts0rbw بَرِعَ 0 240284 1097177 2026-07-21T23:08:13Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097177 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1544938}} === المعاني === '''بَرِعَ''' {{سمع}} {{معجمية|L1544938|معاني}} === النطق === * {{أصد-عر|بَرِعَ}} {{-}} === التصريفات === {{تصريف|جذر=برع|وزن=فعِل يفعَل}} === المراجع === {{مراجع}} cl3srrenmxl9to6579mjwj7bjuse20o أَبَصَّ 0 240285 1097178 2026-07-21T23:09:35Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097178 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533045}} === المعاني === '''أَبَصَّ''' {{أفعل}} {{معجمية|L1533045|معاني}} === النطق === * {{أصد-عر|أَبَصَّ}} {{-}} === التصريفات === {{تصريف|جذر=بصص|وزن=أفعل}} === المراجع === {{مراجع}} pb6ysv1cegb3c54c876mmf22kfcmbdp جَرْجَرَ 0 240286 1097179 2026-07-21T23:13:40Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097179 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1495140}} === المعاني === '''جَرْجَرَ''' {{فعلل}} {{معجمية|L1495140|معاني}} === النطق === * {{أصد-عر|جَرْجَرَ}} {{-}} === التصريفات === {{تصريف|جذر=جرجر|وزن=فعلل}} === المراجع === {{مراجع}} 216z88kexidvbcvmu38mptp4ettjnfb تَجَرَّدَ 0 240287 1097180 2026-07-21T23:15:14Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097180 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1486327}} === المعاني === '''تَجَرَّدَ''' {{تفعّل}} {{معجمية|L1486327|معاني}} === النطق === * {{أصد-عر|تَجَرَّدَ}} {{-}} === التصريفات === {{تصريف|جذر=جرد|وزن=تفعّل}} === المراجع === {{مراجع}} tjrkhythcv2ghcuqxxmx8bcdcqkzx81 جَلْجَلَ 0 240288 1097181 2026-07-21T23:17:20Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097181 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534000}} === المعاني === '''جَلْجَلَ''' {{فعلل}} {{معجمية|L1534000|معاني}} === النطق === * {{أصد-عر|جَلْجَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جلجل|وزن=فعلل}} === المراجع === {{مراجع}} 0kglm75er7khbwpa92j3ofipp46o2w5 اِجْلَعَبَّ 0 240289 1097182 2026-07-21T23:18:42Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097182 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1483748}} === المعاني === '''اِجْلَعَبَّ''' {{افعللّ}} {{معجمية|L1483748|معاني}} === النطق === * {{أصد-عر|اِجْلَعَبَّ}} {{-}} === التصريفات === {{تصريف|جذر=جلعب|وزن=افعللّ}} === المراجع === {{مراجع}} sl32q495x8rpmmni0jq66kzi03xifjn اِسْتَسْقَى 0 240290 1097183 2026-07-21T23:20:45Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097183 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1482647}} === المعاني === '''اِسْتَسْقَى''' {{استفعل}} {{معجمية|L1482647|معاني}} === النطق === * {{أصد-عر|اِسْتَسْقَى}} {{-}} === التصريفات === {{تصريف|جذر=سقي|وزن=استفعل}} === المراجع === {{مراجع}} i1frlt0s8xc53f74mdjx1kqiyzlv7e1 جَنَّصَ 0 240291 1097184 2026-07-21T23:22:20Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097184 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534088}} === المعاني === '''جَنَّصَ''' {{فعّل}} {{معجمية|L1534088|معاني}} === النطق === * {{أصد-عر|جَنَّصَ}} {{-}} === التصريفات === {{تصريف|جذر=جنص|وزن=فعّل}} === المراجع === {{مراجع}} eh9g9ll9faospki9zm544pj6m2r26m7 جَنَشَ 0 240292 1097185 2026-07-21T23:24:35Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097185 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1544787}} === المعاني === '''جَنَشَ''' {{ضرب}} {{معجمية|L1544787|معاني}} === النطق === * {{أصد-عر|جَنَشَ}} {{-}} === التصريفات === {{تصريف|جذر=جنش|وزن=فعَل يفعِل}} === المراجع === {{مراجع}} qfbsr6l1c5r8zb3gq79hc8p196k4v5p أَجْهَى 0 240293 1097186 2026-07-21T23:26:27Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097186 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534110}} === المعاني === '''أَجْهَى''' {{أفعل}} {{معجمية|L1534110|معاني}} === النطق === * {{أصد-عر|أَجْهَى}} {{-}} === التصريفات === {{تصريف|جذر=جهي|وزن=أفعل}} === المراجع === {{مراجع}} 8ai7m8yvabxr96vilxaxoqzdoix6gzx حَوْقَلَ 0 240294 1097187 2026-07-21T23:29:29Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097187 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1492114}} === المعاني === '''حَوْقَلَ''' {{فعلل}} {{معجمية|L1492114|معاني}} === النطق === * {{أصد-عر|حَوْقَلَ}} {{-}} === التصريفات === {{تصريف|جذر=حوقل|وزن=فعلل}} === المراجع === {{مراجع}} 7l6vcztgfo0yw9o90g5eo661ofizlpe أَحَالَ 0 240295 1097188 2026-07-21T23:31:49Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097188 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1491674}} === المعاني === '''أَحَالَ''' {{أفعل}} {{معجمية|L1491674|معاني}} === النطق === * {{أصد-عر|أَحَالَ}} {{-}} === التصريفات === {{تصريف|جذر=حول|وزن=أفعل}} === المراجع === {{مراجع}} 20gfjpfs18ib0cmyeg6w4kv5mol6g0s اِخْتَرَقَ 0 240296 1097189 2026-07-21T23:33:56Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097189 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1484285}} === المعاني === '''اِخْتَرَقَ''' {{افتعل}} {{معجمية|L1484285|معاني}} === النطق === * {{أصد-عر|اِخْتَرَقَ}} {{-}} === التصريفات === {{تصريف|جذر=خرق|وزن=افتعل}} === المراجع === {{مراجع}} 2353ojn9dbq8y7uwltcm79oterir6b2 اِخْتَضَرَ 0 240297 1097190 2026-07-21T23:36:15Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097190 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535047}} === المعاني === '''اِخْتَضَرَ''' {{افتعل}} {{معجمية|L1535047|معاني}} === النطق === * {{أصد-عر|اِخْتَضَرَ}} {{-}} === التصريفات === {{تصريف|جذر=خضر|وزن=افتعل}} === المراجع === {{مراجع}} japlghzfxzfra74nzu8hx1szeeupefu اِخْتَلَّ 0 240298 1097191 2026-07-21T23:38:14Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097191 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1480278}} === المعاني === '''اِخْتَلَّ''' {{افتعل}} {{معجمية|L1480278|معاني}} === النطق === * {{أصد-عر|اِخْتَلَّ}} {{-}} === التصريفات === {{تصريف|جذر=خلل|وزن=افتعل}} === المراجع === {{مراجع}} bhz1jmljry1dacciyu4cnvlsnj74zfj تَخَلَّلَ 0 240299 1097192 2026-07-21T23:39:56Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097192 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535135}} === المعاني === '''تَخَلَّلَ''' {{تفعّل}} {{معجمية|L1535135|معاني}} === النطق === * {{أصد-عر|تَخَلَّلَ}} {{-}} === التصريفات === {{تصريف|جذر=خلل|وزن=تفعّل}} === المراجع === {{مراجع}} 7oadkoerjpm7146xch27efc8zs5cnk6 أَخْلَى 0 240300 1097193 2026-07-21T23:41:38Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097193 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1480746}} === المعاني === '''أَخْلَى''' {{أفعل}} {{معجمية|L1480746|معاني}} === النطق === * {{أصد-عر|أَخْلَى}} {{-}} === التصريفات === {{تصريف|جذر=خلو|وزن=أفعل}} === المراجع === {{مراجع}} q3gkzojcr1xsxb3vfgxjp3w4n889tqj خَوَّى 0 240301 1097194 2026-07-21T23:44:01Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097194 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535240}} === المعاني === '''خَوَّى''' {{فعّل}} {{معجمية|L1535240|معاني}} === النطق === * {{أصد-عر|خَوَّى}} {{-}} === التصريفات === {{تصريف|جذر=خوي|وزن=فعّل}} === المراجع === {{مراجع}} 5ibztezjhywjxmgakwvrt6t2p3lqm7a دَبَّحَ 0 240302 1097195 2026-07-21T23:46:23Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097195 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535267}} === المعاني === '''دَبَّحَ''' {{فعّل}} {{معجمية|L1535267|معاني}} === النطق === * {{أصد-عر|دَبَّحَ}} {{-}} === التصريفات === {{تصريف|جذر=دبح|وزن=فعّل}} === المراجع === {{مراجع}} a2itb6tcga85snzmvmbwmt21tgisyim دَمْدَمَ 0 240303 1097196 2026-07-21T23:49:56Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097196 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1489229}} === المعاني === '''دَمْدَمَ''' {{فعلل}} {{معجمية|L1489229|معاني}} === النطق === * {{أصد-عر|دَمْدَمَ}} {{-}} === التصريفات === {{تصريف|جذر=دمدم|وزن=فعلل}} === المراجع === {{مراجع}} jw3tuarq1aadq626xs0t2uamisq9288 دَمَّى 0 240304 1097197 2026-07-21T23:51:31Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097197 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1495283}} === المعاني === '''دَمَّى''' {{فعّل}} {{معجمية|L1495283|معاني}} === النطق === * {{أصد-عر|دَمَّى}} {{-}} === التصريفات === {{تصريف|جذر=دمي|وزن=فعّل}} === المراجع === {{مراجع}} c4v8u79emfw8n7ou0s9llw74961fbg6 رَدَسَ 0 240305 1097198 2026-07-21T23:54:15Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097198 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1488521}} === المعاني === '''رَدَسَ''' {{نصر}} {{معجمية|L1488521|معاني}} === النطق === * {{أصد-عر|رَدَسَ}} {{-}} === التصريفات === {{تصريف|جذر=ردس|وزن=فعَل يفعُل}} === المراجع === {{مراجع}} qzo0vsq86vl1j27qdmjv5ol6ukijctq رَدَمَ 0 240306 1097199 2026-07-21T23:57:20Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097199 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1477008}} === المعاني === '''رَدَمَ''' {{نصر}} {{معجمية|L1477008|معاني}} === النطق === * {{أصد-عر|رَدَمَ}} {{-}} === التصريفات === {{تصريف|جذر=ردم|وزن=فعَل يفعُل}} === المراجع === {{مراجع}} dy25ibyldjqvk0jwy82ch3lmg61ifh9 أَرْهَى 0 240307 1097200 2026-07-22T00:00:11Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097200 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536316}} === المعاني === '''أَرْهَى''' {{أفعل}} {{معجمية|L1536316|معاني}} === النطق === * {{أصد-عر|أَرْهَى}} {{-}} === التصريفات === {{تصريف|جذر=رهو|وزن=أفعل}} === المراجع === {{مراجع}} 7pv7b32uyguy2zwgk3t90t0znu316xx زَبَرَ 0 240308 1097201 2026-07-22T00:03:04Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097201 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1484549}} === المعاني === '''زَبَرَ''' {{نصر}} {{معجمية|L1484549|معاني}} === النطق === * {{أصد-عر|زَبَرَ}} {{-}} === التصريفات === {{تصريف|جذر=زبر|وزن=فعَل يفعُل}} === المراجع === {{مراجع}} qha2wtree1znkndd1gqddfz5km5llwy زَخَّ 0 240309 1097202 2026-07-22T00:06:21Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097202 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1480396}} === المعاني === '''زَخَّ''' {{نصر}} {{معجمية|L1480396|معاني}} === النطق === * {{أصد-عر|زَخَّ}} {{-}} === التصريفات === {{تصريف|جذر=زخخ|وزن=فعَل يفعُل}} === المراجع === {{مراجع}} 3fkl3umab1jsk5srmjyc8denk0700s6 زَخَرَ 0 240310 1097203 2026-07-22T00:10:21Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097203 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1497754}} === المعاني === '''زَخَرَ''' {{فتح}} {{معجمية|L1497754|معاني}} === النطق === * {{أصد-عر|زَخَرَ}} {{-}} === التصريفات === {{تصريف|جذر=زخر|وزن=فعَل يفعَل}} === المراجع === {{مراجع}} 29smav34s0k6mkywioa9v2129tj7hzx زَعَبَ 0 240311 1097204 2026-07-22T00:14:00Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097204 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1544992}} === المعاني === '''زَعَبَ''' {{فتح}} {{معجمية|L1544992|معاني}} === النطق === * {{أصد-عر|زَعَبَ}} {{-}} === التصريفات === {{تصريف|جذر=زعب|وزن=فعَل يفعَل}} === المراجع === {{مراجع}} 9vrpk8f55nqz8ni893l1xh2w3zfrghy زَمْزَمَ 0 240312 1097205 2026-07-22T00:17:07Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097205 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1477284}} === المعاني === '''زَمْزَمَ''' {{فعلل}} {{معجمية|L1477284|معاني}} === النطق === * {{أصد-عر|زَمْزَمَ}} {{-}} === التصريفات === {{تصريف|جذر=زمزم|وزن=فعلل}} === المراجع === {{مراجع}} 2prj4z5rq46pajbmkn87z6opqpysubs زَهَدَ 0 240313 1097206 2026-07-22T00:18:37Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097206 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1480459}} === المعاني === '''زَهَدَ''' {{فتح}} {{معجمية|L1480459|معاني}} === النطق === * {{أصد-عر|زَهَدَ}} {{-}} === التصريفات === {{تصريف|جذر=زهد|وزن=فعَل يفعَل}} === المراجع === {{مراجع}} 9bscm0w44ys0egde269vq6q42z5qnwj زَهُدَ 0 240314 1097207 2026-07-22T00:19:10Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097207 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1544835}} === المعاني === '''زَهُدَ''' {{كرم}} {{معجمية|L1544835|معاني}} === النطق === * {{أصد-عر|زَهُدَ}} {{-}} === التصريفات === {{تصريف|جذر=زهد|وزن=فعُل يفعُل}} === المراجع === {{مراجع}} fegexn4vww19cnrvwte5rly890rqcsf اِسْتَقَى 0 240315 1097208 2026-07-22T00:20:53Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097208 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1489247}} === المعاني === '''اِسْتَقَى''' {{افتعل}} {{معجمية|L1489247|معاني}} === النطق === * {{أصد-عر|اِسْتَقَى}} {{-}} === التصريفات === {{تصريف|جذر=سقي|وزن=افتعل}} === المراجع === {{مراجع}} bb0rfouoa3tmh8545o5jtll0xz1uiwm نقاش المستخدم:Haziqah26 3 240316 1097210 2026-07-22T08:02:40Z MenoBot 1177 مرحبا! 1097210 wikitext text/x-wiki <div style="width:auto" style="margin-bottom:1.25em;border:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}}; background:white;padding:0"> <div style="height:8px;margin:0;border:0;border-bottom:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}};background: #{{#switch:bleu|bleu=C8D8FF|vert=D7FFC7|jaune=FFFFB9|or=FFE040|orange=FFDD88|violet=C9AEF1|saumon=FBDFBE|sable=F1E2AE|vertmoyen=99CC66|bleufoncé=003399|rouge=FFDAB9|écarlate=FF3333|#default=E0E0E0}};font-size:1px"></div> <div style="padding:5px;font-size:small"><div class="center"><span style="word-spacing:1ex"><small>[[ويكاموس:سفارة|Welcome!]] [[ويكاموس:سفارة|Bienvenue!]] [[ويكاموس:سفارة|Willkommen!]] [[ويكاموس:سفارة|Benvenuti]] [[ويكاموس:سفارة|¡Bienvenido!]] [[ويكاموس:سفارة|ようこそ]] [[ويكاموس:سفارة|Dobrodošli]] [[ويكاموس:سفارة|환영합니다]] [[ويكاموس:سفارة|Добро пожаловать]] [[ويكاموس:سفارة|Bem-vindo!]] [[ويكاموس:سفارة|欢迎]] [[ويكاموس:سفارة|Bonvenon]] [[ويكاموس:سفارة|Welkom]]</small></span></div></div> <div class="center"><big>'''[[ويكاموس:ترحيب بالقادمين الجدد|مرحبا بك]] في [[ويكاموس]]، Haziqah26 !'''</big></div> {| |[[ملف:WiktionaryAr.svg|يمين|40بك]] | [[ويكاموس]] هو <u>مشروع تحرير جماعي لـ'''قاموس علمي وثقافي''' '''بمختلف اللغات'''</u>. لطلب المساعدة في أي وقت تجد وصلة ([[مساعدة:محتويات|'''مساعدة''']]) في هامش كل صفحة على اليمين. لا تتردد في قراءة '''الوصايا الأولى''': * [[ويكاموس:دليل سريع|دليل سريع لتعلم التنسيق]] * [[مساعدة:إنشاء صفحة جديدة|كيف تنشئ صفحة جديدة]] * [[ويكاموس:دروس (التحرير)|دروس مفصلة لتعلم التنسيق]] * [[ويكاموس:صيغة الكتابة|الصيغة الموحدة للكتابة]] * [[ويكاموس:ويكاموس ليس|مبادئ ويكاموس]] لا تتردد في زيارة '''[[مستخدم:Haziqah26/ملعبي|ملعبك الخاص]]''' لاحتواء تجاربك وخطواتك الأولى في التحرير والتعديل. |-- |[[ملف:Presa de decissions.png|يمين|40بك]] | يمكنك الاستفسار و[[ويكاموس:أسئلة|طرح الأسئلة]] المتعلقة بطبيعة العمل في ويكاموس. يمكنك أيضا [{{fullurl:مستخدم:Haziqah26|action=edit}} التعريف] بنفسك في [[مستخدم:Haziqah26|'''صفحتك الشخصية''']]، بكتابة معلومات عنك: [[ويكاموس:بابل|اللغات التي تتكلمها]]، [[ويكاموس:صناديق المستخدم|من أي بلد أنت، ما هي محاور اهتمامك]]... |--- |[[ملف:Crystal Clear app ktip.png|يمين|40بك]] | لا تنس [[ويكاموس:توقيع|'''التوقيع''']] في [[مساعدة:صفحة النقاش|'''صفحات النقاش''']] بكتابة أربع مدّات، هكذا (<nowiki>~~~~</nowiki>). ولكن يجب <u>'''عدم التوقيع في صفحات المقالات القاموسية'''</u>، لأنها تصبح ملكًا للجميع لحظة إنشائها. نرجو منك ألاّ تنسى [[ويكاموس:حقوق التأليف والنشر|<u>'''عدم النسخ من الشابكة'''</u>]] لأسباب [[ويكاموس:حقوق التأليف والنشر|<u>'''حقوق التأليف والنشر'''</u>]]. |-- |[[ملف:Crystal Clear app amor.png|يمين|40بك]] | أخيرا، وهو أهم شيء، نتمى لك أن [[ويكاموس:كن جريئا|'''تتمتع''']] بالمساهمة [[ويكاموس:بوابة المجتمع|'''معنا''']] في هذا المشروع! إذا كانت لديك أي استفسارات أو أسئلة أخرى، يمكنك طرحها في [[ويكاموس:أسئلة|هذه الصفحة]] أو في صفحة نقاشي. |}</div></div> --[[مستخدم:Meno25|Meno25]] ([[نقاش المستخدم:Meno25|نقاش]] • [[خاص:مساهمات/Meno25|مساهمات]]) 08:02، 22 يوليو 2026 (ت ع م) izm4pw43qe3f1zuhrhsqvcb42j7aosw نقاش المستخدم:Cakeborrower 3 240317 1097211 2026-07-22T08:02:42Z MenoBot 1177 مرحبا! 1097211 wikitext text/x-wiki <div style="width:auto" style="margin-bottom:1.25em;border:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}}; background:white;padding:0"> <div style="height:8px;margin:0;border:0;border-bottom:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}};background: #{{#switch:bleu|bleu=C8D8FF|vert=D7FFC7|jaune=FFFFB9|or=FFE040|orange=FFDD88|violet=C9AEF1|saumon=FBDFBE|sable=F1E2AE|vertmoyen=99CC66|bleufoncé=003399|rouge=FFDAB9|écarlate=FF3333|#default=E0E0E0}};font-size:1px"></div> <div style="padding:5px;font-size:small"><div class="center"><span style="word-spacing:1ex"><small>[[ويكاموس:سفارة|Welcome!]] [[ويكاموس:سفارة|Bienvenue!]] [[ويكاموس:سفارة|Willkommen!]] [[ويكاموس:سفارة|Benvenuti]] [[ويكاموس:سفارة|¡Bienvenido!]] [[ويكاموس:سفارة|ようこそ]] [[ويكاموس:سفارة|Dobrodošli]] [[ويكاموس:سفارة|환영합니다]] [[ويكاموس:سفارة|Добро пожаловать]] [[ويكاموس:سفارة|Bem-vindo!]] [[ويكاموس:سفارة|欢迎]] [[ويكاموس:سفارة|Bonvenon]] [[ويكاموس:سفارة|Welkom]]</small></span></div></div> <div class="center"><big>'''[[ويكاموس:ترحيب بالقادمين الجدد|مرحبا بك]] في [[ويكاموس]]، Cakeborrower !'''</big></div> {| |[[ملف:WiktionaryAr.svg|يمين|40بك]] | [[ويكاموس]] هو <u>مشروع تحرير جماعي لـ'''قاموس علمي وثقافي''' '''بمختلف اللغات'''</u>. لطلب المساعدة في أي وقت تجد وصلة ([[مساعدة:محتويات|'''مساعدة''']]) في هامش كل صفحة على اليمين. لا تتردد في قراءة '''الوصايا الأولى''': * [[ويكاموس:دليل سريع|دليل سريع لتعلم التنسيق]] * [[مساعدة:إنشاء صفحة جديدة|كيف تنشئ صفحة جديدة]] * [[ويكاموس:دروس (التحرير)|دروس مفصلة لتعلم التنسيق]] * [[ويكاموس:صيغة الكتابة|الصيغة الموحدة للكتابة]] * [[ويكاموس:ويكاموس ليس|مبادئ ويكاموس]] لا تتردد في زيارة '''[[مستخدم:Cakeborrower/ملعبي|ملعبك الخاص]]''' لاحتواء تجاربك وخطواتك الأولى في التحرير والتعديل. |-- |[[ملف:Presa de decissions.png|يمين|40بك]] | يمكنك الاستفسار و[[ويكاموس:أسئلة|طرح الأسئلة]] المتعلقة بطبيعة العمل في ويكاموس. يمكنك أيضا [{{fullurl:مستخدم:Cakeborrower|action=edit}} التعريف] بنفسك في [[مستخدم:Cakeborrower|'''صفحتك الشخصية''']]، بكتابة معلومات عنك: [[ويكاموس:بابل|اللغات التي تتكلمها]]، [[ويكاموس:صناديق المستخدم|من أي بلد أنت، ما هي محاور اهتمامك]]... |--- |[[ملف:Crystal Clear app ktip.png|يمين|40بك]] | لا تنس [[ويكاموس:توقيع|'''التوقيع''']] في [[مساعدة:صفحة النقاش|'''صفحات النقاش''']] بكتابة أربع مدّات، هكذا (<nowiki>~~~~</nowiki>). ولكن يجب <u>'''عدم التوقيع في صفحات المقالات القاموسية'''</u>، لأنها تصبح ملكًا للجميع لحظة إنشائها. نرجو منك ألاّ تنسى [[ويكاموس:حقوق التأليف والنشر|<u>'''عدم النسخ من الشابكة'''</u>]] لأسباب [[ويكاموس:حقوق التأليف والنشر|<u>'''حقوق التأليف والنشر'''</u>]]. |-- |[[ملف:Crystal Clear app amor.png|يمين|40بك]] | أخيرا، وهو أهم شيء، نتمى لك أن [[ويكاموس:كن جريئا|'''تتمتع''']] بالمساهمة [[ويكاموس:بوابة المجتمع|'''معنا''']] في هذا المشروع! إذا كانت لديك أي استفسارات أو أسئلة أخرى، يمكنك طرحها في [[ويكاموس:أسئلة|هذه الصفحة]] أو في صفحة نقاشي. |}</div></div> --[[مستخدم:Meno25|Meno25]] ([[نقاش المستخدم:Meno25|نقاش]] • [[خاص:مساهمات/Meno25|مساهمات]]) 08:02، 22 يوليو 2026 (ت ع م) 0phc2z8uo9e6ppzz0t94t2f11y8s7lr نقاش المستخدم:Y.miralam 3 240318 1097212 2026-07-22T08:02:44Z MenoBot 1177 مرحبا! 1097212 wikitext text/x-wiki <div style="width:auto" style="margin-bottom:1.25em;border:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}}; background:white;padding:0"> <div style="height:8px;margin:0;border:0;border-bottom:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}};background: #{{#switch:bleu|bleu=C8D8FF|vert=D7FFC7|jaune=FFFFB9|or=FFE040|orange=FFDD88|violet=C9AEF1|saumon=FBDFBE|sable=F1E2AE|vertmoyen=99CC66|bleufoncé=003399|rouge=FFDAB9|écarlate=FF3333|#default=E0E0E0}};font-size:1px"></div> <div style="padding:5px;font-size:small"><div class="center"><span style="word-spacing:1ex"><small>[[ويكاموس:سفارة|Welcome!]] [[ويكاموس:سفارة|Bienvenue!]] [[ويكاموس:سفارة|Willkommen!]] [[ويكاموس:سفارة|Benvenuti]] [[ويكاموس:سفارة|¡Bienvenido!]] [[ويكاموس:سفارة|ようこそ]] [[ويكاموس:سفارة|Dobrodošli]] [[ويكاموس:سفارة|환영합니다]] [[ويكاموس:سفارة|Добро пожаловать]] [[ويكاموس:سفارة|Bem-vindo!]] [[ويكاموس:سفارة|欢迎]] [[ويكاموس:سفارة|Bonvenon]] [[ويكاموس:سفارة|Welkom]]</small></span></div></div> <div class="center"><big>'''[[ويكاموس:ترحيب بالقادمين الجدد|مرحبا بك]] في [[ويكاموس]]، Y.miralam !'''</big></div> {| |[[ملف:WiktionaryAr.svg|يمين|40بك]] | [[ويكاموس]] هو <u>مشروع تحرير جماعي لـ'''قاموس علمي وثقافي''' '''بمختلف اللغات'''</u>. لطلب المساعدة في أي وقت تجد وصلة ([[مساعدة:محتويات|'''مساعدة''']]) في هامش كل صفحة على اليمين. لا تتردد في قراءة '''الوصايا الأولى''': * [[ويكاموس:دليل سريع|دليل سريع لتعلم التنسيق]] * [[مساعدة:إنشاء صفحة جديدة|كيف تنشئ صفحة جديدة]] * [[ويكاموس:دروس (التحرير)|دروس مفصلة لتعلم التنسيق]] * [[ويكاموس:صيغة الكتابة|الصيغة الموحدة للكتابة]] * [[ويكاموس:ويكاموس ليس|مبادئ ويكاموس]] لا تتردد في زيارة '''[[مستخدم:Y.miralam/ملعبي|ملعبك الخاص]]''' لاحتواء تجاربك وخطواتك الأولى في التحرير والتعديل. |-- |[[ملف:Presa de decissions.png|يمين|40بك]] | يمكنك الاستفسار و[[ويكاموس:أسئلة|طرح الأسئلة]] المتعلقة بطبيعة العمل في ويكاموس. يمكنك أيضا [{{fullurl:مستخدم:Y.miralam|action=edit}} التعريف] بنفسك في [[مستخدم:Y.miralam|'''صفحتك الشخصية''']]، بكتابة معلومات عنك: [[ويكاموس:بابل|اللغات التي تتكلمها]]، [[ويكاموس:صناديق المستخدم|من أي بلد أنت، ما هي محاور اهتمامك]]... |--- |[[ملف:Crystal Clear app ktip.png|يمين|40بك]] | لا تنس [[ويكاموس:توقيع|'''التوقيع''']] في [[مساعدة:صفحة النقاش|'''صفحات النقاش''']] بكتابة أربع مدّات، هكذا (<nowiki>~~~~</nowiki>). ولكن يجب <u>'''عدم التوقيع في صفحات المقالات القاموسية'''</u>، لأنها تصبح ملكًا للجميع لحظة إنشائها. نرجو منك ألاّ تنسى [[ويكاموس:حقوق التأليف والنشر|<u>'''عدم النسخ من الشابكة'''</u>]] لأسباب [[ويكاموس:حقوق التأليف والنشر|<u>'''حقوق التأليف والنشر'''</u>]]. |-- |[[ملف:Crystal Clear app amor.png|يمين|40بك]] | أخيرا، وهو أهم شيء، نتمى لك أن [[ويكاموس:كن جريئا|'''تتمتع''']] بالمساهمة [[ويكاموس:بوابة المجتمع|'''معنا''']] في هذا المشروع! إذا كانت لديك أي استفسارات أو أسئلة أخرى، يمكنك طرحها في [[ويكاموس:أسئلة|هذه الصفحة]] أو في صفحة نقاشي. |}</div></div> --[[مستخدم:Meno25|Meno25]] ([[نقاش المستخدم:Meno25|نقاش]] • [[خاص:مساهمات/Meno25|مساهمات]]) 08:02، 22 يوليو 2026 (ت ع م) sosrl74h6gpvk7qcmsi1u1b8cklxd5f نقاش المستخدم:Trimton 3 240319 1097213 2026-07-22T08:02:46Z MenoBot 1177 مرحبا! 1097213 wikitext text/x-wiki <div style="width:auto" style="margin-bottom:1.25em;border:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}}; background:white;padding:0"> <div style="height:8px;margin:0;border:0;border-bottom:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}};background: #{{#switch:bleu|bleu=C8D8FF|vert=D7FFC7|jaune=FFFFB9|or=FFE040|orange=FFDD88|violet=C9AEF1|saumon=FBDFBE|sable=F1E2AE|vertmoyen=99CC66|bleufoncé=003399|rouge=FFDAB9|écarlate=FF3333|#default=E0E0E0}};font-size:1px"></div> <div style="padding:5px;font-size:small"><div class="center"><span style="word-spacing:1ex"><small>[[ويكاموس:سفارة|Welcome!]] [[ويكاموس:سفارة|Bienvenue!]] [[ويكاموس:سفارة|Willkommen!]] [[ويكاموس:سفارة|Benvenuti]] [[ويكاموس:سفارة|¡Bienvenido!]] [[ويكاموس:سفارة|ようこそ]] [[ويكاموس:سفارة|Dobrodošli]] [[ويكاموس:سفارة|환영합니다]] [[ويكاموس:سفارة|Добро пожаловать]] [[ويكاموس:سفارة|Bem-vindo!]] [[ويكاموس:سفارة|欢迎]] [[ويكاموس:سفارة|Bonvenon]] [[ويكاموس:سفارة|Welkom]]</small></span></div></div> <div class="center"><big>'''[[ويكاموس:ترحيب بالقادمين الجدد|مرحبا بك]] في [[ويكاموس]]، Trimton !'''</big></div> {| |[[ملف:WiktionaryAr.svg|يمين|40بك]] | [[ويكاموس]] هو <u>مشروع تحرير جماعي لـ'''قاموس علمي وثقافي''' '''بمختلف اللغات'''</u>. لطلب المساعدة في أي وقت تجد وصلة ([[مساعدة:محتويات|'''مساعدة''']]) في هامش كل صفحة على اليمين. لا تتردد في قراءة '''الوصايا الأولى''': * [[ويكاموس:دليل سريع|دليل سريع لتعلم التنسيق]] * [[مساعدة:إنشاء صفحة جديدة|كيف تنشئ صفحة جديدة]] * [[ويكاموس:دروس (التحرير)|دروس مفصلة لتعلم التنسيق]] * [[ويكاموس:صيغة الكتابة|الصيغة الموحدة للكتابة]] * [[ويكاموس:ويكاموس ليس|مبادئ ويكاموس]] لا تتردد في زيارة '''[[مستخدم:Trimton/ملعبي|ملعبك الخاص]]''' لاحتواء تجاربك وخطواتك الأولى في التحرير والتعديل. |-- |[[ملف:Presa de decissions.png|يمين|40بك]] | يمكنك الاستفسار و[[ويكاموس:أسئلة|طرح الأسئلة]] المتعلقة بطبيعة العمل في ويكاموس. يمكنك أيضا [{{fullurl:مستخدم:Trimton|action=edit}} التعريف] بنفسك في [[مستخدم:Trimton|'''صفحتك الشخصية''']]، بكتابة معلومات عنك: [[ويكاموس:بابل|اللغات التي تتكلمها]]، [[ويكاموس:صناديق المستخدم|من أي بلد أنت، ما هي محاور اهتمامك]]... |--- |[[ملف:Crystal Clear app ktip.png|يمين|40بك]] | لا تنس [[ويكاموس:توقيع|'''التوقيع''']] في [[مساعدة:صفحة النقاش|'''صفحات النقاش''']] بكتابة أربع مدّات، هكذا (<nowiki>~~~~</nowiki>). ولكن يجب <u>'''عدم التوقيع في صفحات المقالات القاموسية'''</u>، لأنها تصبح ملكًا للجميع لحظة إنشائها. نرجو منك ألاّ تنسى [[ويكاموس:حقوق التأليف والنشر|<u>'''عدم النسخ من الشابكة'''</u>]] لأسباب [[ويكاموس:حقوق التأليف والنشر|<u>'''حقوق التأليف والنشر'''</u>]]. |-- |[[ملف:Crystal Clear app amor.png|يمين|40بك]] | أخيرا، وهو أهم شيء، نتمى لك أن [[ويكاموس:كن جريئا|'''تتمتع''']] بالمساهمة [[ويكاموس:بوابة المجتمع|'''معنا''']] في هذا المشروع! إذا كانت لديك أي استفسارات أو أسئلة أخرى، يمكنك طرحها في [[ويكاموس:أسئلة|هذه الصفحة]] أو في صفحة نقاشي. |}</div></div> --[[مستخدم:Meno25|Meno25]] ([[نقاش المستخدم:Meno25|نقاش]] • [[خاص:مساهمات/Meno25|مساهمات]]) 08:02، 22 يوليو 2026 (ت ع م) nem12cz1gkd6po1056rcmxgeri7wkxi نقاش المستخدم:Pota8to 3 240320 1097214 2026-07-22T08:02:48Z MenoBot 1177 مرحبا! 1097214 wikitext text/x-wiki <div style="width:auto" style="margin-bottom:1.25em;border:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}}; background:white;padding:0"> <div style="height:8px;margin:0;border:0;border-bottom:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}};background: #{{#switch:bleu|bleu=C8D8FF|vert=D7FFC7|jaune=FFFFB9|or=FFE040|orange=FFDD88|violet=C9AEF1|saumon=FBDFBE|sable=F1E2AE|vertmoyen=99CC66|bleufoncé=003399|rouge=FFDAB9|écarlate=FF3333|#default=E0E0E0}};font-size:1px"></div> <div style="padding:5px;font-size:small"><div class="center"><span style="word-spacing:1ex"><small>[[ويكاموس:سفارة|Welcome!]] [[ويكاموس:سفارة|Bienvenue!]] [[ويكاموس:سفارة|Willkommen!]] [[ويكاموس:سفارة|Benvenuti]] [[ويكاموس:سفارة|¡Bienvenido!]] [[ويكاموس:سفارة|ようこそ]] [[ويكاموس:سفارة|Dobrodošli]] [[ويكاموس:سفارة|환영합니다]] [[ويكاموس:سفارة|Добро пожаловать]] [[ويكاموس:سفارة|Bem-vindo!]] [[ويكاموس:سفارة|欢迎]] [[ويكاموس:سفارة|Bonvenon]] [[ويكاموس:سفارة|Welkom]]</small></span></div></div> <div class="center"><big>'''[[ويكاموس:ترحيب بالقادمين الجدد|مرحبا بك]] في [[ويكاموس]]، Pota8to !'''</big></div> {| |[[ملف:WiktionaryAr.svg|يمين|40بك]] | [[ويكاموس]] هو <u>مشروع تحرير جماعي لـ'''قاموس علمي وثقافي''' '''بمختلف اللغات'''</u>. لطلب المساعدة في أي وقت تجد وصلة ([[مساعدة:محتويات|'''مساعدة''']]) في هامش كل صفحة على اليمين. لا تتردد في قراءة '''الوصايا الأولى''': * [[ويكاموس:دليل سريع|دليل سريع لتعلم التنسيق]] * [[مساعدة:إنشاء صفحة جديدة|كيف تنشئ صفحة جديدة]] * [[ويكاموس:دروس (التحرير)|دروس مفصلة لتعلم التنسيق]] * [[ويكاموس:صيغة الكتابة|الصيغة الموحدة للكتابة]] * [[ويكاموس:ويكاموس ليس|مبادئ ويكاموس]] لا تتردد في زيارة '''[[مستخدم:Pota8to/ملعبي|ملعبك الخاص]]''' لاحتواء تجاربك وخطواتك الأولى في التحرير والتعديل. |-- |[[ملف:Presa de decissions.png|يمين|40بك]] | يمكنك الاستفسار و[[ويكاموس:أسئلة|طرح الأسئلة]] المتعلقة بطبيعة العمل في ويكاموس. يمكنك أيضا [{{fullurl:مستخدم:Pota8to|action=edit}} التعريف] بنفسك في [[مستخدم:Pota8to|'''صفحتك الشخصية''']]، بكتابة معلومات عنك: [[ويكاموس:بابل|اللغات التي تتكلمها]]، [[ويكاموس:صناديق المستخدم|من أي بلد أنت، ما هي محاور اهتمامك]]... |--- |[[ملف:Crystal Clear app ktip.png|يمين|40بك]] | لا تنس [[ويكاموس:توقيع|'''التوقيع''']] في [[مساعدة:صفحة النقاش|'''صفحات النقاش''']] بكتابة أربع مدّات، هكذا (<nowiki>~~~~</nowiki>). ولكن يجب <u>'''عدم التوقيع في صفحات المقالات القاموسية'''</u>، لأنها تصبح ملكًا للجميع لحظة إنشائها. نرجو منك ألاّ تنسى [[ويكاموس:حقوق التأليف والنشر|<u>'''عدم النسخ من الشابكة'''</u>]] لأسباب [[ويكاموس:حقوق التأليف والنشر|<u>'''حقوق التأليف والنشر'''</u>]]. |-- |[[ملف:Crystal Clear app amor.png|يمين|40بك]] | أخيرا، وهو أهم شيء، نتمى لك أن [[ويكاموس:كن جريئا|'''تتمتع''']] بالمساهمة [[ويكاموس:بوابة المجتمع|'''معنا''']] في هذا المشروع! إذا كانت لديك أي استفسارات أو أسئلة أخرى، يمكنك طرحها في [[ويكاموس:أسئلة|هذه الصفحة]] أو في صفحة نقاشي. |}</div></div> --[[مستخدم:Meno25|Meno25]] ([[نقاش المستخدم:Meno25|نقاش]] • [[خاص:مساهمات/Meno25|مساهمات]]) 08:02، 22 يوليو 2026 (ت ع م) jbtfti472hkhy2m5gkvu3bv98or0e3x نقاش المستخدم:موك 3 240321 1097215 2026-07-22T08:02:50Z MenoBot 1177 مرحبا! 1097215 wikitext text/x-wiki <div style="width:auto" style="margin-bottom:1.25em;border:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}}; background:white;padding:0"> <div style="height:8px;margin:0;border:0;border-bottom:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}};background: #{{#switch:bleu|bleu=C8D8FF|vert=D7FFC7|jaune=FFFFB9|or=FFE040|orange=FFDD88|violet=C9AEF1|saumon=FBDFBE|sable=F1E2AE|vertmoyen=99CC66|bleufoncé=003399|rouge=FFDAB9|écarlate=FF3333|#default=E0E0E0}};font-size:1px"></div> <div style="padding:5px;font-size:small"><div class="center"><span style="word-spacing:1ex"><small>[[ويكاموس:سفارة|Welcome!]] [[ويكاموس:سفارة|Bienvenue!]] [[ويكاموس:سفارة|Willkommen!]] [[ويكاموس:سفارة|Benvenuti]] [[ويكاموس:سفارة|¡Bienvenido!]] [[ويكاموس:سفارة|ようこそ]] [[ويكاموس:سفارة|Dobrodošli]] [[ويكاموس:سفارة|환영합니다]] [[ويكاموس:سفارة|Добро пожаловать]] [[ويكاموس:سفارة|Bem-vindo!]] [[ويكاموس:سفارة|欢迎]] [[ويكاموس:سفارة|Bonvenon]] [[ويكاموس:سفارة|Welkom]]</small></span></div></div> <div class="center"><big>'''[[ويكاموس:ترحيب بالقادمين الجدد|مرحبا بك]] في [[ويكاموس]]، موك !'''</big></div> {| |[[ملف:WiktionaryAr.svg|يمين|40بك]] | [[ويكاموس]] هو <u>مشروع تحرير جماعي لـ'''قاموس علمي وثقافي''' '''بمختلف اللغات'''</u>. لطلب المساعدة في أي وقت تجد وصلة ([[مساعدة:محتويات|'''مساعدة''']]) في هامش كل صفحة على اليمين. لا تتردد في قراءة '''الوصايا الأولى''': * [[ويكاموس:دليل سريع|دليل سريع لتعلم التنسيق]] * [[مساعدة:إنشاء صفحة جديدة|كيف تنشئ صفحة جديدة]] * [[ويكاموس:دروس (التحرير)|دروس مفصلة لتعلم التنسيق]] * [[ويكاموس:صيغة الكتابة|الصيغة الموحدة للكتابة]] * [[ويكاموس:ويكاموس ليس|مبادئ ويكاموس]] لا تتردد في زيارة '''[[مستخدم:موك/ملعبي|ملعبك الخاص]]''' لاحتواء تجاربك وخطواتك الأولى في التحرير والتعديل. |-- |[[ملف:Presa de decissions.png|يمين|40بك]] | يمكنك الاستفسار و[[ويكاموس:أسئلة|طرح الأسئلة]] المتعلقة بطبيعة العمل في ويكاموس. يمكنك أيضا [{{fullurl:مستخدم:موك|action=edit}} التعريف] بنفسك في [[مستخدم:موك|'''صفحتك الشخصية''']]، بكتابة معلومات عنك: [[ويكاموس:بابل|اللغات التي تتكلمها]]، [[ويكاموس:صناديق المستخدم|من أي بلد أنت، ما هي محاور اهتمامك]]... |--- |[[ملف:Crystal Clear app ktip.png|يمين|40بك]] | لا تنس [[ويكاموس:توقيع|'''التوقيع''']] في [[مساعدة:صفحة النقاش|'''صفحات النقاش''']] بكتابة أربع مدّات، هكذا (<nowiki>~~~~</nowiki>). ولكن يجب <u>'''عدم التوقيع في صفحات المقالات القاموسية'''</u>، لأنها تصبح ملكًا للجميع لحظة إنشائها. نرجو منك ألاّ تنسى [[ويكاموس:حقوق التأليف والنشر|<u>'''عدم النسخ من الشابكة'''</u>]] لأسباب [[ويكاموس:حقوق التأليف والنشر|<u>'''حقوق التأليف والنشر'''</u>]]. |-- |[[ملف:Crystal Clear app amor.png|يمين|40بك]] | أخيرا، وهو أهم شيء، نتمى لك أن [[ويكاموس:كن جريئا|'''تتمتع''']] بالمساهمة [[ويكاموس:بوابة المجتمع|'''معنا''']] في هذا المشروع! إذا كانت لديك أي استفسارات أو أسئلة أخرى، يمكنك طرحها في [[ويكاموس:أسئلة|هذه الصفحة]] أو في صفحة نقاشي. |}</div></div> --[[مستخدم:Meno25|Meno25]] ([[نقاش المستخدم:Meno25|نقاش]] • [[خاص:مساهمات/Meno25|مساهمات]]) 08:02، 22 يوليو 2026 (ت ع م) rzwaybm1d6epcn2mxyx5ppdt9nr84n8 نقاش المستخدم:AprilofOctober 3 240322 1097216 2026-07-22T08:02:52Z MenoBot 1177 مرحبا! 1097216 wikitext text/x-wiki <div style="width:auto" style="margin-bottom:1.25em;border:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}}; background:white;padding:0"> <div style="height:8px;margin:0;border:0;border-bottom:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}};background: #{{#switch:bleu|bleu=C8D8FF|vert=D7FFC7|jaune=FFFFB9|or=FFE040|orange=FFDD88|violet=C9AEF1|saumon=FBDFBE|sable=F1E2AE|vertmoyen=99CC66|bleufoncé=003399|rouge=FFDAB9|écarlate=FF3333|#default=E0E0E0}};font-size:1px"></div> <div style="padding:5px;font-size:small"><div class="center"><span style="word-spacing:1ex"><small>[[ويكاموس:سفارة|Welcome!]] [[ويكاموس:سفارة|Bienvenue!]] [[ويكاموس:سفارة|Willkommen!]] [[ويكاموس:سفارة|Benvenuti]] [[ويكاموس:سفارة|¡Bienvenido!]] [[ويكاموس:سفارة|ようこそ]] [[ويكاموس:سفارة|Dobrodošli]] [[ويكاموس:سفارة|환영합니다]] [[ويكاموس:سفارة|Добро пожаловать]] [[ويكاموس:سفارة|Bem-vindo!]] [[ويكاموس:سفارة|欢迎]] [[ويكاموس:سفارة|Bonvenon]] [[ويكاموس:سفارة|Welkom]]</small></span></div></div> <div class="center"><big>'''[[ويكاموس:ترحيب بالقادمين الجدد|مرحبا بك]] في [[ويكاموس]]، AprilofOctober !'''</big></div> {| |[[ملف:WiktionaryAr.svg|يمين|40بك]] | [[ويكاموس]] هو <u>مشروع تحرير جماعي لـ'''قاموس علمي وثقافي''' '''بمختلف اللغات'''</u>. لطلب المساعدة في أي وقت تجد وصلة ([[مساعدة:محتويات|'''مساعدة''']]) في هامش كل صفحة على اليمين. لا تتردد في قراءة '''الوصايا الأولى''': * [[ويكاموس:دليل سريع|دليل سريع لتعلم التنسيق]] * [[مساعدة:إنشاء صفحة جديدة|كيف تنشئ صفحة جديدة]] * [[ويكاموس:دروس (التحرير)|دروس مفصلة لتعلم التنسيق]] * [[ويكاموس:صيغة الكتابة|الصيغة الموحدة للكتابة]] * [[ويكاموس:ويكاموس ليس|مبادئ ويكاموس]] لا تتردد في زيارة '''[[مستخدم:AprilofOctober/ملعبي|ملعبك الخاص]]''' لاحتواء تجاربك وخطواتك الأولى في التحرير والتعديل. |-- |[[ملف:Presa de decissions.png|يمين|40بك]] | يمكنك الاستفسار و[[ويكاموس:أسئلة|طرح الأسئلة]] المتعلقة بطبيعة العمل في ويكاموس. يمكنك أيضا [{{fullurl:مستخدم:AprilofOctober|action=edit}} التعريف] بنفسك في [[مستخدم:AprilofOctober|'''صفحتك الشخصية''']]، بكتابة معلومات عنك: [[ويكاموس:بابل|اللغات التي تتكلمها]]، [[ويكاموس:صناديق المستخدم|من أي بلد أنت، ما هي محاور اهتمامك]]... |--- |[[ملف:Crystal Clear app ktip.png|يمين|40بك]] | لا تنس [[ويكاموس:توقيع|'''التوقيع''']] في [[مساعدة:صفحة النقاش|'''صفحات النقاش''']] بكتابة أربع مدّات، هكذا (<nowiki>~~~~</nowiki>). ولكن يجب <u>'''عدم التوقيع في صفحات المقالات القاموسية'''</u>، لأنها تصبح ملكًا للجميع لحظة إنشائها. نرجو منك ألاّ تنسى [[ويكاموس:حقوق التأليف والنشر|<u>'''عدم النسخ من الشابكة'''</u>]] لأسباب [[ويكاموس:حقوق التأليف والنشر|<u>'''حقوق التأليف والنشر'''</u>]]. |-- |[[ملف:Crystal Clear app amor.png|يمين|40بك]] | أخيرا، وهو أهم شيء، نتمى لك أن [[ويكاموس:كن جريئا|'''تتمتع''']] بالمساهمة [[ويكاموس:بوابة المجتمع|'''معنا''']] في هذا المشروع! إذا كانت لديك أي استفسارات أو أسئلة أخرى، يمكنك طرحها في [[ويكاموس:أسئلة|هذه الصفحة]] أو في صفحة نقاشي. |}</div></div> --[[مستخدم:Meno25|Meno25]] ([[نقاش المستخدم:Meno25|نقاش]] • [[خاص:مساهمات/Meno25|مساهمات]]) 08:02، 22 يوليو 2026 (ت ع م) bitfg9hmgvddhnietjq3akxu4vndx0n نقاش المستخدم:~2026-40292-28 3 240323 1097217 2026-07-22T08:02:54Z MenoBot 1177 مرحبا! 1097217 wikitext text/x-wiki <div style="width:auto" style="margin-bottom:1.25em;border:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}}; background:white;padding:0"> <div style="height:8px;margin:0;border:0;border-bottom:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}};background: #{{#switch:bleu|bleu=C8D8FF|vert=D7FFC7|jaune=FFFFB9|or=FFE040|orange=FFDD88|violet=C9AEF1|saumon=FBDFBE|sable=F1E2AE|vertmoyen=99CC66|bleufoncé=003399|rouge=FFDAB9|écarlate=FF3333|#default=E0E0E0}};font-size:1px"></div> <div style="padding:5px;font-size:small"><div class="center"><span style="word-spacing:1ex"><small>[[ويكاموس:سفارة|Welcome!]] [[ويكاموس:سفارة|Bienvenue!]] [[ويكاموس:سفارة|Willkommen!]] [[ويكاموس:سفارة|Benvenuti]] [[ويكاموس:سفارة|¡Bienvenido!]] [[ويكاموس:سفارة|ようこそ]] [[ويكاموس:سفارة|Dobrodošli]] [[ويكاموس:سفارة|환영합니다]] [[ويكاموس:سفارة|Добро пожаловать]] [[ويكاموس:سفارة|Bem-vindo!]] [[ويكاموس:سفارة|欢迎]] [[ويكاموس:سفارة|Bonvenon]] [[ويكاموس:سفارة|Welkom]]</small></span></div></div> <div class="center"><big>'''[[ويكاموس:ترحيب بالقادمين الجدد|مرحبا بك]] في [[ويكاموس]]، &#126;2026-40292-28 !'''</big></div> {| |[[ملف:WiktionaryAr.svg|يمين|40بك]] | [[ويكاموس]] هو <u>مشروع تحرير جماعي لـ'''قاموس علمي وثقافي''' '''بمختلف اللغات'''</u>. لطلب المساعدة في أي وقت تجد وصلة ([[مساعدة:محتويات|'''مساعدة''']]) في هامش كل صفحة على اليمين. لا تتردد في قراءة '''الوصايا الأولى''': * [[ويكاموس:دليل سريع|دليل سريع لتعلم التنسيق]] * [[مساعدة:إنشاء صفحة جديدة|كيف تنشئ صفحة جديدة]] * [[ويكاموس:دروس (التحرير)|دروس مفصلة لتعلم التنسيق]] * [[ويكاموس:صيغة الكتابة|الصيغة الموحدة للكتابة]] * [[ويكاموس:ويكاموس ليس|مبادئ ويكاموس]] لا تتردد في زيارة '''[[مستخدم:&#126;2026-40292-28/ملعبي|ملعبك الخاص]]''' لاحتواء تجاربك وخطواتك الأولى في التحرير والتعديل. |-- |[[ملف:Presa de decissions.png|يمين|40بك]] | يمكنك الاستفسار و[[ويكاموس:أسئلة|طرح الأسئلة]] المتعلقة بطبيعة العمل في ويكاموس. يمكنك أيضا [{{fullurl:مستخدم:&#126;2026-40292-28|action=edit}} التعريف] بنفسك في [[مستخدم:&#126;2026-40292-28|'''صفحتك الشخصية''']]، بكتابة معلومات عنك: [[ويكاموس:بابل|اللغات التي تتكلمها]]، [[ويكاموس:صناديق المستخدم|من أي بلد أنت، ما هي محاور اهتمامك]]... |--- |[[ملف:Crystal Clear app ktip.png|يمين|40بك]] | لا تنس [[ويكاموس:توقيع|'''التوقيع''']] في [[مساعدة:صفحة النقاش|'''صفحات النقاش''']] بكتابة أربع مدّات، هكذا (<nowiki>~~~~</nowiki>). ولكن يجب <u>'''عدم التوقيع في صفحات المقالات القاموسية'''</u>، لأنها تصبح ملكًا للجميع لحظة إنشائها. نرجو منك ألاّ تنسى [[ويكاموس:حقوق التأليف والنشر|<u>'''عدم النسخ من الشابكة'''</u>]] لأسباب [[ويكاموس:حقوق التأليف والنشر|<u>'''حقوق التأليف والنشر'''</u>]]. |-- |[[ملف:Crystal Clear app amor.png|يمين|40بك]] | أخيرا، وهو أهم شيء، نتمى لك أن [[ويكاموس:كن جريئا|'''تتمتع''']] بالمساهمة [[ويكاموس:بوابة المجتمع|'''معنا''']] في هذا المشروع! إذا كانت لديك أي استفسارات أو أسئلة أخرى، يمكنك طرحها في [[ويكاموس:أسئلة|هذه الصفحة]] أو في صفحة نقاشي. |}</div></div> --[[مستخدم:Meno25|Meno25]] ([[نقاش المستخدم:Meno25|نقاش]] • [[خاص:مساهمات/Meno25|مساهمات]]) 08:02، 22 يوليو 2026 (ت ع م) k1lcbpwayt1sc5vdqykfj9h94pai0kj نقاش المستخدم:Meer83 3 240324 1097218 2026-07-22T08:02:56Z MenoBot 1177 مرحبا! 1097218 wikitext text/x-wiki <div style="width:auto" style="margin-bottom:1.25em;border:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}}; background:white;padding:0"> <div style="height:8px;margin:0;border:0;border-bottom:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}};background: #{{#switch:bleu|bleu=C8D8FF|vert=D7FFC7|jaune=FFFFB9|or=FFE040|orange=FFDD88|violet=C9AEF1|saumon=FBDFBE|sable=F1E2AE|vertmoyen=99CC66|bleufoncé=003399|rouge=FFDAB9|écarlate=FF3333|#default=E0E0E0}};font-size:1px"></div> <div style="padding:5px;font-size:small"><div class="center"><span style="word-spacing:1ex"><small>[[ويكاموس:سفارة|Welcome!]] [[ويكاموس:سفارة|Bienvenue!]] [[ويكاموس:سفارة|Willkommen!]] [[ويكاموس:سفارة|Benvenuti]] [[ويكاموس:سفارة|¡Bienvenido!]] [[ويكاموس:سفارة|ようこそ]] [[ويكاموس:سفارة|Dobrodošli]] [[ويكاموس:سفارة|환영합니다]] [[ويكاموس:سفارة|Добро пожаловать]] [[ويكاموس:سفارة|Bem-vindo!]] [[ويكاموس:سفارة|欢迎]] [[ويكاموس:سفارة|Bonvenon]] [[ويكاموس:سفارة|Welkom]]</small></span></div></div> <div class="center"><big>'''[[ويكاموس:ترحيب بالقادمين الجدد|مرحبا بك]] في [[ويكاموس]]، Meer83 !'''</big></div> {| |[[ملف:WiktionaryAr.svg|يمين|40بك]] | [[ويكاموس]] هو <u>مشروع تحرير جماعي لـ'''قاموس علمي وثقافي''' '''بمختلف اللغات'''</u>. لطلب المساعدة في أي وقت تجد وصلة ([[مساعدة:محتويات|'''مساعدة''']]) في هامش كل صفحة على اليمين. لا تتردد في قراءة '''الوصايا الأولى''': * [[ويكاموس:دليل سريع|دليل سريع لتعلم التنسيق]] * [[مساعدة:إنشاء صفحة جديدة|كيف تنشئ صفحة جديدة]] * [[ويكاموس:دروس (التحرير)|دروس مفصلة لتعلم التنسيق]] * [[ويكاموس:صيغة الكتابة|الصيغة الموحدة للكتابة]] * [[ويكاموس:ويكاموس ليس|مبادئ ويكاموس]] لا تتردد في زيارة '''[[مستخدم:Meer83/ملعبي|ملعبك الخاص]]''' لاحتواء تجاربك وخطواتك الأولى في التحرير والتعديل. |-- |[[ملف:Presa de decissions.png|يمين|40بك]] | يمكنك الاستفسار و[[ويكاموس:أسئلة|طرح الأسئلة]] المتعلقة بطبيعة العمل في ويكاموس. يمكنك أيضا [{{fullurl:مستخدم:Meer83|action=edit}} التعريف] بنفسك في [[مستخدم:Meer83|'''صفحتك الشخصية''']]، بكتابة معلومات عنك: [[ويكاموس:بابل|اللغات التي تتكلمها]]، [[ويكاموس:صناديق المستخدم|من أي بلد أنت، ما هي محاور اهتمامك]]... |--- |[[ملف:Crystal Clear app ktip.png|يمين|40بك]] | لا تنس [[ويكاموس:توقيع|'''التوقيع''']] في [[مساعدة:صفحة النقاش|'''صفحات النقاش''']] بكتابة أربع مدّات، هكذا (<nowiki>~~~~</nowiki>). ولكن يجب <u>'''عدم التوقيع في صفحات المقالات القاموسية'''</u>، لأنها تصبح ملكًا للجميع لحظة إنشائها. نرجو منك ألاّ تنسى [[ويكاموس:حقوق التأليف والنشر|<u>'''عدم النسخ من الشابكة'''</u>]] لأسباب [[ويكاموس:حقوق التأليف والنشر|<u>'''حقوق التأليف والنشر'''</u>]]. |-- |[[ملف:Crystal Clear app amor.png|يمين|40بك]] | أخيرا، وهو أهم شيء، نتمى لك أن [[ويكاموس:كن جريئا|'''تتمتع''']] بالمساهمة [[ويكاموس:بوابة المجتمع|'''معنا''']] في هذا المشروع! إذا كانت لديك أي استفسارات أو أسئلة أخرى، يمكنك طرحها في [[ويكاموس:أسئلة|هذه الصفحة]] أو في صفحة نقاشي. |}</div></div> --[[مستخدم:Meno25|Meno25]] ([[نقاش المستخدم:Meno25|نقاش]] • [[خاص:مساهمات/Meno25|مساهمات]]) 08:02، 22 يوليو 2026 (ت ع م) bq1e22lt7bniy94efj63btv70waa9jw نقاش المستخدم:سام فارشافشيك 3 240325 1097219 2026-07-22T08:02:58Z MenoBot 1177 مرحبا! 1097219 wikitext text/x-wiki <div style="width:auto" style="margin-bottom:1.25em;border:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}}; background:white;padding:0"> <div style="height:8px;margin:0;border:0;border-bottom:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}};background: #{{#switch:bleu|bleu=C8D8FF|vert=D7FFC7|jaune=FFFFB9|or=FFE040|orange=FFDD88|violet=C9AEF1|saumon=FBDFBE|sable=F1E2AE|vertmoyen=99CC66|bleufoncé=003399|rouge=FFDAB9|écarlate=FF3333|#default=E0E0E0}};font-size:1px"></div> <div style="padding:5px;font-size:small"><div class="center"><span style="word-spacing:1ex"><small>[[ويكاموس:سفارة|Welcome!]] [[ويكاموس:سفارة|Bienvenue!]] [[ويكاموس:سفارة|Willkommen!]] [[ويكاموس:سفارة|Benvenuti]] [[ويكاموس:سفارة|¡Bienvenido!]] [[ويكاموس:سفارة|ようこそ]] [[ويكاموس:سفارة|Dobrodošli]] [[ويكاموس:سفارة|환영합니다]] [[ويكاموس:سفارة|Добро пожаловать]] [[ويكاموس:سفارة|Bem-vindo!]] [[ويكاموس:سفارة|欢迎]] [[ويكاموس:سفارة|Bonvenon]] [[ويكاموس:سفارة|Welkom]]</small></span></div></div> <div class="center"><big>'''[[ويكاموس:ترحيب بالقادمين الجدد|مرحبا بك]] في [[ويكاموس]]، سام فارشافشيك !'''</big></div> {| |[[ملف:WiktionaryAr.svg|يمين|40بك]] | [[ويكاموس]] هو <u>مشروع تحرير جماعي لـ'''قاموس علمي وثقافي''' '''بمختلف اللغات'''</u>. لطلب المساعدة في أي وقت تجد وصلة ([[مساعدة:محتويات|'''مساعدة''']]) في هامش كل صفحة على اليمين. لا تتردد في قراءة '''الوصايا الأولى''': * [[ويكاموس:دليل سريع|دليل سريع لتعلم التنسيق]] * [[مساعدة:إنشاء صفحة جديدة|كيف تنشئ صفحة جديدة]] * [[ويكاموس:دروس (التحرير)|دروس مفصلة لتعلم التنسيق]] * [[ويكاموس:صيغة الكتابة|الصيغة الموحدة للكتابة]] * [[ويكاموس:ويكاموس ليس|مبادئ ويكاموس]] لا تتردد في زيارة '''[[مستخدم:سام فارشافشيك/ملعبي|ملعبك الخاص]]''' لاحتواء تجاربك وخطواتك الأولى في التحرير والتعديل. |-- |[[ملف:Presa de decissions.png|يمين|40بك]] | يمكنك الاستفسار و[[ويكاموس:أسئلة|طرح الأسئلة]] المتعلقة بطبيعة العمل في ويكاموس. يمكنك أيضا [{{fullurl:مستخدم:سام فارشافشيك|action=edit}} التعريف] بنفسك في [[مستخدم:سام فارشافشيك|'''صفحتك الشخصية''']]، بكتابة معلومات عنك: [[ويكاموس:بابل|اللغات التي تتكلمها]]، [[ويكاموس:صناديق المستخدم|من أي بلد أنت، ما هي محاور اهتمامك]]... |--- |[[ملف:Crystal Clear app ktip.png|يمين|40بك]] | لا تنس [[ويكاموس:توقيع|'''التوقيع''']] في [[مساعدة:صفحة النقاش|'''صفحات النقاش''']] بكتابة أربع مدّات، هكذا (<nowiki>~~~~</nowiki>). ولكن يجب <u>'''عدم التوقيع في صفحات المقالات القاموسية'''</u>، لأنها تصبح ملكًا للجميع لحظة إنشائها. نرجو منك ألاّ تنسى [[ويكاموس:حقوق التأليف والنشر|<u>'''عدم النسخ من الشابكة'''</u>]] لأسباب [[ويكاموس:حقوق التأليف والنشر|<u>'''حقوق التأليف والنشر'''</u>]]. |-- |[[ملف:Crystal Clear app amor.png|يمين|40بك]] | أخيرا، وهو أهم شيء، نتمى لك أن [[ويكاموس:كن جريئا|'''تتمتع''']] بالمساهمة [[ويكاموس:بوابة المجتمع|'''معنا''']] في هذا المشروع! إذا كانت لديك أي استفسارات أو أسئلة أخرى، يمكنك طرحها في [[ويكاموس:أسئلة|هذه الصفحة]] أو في صفحة نقاشي. |}</div></div> --[[مستخدم:Meno25|Meno25]] ([[نقاش المستخدم:Meno25|نقاش]] • [[خاص:مساهمات/Meno25|مساهمات]]) 08:02، 22 يوليو 2026 (ت ع م) mt6wkpstf0pz2gqtfgcuq924zk7s4ul نقاش المستخدم:Rrrrarar 3 240326 1097220 2026-07-22T08:03:00Z MenoBot 1177 مرحبا! 1097220 wikitext text/x-wiki <div style="width:auto" style="margin-bottom:1.25em;border:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}}; background:white;padding:0"> <div style="height:8px;margin:0;border:0;border-bottom:1px solid #{{#switch:bleu|bleu=8898BF|vert=97BF87|jaune=AAAA66|or=777777|orange=AA8833|violet=7755AA|saumon=AA8866|sable=AA9955|vertmoyen=88BB55|bleufoncé=1144AA|rouge=AA8866|écarlate=AAAAAA|#default=AAAAAA}};background: #{{#switch:bleu|bleu=C8D8FF|vert=D7FFC7|jaune=FFFFB9|or=FFE040|orange=FFDD88|violet=C9AEF1|saumon=FBDFBE|sable=F1E2AE|vertmoyen=99CC66|bleufoncé=003399|rouge=FFDAB9|écarlate=FF3333|#default=E0E0E0}};font-size:1px"></div> <div style="padding:5px;font-size:small"><div class="center"><span style="word-spacing:1ex"><small>[[ويكاموس:سفارة|Welcome!]] [[ويكاموس:سفارة|Bienvenue!]] [[ويكاموس:سفارة|Willkommen!]] [[ويكاموس:سفارة|Benvenuti]] [[ويكاموس:سفارة|¡Bienvenido!]] [[ويكاموس:سفارة|ようこそ]] [[ويكاموس:سفارة|Dobrodošli]] [[ويكاموس:سفارة|환영합니다]] [[ويكاموس:سفارة|Добро пожаловать]] [[ويكاموس:سفارة|Bem-vindo!]] [[ويكاموس:سفارة|欢迎]] [[ويكاموس:سفارة|Bonvenon]] [[ويكاموس:سفارة|Welkom]]</small></span></div></div> <div class="center"><big>'''[[ويكاموس:ترحيب بالقادمين الجدد|مرحبا بك]] في [[ويكاموس]]، Rrrrarar !'''</big></div> {| |[[ملف:WiktionaryAr.svg|يمين|40بك]] | [[ويكاموس]] هو <u>مشروع تحرير جماعي لـ'''قاموس علمي وثقافي''' '''بمختلف اللغات'''</u>. لطلب المساعدة في أي وقت تجد وصلة ([[مساعدة:محتويات|'''مساعدة''']]) في هامش كل صفحة على اليمين. لا تتردد في قراءة '''الوصايا الأولى''': * [[ويكاموس:دليل سريع|دليل سريع لتعلم التنسيق]] * [[مساعدة:إنشاء صفحة جديدة|كيف تنشئ صفحة جديدة]] * [[ويكاموس:دروس (التحرير)|دروس مفصلة لتعلم التنسيق]] * [[ويكاموس:صيغة الكتابة|الصيغة الموحدة للكتابة]] * [[ويكاموس:ويكاموس ليس|مبادئ ويكاموس]] لا تتردد في زيارة '''[[مستخدم:Rrrrarar/ملعبي|ملعبك الخاص]]''' لاحتواء تجاربك وخطواتك الأولى في التحرير والتعديل. |-- |[[ملف:Presa de decissions.png|يمين|40بك]] | يمكنك الاستفسار و[[ويكاموس:أسئلة|طرح الأسئلة]] المتعلقة بطبيعة العمل في ويكاموس. يمكنك أيضا [{{fullurl:مستخدم:Rrrrarar|action=edit}} التعريف] بنفسك في [[مستخدم:Rrrrarar|'''صفحتك الشخصية''']]، بكتابة معلومات عنك: [[ويكاموس:بابل|اللغات التي تتكلمها]]، [[ويكاموس:صناديق المستخدم|من أي بلد أنت، ما هي محاور اهتمامك]]... |--- |[[ملف:Crystal Clear app ktip.png|يمين|40بك]] | لا تنس [[ويكاموس:توقيع|'''التوقيع''']] في [[مساعدة:صفحة النقاش|'''صفحات النقاش''']] بكتابة أربع مدّات، هكذا (<nowiki>~~~~</nowiki>). ولكن يجب <u>'''عدم التوقيع في صفحات المقالات القاموسية'''</u>، لأنها تصبح ملكًا للجميع لحظة إنشائها. نرجو منك ألاّ تنسى [[ويكاموس:حقوق التأليف والنشر|<u>'''عدم النسخ من الشابكة'''</u>]] لأسباب [[ويكاموس:حقوق التأليف والنشر|<u>'''حقوق التأليف والنشر'''</u>]]. |-- |[[ملف:Crystal Clear app amor.png|يمين|40بك]] | أخيرا، وهو أهم شيء، نتمى لك أن [[ويكاموس:كن جريئا|'''تتمتع''']] بالمساهمة [[ويكاموس:بوابة المجتمع|'''معنا''']] في هذا المشروع! إذا كانت لديك أي استفسارات أو أسئلة أخرى، يمكنك طرحها في [[ويكاموس:أسئلة|هذه الصفحة]] أو في صفحة نقاشي. |}</div></div> --[[مستخدم:Meno25|Meno25]] ([[نقاش المستخدم:Meno25|نقاش]] • [[خاص:مساهمات/Meno25|مساهمات]]) 08:03، 22 يوليو 2026 (ت ع م) 6g0u4xz2v5pmpphm2ofumkr8x6ehibk ذَجَّ 0 240327 1097221 2026-07-22T08:28:41Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097221 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1543929}} === المعاني === '''ذَجَّ''' {{نصر}} {{معجمية|L1543929|معاني}} === النطق === * {{أصد-عر|ذَجَّ}} {{-}} === التصريفات === {{تصريف|جذر=ذجج|وزن=فعَل يفعُل}} === المراجع === {{مراجع}} 3mz68ckfudclf14cvjj4d3jn7v3gg9l جَانَى 0 240328 1097222 2026-07-22T09:04:51Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097222 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1484219}} === المعاني === '''جَانَى''' {{فاعل}} {{معجمية|L1484219|معاني}} === النطق === * {{أصد-عر|جَانَى}} {{-}} === التصريفات === {{تصريف|جذر=جني|وزن=فاعل}} === المراجع === {{مراجع}} 4edjgl3fr6o34i7e8uh9sd00xig2hnq جَنْدَلَ 0 240329 1097223 2026-07-22T09:05:45Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097223 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1486391}} === المعاني === '''جَنْدَلَ''' {{فعلل}} {{معجمية|L1486391|معاني}} === النطق === * {{أصد-عر|جَنْدَلَ}} {{-}} === التصريفات === {{تصريف|جذر=جندل|وزن=فعلل}} === المراجع === {{مراجع}} neclnuacz0ixqb93xp1jx8g8wazyr4h تَجَاهَرَ 0 240330 1097224 2026-07-22T09:08:48Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097224 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1497595}} === المعاني === '''تَجَاهَرَ''' {{تفاعل}} {{معجمية|L1497595|معاني}} === النطق === * {{أصد-عر|تَجَاهَرَ}} {{-}} === التصريفات === {{تصريف|جذر=جهر|وزن=تفاعل}} === المراجع === {{مراجع}} owqeiyeubhh2awgv0y4guz36ti4kpsm بَحْظَلَ 0 240331 1097225 2026-07-22T12:40:23Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097225 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532826}} === المعاني === '''بَحْظَلَ''' {{فعلل}} {{معجمية|L1532826|معاني}} === النطق === * {{أصد-عر|بَحْظَلَ}} {{-}} === التصريفات === {{تصريف|جذر=بحظل|وزن=فعلل}} === المراجع === {{مراجع}} bvk5bt781kvfop8qomcvxmqt4npgsmt تَبَادَهَ 0 240332 1097226 2026-07-22T12:41:49Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097226 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532869}} === المعاني === '''تَبَادَهَ''' {{تفاعل}} {{معجمية|L1532869|معاني}} === النطق === * {{أصد-عر|تَبَادَهَ}} {{-}} === التصريفات === {{تصريف|جذر=بده|وزن=تفاعل}} === المراجع === {{مراجع}} ryr76ywcira94s9rvcsm16js68gi54k تَبَرَّرَ 0 240333 1097227 2026-07-22T12:48:28Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097227 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1486106}} === المعاني === '''تَبَرَّرَ''' {{تفعّل}} {{معجمية|L1486106|معاني}} === النطق === * {{أصد-عر|تَبَرَّرَ}} {{-}} === التصريفات === {{تصريف|جذر=برر|وزن=تفعّل}} === المراجع === {{مراجع}} 3x26p005t6jvubqppn9mb3qvq29cyfx تَبَارَزَ 0 240334 1097228 2026-07-22T12:57:22Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097228 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1496923}} === المعاني === '''تَبَارَزَ''' {{تفاعل}} {{معجمية|L1496923|معاني}} === النطق === * {{أصد-عر|تَبَارَزَ}} {{-}} === التصريفات === {{تصريف|جذر=برز|وزن=تفاعل}} === المراجع === {{مراجع}} iqnebkcbyib67ca5kr9h9sh8vthfli4 بَرْشَكَ 0 240335 1097229 2026-07-22T13:00:23Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097229 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532936}} === المعاني === '''بَرْشَكَ''' {{فعلل}} {{معجمية|L1532936|معاني}} === النطق === * {{أصد-عر|بَرْشَكَ}} {{-}} === التصريفات === {{تصريف|جذر=برشك|وزن=فعلل}} === المراجع === {{مراجع}} 5e8lqikkl7aw41ya41jmw51l2l05i41 بَرْطَسَ 0 240336 1097230 2026-07-22T13:02:08Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097230 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532944}} === المعاني === '''بَرْطَسَ''' {{فعلل}} {{معجمية|L1532944|معاني}} === النطق === * {{أصد-عر|بَرْطَسَ}} {{-}} === التصريفات === {{تصريف|جذر=برطس|وزن=فعلل}} === المراجع === {{مراجع}} j5oye3ny45vf7bxmzwvzb2ildxlxutv اِبْرَنْطَمَ 0 240337 1097231 2026-07-22T13:07:06Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097231 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532946}} === المعاني === '''اِبْرَنْطَمَ''' {{افعنلل}} {{معجمية|L1532946|معاني}} === النطق === * {{أصد-عر|اِبْرَنْطَمَ}} {{-}} === التصريفات === {{تصريف|جذر=برطم|وزن=افعنلل}} === المراجع === {{مراجع}} ork0rad8ryjzh3y5rxo61km0rm5wao7 اِبْرَغَشَّ 0 240338 1097232 2026-07-22T13:08:01Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097232 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1483808}} === المعاني === '''اِبْرَغَشَّ''' {{افعللّ}} {{معجمية|L1483808|معاني}} === النطق === * {{أصد-عر|اِبْرَغَشَّ}} {{-}} === التصريفات === {{تصريف|جذر=برغش|وزن=افعللّ}} === المراجع === {{مراجع}} 597k3y5ijjr98rl3vwu23jmcqfmi4no تَبَرْقَحَ 0 240339 1097233 2026-07-22T13:08:48Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097233 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532954}} === المعاني === '''تَبَرْقَحَ''' {{تفعلل}} {{معجمية|L1532954|معاني}} === النطق === * {{أصد-عر|تَبَرْقَحَ}} {{-}} === التصريفات === {{تصريف|جذر=برقح|وزن=تفعلل}} === المراجع === {{مراجع}} q93ycgfftpkvb3vq5vh2n3y6b4d0v74 تَبَرَّكَ 0 240340 1097234 2026-07-22T13:10:39Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097234 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1495783}} === المعاني === '''تَبَرَّكَ''' {{تفعّل}} {{معجمية|L1495783|معاني}} === النطق === * {{أصد-عر|تَبَرَّكَ}} {{-}} === التصريفات === {{تصريف|جذر=برك|وزن=تفعّل}} === المراجع === {{مراجع}} ajjbcwb44lzfvn64g96xjrpm99xffeb دَحْدَرَ 0 240341 1097239 2026-07-22T14:53:11Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097239 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535299}} === المعاني === '''دَحْدَرَ''' {{فعلل}} {{معجمية|L1535299|معاني}} === النطق === * {{أصد-عر|دَحْدَرَ}} {{-}} === التصريفات === {{تصريف|جذر=دحدر|وزن=فعلل}} === المراجع === {{مراجع}} sluvw93tfw8i8mz95oqxywj4a4v22pb زَعَمَ 0 240342 1097240 2026-07-22T14:55:19Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097240 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1482094}} === المعاني === '''زَعَمَ''' {{فتح}} {{معجمية|L1482094|معاني}} === النطق === * {{أصد-عر|زَعَمَ}} {{-}} === التصريفات === {{تصريف|جذر=زعم|وزن=فعَل يفعَل}} === المراجع === {{مراجع}} q93mw9pit2wh0yl8nxlosmrj03u7jrh اِجْثَأَلَّ 0 240343 1097241 2026-07-22T14:56:18Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097241 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533726}} === المعاني === '''اِجْثَأَلَّ''' {{افعللّ}} {{معجمية|L1533726|معاني}} === النطق === * {{أصد-عر|اِجْثَأَلَّ}} {{-}} === التصريفات === {{تصريف|جذر=جثأل|وزن=افعللّ}} === المراجع === {{مراجع}} mjuzudb8ed1lmmwez8eq0ggra32tns0 تَدَلْمَصَ 0 240344 1097242 2026-07-22T14:57:04Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097242 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535535}} === المعاني === '''تَدَلْمَصَ''' {{تفعلل}} {{معجمية|L1535535|معاني}} === النطق === * {{أصد-عر|تَدَلْمَصَ}} {{-}} === التصريفات === {{تصريف|جذر=دلمص|وزن=تفعلل}} === المراجع === {{مراجع}} sqwce9huxuuv8a5852p2efdyl0q08k3 خَتْرَبَ 0 240345 1097243 2026-07-22T14:57:33Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097243 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534816}} === المعاني === '''خَتْرَبَ''' {{فعلل}} {{معجمية|L1534816|معاني}} === النطق === * {{أصد-عر|خَتْرَبَ}} {{-}} === التصريفات === {{تصريف|جذر=خترب|وزن=فعلل}} === المراجع === {{مراجع}} 4l2el62f8b99m6qtrj3o8cxx8ub7zbr سَارَى 0 240346 1097244 2026-07-22T15:03:14Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097244 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1496764}} === المعاني === '''سَارَى''' {{فاعل}} {{معجمية|L1496764|معاني}} === النطق === * {{أصد-عر|سَارَى}} {{-}} === التصريفات === {{تصريف|جذر=سري|وزن=فاعل}} === المراجع === {{مراجع}} 5k8wvby8r1rjyjr7i93mr6gatrcjlfb اِزْرَنْقَفَ 0 240347 1097245 2026-07-22T15:04:03Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097245 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536488}} === المعاني === '''اِزْرَنْقَفَ''' {{افعنلل}} {{معجمية|L1536488|معاني}} === النطق === * {{أصد-عر|اِزْرَنْقَفَ}} {{-}} === التصريفات === {{تصريف|جذر=زرقف|وزن=افعنلل}} === المراجع === {{مراجع}} 5vco93zx1lzwl29zsrjb6wvvwg3myje اِدَّسَعَ 0 240348 1097246 2026-07-22T15:04:46Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097246 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535394}} === المعاني === '''اِدَّسَعَ''' {{افتعل}} {{معجمية|L1535394|معاني}} === النطق === * {{أصد-عر|اِدَّسَعَ}} {{-}} === التصريفات === {{تصريف|جذر=دسع|وزن=افتعل}} === المراجع === {{مراجع}} 0ybm40u6ps3mjeg6zki1beauoeykm62 اِسْتَحْفَظَ 0 240349 1097247 2026-07-22T15:05:22Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097247 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1480943}} === المعاني === '''اِسْتَحْفَظَ''' {{استفعل}} {{معجمية|L1480943|معاني}} === النطق === * {{أصد-عر|اِسْتَحْفَظَ}} {{-}} === التصريفات === {{تصريف|جذر=حفظ|وزن=استفعل}} === المراجع === {{مراجع}} 25a3pq19b4ih42bj7fslffhhz660a22 زَرْدَمَ 0 240350 1097248 2026-07-22T15:06:21Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097248 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536471}} === المعاني === '''زَرْدَمَ''' {{فعلل}} {{معجمية|L1536471|معاني}} === النطق === * {{أصد-عر|زَرْدَمَ}} {{-}} === التصريفات === {{تصريف|جذر=زردم|وزن=فعلل}} === المراجع === {{مراجع}} d32bntb8aml7uycpe4iwv044e9qa0j0 تَدَيَّنَ 0 240351 1097249 2026-07-22T15:07:02Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097249 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1487590}} === المعاني === '''تَدَيَّنَ''' {{تفعّل}} {{معجمية|L1487590|معاني}} === النطق === * {{أصد-عر|تَدَيَّنَ}} {{-}} === التصريفات === {{تصريف|جذر=دين|وزن=تفعّل}} === المراجع === {{مراجع}} 59673caqnc6pwmk7gw8nxtynw21hjtf سَدَّحَ 0 240352 1097250 2026-07-22T15:07:33Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097250 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536851}} === المعاني === '''سَدَّحَ''' {{فعّل}} {{معجمية|L1536851|معاني}} === النطق === * {{أصد-عر|سَدَّحَ}} {{-}} === التصريفات === {{تصريف|جذر=سدح|وزن=فعّل}} === المراجع === {{مراجع}} 9l1j48v0huttyd9ffz254529mchck5k رَازَغَ 0 240353 1097251 2026-07-22T15:08:15Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097251 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535988}} === المعاني === '''رَازَغَ''' {{فاعل}} {{معجمية|L1535988|معاني}} === النطق === * {{أصد-عر|رَازَغَ}} {{-}} === التصريفات === {{تصريف|جذر=رزغ|وزن=فاعل}} === المراجع === {{مراجع}} eaeeyaheoomq93icgtv5w0mjf128yb9 تَجَنَّى 0 240354 1097252 2026-07-22T15:32:51Z نور إسماعيل 37425 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097252 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1486162}} === المعاني === '''تَجَنَّى''' {{تفعّل}} {{معجمية|L1486162|معاني}} === النطق === * {{أصد-عر|تَجَنَّى}} {{-}} === التصريفات === {{تصريف|جذر=جني|وزن=تفعّل}} === المراجع === {{مراجع}} i86rtepnqxxd3prdp801cbkvbnujku7 زَأَطَ 0 240355 1097255 2026-07-22T16:05:23Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097255 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1487998}} === المعاني === '''زَأَطَ''' {{فتح}} {{معجمية|L1487998|معاني}} === النطق === * {{أصد-عر|زَأَطَ}} {{-}} === التصريفات === {{تصريف|جذر=زأط|وزن=فعَل يفعَل}} === المراجع === {{مراجع}} lotywyvyjnlta436hmyf4ouyb0gbcn6 زَأَكَ 0 240356 1097256 2026-07-22T16:06:58Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097256 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1544828}} === المعاني === '''زَأَكَ''' {{فتح}} {{معجمية|L1544828|معاني}} === النطق === * {{أصد-عر|زَأَكَ}} {{-}} === التصريفات === {{تصريف|جذر=زأك|وزن=فعَل يفعَل}} === المراجع === {{مراجع}} 7bo4nqu356suhdffgliya2apwmegi5g زَأَّمَ 0 240357 1097257 2026-07-22T16:09:55Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097257 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536393}} === المعاني === '''زَأَّمَ''' {{فعّل}} {{معجمية|L1536393|معاني}} === النطق === * {{أصد-عر|زَأَّمَ}} {{-}} === التصريفات === {{تصريف|جذر=زأم|وزن=فعّل}} === المراجع === {{مراجع}} 22ufzm6jp2irs17yflo8vgiady9u7ra أَزْأَى 0 240358 1097258 2026-07-22T16:12:25Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097258 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536394}} === المعاني === '''أَزْأَى''' {{أفعل}} {{معجمية|L1536394|معاني}} === النطق === * {{أصد-عر|أَزْأَى}} {{-}} === التصريفات === {{تصريف|جذر=زأي|وزن=أفعل}} === المراجع === {{مراجع}} 5i05jiht10kr8jpz7q1fg3no25zm9eq بَشْبَشَ 0 240359 1097259 2026-07-22T16:13:12Z ForzaGreen 28665 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097259 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1533025}} === المعاني === '''بَشْبَشَ''' {{فعلل}} {{معجمية|L1533025|معاني}} === النطق === * {{أصد-عر|بَشْبَشَ}} {{-}} === التصريفات === {{تصريف|جذر=بشبش|وزن=فعلل}} === المراجع === {{مراجع}} g2chs4g8voi49zf7z0m9vlb58x3fm77 اِزْبَغَلَّ 0 240360 1097260 2026-07-22T16:18:05Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097260 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536410}} === المعاني === '''اِزْبَغَلَّ''' {{افعللّ}} {{معجمية|L1536410|معاني}} === النطق === * {{أصد-عر|اِزْبَغَلَّ}} {{-}} === التصريفات === {{تصريف|جذر=زبغل|وزن=افعللّ}} === المراجع === {{مراجع}} oi5gwksk6ex3c05mwc1gv34tcwvyodm اِزْدَبَلَ 0 240361 1097261 2026-07-22T16:21:19Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097261 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536412}} === المعاني === '''اِزْدَبَلَ''' {{افتعل}} {{معجمية|L1536412|معاني}} === النطق === * {{أصد-عر|اِزْدَبَلَ}} {{-}} === التصريفات === {{تصريف|جذر=زبل|وزن=افتعل}} === المراجع === {{مراجع}} 9c2pisekzwgs9aj8hhhswmccf5v6eku زَبَّلَ 0 240362 1097262 2026-07-22T16:22:19Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097262 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1487697}} === المعاني === '''زَبَّلَ''' {{فعّل}} {{معجمية|L1487697|معاني}} === النطق === * {{أصد-عر|زَبَّلَ}} {{-}} === التصريفات === {{تصريف|جذر=زبل|وزن=فعّل}} === المراجع === {{مراجع}} dodbgpfqrlf8pzkyapj4gfnkmu2h1hr اِسْتَزْبَنَ 0 240363 1097263 2026-07-22T16:23:35Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097263 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536413}} === المعاني === '''اِسْتَزْبَنَ''' {{استفعل}} {{معجمية|L1536413|معاني}} === النطق === * {{أصد-عر|اِسْتَزْبَنَ}} {{-}} === التصريفات === {{تصريف|جذر=زبن|وزن=استفعل}} === المراجع === {{مراجع}} 9hcyshtwot6wc76mb7nh28aso4hicxr تَزَابَنَ 0 240364 1097264 2026-07-22T16:26:35Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097264 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536415}} === المعاني === '''تَزَابَنَ''' {{تفاعل}} {{معجمية|L1536415|معاني}} === النطق === * {{أصد-عر|تَزَابَنَ}} {{-}} === التصريفات === {{تصريف|جذر=زبن|وزن=تفاعل}} === المراجع === {{مراجع}} eczmeimalg6rgd9g0ejwob0e6k7lkhw تَزَبَّنَ 0 240365 1097265 2026-07-22T16:29:22Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097265 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536416}} === المعاني === '''تَزَبَّنَ''' {{تفعّل}} {{معجمية|L1536416|معاني}} === النطق === * {{أصد-عر|تَزَبَّنَ}} {{-}} === التصريفات === {{تصريف|جذر=زبن|وزن=تفعّل}} === المراجع === {{مراجع}} 1ra56bfozkhxgzqd3p58o3pgb30p3kn اِزْدَبَى 0 240366 1097266 2026-07-22T16:41:42Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097266 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536419}} === المعاني === '''اِزْدَبَى''' {{افتعل}} {{معجمية|L1536419|معاني}} === النطق === * {{أصد-عر|اِزْدَبَى}} {{-}} === التصريفات === {{تصريف|جذر=زبي|وزن=افتعل}} === المراجع === {{مراجع}} dq0xbbb89djrv1lgzfiljw6yfh6gymy زَبَّى 0 240367 1097267 2026-07-22T16:46:31Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097267 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536422}} === المعاني === '''زَبَّى''' {{فعّل}} {{معجمية|L1536422|معاني}} === النطق === * {{أصد-عر|زَبَّى}} {{-}} === التصريفات === {{تصريف|جذر=زبي|وزن=فعّل}} === المراجع === {{مراجع}} 7a22kblh4l1vmzkbwcnbpxmhijvbsgz أَزْبَى 0 240368 1097268 2026-07-22T16:49:15Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097268 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536418}} === المعاني === '''أَزْبَى''' {{أفعل}} {{معجمية|L1536418|معاني}} === النطق === * {{أصد-عر|أَزْبَى}} {{-}} === التصريفات === {{تصريف|جذر=زبي|وزن=أفعل}} === المراجع === {{مراجع}} sd0ago95c8pf288ko71kbiqeawdm6ek تَزَابَى 0 240369 1097269 2026-07-22T16:53:12Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097269 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536420}} === المعاني === '''تَزَابَى''' {{تفاعل}} {{معجمية|L1536420|معاني}} === النطق === * {{أصد-عر|تَزَابَى}} {{-}} === التصريفات === {{تصريف|جذر=زبي|وزن=تفاعل}} === المراجع === {{مراجع}} sfya2vhsgqptz2lunw594x00hhnls1z تَزَبَّى 0 240370 1097270 2026-07-22T16:56:06Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097270 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536421}} === المعاني === '''تَزَبَّى''' {{تفعّل}} {{معجمية|L1536421|معاني}} === النطق === * {{أصد-عر|تَزَبَّى}} {{-}} === التصريفات === {{تصريف|جذر=زبي|وزن=تفعّل}} === المراجع === {{مراجع}} fiupr1e018tqlt2c7wfher7h4hovbhk زَبَى 0 240371 1097271 2026-07-22T17:01:09Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097271 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1543410}} === المعاني === '''زَبَى''' {{ضرب}} {{معجمية|L1543410|معاني}} === النطق === * {{أصد-عر|زَبَى}} {{-}} === التصريفات === {{تصريف|جذر=زبي|وزن=فعَل يفعِل}} === المراجع === {{مراجع}} depi4tlnrci8vqp1lrh04d4mew7v2y7 تَزَحْزَحَ 0 240372 1097272 2026-07-22T17:45:08Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097272 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1488296}} === المعاني === '''تَزَحْزَحَ''' {{تفعلل}} {{معجمية|L1488296|معاني}} === النطق === * {{أصد-عر|تَزَحْزَحَ}} {{-}} === التصريفات === {{تصريف|جذر=زحزح|وزن=تفعلل}} === المراجع === {{مراجع}} 0t7h58gnu48q97u3ozgcltcw5yns5b6 زَحْزَحَ 0 240373 1097273 2026-07-22T17:48:06Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097273 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1477070}} === المعاني === '''زَحْزَحَ''' {{فعلل}} {{معجمية|L1477070|معاني}} === النطق === * {{أصد-عر|زَحْزَحَ}} {{-}} === التصريفات === {{تصريف|جذر=زحزح|وزن=فعلل}} === المراجع === {{مراجع}} fsdax5jiyazlzn80y9ecdqu5i72sdvo اِزْدَحَفَ 0 240374 1097274 2026-07-22T17:55:28Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097274 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536436}} === المعاني === '''اِزْدَحَفَ''' {{افتعل}} {{معجمية|L1536436|معاني}} === النطق === * {{أصد-عر|اِزْدَحَفَ}} {{-}} === التصريفات === {{تصريف|جذر=زحف|وزن=افتعل}} === المراجع === {{مراجع}} df43q47ferxlx9dhjqqd84vgt9p1f6p تَزَاحَفَ 0 240375 1097275 2026-07-22T18:19:38Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097275 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1497880}} === المعاني === '''تَزَاحَفَ''' {{تفاعل}} {{معجمية|L1497880|معاني}} === النطق === * {{أصد-عر|تَزَاحَفَ}} {{-}} === التصريفات === {{تصريف|جذر=زحف|وزن=تفاعل}} === المراجع === {{مراجع}} h3gube47a5wpeha7kicdwijhhw430fm زَاحَفَ 0 240376 1097276 2026-07-22T18:21:21Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097276 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1497680}} === المعاني === '''زَاحَفَ''' {{فاعل}} {{معجمية|L1497680|معاني}} === النطق === * {{أصد-عر|زَاحَفَ}} {{-}} === التصريفات === {{تصريف|جذر=زحف|وزن=فاعل}} === المراجع === {{مراجع}} 4eh8rl0xslegmx5z1pbbx4szf56bnso زَحَّفَ 0 240377 1097277 2026-07-22T18:24:01Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097277 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536438}} === المعاني === '''زَحَّفَ''' {{فعّل}} {{معجمية|L1536438|معاني}} === النطق === * {{أصد-عر|زَحَّفَ}} {{-}} === التصريفات === {{تصريف|جذر=زحف|وزن=فعّل}} === المراجع === {{مراجع}} 9cl3utap5yfr2tq0tv49xaaiemlda57 أَزْحَكَ 0 240378 1097278 2026-07-22T18:31:38Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097278 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536439}} === المعاني === '''أَزْحَكَ''' {{أفعل}} {{معجمية|L1536439|معاني}} === النطق === * {{أصد-عر|أَزْحَكَ}} {{-}} === التصريفات === {{تصريف|جذر=زحك|وزن=أفعل}} === المراجع === {{مراجع}} 918dwgpp8syub4n934sqgs7wlwsb3i2 تَزَاحَكَ 0 240379 1097279 2026-07-22T18:34:53Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097279 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536440}} === المعاني === '''تَزَاحَكَ''' {{تفاعل}} {{معجمية|L1536440|معاني}} === النطق === * {{أصد-عر|تَزَاحَكَ}} {{-}} === التصريفات === {{تصريف|جذر=زحك|وزن=تفاعل}} === المراجع === {{مراجع}} i71zuxm9b1cmnhuhtl48hjxenwy8xj2 زَاحَكَ 0 240380 1097280 2026-07-22T18:36:55Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097280 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536441}} === المعاني === '''زَاحَكَ''' {{فاعل}} {{معجمية|L1536441|معاني}} === النطق === * {{أصد-عر|زَاحَكَ}} {{-}} === التصريفات === {{تصريف|جذر=زحك|وزن=فاعل}} === المراجع === {{مراجع}} ses8048yzs4qbcm407uwjm44adyct9c زَحَكَ 0 240381 1097281 2026-07-22T18:46:08Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097281 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1544458}} === المعاني === '''زَحَكَ''' {{فتح}} {{معجمية|L1544458|معاني}} === النطق === * {{أصد-عر|زَحَكَ}} {{-}} === التصريفات === {{تصريف|جذر=زحك|وزن=فعَل يفعَل}} === المراجع === {{مراجع}} 43cgw21vghun7izgbuxlrtplwf15fc3 أَزْحَلَ 0 240382 1097282 2026-07-22T18:51:53Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097282 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536442}} === المعاني === '''أَزْحَلَ''' {{أفعل}} {{معجمية|L1536442|معاني}} === النطق === * {{أصد-عر|أَزْحَلَ}} {{-}} === التصريفات === {{تصريف|جذر=زحل|وزن=أفعل}} === المراجع === {{مراجع}} 9exi4dcr525n7akowoz6llbqw4opqec اِزْحَالَّ 0 240383 1097283 2026-07-22T18:53:15Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097283 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536443}} === المعاني === '''اِزْحَالَّ''' {{افعالّ}} {{معجمية|L1536443|معاني}} === النطق === * {{أصد-عر|اِزْحَالَّ}} {{-}} === التصريفات === {{تصريف|جذر=زحل|وزن=افعالّ}} === المراجع === {{مراجع}} hu7tg0p6jvm7iscbov5jkgb4ek6h08p زَحْمَرَ 0 240384 1097289 2026-07-22T23:09:20Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097289 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536448}} === المعاني === '''زَحْمَرَ''' {{فعلل}} {{معجمية|L1536448|معاني}} === النطق === * {{أصد-عر|زَحْمَرَ}} {{-}} === التصريفات === {{تصريف|جذر=زحمر|وزن=فعلل}} === المراجع === {{مراجع}} m7mm4or83gq22a4065ay0pmm09ywkep تَزَحْوَلَ 0 240385 1097290 2026-07-22T23:13:04Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097290 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536451}} === المعاني === '''تَزَحْوَلَ''' {{تفعلل}} {{معجمية|L1536451|معاني}} === النطق === * {{أصد-عر|تَزَحْوَلَ}} {{-}} === التصريفات === {{تصريف|جذر=زحول|وزن=تفعلل}} === المراجع === {{مراجع}} cle68grt7jb73k0hri407ejcpgpwghb زَخْزَخَ 0 240386 1097291 2026-07-22T23:17:21Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097291 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536453}} === المعاني === '''زَخْزَخَ''' {{فعلل}} {{معجمية|L1536453|معاني}} === النطق === * {{أصد-عر|زَخْزَخَ}} {{-}} === التصريفات === {{تصريف|جذر=زخزخ|وزن=فعلل}} === المراجع === {{مراجع}} f9n6d9g0zgvl2m4imxy6zd7m5oh30t6 تَزَخَّفَ 0 240387 1097292 2026-07-22T23:19:54Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097292 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536454}} === المعاني === '''تَزَخَّفَ''' {{تفعّل}} {{معجمية|L1536454|معاني}} === النطق === * {{أصد-عر|تَزَخَّفَ}} {{-}} === التصريفات === {{تصريف|جذر=زخف|وزن=تفعّل}} === المراجع === {{مراجع}} adcior7g85u3yfjcjcnzi2alzgv1z9n اِزْرَبَّ 0 240388 1097293 2026-07-22T23:29:12Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097293 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536464}} === المعاني === '''اِزْرَبَّ''' {{افعلّ}} {{معجمية|L1536464|معاني}} === النطق === * {{أصد-عر|اِزْرَبَّ}} {{-}} === التصريفات === {{تصريف|جذر=زرب|وزن=افعلّ}} === المراجع === {{مراجع}} h262vcu7o2xkz5qo8cdv4xx05pf8foq اِنْزَرَبَ 0 240389 1097294 2026-07-22T23:37:37Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097294 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536465}} === المعاني === '''اِنْزَرَبَ''' {{انفعل}} {{معجمية|L1536465|معاني}} === النطق === * {{أصد-عر|اِنْزَرَبَ}} {{-}} === التصريفات === {{تصريف|جذر=زرب|وزن=انفعل}} === المراجع === {{مراجع}} fq39ymtcetz3ip81adm53dorif0q6h3 أَزْدَى 0 240390 1097295 2026-07-22T23:43:50Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097295 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536461}} === المعاني === '''أَزْدَى''' {{أفعل}} {{معجمية|L1536461|معاني}} === النطق === * {{أصد-عر|أَزْدَى}} {{-}} === التصريفات === {{تصريف|جذر=زدو|وزن=أفعل}} === المراجع === {{مراجع}} 2uugk8anlvjcfe2dd9qary0vzd47hiq زَرَجَ 0 240391 1097296 2026-07-22T23:47:36Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097296 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1545338}} === المعاني === '''زَرَجَ''' {{نصر}} {{معجمية|L1545338|معاني}} === النطق === * {{أصد-عر|زَرَجَ}} {{-}} === التصريفات === {{تصريف|جذر=زرج|وزن=فعَل يفعُل}} === المراجع === {{مراجع}} g9jb8y0m8ac0512m9f81rlqsm1jr5ew زَرَطَ 0 240392 1097297 2026-07-22T23:52:41Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097297 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1543769}} === المعاني === '''زَرَطَ''' {{ضرب}} {{معجمية|L1543769|معاني}} === النطق === * {{أصد-عر|زَرَطَ}} {{-}} === التصريفات === {{تصريف|جذر=زرط|وزن=فعَل يفعِل}} === المراجع === {{مراجع}} mge2ydoa1h9zpjh00o7ecbqb9r5dtku زَرْدَبَ 0 240393 1097298 2026-07-22T23:54:45Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097298 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536470}} === المعاني === '''زَرْدَبَ''' {{فعلل}} {{معجمية|L1536470|معاني}} === النطق === * {{أصد-عر|زَرْدَبَ}} {{-}} === التصريفات === {{تصريف|جذر=زردب|وزن=فعلل}} === المراجع === {{مراجع}} 0f6dfs3ff8ipj8tvwafahowzbsb8ack زَرْفَنَ 0 240394 1097299 2026-07-22T23:57:10Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097299 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536483}} === المعاني === '''زَرْفَنَ''' {{فعلل}} {{معجمية|L1536483|معاني}} === النطق === * {{أصد-عر|زَرْفَنَ}} {{-}} === التصريفات === {{تصريف|جذر=زرفن|وزن=فعلل}} === المراجع === {{مراجع}} 69kq41h4kj5o38nayjn4p27j426x6b6 زَرْقَفَ 0 240395 1097300 2026-07-23T00:05:29Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097300 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536487}} === المعاني === '''زَرْقَفَ''' {{فعلل}} {{معجمية|L1536487|معاني}} === النطق === * {{أصد-عر|زَرْقَفَ}} {{-}} === التصريفات === {{تصريف|جذر=زرقف|وزن=فعلل}} === المراجع === {{مراجع}} ebm7ag6rti1zgmnav9qzzw3s1yonhzq اِزْدَعَبَ 0 240396 1097301 2026-07-23T00:14:03Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097301 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536499}} === المعاني === '''اِزْدَعَبَ''' {{افتعل}} {{معجمية|L1536499|معاني}} === النطق === * {{أصد-عر|اِزْدَعَبَ}} {{-}} === التصريفات === {{تصريف|جذر=زعب|وزن=افتعل}} === المراجع === {{مراجع}} 2nb1393hph9mnpwk8k3d7mat4ev618e تَبَحْثَنَ 0 240397 1097302 2026-07-23T00:57:37Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097302 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532820}} === المعاني === '''تَبَحْثَنَ''' {{تفعلل}} {{معجمية|L1532820|معاني}} === النطق === * {{أصد-عر|تَبَحْثَنَ}} {{-}} === التصريفات === {{تصريف|جذر=بحثن|وزن=تفعلل}} === المراجع === {{مراجع}} i7nf3g72p4esu1b0tmaupw0a01vbuvu تَبَرْزَقَ 0 240398 1097303 2026-07-23T00:58:14Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097303 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1532929}} === المعاني === '''تَبَرْزَقَ''' {{تفعلل}} {{معجمية|L1532929|معاني}} === النطق === * {{أصد-عر|تَبَرْزَقَ}} {{-}} === التصريفات === {{تصريف|جذر=برزق|وزن=تفعلل}} === المراجع === {{مراجع}} 23lecmj6lfzf1fny726bpowwipgq7a2 اِنْسَحَجَ 0 240399 1097304 2026-07-23T01:05:22Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097304 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536809}} === المعاني === '''اِنْسَحَجَ''' {{انفعل}} {{معجمية|L1536809|معاني}} === النطق === * {{أصد-عر|اِنْسَحَجَ}} {{-}} === التصريفات === {{تصريف|جذر=سحج|وزن=انفعل}} === المراجع === {{مراجع}} av101apqjwljvc9q4f2kax1tf0kuf7o سَخَّدَ 0 240400 1097305 2026-07-23T01:06:24Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097305 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536837}} === المعاني === '''سَخَّدَ''' {{فعّل}} {{معجمية|L1536837|معاني}} === النطق === * {{أصد-عر|سَخَّدَ}} {{-}} === التصريفات === {{تصريف|جذر=سخد|وزن=فعّل}} === المراجع === {{مراجع}} f09xfbvr35l5ldqml5ra30pdmwecs2k أَسْخَفَ 0 240401 1097306 2026-07-23T01:06:50Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097306 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536839}} === المعاني === '''أَسْخَفَ''' {{أفعل}} {{معجمية|L1536839|معاني}} === النطق === * {{أصد-عر|أَسْخَفَ}} {{-}} === التصريفات === {{تصريف|جذر=سخف|وزن=أفعل}} === المراجع === {{مراجع}} 2jorusbt1a4yr19krotb7rljkhroajp تَسَدَّجَ 0 240402 1097307 2026-07-23T01:07:40Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097307 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536848}} === المعاني === '''تَسَدَّجَ''' {{تفعّل}} {{معجمية|L1536848|معاني}} === النطق === * {{أصد-عر|تَسَدَّجَ}} {{-}} === التصريفات === {{تصريف|جذر=سدج|وزن=تفعّل}} === المراجع === {{مراجع}} 8fxvawtfxnssjwgrlsyqivmtbavacln اِنْسَدَمَ 0 240403 1097308 2026-07-23T01:08:14Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097308 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1536861}} === المعاني === '''اِنْسَدَمَ''' {{انفعل}} {{معجمية|L1536861|معاني}} === النطق === * {{أصد-عر|اِنْسَدَمَ}} {{-}} === التصريفات === {{تصريف|جذر=سدم|وزن=انفعل}} === المراجع === {{مراجع}} b58bipzdfjfjslhzlz3t6ptpg9ni7k1 زَنَأَ 0 240404 1097309 2026-07-23T01:12:45Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097309 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1488396}} === المعاني === '''زَنَأَ''' {{فتح}} {{معجمية|L1488396|معاني}} === النطق === * {{أصد-عر|زَنَأَ}} {{-}} === التصريفات === {{تصريف|جذر=زنأ|وزن=فعَل يفعَل}} === المراجع === {{مراجع}} dnuapqhn71wur7zq7ja201dhe2degp5 رَاءَفَ 0 240405 1097310 2026-07-23T01:13:40Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097310 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1535811}} === المعاني === '''رَاءَفَ''' {{فاعل}} {{معجمية|L1535811|معاني}} === النطق === * {{أصد-عر|رَاءَفَ}} {{-}} === التصريفات === {{تصريف|جذر=رأف|وزن=فاعل}} === المراجع === {{مراجع}} l3x3q7pqzalbdrx0a0j8epyoctq0dnv رَاحَلَ 0 240406 1097311 2026-07-23T01:14:47Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097311 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1497331}} === المعاني === '''رَاحَلَ''' {{فاعل}} {{معجمية|L1497331|معاني}} === النطق === * {{أصد-عر|رَاحَلَ}} {{-}} === التصريفات === {{تصريف|جذر=رحل|وزن=فاعل}} === المراجع === {{مراجع}} fdumwkyig4u6q9lm70bapyi3gjg7ace تَرَحَّمَ 0 240407 1097312 2026-07-23T01:15:26Z رِفْد 37814 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097312 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1486223}} === المعاني === '''تَرَحَّمَ''' {{تفعّل}} {{معجمية|L1486223|معاني}} === النطق === * {{أصد-عر|تَرَحَّمَ}} {{-}} === التصريفات === {{تصريف|جذر=رحم|وزن=تفعّل}} === المراجع === {{مراجع}} mbrzbiuzn59ab2ep38koyxt89ev3b46 اِحْبَجَرَّ 0 240408 1097313 2026-07-23T09:55:18Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097313 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534169}} === المعاني === '''اِحْبَجَرَّ''' {{افعللّ}} {{معجمية|L1534169|معاني}} === النطق === * {{أصد-عر|اِحْبَجَرَّ}} {{-}} === التصريفات === {{تصريف|جذر=حبجر|وزن=افعللّ}} === المراجع === {{مراجع}} 8ugpkrtkmdvksh8773nrpnuph6y9puo اِحْبَنْجَرَ 0 240409 1097314 2026-07-23T09:57:27Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097314 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534170}} === المعاني === '''اِحْبَنْجَرَ''' {{افعنلل}} {{معجمية|L1534170|معاني}} === النطق === * {{أصد-عر|اِحْبَنْجَرَ}} {{-}} === التصريفات === {{تصريف|جذر=حبجر|وزن=افعنلل}} === المراجع === {{مراجع}} a4lz5c6q4e43ssarxwpdz44k0zt34ix تَحَبْجَرَ 0 240410 1097315 2026-07-23T10:01:02Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097315 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534171}} === المعاني === '''تَحَبْجَرَ''' {{تفعلل}} {{معجمية|L1534171|معاني}} === النطق === * {{أصد-عر|تَحَبْجَرَ}} {{-}} === التصريفات === {{تصريف|جذر=حبجر|وزن=تفعلل}} === المراجع === {{مراجع}} 24ygdzfypz6shb5uktcf3y9tf002v2o حَبَّضَ 0 240411 1097316 2026-07-23T10:03:19Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097316 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534181}} === المعاني === '''حَبَّضَ''' {{فعّل}} {{معجمية|L1534181|معاني}} === النطق === * {{أصد-عر|حَبَّضَ}} {{-}} === التصريفات === {{تصريف|جذر=حبض|وزن=فعّل}} === المراجع === {{مراجع}} go5slkigi1zgnnjmfnta6w246y98q39 أَحْبَقَ 0 240412 1097317 2026-07-23T10:09:04Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097317 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534186}} === المعاني === '''أَحْبَقَ''' {{أفعل}} {{معجمية|L1534186|معاني}} === النطق === * {{أصد-عر|أَحْبَقَ}} {{-}} === التصريفات === {{تصريف|جذر=حبق|وزن=أفعل}} === المراجع === {{مراجع}} ngxjjm5s27xnzjtiprfks777cffj0fz تَحَبْكَرَ 0 240413 1097318 2026-07-23T10:10:48Z أبو هشام 20788 إنشاء صفحة فعل من بيانات المعاجم (ar-senses tool) 1097318 wikitext text/x-wiki == {{اللغة|عربية}} == {{صندوق معلومات فعل|L1534191}} === المعاني === '''تَحَبْكَرَ''' {{تفعلل}} {{معجمية|L1534191|معاني}} === النطق === * {{أصد-عر|تَحَبْكَرَ}} {{-}} === التصريفات === {{تصريف|جذر=حبكر|وزن=تفعلل}} === المراجع === {{مراجع}} oktgx0y7kjc9pht4bpvxasj2y78ary8 وحدة:WdItem/ملعب 828 240414 1097321 2026-07-23T11:21:30Z حبيشان 31560 ملعب الوحدة 1097321 Scribunto text/plain -- Module: WdItem -- Object-oriented Wikidata access module for Lua -- Refactored from WikidataIB for direct Lua usage require("strict") local p = {} -- i18n configuration local i18n = { ["errors"] = { ["property-not-found"] = "الخاصية غير موجودة.", ["entity-not-found"] = "الكيان على ويكي بيانات غير موجود.", ["unknown-claim-type"] = "نوع الادعاء غير معروف.", ["local-article-not-found"] = "المعرف متاح على ويكي بيانات، ولكن المقال غير متاح على ويكيبيديا", }, ["months"] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, ["Unknown"] = "Unknown", ["NaN"] = "Not a number", ["missinginfocat"] = "[[تصنيف:Articles with missing Wikidata information]]", ["list separator"] = ", ", ["list separator-ar"] = "، ", } -- Date precision constants local dp = { [6] = "millennium", [7] = "century", [8] = "decade", [9] = "year", [10] = "month", [11] = "day", } local options_aliases = { ["osd"] = "onlysourced", ["wdlinks"] = "wdl", ["uabbr"] = "unitabbr", ["qo"] = "qualsonly", ["lp"] = "linkprefix", ["lprefix"] = "linkprefix", ["qlp"] = "qlinkprefix", ["sn"] = "shortname", ["uselabel"] = "uselbl", ["plaindate"] = "pd", ["qualifierdateformat"] = "qdf", ["df"] = "qdf", ["qshortname"] = "qsn" } setmetatable(options_aliases, { __index = function(t, k) return k end }) ------------------------------------------------------------------------------- -- Internal helper functions ------------------------------------------------------------------------------- local function findLang(langcode) local langobj langcode = mw.text.trim(langcode or "") if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langcode = mw.getCurrentFrame():callParserFunction('int', {'lang'}) if mw.language.isKnownLanguageTag(langcode) then langobj = mw.language.new(langcode) else langobj = mw.language.getContentLanguage() end end return langobj end local function parseParam(param, default) if param == nil then return default end return param end local function setRanks(rank) rank = (rank or ""):lower() local ranks = {} for w in string.gmatch(rank, "%a+") do if w == "best" or w == "preferred" or w == "normal" or w == "deprecated" then ranks[w] = true end end if ranks.best or not next(ranks) then ranks.preferred = true ranks.normal = true ranks.deprecated = false end return ranks end local function labelOrId(id, lang) if lang == "default" then lang = findLang().code end local label if lang then label = mw.wikibase.getLabelByLang(id, lang) end if not label then local trylang = {"ar","en","fr", "mul"} local triedlang = lang for _,lang in pairs(trylang) do if triedlang ~= lang then label = mw.wikibase.getLabelByLang(id, lang) if label ~= "" then break end end end end if label then return mw.text.nowiki(label), true else return id, false end end local function roundto(x, sf) if x == 0 then return 0 end local s = 1 if x < 0 then x = -x s = -1 end if sf < 1 then sf = 1 end local p = 10 ^ (math.floor(math.log10(x)) - sf + 1) x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end return x end local function decimalPrecision(x, p) local s = 1 if x < 0 then x = -x s = -1 end if not tonumber(p) then p = 1e-4 elseif p > 1 then p = 1 elseif p < 1e-6 then p = 1e-6 else p = 10 ^ math.floor(math.log10(p)) end x = math.floor(x / p + 0.5) * p * s if x == math.floor(x) then x = math.floor(x) end if math.abs(x) < 1e-4 then x = string.format("%f", x) end return x end local function decimalToDMS(x, p) if not tonumber(p) then p = 1e-4 end local d = math.floor(x) local ms = (x - d) * 60 if p > 0.5 then if ms > 30 then d = d + 1 end ms = 0 end local m = math.floor(ms) local s = (ms - m) * 60 if p > 0.008 then if s > 30 then m = m +1 end s = 0 elseif p > 0.00014 then s = math.floor(s + 0.5) elseif p > 0.000014 then s = math.floor(10 * s + 0.5) / 10 elseif p > 0.0000014 then s = math.floor(100 * s + 0.5) / 100 else s = math.floor(1000 * s + 0.5) / 1000 end return d, m, s end local function rawValue(dataValue) if dataValue.type == "string" then return dataValue.value elseif dataValue.type == "wikibase-entityid" then return dataValue.value and dataValue.value.id elseif dataValue.type == "monolingualtext" then return dataValue.value.text elseif dataValue.type == "quantity" then return tonumber(dataValue.value.amount) elseif dataValue.type == 'time' then return dataValue.value.time elseif dataValue.type == "globecoordinate" then return dataValue.value.latitude .. '/' .. dataValue.value.longitude end end local function compareValue(dataValue, strValue) return rawValue(dataValue) == strValue end local function dateFormat(timestamp, dprec, df, bcf, pd, qualifiers, lang, adj, model) df = (df or ""):lower() if df == "ymd" then if timestamp:sub(1,1) == "+" then return timestamp:sub(2,11) else local yr = tonumber(timestamp:sub(2,5)) - 1 yr = ("000" .. yr):sub(-4) if yr ~= "0000" then yr = "-" .. yr end return yr .. timestamp:sub(6,11) end end timestamp = timestamp:gsub("%-00%-00T", "-01-01T") dprec = dprec or 11 if df == "y" and dprec > 9 then dprec = 9 end dprec = dprec>11 and 11 or dprec dprec = dprec<6 and 6 or dprec bcf = (bcf or ""):upper() pd = (pd or ""):sub(1,1):lower() if pd == "" or pd == "n" or pd == "f" or pd == "0" then pd = false end lang = lang or findLang().code adj = adj or "" local bc = timestamp:sub(1, 1)=="-" and "BC" or "" local year, month, day = timestamp:match("[+-](%d*)-(%d*)-(%d*)T") local iso = tonumber(year) if dprec == 6 then iso = math.floor( (iso - 1) / 1000 ) + 1 end if dprec == 7 then iso = math.floor( (iso - 1) / 100 ) + 1 end if dprec == 8 then iso = math.floor( iso / 10 ) .. "0" end if dprec == 10 then iso = year .. "-" .. month end if dprec == 11 then iso = year .. "-" .. month .. "-" .. day end local sc = not pd and qualifiers and qualifiers.P1480 if sc then for k1, v1 in pairs(sc) do if v1.datavalue and v1.datavalue.value.id == "Q5727902" then adj = "circa" break end end end local calendarmodel = "" if tonumber(year) > 1582 and dprec > 8 and not pd and model == "http://www.wikidata.org/entity/Q1985786" then calendarmodel = "julian" end -- Simplified date formatting (complex date module not available) local fdate = tostring(iso) if bc ~= "" then fdate = fdate .. " " .. (bcf == "BC" and "BC" or "BCE") end if adj == "circa" then fdate = "c. " .. fdate end return fdate end local function hijriFormat(qualifiers, dateformat, lang) if not qualifiers.P4241 then return; end local year, month, day local val local qhmonths = {["Q1952053"]=1,["Q489557"]=2, ["Q474167"] = 3, ["Q273815"] = 4, ["Q852002"] = 5, ["Q822218"] = 6, ["Q194210"] = 7, ["Q220914"] = 8, ["Q8867089"]=9, ["Q685440"]=10,["Q150853"]=11,["Q186022"]=12 } local hmonths = {"محرم","صفر","ربيع الأول","ربيع الآخر","جمادى الأولى","جمادى الآخرة","رجب","شعبان","رمضان","شوال","ذو القعدة","ذو الحجة"} local hmonths_inv = {["محرم"] = 1, ["صفر"]=2, ["ربيع الأول"]=3, ["ربيع الآخر"]=4, ["جمادى الأولى"]=5, ["جمادى الآخرة"]=6, ["رجب"]=7, ["شعبان"]=8, ["رمضان"]=9, ["شوال"]=10, ["ذو القعدة"]=11, ["ذو الحجة"]=12} for _, item in ipairs(qualifiers.P4241) do local timeQ = item.datavalue and item.datavalue.value and item.datavalue.value.id local hastime = false if timeQ then local timeQt = mw.wikibase.getBestStatements(timeQ, "P361") for _,timeQsnak in pairs(timeQt) do local timeType = timeQsnak.mainsnak and timeQsnak.mainsnak.datavalue and timeQsnak.mainsnak.datavalue.value and timeQsnak.mainsnak.datavalue.value.id if timeType == "Q28892" then local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then year = mw.ustring.match(timeLableAr, "^(%d+) *هـ$") end if not year then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then year = mw.ustring.match(timeLableAr, "^(%d+) *AH$") end end hastime=true elseif qhmonths[timeType] then month = qhmonths[timeType] if month>0 and month<13 then month = hmonths[month] end local timeLableAr = mw.wikibase.getLabelByLang(timeQ, "ar") if timeLableAr then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end if not day then local timeLableEn = mw.wikibase.getLabelByLang(timeQ, "en") if timeLableEn then day = mw.ustring.match(timeLableAr, "^(%d+) *%a+$") end end hastime=true end end if not hastime then timeQt = mw.wikibase.getBestStatements(timeQ, "P31") if "Q125390868" == (timeQt[1].mainsnak and timeQt[1].mainsnak.datavalue and timeQt[1].mainsnak.datavalue.value and timeQt[1].mainsnak.datavalue.value.id ) then val = mw.wikibase.getLabelByLang(timeQ, "ar") month, year = mw.ustring.match(val, "^(%a[%a ]+%a) *(%d+) *هـ?$") end end end end if year then if dateformat == "y" then return year; elseif day and month then return day .. ' ' .. month .. ' ' .. year; elseif month then return month .. ' ' .. year; end end return nil; end local function sourced(claim) if claim.references then for kr, vr in pairs(claim.references) do local ref = mw.wikibase.renderSnaks(vr.snaks) if not ref:find("Wiki") then return true end end end end local function linkedItem(id, args) local lprefix = (args.linkprefix or ""):gsub('"', '') local lpostfix = (args.lpostfix or ""):gsub('"', '') local prefix = (args.prefix or ""):gsub('"', '') local postfix = (args.postfix or ""):gsub('"', '') local wikilinkprefix = (args.wikilinkprefix or ""):gsub('"', '') local dtxt = args.dtxt local uselbl = parseParam( args.uselbl, true) local disp local sitelink = mw.wikibase.getSitelink(id, args.linksproject) local label, islabel if dtxt then label, islabel = dtxt, true else label, islabel = labelOrId(id, args.lang) end if sitelink then if not uselbl then local pos = sitelink:find(":") or 0 local slink = sitelink if pos > 0 then local pfx = sitelink:sub(1,pos-1) if mw.site.namespaces[pfx] then slink = sitelink:sub(pos+1) end end slink = slink:gsub("%s%(.+%)$", ""):gsub(",.+$", "") if label:find("^%u") then label = slink:gsub("^(%l)", string.upper) else label = slink:gsub("^(%u)", string.lower) end end disp = "[[" .. wikilinkprefix .. sitelink .. lpostfix .. "|" .. prefix .. label .. postfix .. "]]" elseif islabel then disp = prefix .. label .. postfix else disp = prefix .. label .. postfix .. i18n.missinginfocat end return disp end local function rendersnak(propval, args, linked, lpre, lpost, pre, post, uabbr, filter) lpre = lpre or "" lpost = lpost or "" pre = pre or "" post = post or "" args.lang = args.lang or findLang().code local snak = propval.mainsnak or propval local dtype = snak.datatype local dv = snak.datavalue dv = dv and dv.value local val, mlt local namedas; namedas = propval.qualifiers and propval.qualifiers.P1932 and propval.qualifiers.P1932[1].datavalue and propval.qualifiers.P1932[1].datavalue.value or nil args.dtxt = namedas if propval.rank and not args.reqranks[propval.rank] then return nil elseif snak.snaktype == "somevalue" then val = namedas or i18n["Unknown"] elseif snak.snaktype == "novalue" then -- return nothing elseif dtype == "wikibase-item" then local qnumber = dv.id if linked then val = linkedItem(qnumber, args) else if namedas then val = pre .. namedas .. post else local label, islabel = labelOrId(qnumber, args.lang) val = pre .. label .. post end end elseif dtype == "time" then if args.hijri then val = hijriFormat(propval.qualifiers, args.df, args.lang) else val = dateFormat(dv.time, dv.precision, args.df, args.bc, args.pd, propval.qualifiers, args.lang, "", dv.calendarmodel) end elseif dtype == "commonsMedia" or dtype == "external-id" or dtype == "string" or dtype == "url" then if (lpre == "" or lpre == ":") and lpost == "" then val = pre .. dv .. post elseif dtype == "external-id" then val = "[" .. lpre .. dv .. lpost .. " " .. pre .. dv .. post .. "]" else val = "[[" .. lpre .. dv .. lpost .. "|" .. pre .. dv .. post .. "]]" end elseif dtype == "quantity" then local amount = tonumber(dv.amount) or i18n["NaN"] local unit = "" local unitqid = string.match(dv.unit, "(Q%d+)") if filter and unitqid ~= filter then return nil end if unitqid then local uname = mw.wikibase.getLabelByLang(unitqid, args.lang) or "" if uname ~= "" then unit = " " .. uname end end val = tostring(amount) .. unit elseif dtype == "globe-coordinate" then local lat, long, prec = dv.latitude, dv.longitude, dv.precision local show = (args.show or ""):lower() if show == "lat" then val = decimalPrecision(lat, prec) elseif show == "lon" then val = decimalPrecision(long, prec) elseif show == "longlat" then val = decimalPrecision(long, prec) .. ", " .. decimalPrecision(lat, prec) else local ns = lat < 0 and "S" or "N" local ew = long < 0 and "W" or "E" if lat < 0 then lat = -lat end if long < 0 then long = -long end val = decimalPrecision(lat, prec) .. "°" .. ns .. " " .. decimalPrecision(long, prec) .. "°" .. ew end elseif dtype == "monolingualtext" then val = pre .. dv.text .. post mlt = dv.language else val = "unknown data type: " .. dtype end return val, mlt end local function assembleoutput(out, args, entityID, propertyID) local sorted = parseParam(args.sorted, false) local noic = parseParam(args.noicon, false) local list = args.list or "" local separator = args.sep or "" separator = string.gsub(separator, '"', '') if separator == "" then local rtl_lang = {ar = true, fa = true, ur = true, ku = true, he = true} separator = rtl_lang[args.lang] and i18n["list separator-ar"] or i18n["list separator"] end local strout if #out > 0 then if sorted then table.sort(out) end if list == "" then strout = table.concat(out, separator) elseif list:lower() == "prose" then strout = mw.text.listToText(out) else strout = mw.getCurrentFrame():expandTemplate{title = list, args = out} end else strout = nil end return strout end local function propertyvalueandquals(objproperty, args, qualID) -- needs this style of declaration because it's re-entrant -- onlysourced is a boolean passed to return only values sourced to other than Wikipedia -- if nothing or an empty string is passed set it true local onlysrc = parseParam(args.onlysourced, false) -- linked is a a boolean that enables the link to a local page via sitelink -- if nothing or an empty string is passed set it true local linked = parseParam(args.linked, true) -- prefix is a string that may be nil, empty (""), or a string of characters -- this is prefixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local prefix = (args.prefix or ""):gsub('"', '') -- postfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local postfix = (args.postfix or ""):gsub('"', '') -- linkprefix is a string that may be nil, empty (""), or a string of characters -- this creates a link and is then prefixed to each value -- useful when when multiple values are returned and indirect links are needed -- any double-quotes " are stripped out, so that spaces may be passed local lprefix = (args.linkprefix or ""):gsub('"', '') -- linkpostfix is a string that may be nil, empty (""), or a string of characters -- this is postfixed to each value when linking is enabled with lprefix -- useful when when multiple values are returned -- any double-quotes " are stripped out, so that spaces may be passed local lpostfix = (args.linkpostfix or ""):gsub('"', '') -- wdlinks is a boolean passed to enable links to Wikidata when no article exists -- if nothing or an empty string is passed set it false local wdl = parseParam(args.wdl, false) -- unitabbr is a boolean passed to enable unit abbreviations for common units -- if nothing or an empty string is passed set it false local uabbr = parseParam(args.unitabbr, false) -- qualsonly is a boolean passed to return just the qualifiers -- if nothing or an empty string is passed set it false local qualsonly = parseParam(args.qualsonly, false) -- maxvals is a string that may be nil, empty (""), or a number -- this determines how many items may be returned when multiple values are available -- setting it = 1 is useful where the returned string is used within another call, e.g. image local maxvals = tonumber(args.maxvals) or 0 -- pd boolean -- to disable/enable "sourcing cirumstances" or use adjectival form for the plain date local pd = args.pd or false args.pd = pd -- allow qualifiers to have a different date format; default to year unless qualsonly is set args.qdf = args.qdf or (not qualsonly and "y") local lang = args.lang or (args.langs and args.langs[1]) or findLang().code -- qualID is a string list of wanted qualifiers or "ALL" qualID = qualID or "" -- capitalise list of wanted qualifiers and substitute "DATES" qualID = qualID:upper():gsub("DATES", "P580, P582") local allflag = (qualID == "ALL") -- create table of wanted qualifiers as key local qwanted = {} -- create sequence of wanted qualifiers local qorder = {} for q in mw.text.gsplit(qualID, "%p") do -- split at punctuation and iterate local qtrim = mw.text.trim(q) if qtrim ~= "" then qwanted[mw.text.trim(q)] = true qorder[#qorder+1] = qtrim end end -- qsep is the output separator for rendering qualifier list local qsep = (args.qsep or ""):gsub('"', '') -- qargs are the arguments to supply to assembleoutput() local qargs = { ["osd"] = "false", ["linked"] = tostring(linked), ["prefix"] = args.qprefix, ["postfix"] = args.qpostfix, ["linkprefix"] = args.qlinkprefix, ["linkpostfix"] = args.qlinkpostfix, ["wdl"] = "false", ["unitabbr"] = tostring(uabbr), ["maxvals"] = 0, ["sorted"] = tostring(args.qsorted), ["noicon"] = "true", ["list"] = args.qlist, ["sep"] = qsep, -- ["langobj"] = args.langobj, ["lang"] = args.lang or (args.langs and args.lang[1]), ["df"] = args.qdf, ["sn"] = parseParam(args.qsn, false), } -- all proper values of a Wikidata property will be the same type as the first -- qualifiers don't have a mainsnak, properties do --#Modified line local datatype = objproperty[1].datatype or (objproperty[1].mainsnak and objproperty[1].mainsnak.datatype) -- out[] holds the a list of returned values for this property -- mlt[] holds the language code if the datatype is monolingual text local out = {} local mlt = {} for k, v in ipairs(objproperty) do local hasvalue = true if (onlysrc and not sourced(v)) then -- no value: it isn't sourced when onlysourced=true hasvalue = false else local val, lcode = rendersnak(v, args, linked, lprefix, lpostfix, prefix, postfix, uabbr) if not val then hasvalue = false -- rank doesn't match elseif qualsonly and qualID then -- suppress value returned: only qualifiers are requested else out[#out+1], mlt[#out+1] = val, lcode end end -- See if qualifiers are to be returned: local snak = v.mainsnak or v if hasvalue and v.qualifiers and qualID ~= "" and snak.snaktype~="novalue" then -- collect all wanted qualifier values returned in qlist, indexed by propertyID local qlist = {} local timestart, timeend = "", "" -- loop through qualifiers for k1, v1 in pairs(v.qualifiers) do if allflag or qwanted[k1] then if k1 == "P1326" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "before") elseif k1 == "P1319" then local ts = v1[1].datavalue.value.time local dp = v1[1].datavalue.value.precision qlist[k1] = dateFormat(ts, dp, args.qdf, args.bc, pd, "", lang, "after") elseif k1 == "P580" then timestart = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one start time as valid elseif k1 == "P582" then timeend = propertyvalueandquals(v1, qargs)[1] or "" -- treat only one end time as valid else local q = assembleoutput(propertyvalueandquals(v1, qargs), qargs) -- we already deal with circa via 'sourcing circumstances' if the datatype was time -- circa may be either linked or unlinked *** internationalise later *** if datatype ~= "time" or q ~= "circa" and not (type(q) == "string" and q:find("circa]]")) then qlist[k1] = q end end end -- of test for wanted end -- of loop through qualifiers -- set date separator local t = timestart .. timeend -- *** internationalise date separators later *** local dsep = "&ndash;" if t:find("%s") or t:find("&nbsp;") then dsep = " &ndash; " end -- set the order for the list of qualifiers returned; start time and end time go last if next(qlist) then local qlistout = {} if allflag then for k2, v2 in pairs(qlist) do qlistout[#qlistout+1] = v2 end else for i2, v2 in ipairs(qorder) do qlistout[#qlistout+1] = qlist[v2] end end if t ~= "" then qlistout[#qlistout+1] = timestart .. dsep .. timeend end local qstr = assembleoutput(qlistout, qargs) if qualsonly then out[#out+1] = qstr else out[#out] = out[#out] .. " (" .. qstr .. ")" end elseif t ~= "" then if qualsonly then if timestart == "" then out[#out+1] = timeend elseif timeend == "" then out[#out+1] = timestart else out[#out+1] = timestart .. dsep .. timeend end else out[#out] = out[#out] .. " (" .. timestart .. dsep .. timeend .. ")" end end end -- of test for qualifiers wanted if maxvals > 0 and #out >= maxvals then break end end -- of for each value loop -- we need to pick one value to return if the datatype was "monolingualtext" -- if there's only one value, use that -- otherwise look through the fallback languages for a match if datatype == "monolingualtext" and #out >1 then lang = mw.text.split( lang, '-', true )[1] local fbtbl = mw.language.getFallbacksFor( lang ) table.insert( fbtbl, 1, lang ) local bestval = "" local found = false for idx1, lang1 in ipairs(fbtbl) do for idx2, lang2 in ipairs(mlt) do if (lang1 == lang2) and not found then bestval = out[idx2] found = true break end end -- loop through values of property end -- loop through fallback languages if found then -- replace output table with a table containing the best value out = { bestval } else -- more than one value and none of them on the list of fallback languages -- sod it, just give them the first one out = { out[1] } end end return out end local function mergeOptions(defaults, overrides) overrides = overrides or {} defaults = defaults or {} local result = {} for k, v in pairs(defaults) do result[k] = v end for k, v in pairs(overrides) do result[k] = v if k == 'rank' then result.reqranks = setRanks(v) end end return result end local function filterbyqualifier(statements,qual,value) local filtered_statements = {} for _, statement in ipairs(statements) do if statement.qualifiers and statement.qualifiers[qual] then if '*' == value then table.insert(filtered_statements, statement) else for _, q in ipairs(statement.qualifiers[qual]) do if q.datavalue and (rawValue(q.datavalue) == value) then table.insert(filtered_statements, statement) break end end end end end return filtered_statements end local function orderbyrank(statements) local pref_count = 0 local sorted_statements = {} for k,v in ipairs(statements) do if v.rank == 'preferred' then pref_count = pref_count + 1 table.insert(sorted_statements, pref_count, v) else table.insert(sorted_statements, v) end end return sorted_statements end ------------------------------------------------------------------------------- -- helper class functions ------------------------------------------------------------------------------- local function class() local c = {} c.__index = c function c:new(...) local o = setmetatable({}, c) if o.init then o:init(...) end return o end return c end ------------------------------------------------------------------------------- -- Statement Class Definition ------------------------------------------------------------------------------- local WdStatement = class() function WdStatement:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statement = self._statement if not statement then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals({statement}, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatement:getRawValue() if not self._statement then return nil end if self._statement.mainsnak.snaktype == "value" then return rawValue(self._statement.mainsnak.datavalue) else return self._statement.mainsnak.snaktype end end function WdStatement:getRawQual(qualID) local ret = {} local s = self._statement if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(ret, rawValue(q.datavalue)) else table.insert(ret, q.snaktype) end end end return ret end ------------------------------------------------------------------------------- -- Statements Class Definition ------------------------------------------------------------------------------- local WdStatements = class() function WdStatements:getStatmentsTable() return self._statements end function WdStatements:count() return #self._statements end function WdStatements:getFilters() return self.filtered_by end function WdStatements:filter(filter_t) local statements = self._statements if #statements == 0 then return self; end local ret = WdStatements:new() ret.parent = self.parent ret.filtered_by = {} for _,v in ipairs(self.filtered_by) do table.insert(ret.filtered_by, v) end local filtered_statements = {} for k,v in pairs(filter_t) do filtered_statements = filterbyqualifier(statements, k, v) table.insert(ret.filtered_by, {[k] = v}) if #filtered_statements == 0 then break; else statements = filtered_statements end end ret._statements = filtered_statements return ret end function WdStatements:getValue(opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getQual(qualID, opts) local mergedOpts = mergeOptions(self.parent.options, opts) local statements = self._statements if not statements or #statements == 0 then return nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.parent.qid, self.pid) end function WdStatements:getRawQual(qualID) local ret = {} for _,s in pairs(self._statements) do local qual_t = {} if s.qualifiers and s.qualifiers[qualID] then for _,q in pairs(s.qualifiers[qualID]) do if q.snaktype == "value" then table.insert(qual_t, rawValue(q.datavalue)) else table.insert(qual_t, q.snaktype) end end end table.insert(ret,qual_t) end return ret end function WdStatements:getRawValue() local ret = {} for _,v in pairs(self._statements) do if v.mainsnak.snaktype=="value" then table.insert(ret, rawValue(v.mainsnak.datavalue)) else table.insert(ret, v.mainsnak.snaktype) end end return ret end function WdStatements:get(index) local ret = WdStatement:new() ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = self._statements[index] ret.pid = ret.pid return ret end function WdStatements:iter() local i = 0 local n = self._statements and #self._statements or 0 return function() i = i + 1 if i <= n then return i, self:get(i) end end end function WdStatements:ipairs() return self:iter() end function WdStatements:getBestOne() local orderd_statements = orderbyrank(self._statements) local ret = WdStatement:new() --setmetatable({}, WdStatement) ret.parent = self.parent ret.filtered_by = ret.filtered_by ret._statement = orderd_statements[1] ret.pid = ret.pid return ret end ------------------------------------------------------------------------------- -- WdItem Class Definition ------------------------------------------------------------------------------- local WdItem = class() function WdItem:__tostring() return "WdItem: " .. (self.qid or "no QID") end function WdItem:UpdateOptions(newOpts) for k, v in pairs(newOpts or {}) do local key = options_aliases[k] self.options[key] = v -- Set default options if key == 'langs' and #v > 0 then self.options.langobj = findLang(self.options.langs[1]) self.options.lang = self.options.langobj.code if not self.options.langobj then self.options.langobj = findLang(self.options.lang) self.options.lang = self.options.langobj.code end end if key == 'rank' then self.options.reqranks = setRanks(self.options.rank) end end if not self.options.reqranks then self.options.reqranks = setRanks('preferred normal') end end function WdItem:init(qid, options,snak) if qid == "" then qid = nil; end self.qid = qid self.snak = snak self.options = options or {} self:UpdateOptions(options) return self end function WdItem:newFromSnaks(snakTable, options) local self = WdItem:new(nil, options or {}, snakTable) self:UpdateOptions(options) return self end function WdItem:setOptions(newOpts) self:UpdateOptions(newOpts) end function WdItem:getStatements(pid, opts) local mergedOpts = mergeOptions(self.options, opts or {}) local statements local ret = WdStatements:new() ret.parent = self ret.filtered_by = {} ret._statements = {} ret.pid = pid if self.snak and self.snak[pid] then statements = self.snak[pid] elseif not self.qid or not mw.wikibase then statements = {} elseif mergedOpts.reqranks and mergedOpts.reqranks.best then statements = mw.wikibase.getBestStatements(self.qid, pid) or {} else statements = mw.wikibase.getAllStatements(self.qid, pid) or {} local filtered_statements = {} if not (mergedOpts.reqranks.deprecated == true and mergedOpts.reqranks.preferred == true and mergedOpts.reqranks.normal == true) then for _,s in pairs(statements) do if mergedOpts.reqranks[s.rank] then table.insert(filtered_statements,s) end end end statements = filtered_statements end if #statements > 0 and mergedOpts.qualifiedaspossible and mergedOpts.qualifiedaspossible ~= {} then local filtered_statements = {} for q,qv in pairs(mergedOpts.qualifiedaspossible) do filtered_statements = filterbyqualifier(statements, q, qv) if #filtered_statements > 0 then table.insert(ret.filtered_by, {[q] = qv}) statements = filtered_statements end end end if #statements > 0 and mergedOpts.qualified and mergedOpts.qualified ~= {} then for q,qv in pairs(mergedOpts.qualified) do statements = filterbyqualifier(statements, q, qv) table.insert(ret.filtered_by, {[q] = qv}) if #statements == 0 then break; end end end ret._statements = statements return ret end function WdItem:getValue(pid, opts) local mergedOpts = mergeOptions(self.options, opts) local statements = self:getStatements(pid, mergedOpts):getStatmentsTable() if not statements or #statements == 0 then return nil end local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = propertyvalueandquals(statements, mergedOpts, qualID) return assembleoutput(out, mergedOpts, self.qid, pid) end function WdItem:getValueFromSnaks(pid, opts) if not self.snak or not self.snak[pid] then return nil end local mergedOpts = mergeOptions(self.options, opts) local props = self.snak[pid] local out = propertyvalueandquals(props, mergedOpts) return assembleoutput(out, mergedOpts, nil, pid) end function WdItem:getPropertyIDsTable(pid, opts) local mergedOpts = mergeOptions(self.options, opts) mergedOpts.noicon = tostring(parseParam(mergedOpts.noicon or "", true)) local statements = self:getStatements(pid, opts) if not statements or #statements == 0 then return {} end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local out = {} for i, v in ipairs(statements) do local snak = v.mainsnak if (snak.datatype == "wikibase-item") and (v.rank and mergedOpts.reqranks[v.rank:sub(1, 1)]) and (snak.snaktype == "value") and (sourced(v) or not onlysrc) then out[#out+1] = snak.datavalue.value.id end if maxvals > 0 and #out >= maxvals then break end end return out end function WdItem:getPropertyIDs(pid, opts) local out = WdItem:getPropertyIDsTable(pid, opts) if #out == 0 then return nil end return assembleoutput(out, mergeOptions(self.options, opts), self.qid, pid) end function WdItem:getPropOfProp(prop1, prop2, opts) local mergedOpts = mergeOptions(self.options, opts) if not self.qid then return nil end local statements1 = self:getStatements(prop1, opts) if not statements1 or #statements1 == 0 then return nil end local onlysrc = parseParam(mergedOpts.onlysourced or mergedOpts.osd, true) local maxvals = tonumber(mergedOpts.maxvals) or 0 local qualID = mw.text.trim(mergedOpts.qual or ""):upper() if qualID == "" then qualID = nil end local out = {} for k, v in ipairs(statements1) do if not onlysrc or sourced(v) then local snak = v.mainsnak if snak.datatype == "wikibase-item" and snak.snaktype == "value" then local qid2 = snak.datavalue.value.id local item2 = WdItem.new(qid2, mergedOpts) local statements2 = item2:getStatements(prop2, opts) if statements2 and statements2[1] then local out2 = propertyvalueandquals(statements2, mergedOpts, qualID) out[#out+1] = assembleoutput(out2, mergedOpts, qid2, prop2) end end end if maxvals > 0 and #out >= maxvals then break end end return assembleoutput(out, mergedOpts, self.qid, prop1) end function WdItem:getLangOfProp(pid) if not pid then return {}; end local out = {} local props = self.snak and self.snak[pid] or (self.qid and mw.wikibase.getAllStatements(self.qid, pid)) or {} for _, v in ipairs(props) do if v.mainsnak.datatype == "monolingualtext" and v.mainsnak.datavalue then out[#out + 1] = v.mainsnak.datavalue.value.language end end return out end function WdItem:followQid(props, all) all = parseParam(all, false) props = (props or ""):upper() if not self.qid then return nil end if props == "" then return self.qid end local out = {} for p in mw.text.gsplit(props, "%p") do p = mw.text.trim(p) for i, v in ipairs(mw.wikibase.getBestStatements(self.qid, p)) do local linkedid = v.mainsnak.datavalue and v.mainsnak.datavalue.value.id if linkedid then if all then out[#out+1] = linkedid else return linkedid end end end end if #out > 0 then return table.concat(out, " ") else return self.qid end end ------------------------------------------------------------------------------- -- Public API - WdItem Constructors ------------------------------------------------------------------------------- p.WdItem = WdItem function p.newItem(qid, opts, snak ) return WdItem:new(qid, opts, snak) end function p.newSnakItem(snakTable, opts) return WdItem:newFromSnaks(snakTable, opts) end return p i1i400465y4qj7zr77x6mpyh1o1dml3