Moduł:Kalendarium: Różnice pomiędzy wersjami

Z Wikipedii, wolnej encyklopedii
[wersja przejrzana][wersja przejrzana]
Usunięta treść Dodana treść
+wybór z listy
m +mini
Linia 610: Linia 610:
params.statisticsFile = { "", "", "" }
params.statisticsFile = { "", "", "" }
params.statisticsReady = ""
params.statisticsReady = ""
params.statisticsMinimum = ""
params.statisticsMinimum = " → <span style=\"color:#2EB82E\">MINI</span>"
params.statisticsNotReady = " → <span style=\"color:red\">UZUPEŁNIĆ</span>"
params.statisticsNotReady = " → <span style=\"color:red\">UZUPEŁNIĆ</span>"
params.statisticsNoFiles = " → <span style=\"color:blue\">BRAK PLIKÓW</span>"
params.statisticsNoFiles = " → <span style=\"color:blue\">BRAK PLIKÓW</span>"

Wersja z 11:54, 28 cze 2014

 Dokumentacja modułu [zobacz] [edytuj] [historia] [odśwież]

Moduł wspomagający automatyzację treści strony głównej Wikipedii i niektórych portali.

Raport

Funkcja do przygotowania podglądu z listą wszystkich dostępnych wydarzeń na zadany dzień.

Pole Do czego służy? Jak wypełnić?
1 Data dzienna Np. 2024-05-20.

Rocznice

Funkcja generująca treść do sekcji Rocznice na stronie głównej.

Pole Do czego służy? Jak wypełnić?
1 Data dzienna Np. 2024-05-20.

Imieniny

Funkcja generująca listę imion na zadany dzień.

Pole Do czego służy? Jak wypełnić?
1 Data dzienna Np. 2024-05-20.
2 Liczba losowanych imion Np. 4, domyślnie 3.
3 Separator między imionami Można nie wypełniać, domyślnie przecinek.
4 Separator przed ostatnim imieniem Można nie wypełniać, domyślnie „i”.

Święta

Funkcja generująca listę świąt na zadany dzień.

Pole Do czego służy? Jak wypełnić?
1 Data dzienna Np. 2024-05-20.
2 Separator między świętami Najlepiej ;
3 Separator przed ostatnim świętem Najlepiej ;.

Wydarzenia

Funkcja generująca listę wydarzeń, których możliwie okrągła rocznica wypada z zadanym dniu.

Pole Do czego służy? Jak wypełnić?
1 Data dzienna Np. 2024-05-20.
2 Minimalna liczba wydarzeń domyślnie 5
3 Maksymalna liczba obrazków? (do sprawdzenia) domyślnie 2.
4 Maksymalna liczba wydarzeń domyślnie minimalna liczba wydarzeń

Statystyka

Funkcja generująca statystykę dla dokumentacji modułu z listą wydarzeń dla konkretnego dnia.

Pole Do czego służy? Jak wypełnić?
1 Data dzienna Np. 2024-05-20.

ministat

Funkcja generująca linię z ministatystyką dla wybranego dnia.

Pole Do czego służy? Jak wypełnić?
1 Data dzienna Np. 2024-05-20.

leap

Funkcja generująca najbliższy rok przestępny względem podanego roku.

Pole Do czego służy? Jak wypełnić?
1 Rok. Jeśli jest przestępny to jest wynikiem funkcji. Jeśli nie jest przestępny to wynikiem jest najbliższy przyszły rok przestępny. Np. 2024.

Wybierz z listy

Implementacja {{Wybierz z listy}}.

Ilustracja na medal

Funkcja „losująca” ilustrację na medal używana w przypadku, gdy nie jest zdefiniowana zaplanowana ilustracja na zadany dzień.

Pole Do czego służy? Jak wypełnić?
1 Data dzienna Np. 2024-05-20.

Ilustracje wybierane są z galerii Wikipedia:Ilustracje na Medal. Bardzo płaskie lub wysokie i wąskie obrazy należy oznaczyć komentarzem <-- PANORAMA szerokość_x_wysokość -->, dzięki któremu pod lub obok ilustracji umieszczany jest pomocniczy pasek przewijania co pozwala na lepszą prezentację. Przykłady można obejrzeć w Wikipedia:Ilustracje na Medal/geografia.

Błędy

Błędy należy zgłaszać na stronie Wikipedia:Kawiarenka/Kwestie techniczne.

Zobacz też

local function loadOffsetDay(offset)
    if offset < -1 then
        return string.format(" %d days", offset)
    elseif offset == -1 then
        return " -1 day"
    elseif offset == 0 then
        return ""
    elseif offset == 1 then
        return " +1 day"
    else -- if offset > 1 then
        return string.format(" +%d days", offset)
    end
end
 
local function loadFeasts(params)
	local lang = mw.getContentLanguage()
	local feasts = mw.loadData( 'Module:Kalendarium/święta' )
	local date = params.year.."-"..params.base
	local romanEaster = false
	local orthodoxEaster = false
 
	local result = {}
	for _, v in ipairs(feasts) do
		if v.type == "fixed" then
			local info = v[params.base]
			if info then
				for _, w in ipairs(info) do
					table.insert(result, w)
				end
			end
		elseif v.type == "other" then
			-- standard fixed date
			for _, w in ipairs(v) do
				if w == date then
					table.insert(result, v.info)
					break
				end
			end
		elseif (v.type == "easter") and (params.year >= 326) and (params.year <= 4099) then
			local date1 = false
			if v.info1 then
				if not orthodoxEaster then
					orthodoxEaster = require("Moduł:Wielkanoc").Wyznacz({args = { tostring(params.year), metoda = "wschodnia", format="nie", ["dzień"]=0, },})
				end
 
				date1 = lang:formatDate("Y-m-d", orthodoxEaster..loadOffsetDay(v.offset)) == date
			end
 
			local date2 = false
			if v.info2 then
				if not romanEaster then
					romanEaster = require("Moduł:Wielkanoc").Wyznacz({args = { tostring(params.year), metoda = "zachodnia", format="nie", ["dzień"]=0, },})
				end
 
				date2 = lang:formatDate("Y-m-d", romanEaster..loadOffsetDay(v.offset)) == date
			end
 
			if date1 and date2 and v.info3 then
				table.insert(result, v.info3)
			else
				if date1 then
					table.insert(result, v.info1)
				end
				if date2 then
					table.insert(result, v.info2)
				end
			end
		else
			-- type not supported
		end
	end
 
 	return #result > 0 and mw.text.listToText(result, params.feastSeparator, params.feastConjunction) or ""
end

local function prepareDataIndex(data, except)
	-- prepare set of excluded values
	local exceptions = {}
	for _, v in ipairs(except or {}) do
		exceptions[v] = true
	end
 
	local result = {}
	for i, _ in ipairs(data or {}) do
		if not exceptions[i] then
			table.insert(result, i)
		end
	end
 
	return result
end
 
local function selectRandomItems(index, count)
	if #index <= count then
		return index
	end
 
	local result = {}
	while count > 0 do
		local i = math.random(1, #index)
		table.insert(result, index[i])
		table.remove(index, i)
		count = count - 1
	end
 
	return result
end
 
local function selectRandomData(data, count, except)
	-- prepare source index
	local fullIndex = prepareDataIndex(data, except)
	local index = selectRandomItems(fullIndex, count)
	table.sort(index)
 
	-- prepare result
	local result = {}
	for _, i in ipairs(index) do
		table.insert(result, data[i])
	end
 
	return result
end

local function loadDate(date)
	local lang = mw.getContentLanguage()
	-- minimize usage of #time function due to 6000 limit of output characters
	local stamp = lang:formatDate("U", date, true)
	local ymd = lang:formatDate("Ymd", date or ("@"..stamp), true)
	return {
		date = date,
		seed = tonumber(stamp),
		year = tonumber(string.sub(ymd, 1, 4)),
		base = string.sub(ymd, 5, 6).."-"..string.sub(ymd, 7, 8)
	}
end

local function chooseNames(params)
	local data = mw.loadData("Module:Kalendarium/imieniny")
	math.randomseed(params.seed)
	local names = selectRandomData(data[params.base], params.namesCount)
	return mw.text.listToText(names, params.namesSeparator, params.namesConjunction)
end

local function loadYear(year)
	if type(year) == "number" then
		return ((year > 0) and (year <= 9999)) and year or false
	elseif type(year) ~= "string" then
		return false
	end

	local yearpne = string.match(year, "^(%d%d?%d?%d?) p%.n%.e%.$")
	if not yearpne then
		return false
	end

	return 1-tonumber(yearpne)
end

local function loadEvents(events, data, accept, maxImages, maxEvents, imageSizeLimit)
	local result = 0
 
 	local fileFormat = "[[Plik:%2|"..(imageSizeLimit or "100x120px").."|right|%1]]"

	-- extract events that satisfy the selection rule
	local candidates = {}
	local imageIndex = {}
	for _, v in ipairs(data) do
		local event = {}
		event.year = loadYear(v.rok)
		event.priority = v.priorytet
		if event.year and v.tekst and accept(event) then
			table.insert(candidates, event)
			local text = v.tekst
			local images = {}
			local infos = {}
			while true do
				local info, files = mw.ustring.match(text, "%s?%(%((.-)||(.-)%)%)")
				if not files then
					event.text = text
					if #images > 0 then
						event.image = table.concat(images, "")
						event.info = infos
						table.insert(imageIndex, #candidates)
					end
					break
				end
 
				text = mw.ustring.gsub(text, "%s?%(%(.-||.-%)%)", "(**)", 1)
				table.insert(infos, " <small>(''"..info.."'')</small>")
				local sizeLimit = imageSizeLimit or "100x120px"
				local files = mw.ustring.gsub(files, "([^|]+)|([^|]+)|?", fileFormat)
				table.insert(images, files)
			end
		end
	end
 
	-- adjust number of required images and events
	for _, v in ipairs(events) do
		if v.image then
			-- the image is already loaded
			maxImages = maxImages - 1
		end
 
		maxEvents = maxEvents - 1
	end
 
	-- do not load more than required maximum elements
	if maxImages > maxEvents then
		maxImages = maxEvents
	end
 
	-- choose more images
	local usedImagesIndex = {}
	if maxImages > 0 then
		local selectedImages = selectRandomData(imageIndex, maxImages)
		for _, index in ipairs(selectedImages) do
			table.insert(usedImagesIndex, index)
			local item = candidates[index]
			-- print picture description in the message
			for _, info in ipairs(item.info) do
				item.text = mw.ustring.gsub(item.text, "%(%*%*%)", info, 1)
			end
			table.insert(events, item)
			result = result + 1
			maxEvents = maxEvents - 1
		end
	end
 
	-- choose remaing events but drop image for rest
	if maxEvents > 0 then
		local selectedEvents = selectRandomData(candidates, maxEvents, usedImagesIndex)
		for _, item in ipairs(selectedEvents) do
			-- exclude picture from the message
			item.text = mw.ustring.gsub(item.text, "%(%*%*%)", "")
			item.image = nil
			item.info = nil
			table.insert(events, item)
			result = result + 1
		end
	end
 
	return result
end

local function compactEvents(events)
	local function join(i,j)
		if i == j then
			-- nothing to compact - simple copy is enough
			return events[i]
		end
 
		-- split events into merge categories
		local bi = {} local bt = {} local bf=0 local bm=0
		local di = {} local dt = {} local df=0 local dm=0
		local oi = {} local ot = {}
		while i <= j do
			local text = events[i].text
			local ba, b = mw.ustring.match(text, "^urodził(a?) się(.+)$")
			local da, d = mw.ustring.match(text, "^zmarł(a?)(.+)$")
			if b then
				if ba == "a" then bf = bf + 1 else bm = bm + 1 end
				table.insert(bi, i)
				table.insert(bt, b)
			elseif d then
				if da == "a" then df = df + 1 else dm = dm + 1 end
				table.insert(di, i)
				table.insert(dt, d)
			else
				table.insert(oi, i)
				table.insert(ot, text)
			end
 
			i = i + 1
		end
 
		local images = {}
		for _, v in ipairs(bi) do
			local image = events[v].image
			if image then
				table.insert(images, image)
			end
		end
		for _, v in ipairs(di) do
			local image = events[v].image
			if image then
				table.insert(images, image)
			end
		end
		for _, v in ipairs(oi) do
			local image = events[v].image
			if image then
				table.insert(images, image)
			end
		end
 
		if (#bt == 0) and (#dt == 0) then
			return {
				year = events[j].year,
				text = mw.text.listToText(ot, "; ", "; tegoż dnia "),
				image = table.concat(images, ""),
			}
		end
 
		local buffer = {}
		if #bt == 1 then
			table.insert(buffer, events[bi[1]].text)
		elseif #bt > 1 then
			local phrase = (bm ~= 0 and "urodzili się: " or "urodziły się: ")..mw.text.listToText(bt, ", ", " oraz ")
			table.insert(buffer, phrase)
		end
		if #dt == 1 then
			table.insert(buffer, events[di[1]].text)
		elseif #dt > 1 then
			local phrase = (dm ~= 0 and "zmarli: " or "zmarły: ")..mw.text.listToText(dt, ", ", " oraz ")
			table.insert(buffer, phrase)
		end
		if #ot > 0 then
			local phrase = mw.text.listToText(ot, "; ", "; ")
			table.insert(buffer, phrase)
		end
		return {
			year = events[j].year,
			text = mw.text.listToText(buffer, "; ", "; tegoż dnia "),
			image = table.concat(images, ""),
		}
	end
 
	local result = {}
 
	local i0 = false
	local lastYear = false
 
	for i, v in ipairs(events) do
		if v.year ~= lastYear then
			if i0 then
				table.insert(result, join(i0, i-1))
			end
			i0 = i
			lastYear = v.year
		end
	end
	if i0 then
		table.insert(result, join(i0,#events))
	end
 
	return result
end

local function expandEmbeddedTemplates(events)
	local frame = mw.getCurrentFrame()
 
	local function expand(substring)
		return mw.getCurrentFrame():preprocess(substring)
	end
 
	for i, v in ipairs(events) do
		v.text = mw.ustring.gsub(v.text, "{{.-}}", expand)
	end
end

local function chooseEvents(params)
	local data = mw.loadData( 'Module:Kalendarium/'..params.base )
	math.randomseed(params.seed)
	local events = {}
	local count10 = loadEvents(events, data, function(event) local delta = params.year - event.year return (delta > 0) and ((delta % 10) == 0) and event.priority end, params.maximumImages, params.maximumEvents, params.imageSizeLimit)
	local count5 = loadEvents(events, data, function(event) local delta = params.year - event.year return (delta > 0) and ((delta % 10) == 5) and event.priority end, params.maximumImages, params.maximumEvents, params.imageSizeLimit)
	local count1 = 0
	if #events < params.minimumEvents then
		count10 = count10 + loadEvents(events, data, function(event) local delta = params.year - event.year return (delta > 0) and ((delta % 10) == 0) and not event.priority end, params.maximumImages, params.maximumEvents, params.imageSizeLimit)
	end

	if #events < params.minimumEvents then
		count5 = count5 + loadEvents(events, data, function(event) local delta = params.year - event.year return (delta > 0) and ((delta % 10) == 5) and not event.priority end, params.maximumImages, params.maximumEvents, params.imageSizeLimit)
	end

	if #events < params.minimumEvents then
		count1 = loadEvents(events, data, function(event) local delta = params.year - event.year return (delta > 0) and ((delta % 5) ~= 0) end, params.maximumImages, params.maximumEvents, params.imageSizeLimit)
	end

	local info = "Wybrane rocznice:"
	if count1 > 0 then
	elseif count5 > 0 then
		info = "Okrągłe, pięcioletnie rocznice:"
	elseif count10 > 0 then
		info = "Okrągłe, dziesięcioletnie rocznice:"
	end
	
	-- sort events by year
	table.sort(events, function(a,b) return a.year < b.year end)
	
	local events = compactEvents(events)
	
	expandEmbeddedTemplates(events)
	
	-- convert years to text
	for _, v in ipairs(events) do
		v.year = v.year > 0 and tostring(v.year) or tostring(1-v.year).." p.n.e."
	end
	
	-- format output
	local result = {}
	if #events > 0 then
		-- print header
		table.insert(result, info)
		-- print images
		for i, v in ipairs(events) do
			if v.image then
				table.insert(result,"\n")
				table.insert(result,v.image)
			end
		end
		-- print events
		local lastYear = nil
		for i, v in ipairs(events) do
			table.insert(result, "\n* ")
			if v.year ~= lastYear then
				table.insert(result, "[[")
			end
			table.insert(result, v.year)
			if v.year ~= lastYear then
				table.insert(result, "]]")
			end
			table.insert(result, " – ")
			table.insert(result, v.text)
			lastYear = v.year
		end
	end

	return table.concat(result, "")
end

local function anniversaries(params)
	params.namesSeparator = ", "
	params.namesConjunction = " i "
	params.feastSeparator = "; "
	params.feastConjunction = "; "

	-- format output
	local result = {}
	table.insert(result, "'''")
	table.insert(result, mw.getContentLanguage():formatDate("j xg", params.year.."-"..params.base, true))
	table.insert(result, "''': [[imieniny]] obchodzą m.in.: ")
	table.insert(result, chooseNames(params))
	local feasts = loadFeasts(params)
	if #feasts > 0 then
		table.insert(result, params.feastSeparator)
		table.insert(result, feasts)
	end
	local events = chooseEvents(params)
	if #events > 0 then
		table.insert(result, "<br/>")
		table.insert(result, events)
	end
	table.insert(result, "<br style=\"clear:right;\" />")
	
	return table.concat(result, "")
end

local function statistics(params)
	local success, data = pcall(mw.loadData, 'Module:Kalendarium/'..params.base)
	if not success then
		data = {}
	end
	local stats =
	{
		[0] = { count = 0, text = 0, images = 0 },
		[1] = { count = 0, text = 0, images = 0 },
		[2] = { count = 0, text = 0, images = 0 },
		[3] = { count = 0, text = 0, images = 0 },
		[4] = { count = 0, text = 0, images = 0 },
		[5] = { count = 0, text = 0, images = 0 },
	}
	for _, v in ipairs(data) do
		local year = loadYear(v.rok)
		local stat = stats[year and (((year - params.year) % 5) + 1) or 0]
		local text, count = mw.ustring.gsub(v.tekst, "%(%(.-%)%)", "")
		text = mw.ustring.gsub(text, "{{.-}}", "")
		stat.count = stat.count + 1
		stat.text = stat.text + mw.ustring.len(text)
		stat.images = stat.images + count
	end
	local result = {}
	local lang = mw.getContentLanguage()
	for i, v in ipairs(stats) do
		local year = (params.base == "02-29") and tostring(params.year + (4 * (i - 1))) or tostring(params.year + i - 1)
		local hint = string.format(params.statisticsHint, year % 5, 5 + (year % 5))
		local count = tostring(v.count)..lang:convertPlural(v.count, params.statisticsCount)
		local text = tostring(v.text)..lang:convertPlural(v.text, params.statisticsSize)
		local images = tostring(v.images)..lang:convertPlural(v.images, params.statisticsFile)
		local status = v.count < params.minimumEvents and params.statisticsNotReady or v.images <= 0 and params.statisticsNoFiles or v.count <= params.maximumEvents and params.statisticsMinimum or params.statisticsReady
--		local status = v.count > params.maximumEvents and (images > 0 and params.statisticsReady or params.statistics) or (v.count >= params.minimumEvents and params.statisticsMinimum or params.statisticsNotReady)
		local info = string.format(params.statisticsFormat, year, hint, count, text, images, status)
		table.insert(result, info)
	end
 
	if stats[0].count > 0 then
		local v = stats[0]
		local count = tostring(v.count)..lang:convertPlural(v.count, params.statisticsCount1, params.statisticsCount2, params.statisticsCount5)
		local text = tostring(v.text)..lang:convertPlural(v.text, params.statisticsSize1, params.statisticsSize2, params.statisticsSize5)
		local images = tostring(v.images)..lang:convertPlural(v.images, params.statisticsFile1, params.statisticsFile2, params.statisticsFile5)
		local info = string.format(params.statisticsOther, count, text, images)
		table.insert(result, info)
	end
 
	return table.concat(result, params.statisticsSeparator)
end

function selectFewFromList(params)
	if not params.text then
		return nil
	end
	
	local lines = mw.text.split(params.text, params.splitter, false)
	if params.trimPrefix then
		if #lines[1] == 0 then
			table.remove(lines,1)
		elseif #params.trimPrefix > 0 then
			lines[1] = mw.ustring.gsub(lines[1], params.trimPrefix, "", 1)
		end
	end

	if (#lines > 1) and params.trimSuffix then
		lines[#lines] = mw.ustring.gsub(lines[#lines], params.trimSuffix, "", 1)
	end

	math.randomseed(params.seed)
	local result = selectRandomItems(lines, params.count)
	return params.prefix..table.concat(result, params.joiner)..params.suffix
end

return {
	["Raport"] = function(frame)
		local params = loadDate(frame.args[1])
		params.namesCount = 1e10
		params.minimumEvents = 1e10
		params.maximumImages = 1e10
		params.maximumEvents = 1e10
		params.imageSizeLimit = "60px"
		mw.log(anniversaries(params))
		return anniversaries(params)
	end,
	
	["Rocznice"] = function(frame)
		local params = loadDate(frame.args[1])
		params.namesCount = 3
		params.minimumEvents = 6
		params.maximumImages = 2
		params.maximumEvents = 7
		params.imageSizeLimit = "100x120px"
		mw.log(anniversaries(params))
		return anniversaries(params)
	end,
	
	["Imieniny"] = function(frame)
		local params = loadDate(frame.args[1])
		params.namesCount = tonumber(frame.args[2]) or 3
		params.namesSeparator = frame.args[3]
		params.namesConjunction = frame.args[4]
		mw.log(chooseNames(params))
		return chooseNames(params)
	end,
	
	["Święta"] = function(frame)
		local params = loadDate(frame.args[1])
		params.feastSeparator = frame.args[2]
		params.feastConjunction = frame.args[3]
		mw.log(loadFeasts(params))
		return loadFeasts(params)
	end,
	
	["Wydarzenia"] = function(frame)
		local params = loadDate(frame.args[1])
		params.minimumEvents = tonumber(frame.args[2]) or 5
		params.maximumImages = tonumber(frame.args[3]) or 2
		params.maximumEvents = tonumber(frame.args[4]) or params.minimumEvents
		params.imageSizeLimit = "100x120px"
		mw.log(chooseEvents(params))
		return chooseEvents(params)
	end,
	
	["Statystyka"] = function(frame)
		local params = loadDate(frame.args[1])
		params.minimumEvents = 6
		params.maximumEvents = 7
		params.statisticsFormat = "\n*'''%s'''%s – %s, %s, %s%s"
		params.statisticsOther = "\n*'''INNE''' – %s, %s, %s"
		params.statisticsHint = " (<small>lata zakończone na</small> '''%d''' <small>lub</small> '''%d''')"
		params.statisticsSeparator = ""
		params.statisticsCount = { " wydarzenie", " wydarzenia", " wydarzeń" }
		params.statisticsSize =  { " znak", " znaki", " znaków" }
		params.statisticsFile = { " grupa plików", " grupy plików", " grup plików" }
		params.statisticsReady = ""
		params.statisticsMinimum = " → wymagane minimum"
		params.statisticsNotReady = " → <span style=\"color:red\">WYMAGA UZUPEŁNIENIA</span>"
		params.statisticsNoFiles = " → <span style=\"color:blue\">BRAK PLIKÓW</span>"
		mw.log(statistics(params))
		return statistics(params)
	end,
 
	["ministat"] = function(frame)
		local params = loadDate(frame.args[1])
		params.minimumEvents = 6
		params.maximumEvents = 7
		params.statisticsFormat = "'''%s'''%s: %s/%s/%s%s"
		params.statisticsOther = "'''INNE''': %s/%s/%s"
		params.statisticsHint = ""
		params.statisticsSeparator = "; "
		params.statisticsCount = { "", "", "" }
		params.statisticsSize =  { "", "", "" }
		params.statisticsFile = { "", "", "" }
		params.statisticsReady = ""
		params.statisticsMinimum = " → <span style=\"color:#2EB82E\">MINI</span>"
		params.statisticsNotReady = " → <span style=\"color:red\">UZUPEŁNIĆ</span>"
		params.statisticsNoFiles = " → <span style=\"color:blue\">BRAK PLIKÓW</span>"
		mw.log(statistics(params))
		return statistics(params)
	end,

	["Wybierz z listy"] = function(frame)
		local f = frame:getParent()
		local params = {}
		params.seed = tonumber(f.args.los) or 0
		params.count = tonumber(f.args.ile) or 5
		params.text = f.args[1]
		params.splitter =  "%s-\n%*%s*"
		params.joiner = "\n*"
		params.prefix = "*"
		params.suffix = ""
		params.trimPrefix = "^%*%s*"
		params.trimSuffix = "%s+$"
		return selectFewFromList(params)
	end,

}