Modul:Datei: Unterschied zwischen den Versionen
Aus FürthWiki
(typo BeschreibungMaxWortlänge) |
(Dateiinfo Bild-Unterschrift und Info-Box) |
||
| (6 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
local p = {} | local p = {} | ||
local com = require(" | local com = require("Modul:Common") | ||
local str = require(" | local dev = require("Modul:Development") | ||
local wik = require(" | local str = require("Modul:String") | ||
local lfd = require(" | local wik = require("Modul:Wiki") | ||
local lfd = require("Modul:LinkFormDatum") | |||
local wob = require("Modul:Wörterbuch") | |||
function p. | function p.Dateibox(frame) | ||
-- mw.log("Dateibox(frame)") | |||
local | -- mw.logObject(frame, "frame") | ||
local | -- Kommando-Zeile zum Debuggen: | ||
local | -- =p.Dateibox{pargs={["fullpagename"]="Datei:test.jpg",["Genre"]="g1;g2",["Attribut1"]="a1",["Wert1"]="w1;w2"}} | ||
-- =p.Dateibox{pargs={["fullpagename"]="Datei:test.jpg",["Beschreibung"]="Int. Tag gegen Gewalt an Frauen: Aktive vom ''Unabhängige Frauen Fürth e. V.'' an einem Infostand, Nov. 2019"}} | |||
-- =p.Dateibox{pargs={["fullpagename"]="Datei:test.jpg",["Attribut1"]="Gebäude",["Wert1"]="Wolfringstraße 1",["Attribut2"]="Gebäude",["Wert2"]="Königstraße 86"}} | |||
local frame, pargs = dev.GetFrameAndParentArgs(frame) | |||
local title = pargs["fullpagename"] or wik.fullpagename() -- pargs["fullpagename"] zum Testen/Debuggen | |||
local t, v = "", "" | |||
-- Tabellenkopf | |||
t = t .. "<table class = \"wikitable\">" | |||
t = t .. "<th colspan = \"4\">" .. title .. "</th>" | |||
-- Genre-Kategorien | |||
v = "" | |||
for i, g in ipairs(str.splitAndStrip(pargs["Genre"], ";")) do | |||
if i > 1 then | |||
v = v .. ", " | |||
end | |||
v = v .. "[[:Kategorie:" .. g .. "|" .. g .. "]]{{#set:Genre=" .. g .. "}}[[Kategorie:" .. g .. "]]" | |||
end | end | ||
t = t .. p.attrZeile("Genre", v) | |||
-- | |||
-- Freiattribute | |||
local aw = {} | |||
local aw_fail = false | |||
for i = 1, 6 do | for i = 1, 6 do | ||
a = | local a = pargs["Attribut" .. i] or "" | ||
w = | local w = pargs["Wert" .. i] or "" | ||
if | if a ~= "" and w ~= "" then | ||
if | aw[a] = (aw[a] or "") .. w .. ";" -- Werte zusammenführen | ||
elseif a ~= "" or w ~= "" then | |||
aw_fail = true | |||
end | |||
if | end | ||
if aw_fail then | |||
t = t .. "[[Kategorie:Freiattribut-Fehler]]" | |||
end | |||
for a, w in pairs(aw) do | |||
if a == "Gebäude" then -- zusätzlich Gebäude nach StraßeHnr suchen und hinzufügen | |||
local gebaeude_wert = {} | |||
for _, e in ipairs(str.splitAndStrip(w, ";")) do -- direkt über Wertx angegebene Gebäude | |||
gebaeude_wert[e] = true | |||
end | |||
local gebaeude_query = {} | |||
for g, _ in pairs(gebaeude_wert) do -- über query ermittelte Gebäude | |||
local q = "[[:+]][[Kategorie:Gebäude]][[StraßeHnr::" .. g .. "]]|?#-" | |||
q = mw.smw.ask(q) or {} | |||
for _, qg in ipairs(q) do | |||
qg = qg[1] | |||
if gebaeude_wert[qg] ~= true then -- nur, wenn nicht schon direkt angegeben (auch nil!) | |||
gebaeude_query[qg] = true | |||
end | |||
end | |||
end | |||
v = "" -- jetzt den Anzeigetext zusammenbauen | |||
for g, _ in pairs(gebaeude_wert) do -- erst die direkt angegebenen Gebäude | |||
if v ~= "" then | |||
v = v .. ", " | |||
end | |||
v = v .. "[[" .. a .. "::" .. g .. "]]" | |||
end | |||
local v_query = "" -- dann die via query ermittelten Gebäude | |||
for g, _ in pairs(gebaeude_query) do | |||
if v_query ~= "" then | |||
v_query = v_query .. ", " | |||
end | end | ||
v_query = v_query .. "[[" .. a .. "::" .. g .. "]]" | |||
end | |||
if v_query ~= "" then | |||
v = v .. "<br>automatisch ermittelt über Straße/Hausnummer: " .. v_query | |||
end | end | ||
else | |||
v = p.attrValList(a, {[a] = w}) | |||
end | end | ||
t = t .. p.attrZeile(a, v) | |||
end | end | ||
-- normale Zeilen | |||
t = t .. p.attrZeile("Urheber", p.attrValList("Urheber", pargs)) | |||
t = t .. p.attrZeile("Quellangaben", p.attrVal("Quellangaben", pargs)) | |||
-- Ort/Straße mit Ausblendung | |||
for _, a in ipairs{{"Straße", "ZeigeNichtInStraße"}, {"Ort", "ZeigeNichtInOrt"}} do | |||
v = p.attrValList(a[1], pargs) | |||
if v ~= "" then | |||
t = t .. p.zeile("[[Attribut:" .. a[1] .. "|" .. wob.attr_text(a[1]) .. "]]", v, "ausgeblendet:", | |||
"[[" .. a[2] .. "::" .. (pargs[a[2]] or "Nein") .. "]]") | |||
end | end | ||
end | end | ||
-- Dateiart/Dateityp | |||
local extension = p.getExtension(title) | |||
local filekind = p.getFilekind(extension) | |||
t = t .. p.attrZeile("Dateiart", "[[Dateiart::" .. filekind .. "]]", | |||
"Dateityp", "[[Dateityp::" .. extension .. "]]") | |||
-- Erstellungsdatum/ÜberDatum | |||
for _, d in ipairs{ | |||
if | {"Erstellungsdatum", "Erstellungstag", "Erstellungsjahr"}, | ||
{"ÜberDatum", "ÜberTag", "ÜberJahr"}} do | |||
local date = pargs[d[1]] or "" | |||
if date ~= "" then | |||
t = t .. p.attrZeile(d[1], lfd.linkFormDate(date, d[1], d[2], d[3])) | |||
end | end | ||
end | end | ||
-- normale Zeilen | |||
t = t .. p.attrZeile("Seitennummer", p.attrValList("Seitennummer", pargs)) | |||
t = t .. p.attrZeile("Signatur", p.attrVal("Signatur", pargs)) | |||
t = t .. p.attrZeile("Länge", p.attrVal("Länge", pargs)) | |||
t = t .. p.attrZeile("Lizenz", p.attrVal("Lizenz", pargs)) | |||
t = t .. p.attrZeile("UploadCommons", p.attrVal("UploadCommons", pargs)) | |||
t = t .. p.attrZeile("Beschreibung", p.attrVal("Beschreibung", pargs)) | |||
-- Dateiinfo erstellen | -- Dateiinfo erstellen | ||
local infotext = "" | local dateiinfo, infotext = "", "" | ||
if not com.isEmpty(pargs["Beschreibung"]) then -- Beschreibung | |||
if not com.isEmpty( | dateiinfo = dateiinfo .. wik.wikiTextLimit(pargs["Beschreibung"], 100) -- max. Zeichenanzahl Bild-Unterschrift | ||
if mw.ustring.len(dateiinfo) ~= mw.ustring.len(pargs["Beschreibung"]) then | |||
dateiinfo = dateiinfo .. wik.wikiTextLimit( | |||
if mw.ustring.len(dateiinfo) ~= mw.ustring.len( | |||
dateiinfo = dateiinfo .. " ..." | dateiinfo = dateiinfo .. " ..." | ||
infotext = infotext .. pargs["Beschreibung"] | |||
end | end | ||
end | end | ||
if | local urheber = str.splitAndStrip(pargs["Urheber"] or "", ";") -- Urheber | ||
if #urheber > 0 then | |||
for u = 1, #urheber do | |||
if wik.pageExists(urheber[u]) then | |||
urheber[u] = "[[" .. urheber[u] .. "]]" | |||
end | |||
end | |||
if infotext ~= "" then | if infotext ~= "" then | ||
infotext = infotext .. "<br>" | infotext = infotext .. "<br>" | ||
end | end | ||
infotext = infotext .. " | infotext = infotext .. wob.attr_text("Urheber") .. ": " .. table.concat(urheber, ", ") | ||
end | |||
for _, d in ipairs{"Erstellungsdatum", "ÜberDatum"} do -- Erstellungsdatum, ÜberDatum | |||
date = pargs[d] or "" | |||
if date ~= "" then | |||
if infotext ~= "" then | |||
infotext = infotext .. "<br>" | |||
end | |||
infotext = infotext .. wob.attr_text(d) .. ": " .. lfd.linkFormDate(date) | |||
end | |||
end | end | ||
if not com.isEmpty( | if not com.isEmpty(pargs["Lizenz"]) then -- Lizenz | ||
if infotext ~= "" then | if infotext ~= "" then | ||
infotext = infotext .. "<br>" | infotext = infotext .. "<br>" | ||
end | end | ||
infotext = infotext .. " | infotext = infotext .. wob.attr_text("Lizenz") .. ": " .. pargs["Lizenz"] | ||
end | end | ||
if infotext ~= "" then | if infotext ~= "" then | ||
| Zeile 195: | Zeile 165: | ||
dateiinfo = dateiinfo .. " " | dateiinfo = dateiinfo .. " " | ||
end | end | ||
dateiinfo = dateiinfo .. "{{#info:" .. infotext .. "}}" | dateiinfo = dateiinfo .. "{{#info:" .. infotext .. "|note}}" | ||
end | end | ||
if dateiinfo ~= "" then | if dateiinfo ~= "" then | ||
t=t.. | t = t .. p.zeile("[[Attribut:Dateiinfo|Dateiinfo]] '''<br>(Bild-Unterschrift und Info-Box,<br>automatisch erstellt)''' ", "[[Dateiinfo::" .. dateiinfo .. "]]") | ||
end | end | ||
t=t.. | -- Tabellenende mit sem. Browsen | ||
t = t .. p.zeile("[[Bild:IconSearch.svg|16px|semantisches Browsen|link=Spezial:Durchsuchen/{{FULLPAGENAME}}]]", | |||
"[[Spezial:Durchsuchen/{{FULLPAGENAME}}|semantisches Browsen]]") | |||
t = t .. "</table>" | |||
t=t.. | |||
-- Seite setzen | |||
t = t .. "{{#set:Seite=" .. wik.fullpagename() .. "}}" | |||
-- mw.logObject(t, "t") | |||
t = frame:preprocess(t) | |||
-- mw.logObject(t, "t") | |||
return t | |||
return | |||
end | end | ||
| Zeile 221: | Zeile 188: | ||
local extension = filename:match("^.+%.([^%.]+)$") | local extension = filename:match("^.+%.([^%.]+)$") | ||
return mw.ustring.lower(extension) | return mw.ustring.lower(extension) | ||
end | end | ||
| Zeile 247: | Zeile 209: | ||
end | end | ||
function p. | function p.attrVal(a, pargs) -- Wert zu Attribut wandeln | ||
local t = "" | |||
local v = pargs[a] or "" | |||
if v ~= "" then | |||
t = t .. "[[" .. a .. "::" .. v .. "]]" | |||
end | |||
return t | |||
end | |||
function p.attrValList(a, pargs) -- Werteliste zu Attributen wandeln | |||
local t = "" | |||
local l = str.splitAndStrip(pargs[a] or "", ";") | |||
for i, v in ipairs(l) do | |||
if i > 1 then | |||
t = t .. ", " | |||
end | |||
t = t .. "[[" .. a .. "::" .. v .. "]]" | |||
end | |||
return t | |||
end | |||
function p.attrZeile(a1, v1, a2, v2) -- Tabellenzeile mit max. 2 Attributen | |||
local t = "" | |||
if v1 ~= "" then | |||
a1 = "[[Attribut:" .. a1 .. "|" .. wob.attr_text(a1) .. "]]" | |||
if a2 ~= nil and v2 ~= nil and v2 ~= "" then | |||
a2 = "[[Attribut:" .. a2 .. "|" .. wob.attr_text(a2) .. "]]" | |||
end | |||
t = t .. p.zeile(a1, v1, a2, v2) | |||
end | |||
return t | |||
end | |||
function p.zeile(a1, v1, a2, v2) -- Tabellenzeile mit max. 2x2 Einträgen | |||
local t = "" | |||
if v1 ~= "" then | |||
t = t .. "<tr>" | |||
t = t .. "<td>'''" .. a1 .. "'''</td>" | |||
if a2 == nil or v2 == nil or v2 == "" then | |||
t = t .. "<td colspan = \"3\">" .. v1 .. "</td>" | |||
else | |||
t = t .. "<td>" .. v1 .. "</td>" | |||
t = t .. "<td>'''" .. a2 .. "'''</td>" | |||
t = t .. "<td>" .. v2 .. "</td>" | |||
end | |||
t = t .. "</tr>" | |||
end | |||
return t | |||
end | end | ||
return p | return p | ||
Aktuelle Version vom 30. November 2025, 17:56 Uhr
Seiten-Übersicht
| Hauptseite | Unterseiten | ||
|---|---|---|---|
| Allgemein | |||
| Faktenbox | Vorlagen | ||
| Formulare |
|
||
| Module | |||
| Abfrage | Vorlagen |
| |
| Formulare |
| ||
| Sonstige | |||
Siehe auch
local p = {}
local com = require("Modul:Common")
local dev = require("Modul:Development")
local str = require("Modul:String")
local wik = require("Modul:Wiki")
local lfd = require("Modul:LinkFormDatum")
local wob = require("Modul:Wörterbuch")
function p.Dateibox(frame)
-- mw.log("Dateibox(frame)")
-- mw.logObject(frame, "frame")
-- Kommando-Zeile zum Debuggen:
-- =p.Dateibox{pargs={["fullpagename"]="Datei:test.jpg",["Genre"]="g1;g2",["Attribut1"]="a1",["Wert1"]="w1;w2"}}
-- =p.Dateibox{pargs={["fullpagename"]="Datei:test.jpg",["Beschreibung"]="Int. Tag gegen Gewalt an Frauen: Aktive vom ''Unabhängige Frauen Fürth e. V.'' an einem Infostand, Nov. 2019"}}
-- =p.Dateibox{pargs={["fullpagename"]="Datei:test.jpg",["Attribut1"]="Gebäude",["Wert1"]="Wolfringstraße 1",["Attribut2"]="Gebäude",["Wert2"]="Königstraße 86"}}
local frame, pargs = dev.GetFrameAndParentArgs(frame)
local title = pargs["fullpagename"] or wik.fullpagename() -- pargs["fullpagename"] zum Testen/Debuggen
local t, v = "", ""
-- Tabellenkopf
t = t .. "<table class = \"wikitable\">"
t = t .. "<th colspan = \"4\">" .. title .. "</th>"
-- Genre-Kategorien
v = ""
for i, g in ipairs(str.splitAndStrip(pargs["Genre"], ";")) do
if i > 1 then
v = v .. ", "
end
v = v .. "[[:Kategorie:" .. g .. "|" .. g .. "]]{{#set:Genre=" .. g .. "}}[[Kategorie:" .. g .. "]]"
end
t = t .. p.attrZeile("Genre", v)
-- Freiattribute
local aw = {}
local aw_fail = false
for i = 1, 6 do
local a = pargs["Attribut" .. i] or ""
local w = pargs["Wert" .. i] or ""
if a ~= "" and w ~= "" then
aw[a] = (aw[a] or "") .. w .. ";" -- Werte zusammenführen
elseif a ~= "" or w ~= "" then
aw_fail = true
end
end
if aw_fail then
t = t .. "[[Kategorie:Freiattribut-Fehler]]"
end
for a, w in pairs(aw) do
if a == "Gebäude" then -- zusätzlich Gebäude nach StraßeHnr suchen und hinzufügen
local gebaeude_wert = {}
for _, e in ipairs(str.splitAndStrip(w, ";")) do -- direkt über Wertx angegebene Gebäude
gebaeude_wert[e] = true
end
local gebaeude_query = {}
for g, _ in pairs(gebaeude_wert) do -- über query ermittelte Gebäude
local q = "[[:+]][[Kategorie:Gebäude]][[StraßeHnr::" .. g .. "]]|?#-"
q = mw.smw.ask(q) or {}
for _, qg in ipairs(q) do
qg = qg[1]
if gebaeude_wert[qg] ~= true then -- nur, wenn nicht schon direkt angegeben (auch nil!)
gebaeude_query[qg] = true
end
end
end
v = "" -- jetzt den Anzeigetext zusammenbauen
for g, _ in pairs(gebaeude_wert) do -- erst die direkt angegebenen Gebäude
if v ~= "" then
v = v .. ", "
end
v = v .. "[[" .. a .. "::" .. g .. "]]"
end
local v_query = "" -- dann die via query ermittelten Gebäude
for g, _ in pairs(gebaeude_query) do
if v_query ~= "" then
v_query = v_query .. ", "
end
v_query = v_query .. "[[" .. a .. "::" .. g .. "]]"
end
if v_query ~= "" then
v = v .. "<br>automatisch ermittelt über Straße/Hausnummer: " .. v_query
end
else
v = p.attrValList(a, {[a] = w})
end
t = t .. p.attrZeile(a, v)
end
-- normale Zeilen
t = t .. p.attrZeile("Urheber", p.attrValList("Urheber", pargs))
t = t .. p.attrZeile("Quellangaben", p.attrVal("Quellangaben", pargs))
-- Ort/Straße mit Ausblendung
for _, a in ipairs{{"Straße", "ZeigeNichtInStraße"}, {"Ort", "ZeigeNichtInOrt"}} do
v = p.attrValList(a[1], pargs)
if v ~= "" then
t = t .. p.zeile("[[Attribut:" .. a[1] .. "|" .. wob.attr_text(a[1]) .. "]]", v, "ausgeblendet:",
"[[" .. a[2] .. "::" .. (pargs[a[2]] or "Nein") .. "]]")
end
end
-- Dateiart/Dateityp
local extension = p.getExtension(title)
local filekind = p.getFilekind(extension)
t = t .. p.attrZeile("Dateiart", "[[Dateiart::" .. filekind .. "]]",
"Dateityp", "[[Dateityp::" .. extension .. "]]")
-- Erstellungsdatum/ÜberDatum
for _, d in ipairs{
{"Erstellungsdatum", "Erstellungstag", "Erstellungsjahr"},
{"ÜberDatum", "ÜberTag", "ÜberJahr"}} do
local date = pargs[d[1]] or ""
if date ~= "" then
t = t .. p.attrZeile(d[1], lfd.linkFormDate(date, d[1], d[2], d[3]))
end
end
-- normale Zeilen
t = t .. p.attrZeile("Seitennummer", p.attrValList("Seitennummer", pargs))
t = t .. p.attrZeile("Signatur", p.attrVal("Signatur", pargs))
t = t .. p.attrZeile("Länge", p.attrVal("Länge", pargs))
t = t .. p.attrZeile("Lizenz", p.attrVal("Lizenz", pargs))
t = t .. p.attrZeile("UploadCommons", p.attrVal("UploadCommons", pargs))
t = t .. p.attrZeile("Beschreibung", p.attrVal("Beschreibung", pargs))
-- Dateiinfo erstellen
local dateiinfo, infotext = "", ""
if not com.isEmpty(pargs["Beschreibung"]) then -- Beschreibung
dateiinfo = dateiinfo .. wik.wikiTextLimit(pargs["Beschreibung"], 100) -- max. Zeichenanzahl Bild-Unterschrift
if mw.ustring.len(dateiinfo) ~= mw.ustring.len(pargs["Beschreibung"]) then
dateiinfo = dateiinfo .. " ..."
infotext = infotext .. pargs["Beschreibung"]
end
end
local urheber = str.splitAndStrip(pargs["Urheber"] or "", ";") -- Urheber
if #urheber > 0 then
for u = 1, #urheber do
if wik.pageExists(urheber[u]) then
urheber[u] = "[[" .. urheber[u] .. "]]"
end
end
if infotext ~= "" then
infotext = infotext .. "<br>"
end
infotext = infotext .. wob.attr_text("Urheber") .. ": " .. table.concat(urheber, ", ")
end
for _, d in ipairs{"Erstellungsdatum", "ÜberDatum"} do -- Erstellungsdatum, ÜberDatum
date = pargs[d] or ""
if date ~= "" then
if infotext ~= "" then
infotext = infotext .. "<br>"
end
infotext = infotext .. wob.attr_text(d) .. ": " .. lfd.linkFormDate(date)
end
end
if not com.isEmpty(pargs["Lizenz"]) then -- Lizenz
if infotext ~= "" then
infotext = infotext .. "<br>"
end
infotext = infotext .. wob.attr_text("Lizenz") .. ": " .. pargs["Lizenz"]
end
if infotext ~= "" then
if dateiinfo ~= "" then
dateiinfo = dateiinfo .. " "
end
dateiinfo = dateiinfo .. "{{#info:" .. infotext .. "|note}}"
end
if dateiinfo ~= "" then
t = t .. p.zeile("[[Attribut:Dateiinfo|Dateiinfo]] '''<br>(Bild-Unterschrift und Info-Box,<br>automatisch erstellt)''' ", "[[Dateiinfo::" .. dateiinfo .. "]]")
end
-- Tabellenende mit sem. Browsen
t = t .. p.zeile("[[Bild:IconSearch.svg|16px|semantisches Browsen|link=Spezial:Durchsuchen/{{FULLPAGENAME}}]]",
"[[Spezial:Durchsuchen/{{FULLPAGENAME}}|semantisches Browsen]]")
t = t .. "</table>"
-- Seite setzen
t = t .. "{{#set:Seite=" .. wik.fullpagename() .. "}}"
-- mw.logObject(t, "t")
t = frame:preprocess(t)
-- mw.logObject(t, "t")
return t
end
function p.getExtension(filename)
local extension = filename:match("^.+%.([^%.]+)$")
return mw.ustring.lower(extension)
end
function p.getFilekind(filetype)
local t = {
["Bild"] = {"webp", "png", "gif", "jpg", "jpeg", "svg"},
["Dokument"] = {"pdf"},
["Audio"] = {"mp3", "ogg", "oga", "flac", "opus", "wav"},
["Midi"] = {"midi", "mid"},
["Video"] = {"webm", "mp4", "m4v", "ogv", "mpg", "mpeg"},
["3D-Modell"] = {"obj", "glb", "gltf"},
}
for key, values in pairs(t) do
for _, value in ipairs(values) do
if value == filetype then
return key -- Bricht beide Schleifen ab und gibt den Key zurück
end
end
end
return "" -- Gib leeren String zurück, wenn nichts gefunden wurde
end
function p.attrVal(a, pargs) -- Wert zu Attribut wandeln
local t = ""
local v = pargs[a] or ""
if v ~= "" then
t = t .. "[[" .. a .. "::" .. v .. "]]"
end
return t
end
function p.attrValList(a, pargs) -- Werteliste zu Attributen wandeln
local t = ""
local l = str.splitAndStrip(pargs[a] or "", ";")
for i, v in ipairs(l) do
if i > 1 then
t = t .. ", "
end
t = t .. "[[" .. a .. "::" .. v .. "]]"
end
return t
end
function p.attrZeile(a1, v1, a2, v2) -- Tabellenzeile mit max. 2 Attributen
local t = ""
if v1 ~= "" then
a1 = "[[Attribut:" .. a1 .. "|" .. wob.attr_text(a1) .. "]]"
if a2 ~= nil and v2 ~= nil and v2 ~= "" then
a2 = "[[Attribut:" .. a2 .. "|" .. wob.attr_text(a2) .. "]]"
end
t = t .. p.zeile(a1, v1, a2, v2)
end
return t
end
function p.zeile(a1, v1, a2, v2) -- Tabellenzeile mit max. 2x2 Einträgen
local t = ""
if v1 ~= "" then
t = t .. "<tr>"
t = t .. "<td>'''" .. a1 .. "'''</td>"
if a2 == nil or v2 == nil or v2 == "" then
t = t .. "<td colspan = \"3\">" .. v1 .. "</td>"
else
t = t .. "<td>" .. v1 .. "</td>"
t = t .. "<td>'''" .. a2 .. "'''</td>"
t = t .. "<td>" .. v2 .. "</td>"
end
t = t .. "</tr>"
end
return t
end
return p