wikidata

Dokumentasi untuk modul ini dapat dibuat di Modul:Wikidata/doc

-- version 20190319 from master @cawiki  local p = {}  ----------------------------------------------------------------------------- -- internationalisation at [[Module:Wikidata/i18n]] local i18n = { ["errors"] = { ["property-not-found"] = "Property not found.", ["entity-not-found"] = "Wikidata entity not found.", ["unknown-claim-type"] = "Unknown claim type.", ["unknown-entity-type"] = "Unknown entity type.", ["qualifier-not-found"] = "Qualifier not found.", ["site-not-found"] = "Wiki project not found.", ["unknown-datetime-format"] = "Unknown datetime format.", ["local-article-not-found"] = "Article is not yet available in this wiki.", ['not-from-content-page'] = "Do not invoke from content page. Use a template or use a module subpage like /sandbox for testing ." }, ["datetime"] = { -- $1 is a placeholder for the actual number [0] = "$1 billion years",-- precision: billion years [1] = "$100 million years",-- precision: hundred million years [2] = "$10 million years",-- precision: ten million years [3] = "$1 million years",-- precision: million years [4] = "$100000 years",-- precision: hundred thousand years; thousand separators added afterwards [5] = "$10000 years",-- precision: ten thousand years; thousand separators added afterwards [6] = "$1 millennium",-- precision: millennium [7] = "$1 century",-- precision: century [8] = "$1s",-- precision: decade -- the following use the format of #time parser function [9]  = "Y",-- precision: year,  [10] = "F Y",-- precision: month [11] = "F j, Y",-- precision: day [12] = "F j, Y ga",-- precision: hour [13] = "F j, Y g:ia",-- precision: minute [14] = "F j, Y g:i:sa",-- precision: second  ["beforenow"] = "$1 BCE",-- how to format negative numbers for precisions 0 to 5 ["afternow"] = "$1 CE",-- how to format positive numbers for precisions 0 to 5 ["bc"] = '$1 "BCE"',-- how print negative years ["ad"] = "$1",-- how print positive years ["bc-addon"] = " BC",-- suffix for negative dates ["ad-addon"] = ""-- suffix for 1st century AD dates }, ["monolingualtext"] = '%text',  ["cite"] = {-- Cite web parameters ["url"]          = "url", ["title"]        = "title", ["website"]      = "website", ["access-date"]  = "access-date", ["archive-url"]  = "archive-url", ["archive-date"] = "archive-date", ["author"]       = "author", ["publisher"]    = "publisher", ["quote"]        = "quote", ["language"]     = "language", ["date"]         = "date", ["pages"]        = "pages" } }  local cases = {} -- functions for local grammatical cases defined at [[Module:Wikidata/i18n]]  local wiki =  { langcode = mw.language.getContentLanguage().code, module_title = "Module:Wikidata", module_planetsData = "Module:Mapa cos celeste/dades" -- data for astronomical objects, maps for non Earth globes }  ---------------------------------------------------------------------------- -- module local functions  -- Credit to http://stackoverflow.com/a/1283608/2644759 -- cc-by-sa 3.0 local function tableMerge(t1, t2) for k,v in pairs(t2) do if type(v) == "table" then if type(t1[k] or false) == "table" then tableMerge(t1[k] or {}, t2[k] or {}) else t1[k] = v end else t1[k] = v end end return t1 end  local function loadI18n() local exist, res = pcall(require, wiki.module_title .. "/i18n") if exist and next(res) ~= nil then tableMerge(i18n, res.i18n) cases = res.cases end end  loadI18n()  local function case(word, localcase, lang) if word == nil or word == '' or cases[localcase] == nil then return word end  return cases[localcase](word, lang) end  local function findLang(langcode) if langcode == nil or langcode == "" or mw.language.isKnownLanguageTag(langcode) == false then local myframe = mw.getCurrentFrame() langcode = myframe.args.lang if langcode == nil or langcode == "" or mw.language.isKnownLanguageTag(langcode) == false then langcode = myframe:getParent().args.lang if langcode == nil or langcode == "" or mw.language.isKnownLanguageTag(langcode) == false then if not mw.title.getCurrentTitle().isContentPage then langcode = myframe:preprocess( '{{int:lang}}' ) end if langcode == nil or langcode == "" or mw.language.isKnownLanguageTag(langcode) == false then langcode = wiki.langcode end end end end local languages = mw.language.getFallbacksFor(langcode) table.insert(languages, 1, langcode) return languages end  -- mw.wikibase.getLabelWithLang or getLabelByLang with a table of languages local function getLabelByLangs(id, languages) local label local lang = languages[1] if lang == wiki.langcode then -- using getLabelWithLang when possible instead of getLabelByLang label, lang = mw.wikibase.getLabelWithLang(id) else for _, l in ipairs(languages) do label = mw.wikibase.getLabelByLang(id, l) lang = l if label then break end end end return label, lang end  -- Is gender femenine? true or false local function feminineGender(id) local claims = mw.wikibase.getBestStatements(id or mw.wikibase.getEntityIdForCurrentPage(),'P21') if #claims == 0 then return false else local genderId = claims[1].mainsnak.datavalue.value.id if genderId == "Q6581072" or genderId == "Q1052281" or genderId == "Q43445" then -- female, transgender female, female organism return true end end return false end  -- Fetch female form of label local function feminineForm(id, lang) local feminine_claims = mw.wikibase.getBestStatements(id, 'P2521') -- female form of label for _, feminine_claim in ipairs(feminine_claims) do if feminine_claim.mainsnak.datavalue.value.language == lang then return feminine_claim.mainsnak.datavalue.value.text end end end  -- Fetch unit symbol local function unitSymbol(id, lang) local claims = findClaims(mw.wikibase.getEntity(id), 'P5061') local langclaims = {} if claims then for _, snak in ipairs(claims) do if snak.mainsnak and snak.mainsnak.datavalue and snak.mainsnak.datavalue.value and not langclaims[snak.mainsnak.datavalue.value.language] -- just the first one by language then langclaims[snak.mainsnak.datavalue.value.language] = snak.mainsnak.datavalue.value.text end end for _, l in ipairs(lang) do if langclaims[l] then return langclaims[l] end end end return langclaims["mul"] -- last try end  -- Add a small pencil as icon for edit on Wikidata local function addEditIcon(id, lang, uselang, icon) if icon and lang ~= uselang then return " [[File:Arbcom ru editing.svg|12px|" .. mw.message.new('Translate-taction-translate'):inLanguage(uselang):plain() .. "|link=d:" .. id .. "]]" end return '' end  local function urlEscapes(text) -- escape URL escapes to avoid Lua captures return mw.ustring.gsub(text, "(%%%d)", "%%%1") end  local function expandBraces(text, formatting) if text == nil or formatting == nil then return text end -- only expand braces if provided in argument, not included in value as in Q1164668 if mw.ustring.find(formatting, '{{', 1, true) == nil then return text end if type(text) ~= "string" then text = tostring(text) end  for braces in mw.ustring.gmatch(text, "{{(.-)}}") do local parts = mw.text.split(braces, "|") local title_part = parts[1] local parameters = {} for i = 2, #parts do if mw.ustring.find(parts[i], "=") then local subparts = mw.text.split(parts[i], "=") parameters[subparts[1]] = subparts[2] else table.insert(parameters, parts[i]) end end  local braces_expanded if mw.ustring.find(title_part, ":") and mw.text.split(title_part, ":")[1] ~= mw.site.namespaces[10].name -- not a prefix Template: then braces_expanded = mw.getCurrentFrame():callParserFunction{name=title_part, args=parameters} else braces_expanded = mw.getCurrentFrame():expandTemplate{title=title_part, args=parameters} end braces = mw.ustring.gsub(braces, "([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1") -- escape magic characters braces_expanded = urlEscapes(braces_expanded) text = mw.ustring.gsub(text, "{{" .. braces .. "}}", braces_expanded) end  return text end  local function printDatatypeMath(data) return mw.getCurrentFrame():callParserFunction('#tag:math', data) end  local function printDatavalueString(data, parameters) if parameters.formatting == 'weblink' then  return '[' .. data ..  ' ' ..  mw.text.split(data, '//' )[2] .. ']' elseif mw.ustring.find((parameters.formatting or ''), '$1', 1, true) then -- formatting = a pattern --local escaped_data = mw.ustring.gsub(data, "%%", "%%%") -- escape % character, normally used in url, avoiding invalid capture in gsub -- done in expandBraces return expandBraces(mw.ustring.gsub(parameters.formatting, '$1', data), parameters.formatting) elseif parameters.case then return case(data, parameters.case, parameters.lang[1]) else return data end end  local function printDatavalueUrl(data, parameters) -- escape URL escapes to avoid Lua captures return printDatavalueString(urlEscapes(data), parameters) end  local function printDatavalueCoordinate(data, parameter) if parameter == 'latitude' then return data.latitude elseif parameter == 'longitude' then return data.longitude elseif parameter == 'dimension' then return data.dimension else --default formatting='globe' if data.globe == '' or data.globe == nil or data.globe == 'http://www.wikidata.org/entity/Q2' then return 'earth' else local globenum = mw.text.split(data.globe, 'entity/')[2] -- http://www.wikidata.org/wiki/Q2 if pcall(require, wiki.module_planetsData) then local globetable = mw.loadData(wiki.module_planetsData) for _, globe in pairs(globetable.maps) do if globe.wikidata == globenum then return globe.coord_globe end end end return globenum end end end  local function printDatavalueQuantity(data, parameters) -- exemples: 277±1 Centímetre, 1,94 metre local amount = data.amount amount = mw.ustring.gsub(amount, "%+", "") local sortkey = string.format("%09d", amount) amount = mw.language.new(parameters.lang[1]):formatNum(tonumber(amount)) -- This is used to get the unit name for a numeric value local suffix = "" if parameters.formatting == "unit" or parameters.formatting == "unitcode" then -- get the url for the unit entry on Wikidata: local unitID = data.unit -- and just return the last bit from "Q" to the end (which is the QID): unitID = mw.ustring.sub(unitID, mw.ustring.find(unitID, "Q"), -1) if mw.ustring.sub(unitID, 1, 1) == "Q" then if parameters.formatting == "unitcode" then local unit_symbol = '' if parameters.lang[1] == wiki.langcode and pcall(require, wiki.module_title .. "/Units") then unit_symbol = require(wiki.module_title .. "/Units").getUnit(amount, '', unitID, true, '') end if unit_symbol == '' then unit_symbol = unitSymbol(unitID, parameters.lang) if not unit_symbol then local unit_label, lang = getLabelByLangs(unitID, parameters.lang) unit_symbol = unit_label .. addEditIcon(unitID, lang, parameters.lang[1], parameters.editicon) end end suffix = " " .. unit_symbol else local unit_label, lang = getLabelByLangs(unitID, parameters.lang) if lang == wiki.langcode and pcall(require, wiki.module_title .. "/Units") then suffix = " " .. require(wiki.module_title .. "/Units").getUnit(amount, unit_label, unitID, false, '') else suffix = " " .. (unit_label or unitID) .. addEditIcon(unitID, lang, parameters.lang[1], parameters.editicon) end end end end return amount .. suffix, sortkey end  local function printDatavalueTime(data, parameters) -- Dates and times are stored in ISO 8601 format local timestamp = data.time local sortkey = timestamp local addon = "" local calendar_add = ""  -- check for negative date, ex. "-0027-01-16T00:00:00Z" if string.sub(timestamp, 1, 1) == '-' then timestamp = '+' .. string.sub(timestamp, 2) addon = i18n.datetime["bc-addon"] elseif string.sub(timestamp, 2, 3) == '00' then addon = i18n.datetime["ad-addon"] else -- calendar model local calendar_model = {["Q12138"] = "gregorian", ["Q1985727"] = "gregorian", ["Q11184"] = "julian", ["Q1985786"] = "julian"} local calendar_id = mw.text.split(data.calendarmodel, 'entity/')[2] if (timestamp < "+1582-10-15T00:00:00Z" and calendar_model[calendar_id] == "gregorian") or (timestamp > "+1582-10-04T00:00:00Z" and calendar_model[calendar_id] == "julian") then calendar_add = " (" .. mw.message.new('Wikibase-time-calendar-' .. calendar_model[calendar_id]):inLanguage(parameters.lang[1]):plain() .. ")" end end local function d(f, t) local ts = t or timestamp local form = type(f) == "function" and f(ts) or f -- function in i18n.datetime[precision] return mw.language.new(parameters.lang[1]):formatDate(form, ts) .. addon .. calendar_add end local precision = data.precision or 11 local intyear = tonumber(mw.ustring.match(timestamp, "^\+?%d+")) local ret = ""  -- precision is 10000 years or more if precision <= 5 then local factor = 10 ^ ((5 - precision) + 4) local y2 = math.ceil(math.abs(intyear) / factor) local relative = mw.ustring.gsub(i18n.datetime[precision], "$1", tostring(y2)) if addon == i18n.datetime["bc-addon"] then -- negative date ret = mw.ustring.gsub(i18n.datetime.beforenow, "$1", relative) else ret = mw.ustring.gsub(i18n.datetime.afternow, "$1", relative) end local ret_number = string.match(ret, "%d+") if ret_number ~= nil then ret = mw.ustring.gsub(ret, ret_number, mw.language.new(parameters.lang[1]):formatNum(tonumber(ret_number))) end -- precision is millennia, centuries or decades elseif precision == 6 then local card = math.floor((intyear - 1) / 1000) + 1 if mw.ustring.find(i18n.datetime[6], "$1") then ret = mw.ustring.gsub(i18n.datetime[6], "$1", tostring(card)) .. addon .. calendar_add else ret = d(i18n.datetime[6], string.format("%04d", tostring(card))) end elseif precision == 7 then local card = math.floor((math.abs(intyear) - 1) / 100) + 1 if mw.ustring.find(i18n.datetime[7], "$1") then ret = mw.ustring.gsub(i18n.datetime[7], "$1", tostring(card)) .. addon .. calendar_add else ret = d(i18n.datetime[7], string.format("%04d", tostring(card))) end elseif precision == 8 then local card = math.floor(math.abs(intyear) / 10) * 10 ret = mw.ustring.gsub(i18n.datetime[8], "$1", tostring(card)) .. addon .. calendar_add -- precision is year elseif parameters.formatting == 'Y' or precision == 9 then ret = tostring(intyear) .. addon .. calendar_add -- precision is month elseif precision == 10 then timestamp = timestamp .. " + 1 day" -- formatDate yyyy-mm-00 returns the previous month ret, _ = string.gsub(d(i18n.datetime[10]), " 0+", " ") -- supress leading zeros in year elseif parameters.formatting then ret, _ = string.gsub(d(parameters.formatting), "([ %[])0+", "%1") -- supress leading zeros in year optionally linked else ret, _ = string.gsub(d(i18n.datetime[11]), " 0+", " ") end return ret, sortkey end  local function printDatavalueEntity(data, parameters) local entityId = data['id'] local entityIdPreffix = data['entity-type'] == 'property' and "Property:" .. entityId or entityId if parameters.formatting == 'raw' then return entityId, entityId end local label, lang = getLabelByLangs(entityId, parameters.lang) local sitelink = mw.wikibase.getSitelink(entityId) local parameter = parameters.formatting local labelcase = label or sitelink if parameters.gender == 'feminineform' and lang ~= nil then -- case gender and item is female labelcase = feminineForm(entityId, lang) or labelcase end if parameters.case then labelcase = case(labelcase, parameters.case, lang) end local ret1, ret2 if parameter == 'label' then ret1 = (labelcase or entityId) ret2 = labelcase or entityId elseif parameter == 'sitelink' then ret1 = (sitelink or 'wikidata:' .. entityIdPreffix) ret2 = sitelink or entityId elseif mw.ustring.find((parameter or ''), '$1', 1, true) then -- formatting = a pattern ret1 = mw.ustring.gsub(parameter, '$1', labelcase or entityId) ret1 = expandBraces(ret1, parameter) ret2 = labelcase or entityId else if parameter == "ucfirst" or parameter == "ucinternallink" then labelcase = labelcase and mw.language.new(lang):ucfirst(labelcase) -- only first of a list, reset formatting for next ones if parameter == "ucinterlanllink" then parameters.formatting = 'internallink' else parameters.formatting = nil -- default format end end  if sitelink then ret1 = '[[' .. sitelink .. '|' .. labelcase .. ']]' ret2 = labelcase elseif label and (parameter == 'internallink' or parameter == 'ucinternallink') then ret1 = '[[' .. label .. '|' .. labelcase .. ']]' ret2 = labelcase else ret1 = '[[wikidata:' .. entityIdPreffix .. '|' .. (labelcase or entityId) .. ']]' ret2 = labelcase or entityId end end  return ret1 .. addEditIcon(entityIdPreffix, lang, parameters.lang[1], parameters.editicon), ret2 end  local function printDatavalueMonolingualText(data, parameters) -- data fields: language [string], text [string]  if parameters.list == "lang" and data["language"] ~= parameters.lang[1] then return elseif parameters.formatting == "language" or parameters.formatting == "text" then return data[parameters.formatting] end local result = data["text"] if data["language"] ~= wiki.langcode then result = mw.ustring.gsub(mw.ustring.gsub(i18n.monolingualtext, "%%language", data["language"]), "%%text", data["text"]) end if mw.ustring.find((parameters.formatting or ''), '$', 1, true) then -- output format defined with $text, $language result = mw.ustring.gsub(parameters.formatting, '$text', result) result = mw.ustring.gsub(result, '$language', data["language"]) end return result end  local function printError(key)     return ' .. i18n.errors[key] .. '' end  -- the "qualifiers" and "snaks" field have a respective "qualifiers-order" and "snaks-order" field -- use these as the second parameter and this function instead of the built-in "pairs" function -- to iterate over all qualifiers and snaks in the intended order. local function orderedpairs(array, order) if not order then return pairs(array) end  -- return iterator function local i = 0 return function() i = i + 1 if order[i] then return order[i], array[order[i]] end end end  function findClaims(entity, property) if not property or not entity or not entity.claims then return end  if not mw.ustring.match(property, "^P%d+$") then -- get property id for the given label property = mw.wikibase.resolvePropertyId(property) if not property then return end end  return entity.claims[property] end  local function getSnakValue(snak, parameters) if snak.snaktype == 'value' then -- call the respective snak parser if snak.datatype == 'math' then return printDatatypeMath(snak.datavalue.value) elseif snak.datatype == "url" then return printDatavalueUrl(snak.datavalue.value, parameters) elseif snak.datavalue.type == "string" then return printDatavalueString(snak.datavalue.value, parameters) elseif snak.datavalue.type == "globecoordinate" then return printDatavalueCoordinate(snak.datavalue.value, parameters.formatting) elseif snak.datavalue.type == "quantity" then return printDatavalueQuantity(snak.datavalue.value, parameters) elseif snak.datavalue.type == "time" then return printDatavalueTime(snak.datavalue.value, parameters) elseif snak.datavalue.type == 'wikibase-entityid' then return printDatavalueEntity(snak.datavalue.value, parameters) elseif snak.datavalue.type == 'monolingualtext' then return printDatavalueMonolingualText(snak.datavalue.value, parameters) end elseif snak.snaktype == 'novalue' then return mw.message.new('Wikibase-snakview-snaktypeselector-novalue'):inLanguage(parameters.lang[1]):plain() elseif snak.snaktype == 'somevalue' then return mw.message.new('Wikibase-snakview-snaktypeselector-somevalue'):inLanguage(parameters.lang[1]):plain() end return mw.wikibase.renderSnak(snak) end  local function getQualifierSnak(claim, qualifierId, parameters) -- a "snak" is Wikidata terminology for a typed key/value pair -- a claim consists of a main snak holding the main information of this claim, -- as well as a list of attribute snaks and a list of references snaks if qualifierId then -- search the attribute snak with the given qualifier as key if claim.qualifiers then local qualifier = claim.qualifiers[qualifierId] if qualifier then if qualifier[1].datatype == "monolingualtext" then -- iterate over monolingualtext qualifiers to get local language for idx in pairs(qualifier) do if qualifier[idx].datavalue.value and qualifier[idx].datavalue.value.language == parameters.lang[1] then return qualifier[idx] end end elseif parameters.list then return qualifier else return qualifier[1] end end end return nil, printError("qualifier-not-found") else -- otherwise return the main snak return claim.mainsnak end end  function getValueOfClaim(claim, qualifierId, parameters) local error local snak snak, error = getQualifierSnak(claim, qualifierId, parameters) if not snak then return nil, nil, error elseif snak[1] then -- a multi qualifier local result = {} local sortkey = {} for idx in pairs(snak) do result[#result + 1], sortkey[#sortkey + 1] = getSnakValue(snak[idx], parameters) end return mw.text.listToText(result, parameters.qseparator, parameters.qconjunction), sortkey[1] else -- a property or a qualifier return getSnakValue(snak, parameters) end end  local function getValueOfParentClaim(claim, qualifierId, parameters) local qids = mw.text.split(qualifierId, '/', true) local valueraw, parent_claims, value, sortkey if qids[1] == parameters.property then valueraw, _, _ = getValueOfClaim(claim, nil, {["formatting"]="raw", ["lang"]=parameters.lang}) else valueraw, _, _ = getValueOfClaim(claim, qids[1], {["formatting"]="raw", ["lang"]=parameters.lang}) end if string.sub(valueraw or '', 1, 1) == "Q" then -- protection for 'no value' parent_claims = mw.wikibase.getBestStatements(valueraw, qids[2]) if parent_claims[1] ~= nil then value, sortkey, _ = getValueOfClaim(parent_claims[1], nil, parameters) -- raw parent value needed fot while/black lists, lang for avoiding an error on types other than entity valueraw, _, _ =  getValueOfClaim(parent_claims[1], nil, {["formatting"]="raw", ["lang"]=parameters.lang}) end end return value, sortkey, valueraw end  local function getReferences(claim) local refaliases = { citeWeb         = "Q5637226", author          = "P50", publisher       = "P123", importedFrom    = "P143", statedIn        = "P248", pages           = "P304", publicationDate = "P577", startTime       = "P580", endTime         = "P582", chapter         = "P792", retrieved       = "P813", referenceURL    = "P854", archiveURL      = "P1065", title           = "P1476", quote           = "P1683", shortName       = "P1813", language        = "P2439", archiveDate     = "P2960" } local result = "" -- traverse through all references for ref in pairs(claim.references or {}) do local refparts local refs = {} -- traverse through all parts of the current reference for snakkey, snakval in pairs(claim.references[ref].snaks or {}) do if snakkey ~= refaliases.importedFrom then -- "imported from" is not a proper reference for snakidx = 1, #snakval do if snakidx > 1 then refparts = refparts .. ", " end refparts = refparts or '' .. getSnakValue(snakval[snakidx], {lang={wiki.langcode}}) end refs[snakkey] = refparts refparts = nil end end  -- get title of general template for citing web references local template = mw.wikibase.getSitelink(refaliases.citeWeb) or "" template = mw.text.split(template, ":")[2]  -- split off namespace from front  -- (1) if both "reference URL" and "title" are present, then use the general template for citing web references if refs[refaliases.referenceURL] and (refs[refaliases.title] or refs[refaliases.statedIn]) and template then local citeParams = {} citeParams[i18n['cite']['url']] = refs[refaliases.referenceURL] citeParams[i18n['cite']['title']] = refs[refaliases.title] or refs[refaliases.statedIn]:match("^%[%[.-|(.-)%]%]") citeParams[i18n['cite']['website']] = refs[refaliases.statedIn] citeParams[i18n['cite']['language']] = refs[refaliases.language] citeParams[i18n['cite']['date']] = refs[refaliases.publicationDate] citeParams[i18n['cite']['access-date']] = refs[refaliases.retrieved] citeParams[i18n['cite']['archive-url']] = refs[refaliases.archiveURL] citeParams[i18n['cite']['archive-date']] = refs[refaliases.archiveDate] citeParams[i18n['cite']['publisher']] = refs[refaliases.publisher] citeParams[i18n['cite']['quote']] = refs[refaliases.quote] citeParams[i18n['cite']['pages']] = refs[refaliases.pages] citeParams[i18n['cite']['author']] = refs[refaliases.author] refparts = mw.getCurrentFrame():expandTemplate{title=template, args=citeParams} else -- raw ouput for k, v in orderedpairs(refs or {}, claim.references[ref]["snaks-order"]) do if k and v then if refparts then refparts = refparts .. ", " else refparts = "" end refparts = refparts .. tostring(mw.wikibase.getLabel(k)) .. ": " refparts = refparts .. v end end end if refparts then result = result .. mw.getCurrentFrame():extensionTag("ref", refparts) end end return result end  -- Return the site link (for the current site) for a given data item. function p.getSiteLink(frame)     if frame.args[1] == nil then         entity = mw.wikibase.getEntity()         if not entity then         return nil         end         id = entity.id     else         id = frame.args[1]     end       return mw.wikibase.getSitelink(id) end  -- Set whitelist or blacklist values local function setWhiteOrBlackList(type_list, num_qual, args) local i = 0 local listed = false local list = {} while i <= num_qual do if args[type_list .. i] and args[type_list .. i] ~= '' then listed = true list[tostring(i)] = {} local values = mw.text.split(args[type_list .. i], "/", true) for _, v in ipairs(values) do list[tostring(i)][v] = true end end i = i + 1 end return list, listed end  -- returns the page id (Q...) of the current page or nothing of the page is not connected to Wikidata function p.pageId(frame) local entity = mw.wikibase.getEntityObject() if not entity then return nil else return entity.id end end  function p.claim(frame) if mw.title.new(frame:getParent():getTitle()).isContentPage then if not mw.title.new(frame:getTitle()).isSubpage then -- invoked from a content page and not invoking a module subpage return printError("not-from-content-page") end end return p._main(frame.args, frame:getParent().args) end  -- Entry point from other modules or debugging, with a list of arguments. -- From other modules use: require("Module:Wikidata")._main({item="Q...", property="P...", ...}) -- On debug console use: =p._main({item="Q...", lang="xx", property="P...", ...}) function p._main(args, pargs) --If a value is already set, use it if args.value and args.value ~= '' then return args.value end  -- arguments local id = args.item or (pargs and pargs.item) if id == nil or id == "" then id = mw.wikibase.getEntityIdForCurrentPage() end local languages = findLang(args.lang) local itemgender = args["itemgender"] local idgender if itemgender then if string.match(itemgender, "^P%d+$") then local snak = mw.wikibase.getBestStatements(id, itemgender)[1] if snak and snak.mainsnak and snak.mainsnak.datavalue and snak.mainsnak.datavalue.value then idgender = snak.mainsnak.datavalue.value.id end elseif string.match(itemgender, "^Q%d+$") then idgender = itemgender end end local property = string.upper(args["property"] or "") local qualifierId = {} qualifierId[1] = args["qualifier"] and string.upper(args["qualifier"]) or nil local i = 2 while args["qualifier" .. i] do qualifierId[i] = string.upper(args["qualifier" .. i]) i = i + 1 end local parameter = args["formatting"] or ''; if parameter == "" then parameter = nil end local case = args.case local list = args["list"] or true; if (list == "false" or list == "no") then list = false end local sorting_col = args.tablesort local sorting_up = (args.sorting or "") ~= "-1" local separator = args.separator local conjunction = args.conjunction or args.separator local rowformat = args.rowformat local references = args["references"] local showerrors = args["showerrors"] local default = args["default"] local editicon = not (args.editicon == "false" or args.editicon == "no")  local parameters = {["property"] = property, ["formatting"] = parameter, ["list"] = list, ["case"] = case, ["lang"] = languages, ["editicon"] = editicon, ["separator"] = separator, ["conjunction"] = conjunction, ["qseparator"] = separator, ["qconjunction"] = conjunction}  -- defaults for table local preformat, postformat = "", "" local whitelisted, blacklisted = false, false local whitelist, blacklist = {}, {} if parameters.formatting == "table" then parameters.separator = parameters.separator or "
"
parameters.conjunction = parameters.conjunction or "
"
parameters.qseparator = ", " parameters.qconjunction = ", " if not rowformat then rowformat = "$0 ($1" i = 2 while qualifierId[i] do rowformat = rowformat .. ", $" .. i i = i + 1 end rowformat = rowformat .. ")" elseif mw.ustring.find(rowformat, "^[*#]") then parameters.separator = "
  • " parameters.conjunction = "
  • " if mw.ustring.match(rowformat, "^[*#]") == "*" then preformat = "
    • " postformat = "
    "
    else preformat = "
    1. " postformat = "
    "
    end rowformat = mw.ustring.gsub(rowformat, "^[*#] ?", "") end -- set whitelist and blacklist values whitelist, whitelisted = setWhiteOrBlackList("whitelist", #qualifierId, args) blacklist, blacklisted = setWhiteOrBlackList("blacklist", #qualifierId, args) end if default then showerrors = nil end -- get wikidata entity local entity = mw.wikibase.getEntity(id) if not entity then if showerrors then return printError("entity-not-found") else return default end end -- fetch the first claim of satisfying the given property local claims = findClaims(entity, property) if not claims or not claims[1] then if showerrors then return printError("property-not-found") else return default end end -- set feminine case if gender is requested local genderCase local genderRequested = false if parameters.case == "gender" or idgender then genderRequested = true elseif parameters.formatting == "table" then if args["case0"] and args["case0"] == "gender" then genderRequested = true else for i, qual in ipairs(qualifierId) do if args["case" .. i] and args["case" .. i] == "gender" then genderRequested = true break end end end end if genderRequested then if feminineGender(idgender or id) then genderCase = "feminineform" if parameters.case == "gender" or idgender then parameters.gender = genderCase end end end -- get initial sort indices local sortindices = {} for idx in pairs(claims) do sortindices[#sortindices + 1] = idx end -- sort by claim rank local comparator = function(a, b) local rankmap = { deprecated = 2, normal = 1, preferred = 0 } local ranka = rankmap[claims[a].rank or "normal"] .. string.format("%08d", a) local rankb = rankmap[claims[b].rank or "normal"] .. string.format("%08d", b) return ranka < rankb end table.sort(sortindices, comparator) local result local error if parameters.list or parameters.formatting == "table" then -- convert LF to line feed,
    may not work on some cases
    parameters.separator = parameters.separator == "LF" and "\010" or parameters.separator parameters.conjunction = parameters.conjunction == "LF" and "\010" or parameters.conjunction -- i18n separators parameters.separator = parameters.separator or mw.message.new('Comma-separator'):inLanguage(parameters.lang[1]):plain() parameters.conjunction = parameters.conjunction or (mw.message.new('And'):inLanguage(parameters.lang[1]):plain() .. mw.message.new('Word-separator'):inLanguage(parameters.lang[1]):plain()) -- iterate over all elements and return their value (if existing) local value, valueq local sortkey, sortkeyq local values = {} local sortkeys = {} local refs = {} local firstrank = parameters.list == "firstrank" and claims[sortindices[1]].rank or '' local rowlist = {} -- rows to list with whitelist or blacklist for idx in pairs(claims) do local claim = claims[sortindices[idx]] local reference={} if not whitelisted then rowlist[idx] = true end if firstrank ~= '' and firstrank ~= claim.rank then break end if parameters.formatting == "table" then local params = mw.clone(parameters) params.formatting = args["colformat0"]; if params.formatting == "" then params.formatting = nil end if args["case0"] then if args["case0"] == "gender" then params.gender = genderCase else params.case = args["case0"] end end value, sortkey, error = getValueOfClaim(claim, nil, params) if value then values[#values + 1] = {} sortkeys[#sortkeys + 1] = {} refs[#refs + 1] = {} if whitelist["0"] or blacklist["0"] then local valueraw, _, _ = getValueOfClaim(claim, nil, {["formatting"]="raw", ["lang"]=params.lang}) if whitelist["0"] and whitelist["0"][valueraw or ""] then rowlist[#values] = true elseif blacklist["0"] and blacklist["0"][valueraw or ""] then rowlist[#values] = false end end for i, qual in ipairs(qualifierId) do local j = tostring(i) params.formatting = args["colformat" .. j]; if params.formatting == "" then params.formatting = nil end params.case = parameters.case params.gender = parameters.gender if args["case" .. j] then if args["case" .. j] == "gender" then params.gender = genderCase else params.case = args["case" .. j] end end local valueq, sortkeyq, valueraw if qual == property then -- hack for getting the property with another formatting, i.e. colformat1=raw valueq, sortkeyq, _ = getValueOfClaim(claim, nil, params) else for q in mw.text.gsplit(qual, '%s*OR%s*') do if string.find(q, ".+/.+") then valueq, sortkeyq, valueraw = getValueOfParentClaim(claim, q, params) elseif string.find(q, "^/.+") then local claim2 = findClaims(entity, string.sub(q, 2)) if claim2 then valueq, sortkeyq, _ = getValueOfClaim(claim2[1], nil, params) end else valueq, sortkeyq, _ = getValueOfClaim(claim, q, params) end if valueq then break end end end values[#values]["col" .. j] = valueq sortkeys[#sortkeys]["col" .. j] = sortkeyq or valueq if whitelist[j] or blacklist[j] then valueq = valueraw or getValueOfClaim(claim, qual, {["formatting"]="raw", ["lang"]=params.lang}) if whitelist[j] and whitelist[j][valueq or ""] then rowlist[#values] = true elseif blacklist[j] and blacklist[j][valueq or ""] then rowlist[#values] = false end end end end else value, sortkey, error = getValueOfClaim(claim, qualifierId[1], parameters) values[#values + 1] = {} sortkeys[#sortkeys + 1] = {} refs[#refs + 1] = {} end if not value and showerrors then value = error end if value then if references and claim.references then reference=claim.references end refs[#refs]["col0"] =reference values[#values]["col0"] = value sortkeys[#sortkeys]["col0"] = sortkey or value end end -- sort and format results sortindices = {} for idx in pairs(values) do sortindices[#sortindices + 1] = idx end if sorting_col then local sorting_table = mw.text.split(sorting_col, '/', true) local comparator = function(a, b) local valuea, valueb local i = 1 while valuea == valueb and i <= #sorting_table do valuea = sortkeys[a]["col" .. sorting_table[i]] or '' valueb = sortkeys[b]["col" .. sorting_table[i]] or '' i = i + 1 end if sorting_up then return valueb > valuea end return valueb < valuea end table.sort(sortindices, comparator) end result = {} for idx in pairs(values) do local valuerow = values[sortindices[idx]] local reference = getReferences({["references"] = refs[sortindices[idx]]["col0"]}) value = valuerow["col0"] if parameters.formatting == "table" then if not rowlist[sortindices[idx]] then value = nil else value = mw.ustring.gsub(rowformat .. "$", "$0", value) -- fake end character added for easy gsub value = mw.ustring.gsub(value, "$R0", reference) -- add reference local rowformatting = rowformat .. "$" for i, _ in ipairs(qualifierId) do local valueq = valuerow["col" .. i] if args["rowsubformat" .. i] and valueq then -- add fake end character $ -- gsub $i not followed by a number so $1 doesn't match $10, $11... -- remove fake end character valueq = mw.ustring.gsub(args["rowsubformat" .. i] .. "$", "$" .. i .. "(%D)", valueq .. "%1") valueq = string.sub(valueq, 1, -2) rowformatting = mw.ustring.gsub(rowformatting, "$" .. i .. "(%D)", args["rowsubformat" .. i] .. "%1") end valueq = valueq and urlEscapes(valueq) or '' value = mw.ustring.gsub(value, "$" .. i .. "(%D)", valueq .. "%1") end value = string.sub(value, 1, -2) -- remove fake end character value = expandBraces(value, rowformatting) end else value = expandBraces(value, parameters.formatting) end result[#result + 1] = value if not parameters.list then break end end result = preformat .. mw.text.listToText(result, parameters.separator, parameters.conjunction) .. postformat else -- return first element local claim = claims[sortindices[1]] result, _, error = getValueOfClaim(claim, qualifierId[1], parameters) if result and references then result = result .. getReferences(claim) end end if result then return result else if showerrors then return error else return default end end end -- This is used to get the TA98 (Terminologia Anatomica first edition 1998) values like 'A01.1.00.005' (property P1323) -- which are then linked to http://www.unifr.ch/ifaa/Public/EntryPage/TA98%20Tree/Entity%20TA98%20EN/01.1.00.005%20Entity%20TA98%20EN.htm -- uses the newer mw.wikibase calls instead of directly using the snaks -- formatPropertyValues returns a table with the P1323 values concatenated with ", " so we have to split them out into a table in order to construct the return string p.getTAValue = function(frame) local ent = mw.wikibase.getEntity() local props = ent:formatPropertyValues('P1323') local out = {} local t = {} for k, v in pairs(props) do if k == 'value' then t = mw.text.split( v, ", ") for k2, v2 in pairs(t) do out[#out + 1] = "[http://www.unifr.ch/ifaa/Public/EntryPage/TA98%20Tree/Entity%20TA98%20EN/" .. string.sub(v2, 2) .. "%20Entity%20TA98%20EN.htm " .. v2 .. "]" end end end local ret = table.concat(out, "
    "
    ) if #ret == 0 then ret = "Invalid TA" end return ret end -- debugging functions, see module ../debug. function p.ViewSomething(frame) return require(wiki.module_title .. "/debug").ViewSomething(frame) end function p.Dump(frame) return require(wiki.module_title .. "/debug").Dump(frame) end function p.getEntityFromTree(frame) return require(wiki.module_title .. "/debug").getEntityFromTree(frame) end -- getParentValues: returns a property value with its instance label fetching a recursive tree local function uc_first(word) return mw.ustring.upper(mw.ustring.sub(word, 1, 1)) .. mw.ustring.sub(word, 2) end local function getPropertyValue(id, property, parameter, langs, editicon) local snaks = mw.wikibase.getBestStatements(id, property) local mysnak if snaks and snaks[1] and snaks[1].mainsnak then mysnak = snaks[1].mainsnak else return end local entityId local result = '-' -- default for 'no value' if mysnak.datavalue then entityId = "Q" .. tostring(mysnak.datavalue.value['numeric-id']) result, _ = getSnakValue(mysnak, {formatting=parameter, lang=langs, editicon=editicon}) end return entityId, result end function p.getParentValues(frame) local args = frame.args local id = args.item or frame:getParent().args.item if id == "" or id == nil then id = mw.wikibase.getEntityIdForCurrentPage() if id == nil then return end end local languages = findLang(args.lang) local propertySup = args["property"]; if (propertySup == nil or propertySup == "") then propertySup = "P131" end --administrative entity local propertyLabel = args["label"]; if (propertyLabel == nil or propertyLabel == "") then propertyLabel = "P31" end --instance local propertyLink = args["valuetext"]; if propertyLink == "" then propertyLink = nil end --internallink local upto = args["upto"]; if upto == "" then upto = nil end local labelShow = args["labelshow"]; if labelShow == "" then labelShow = nil end local rowformat = args["rowformat"]; if (rowformat == nil or rowformat == "") then rowformat = "$0 = $1" end local separator = args["separator"]; if (separator == nil or separator == "") then separator = "
    "
    end local sorting = args["sorting"]; if sorting == "" then sorting = nil end local editicon = not (args.editicon == "false" or args.editicon == "no") local lastlabel = uc_first(upto or '') local maxloop = tonumber(upto) or (lastlabel == '' and 10 or 50) local labelFilter = {} if labelShow then for i, v in ipairs(mw.text.split(labelShow, "/")) do labelFilter[uc_first(v)] = true end end local result = {} local label, link, linktext for iter = 1, maxloop do local label, link id, link = getPropertyValue(id, propertySup, args.formatting, languages, editicon) if id then _, label = getPropertyValue(id, propertyLabel, "label", languages) if label and link then if propertyLink then _, linktext = getPropertyValue(id, propertyLink, "label", languages) if linktext then link = mw.ustring.gsub(link, "%[%[(.*)%|(.+)%]%]", "[[%2|" .. linktext .. "]] [[%1|·]]") end end label = case(label, "infoboxlabel", languages[1]) if labelShow == nil or labelFilter[label] then result[#result + 1] = {label, link} labelFilter[label] = nil -- only first label found end if label == lastlabel then break end else break end else break end end local ret = {} local first = 1 local last = #result local iter = 1 if sorting == "-1" then first = #result; last = 1; iter = -1 end for i = first, last, iter do local rowtext = mw.ustring.gsub(rowformat, "$[01]", {["$0"] = result[i][1], ["$1"] = result[i][2]}) ret[#ret +1] = expandBraces(rowtext, rowformat) end return mw.text.listToText(ret, separator, separator) end function p.linkWithParentLabel(frame) local args = {} for k, v in pairs(frame.args) do -- metatable args[k] = v end -- get internal link of property/qualifier args.list = "true" args.formatting = "internallink" args.separator = "/·/" local pargs = frame:getParent().args local link_list = p._main(args, pargs) if link_list == nil or link_list == "" then return end local link_table = mw.text.split(link_list, "/·/", true) -- get id value of property/qualifier args.formatting = "raw" local items_list = p._main(args, pargs) local items_table = mw.text.split(items_list, "/·/", true) -- get label of parent property args.property = args.parent args.qualifier = nil local parent_claims = findClaims(mw.wikibase.getEntity(items_table[1]), args.parent) if parent_claims and parent_claims[1].mainsnak.datatype == 'monolingualtext' then args.formatting = nil args.list = 'lang' else args.formatting = "label" args.list = "false" end for i, v in ipairs(items_table) do args.item = v local link_label = p._main(args, pargs) if link_label and link_label ~= '' then link_table[i] = mw.ustring.gsub(link_table[i] or '', "%[%[(.*)%|.+%]%]", "[[%1|" .. link_label .. "]]") end end return mw.text.listToText(link_table) end function p.years_old(frame) local args = frame.args local id = args.item if id == '' or id == nil then id = mw.wikibase.getEntityIdForCurrentPage() end local lang = mw.language.new('en') local function getBestValue(id, prop) local snak = mw.wikibase.getBestStatements(id, prop)[1] if snak and snak.mainsnak and snak.mainsnak.datavalue and snak.mainsnak.datavalue.value then return snak.mainsnak.datavalue.value end end local birth = getBestValue(id, 'P569') if type(birth) ~= 'table' or birth.time == nil or birth.precision == nil or birth.precision < 8 then return end local death = getBestValue(id, 'P570') if type(death) ~= 'table' or death.time == nil or death.precision == nil then death = {['time'] = lang:formatDate('c'), ['precision'] = 11} -- current date elseif death.precision < 8 then return end local dates = {} dates[1] = {['min'] = {}, ['max'] = {}, ['precision'] = birth.precision} dates[1].min.year = tonumber(mw.ustring.match(birth.time, "^[+-]?%d+")) dates[1].min.month = tonumber(mw.ustring.match(birth.time, "\-(%d%d)\-")) dates[1].min.day = tonumber(mw.ustring.match(birth.time, "\-(%d%d)T")) dates[1].max = mw.clone(dates[1].min) dates[2] = {['min'] = {}, ['max'] = {}, ['precision'] = death.precision} dates[2].min.year = tonumber(mw.ustring.match(death.time, "^[+-]?%d+")) dates[2].min.month = tonumber(mw.ustring.match(death.time, "\-(%d%d)\-")) dates[2].min.day = tonumber(mw.ustring.match(death.time, "\-(%d%d)T")) dates[2].max = mw.clone(dates[2].min) for i, d in ipairs(dates) do if d.precision == 10 then -- month d.min.day = 1 local timestamp = string.format("%04d", tostring(math.abs(d.max.year))) .. string.format("%02d", tostring(d.max.month)) .. "01" d.max.day = tonumber(lang:formatDate("j", timestamp .. " + 1 month - 1 day")) elseif d.precision < 10 then -- year or decade d.min.day = 1 d.min.month = 1 d.max.day = 31 d.max.month = 12 if d.precision == 8 then -- decade d.max.year = d.max.year + 9 end end end local function age(d1, d2) local years = d2.year - d1.year if d2.month < d1.month or (d2.month == d1.month and d2.day < d1.day) then years = years - 1 end if d2.year > 0 and d1.year < 0 then years = years - 1 -- no year 0 end return years end local old_min = age(dates[1].max, dates[2].min) local old_max = age(dates[1].min, dates[2].max) local old = old_min == old_max and old_min or old_min .. "/" .. old_max if args.formatting then old = expandBraces(mw.ustring.gsub(args.formatting, '$1', old), args.formatting) end return old end -- Gets a label in a given language (content language by default) or its fallbacks, optionnally linked. function p.getLabel(frame) local args = frame.args or frame -- via invoke or require local id = mw.text.trim(args[1] or "") if id == "" then return end local editicon = not (args.editicon == "false" or args.editicon == "no") local pencil = '' local label, lang if args.label then label = args.label else local languages = findLang(args.lang) if languages[1] == wiki.langcode then -- exceptions or labels fixed local exist, labels = pcall(require, wiki.module_title .. "/labels") if exist and next(labels.infoboxLabelsFromId) ~= nil then label = labels.infoboxLabelsFromId[id] end end if label == nil then label, lang = getLabelByLangs(id, languages) if label then if args.itemgender and feminineGender(args.itemgender) then label = feminineForm(id, lang) or label end label = mw.language.new(lang):ucfirst(mw.text.nowiki(label)) -- sanitize end pencil = addEditIcon(id, lang, languages[1], editicon) end end local linked = args.linked if linked and linked ~= "" and linked ~= "no" then local article = mw.wikibase.getSitelink(id) or ("d:" .. id) return "[[" .. article .. "|" .. (label or id) .. "]]" .. pencil else return (label or id) .. pencil end end -- Return default language used function p.lang(frame) return findLang(frame.args[1])[1] end --[[ This is used to return an image legend from Wikidata image is property P18 image legend is property P2096 Call as {{#invoke:Wikidata |getImageLegend | | lang= |id=}} Returns PARAMETER, unless it is equal to "FETCH_WIKIDATA", from Item QID (expensive call) If QID is omitted or blank, the current article is used (not an expensive call) If lang is omitted, it uses the local wiki language, otherwise it uses the provided ISO-639 language code ISO-639: https://docs.oracle.com/cd/E13214_01/wli/docs92/xref/xqisocodes.html#wp1252447 Ranks are: 'preferred' > 'normal' This returns the label from the first image with 'preferred' rank Or the label from the first image with 'normal' rank if preferred returns nothing Ranks: https://www.mediawiki.org/wiki/Extension:Wikibase_Client/Lua ]] p.getImageLegend = function(frame) -- look for named parameter id; if it's blank make it nil local id = frame.args.id if id and (#id == 0) then id = nil end -- look for named parameter lang -- it should contain a two-character ISO-639 language code -- if it's blank fetch the language of the local wiki local lang = frame.args.lang if (not lang) or (#lang < 2) then lang = mw.language.getContentLanguage().code end -- first unnamed parameter is the local parameter, if supplied local input_parm = mw.text.trim(frame.args[1] or "") if input_parm == "FETCH_WIKIDATA" then local ent = mw.wikibase.getEntityObject(id) local imgs if ent and ent.claims then imgs = ent.claims.P18 end local imglbl if imgs then -- look for an image with 'preferred' rank for k1, v1 in pairs(imgs) do if v1.rank == "preferred" and v1.qualifiers and v1.qualifiers.P2096 then local imglbls = v1.qualifiers.P2096 for k2, v2 in pairs(imglbls) do if v2.datavalue.value.language == lang then imglbl = v2.datavalue.value.text break end end end end -- if we don't find one, look for an image with 'normal' rank if (not imglbl) then for k1, v1 in pairs(imgs) do if v1.rank == "normal" and v1.qualifiers and v1.qualifiers.P2096 then local imglbls = v1.qualifiers.P2096 for k2, v2 in pairs(imglbls) do if v2.datavalue.value.language == lang then imglbl = v2.datavalue.value.text break end end end end end end return imglbl else return input_parm end end -- This is used to get the QIDs of all of the values of a property, as a comma separated list if multiple values exist -- Usage: {{#invoke:Wikidata |getPropertyIDs | |FETCH_WIKIDATA}} -- Usage: {{#invoke:Wikidata |getPropertyIDs | | |qid=}} p.getPropertyIDs = function(frame) local go, errorOrentity, propclaims = parseInput(frame) if not go then return errorOrentity end local entity = errorOrentity -- if wiki-linked value collect the QID in a table if (propclaims[1] and propclaims[1].mainsnak.snaktype == "value" and propclaims[1].mainsnak.datavalue.type == "wikibase-entityid") then local out = {} for k, v in pairs(propclaims) do out[#out + 1] = "Q" .. v.mainsnak.datavalue.value["numeric-id"] end return table.concat(out, ", ") else -- not a wikibase-entityid, so return empty return "" end end return p
  • Tags:

    🔥 Trending searches on Wiki Hulontalo:

    Freemasonry1942C28 AprilSagñay, Camarines SurKebraon, Karangpilang, SurabayaSalahuddin al-AyyubiKabupaten Parigi MoutongFatufia, Bahodopi, MorowaliSememi, Benowo, SurabayaTamangapa, Manggala, MakassarBahari Makmur, Siotapina, ButonSemolowaru, Sukolilo, SurabayaNabua, Camarines Sur4 Januari1 PebruariAsiaTuren, MalangTaccorong, Gantarang, BulukumbaMaretLimboto Barat, GorontaloTamalanrea, MakassarLahuafu, Bungku Timur, MorowaliDaputari lo kabupaten wawu kota to BaliSiwalankerto, Wonocolo, SurabayaKarangmangu, Purwojati, BanyumasPoyang, Balantak Selatan, BanggaiWonokromo, Tikung, LamonganWikipedia bahasa Bikol Tengah29 MaretBalongsari, Tandes, SurabayaWilliam ShakespeareMahabharataSungai Bakau Kecil, Mempawah Timur, MempawahNambo, Lasalimu, ButonBiau, Gorontalo Utara2 MaretDaerah Istimewa YogyakartaPaccellekang, Pattallassang, GowaJawa TengahLapao-Pao, Wolo, KolakaFSiendeng, Hulonthalangi, GorontaloKwaron, Papar, KediriMenganti, Kesugihan, Cilacap7 PebruariPoliyamaCapalonga, Camarines NorteDaputari lo kabupaten wawu kota to Daerah Istimewa YogyakartaSekeloa, Coblong, BandungTexasDaputari lo kecamatan wawu kelurahan to Kabupaten Jember28 Maret6WITA19 JanuariCikawao, Lengkong, BandungDaputari lo negara wawu jumula lo pendudukTokyoPenolih, Kaligondang, PurbalinggaKhalid bin WalidKarangan, Badegan, Ponorogo10 JuliTumpaan, Kakas, Minahasa🡆 More