Module:沙盒/在咕咕咕的咕子/Sandbox1:修订间差异

来自Arcaea中文维基
(合并Module:DesignerSong,bydAppend和'全难度'持留)
(copy Module:Partnertable)
第1行: 第1行:
p={}
local getArgs = require 'Module:Arguments'.getArgs
local DL = mw.loadJsonData 'Template:DesignersList.json'
local lang = mw.getContentLanguage()
local multiId = mw.loadJsonData 'Template:Transition.json'.multiId
local p = {}
local trans = mw.loadJsonData 'Template:Transition.json'


local mad = require 'Module:AnotherData'
function labelText(text)
local data = require "Module:Arcaea Data"
return mw.html.create 'span':addClass 'label-text':wikitext(text)
local CL = require 'Module:ConvertLink'
end


local CDL = DL.complex
function updateReplace(version)
local SDL = DL.simple
-- local result = string.gsub(version, 'V(%d+%.%d+)', 'v%1')
local specialSong = DL.special
-- local result = string.gsub(version, '(%d+c?)%(', '%1<br>(')
-- local result = string.gsub(version, '[^]%f[(]', '<br>(')
local result = string.gsub(version, '(%d+c?)%(', '%1<br>(')
return result
end


local queryMO = data.allSongInformation("id", "mobile")
function update(version, device, awakenyes, version2) --更新时间
local queryNS = data.allSongInformation("id", "ns")
local deviceEpitaxy = (device == 'ns') and 'NS版' or ' 移动版'
local diffList = {'PST', 'PRS', 'FTR', 'BYD', 'ETR'}
local versionEpitaxy = (awakenyes and version ~= version2 and version2)
local diffNameList = {PST='Past', PRS='Present', FTR='Future', BYD='Beyond', ETR='Eternal'}
and {' 搭档:', updateReplace(version), '<br>觉醒形态:', updateReplace(version2)}
local bydAppend = {[284]='last'}
or {updateReplace(version)}
local dataBox = mw.html.create 'div':addClass 'date-box'
dataBox:tag 'div':node(labelText(deviceEpitaxy)):done()
:tag 'div':wikitext(unpack(versionEpitaxy)):done()
return dataBox
end


local songDiffDesigner={}
function skill(text, skilldiff, label)
local specialDesigner ={}
local result = mw.html.create()
local LinkedDesignerMemory={['/']='/'}
if skilldiff then result:tag 'div':node(labelText(label)) end
local bydAppendInfo={}
result:wikitext(text)
return result
end


local function linkDesigner(designer, songid)
function title(...)
if LinkedDesignerMemory[designer] then return LinkedDesignerMemory[designer] end
return mw.text.listToText({...}, '<br>', '<br>')
local Linked = CL.designerLink(designer, songid)
LinkedDesignerMemory[designer] = Linked
return Linked
end
end


local function readList(appendList)
function version(time)
local pickList = {}
return ({string.find(time, '([vV]%d+%.%d+%.%d+c?)')})[3] or 'unknown'
   local mobileList = {}
   local listMO = mad.listOf('songs', 'mobile')
local function write(songid, songDiffList)
songDiffDesigner[songid]={}
local num, sameCount = 0,0
local lastDesigner = nil
for _,level in ipairs(songDiffList) do
local diff = diffList[level.ratingClass+1]
local designer = level.chartDesigner
num=num+1
if lastDesigner ~= designer then
sameCount = 0
if not pickList[designer] then
pickList[designer] = {}
end
if not pickList[designer][songid] then
pickList[designer][songid] = {}
end
pickList[designer][songid][diff]=true
mobileList[songid]=true
table.insert(songDiffDesigner[songid], {diff, linkDesigner(designer, songid)})
if specialSong[songid] then
specialDesigner[designer]=true
end
lastDesigner=designer
else
sameCount=sameCount+1
table.insert(songDiffDesigner[songid], {diff, nil})
-- if songDiffDesigner[songid][num-sameCount] then
songDiffDesigner[songid][num-sameCount][3]=sameCount+1
-- end
-- songDiffDesigner[songid][num][3]=sameCount+1
end
   end
end
  
   for index, id in pairs(bydAppend) do
bydAppendInfo[id] = listMO[index].difficulties[4]
bydAppendInfo[id].id=listMO[index].id
end
  
   for index, song in ipairs(listMO) do
   local songid = song.id
   local songDiffList = song.difficulties
   if bydAppendInfo[songid] then table.insert(songDiffList,bydAppendInfo[songid]) end
   if not bydAppend[index] then
   write(songid, songDiffList)
   end
   end
  
--  有独占ns曲目再启用
--  for index, song in ipairs(listNS) do
-- local songid = song.id
-- local songDiffList = song.difficulties
-- if not mobileList.songid then
-- write(songid, songDiffList)
-- end
-- end
  
for songid, songDiffList in pairs(appendList) do
   write(songid, songDiffList)
   end
return pickList
end
end


local function genList(pickList)
function getImage(normal, awaken, normalJacket, awakenJacket, awakenyes, type)
local function cate(singleList, cArtist, artist)
local container = mw.html.create 'div':addClass 'container'
local artist = artist or cArtist
local JacketNormal = normalJacket
if not singleList[artist] then singleList[artist] = {} end
if awaken then
     for id,diff in pairs(pickList[cArtist]) do
local JacketAwaken = awakenJacket or normalJacket
     singleList[artist][id]=diff
container -- tab
     end
:tag 'div':addClass 'img-tab':attr('id', 'tab-' .. type)
     return singleList
:tag 'div':wikitext 'Normal':addClass 'img-tab-part normal active':done()
end
:tag 'div':wikitext 'Awaken':addClass 'img-tab-part awaken':done()
container -- part
   local singleList = {}
:tag 'div':wikitext('[[ 文件:', normal, '|300px|none]]'):node(labelText '画师'):wikitext(tostring(JacketNormal)):addClass('active tab-text-' .. type):done()
   for cDesigner,songids in pairs(pickList) do
:tag 'div':wikitext('[[文件:', awaken, '|300px|none]]'):node(labelText '画师'):wikitext(tostring(JacketAwaken)):addClass('tab-text-' .. type):done()
   local designerList={}
else
     if CDL[cDesigner] then
container
if CDL[cDesigner].__FullData__ then
:tag 'div':wikitext('[[ 文件:', normal, '|300px]]'):done()
for _,text in pairs(CDL[cDesigner].__FullData__) do
:tag 'div':node(labelText ' 师'):wikitext(JacketNormal):done()
if text.link then
           local designer = text['link']
if not designerList[designer] then
singleList = cate(singleList, cDesigner, designer)
designerList[designer]=true
end
end
end
else
for link in pairs(CDL[cDesigner]) do
           local designer = link
if not designerList[designer] then
singleList = cate(singleList, cDesigner, designer)
designerList[designer]=true
end
end
end
     else
     local temp_text = cDesigner
     local count = 0
     for _,data in ipairs(SDL) do
local designer = data.link
local dis = data.display
if string.find(temp_text, dis) then
singleList = cate(singleList, cDesigner, designer)
designerList[designer]=true
temp_text = string.gsub(temp_text, dis, '')
count = count + 1
end
end
if count == 0 then
if specialDesigner[cDesigner] then
singleList = cate(singleList, cDesigner, ' 与主线剧情相关的特殊名义')
else
singleList = cate(singleList, cDesigner, ' 其他未确认谱 名义')
end
end
     end
end
end
   return singleList
return container
end
end


-- Function to convert table to string
function p.main(frame)
-- local function t2s(tbl, indent)
local args = getArgs(frame)
--   indent = indent or 0
return p._main(args)
--   local toPrint = string.rep(" ", indent) .. "{\n"
end
  
--   for k, v in pairs(tbl) do
--     local keyString = tostring(k)
--     local valueString


--      if type(v) == "table" then
function p._main(args)
--        valueString = t2s(v, indent + 2)
local awaken  --觉醒判定
--      else
local size   --图片大小
--        valueString = tostring(v)
local belongs  --所属单位
--      end
local skillawaken --觉醒技能
local skillsec -- 第二技能
if args['觉醒形态'] == '有' then awaken = true else awaken = false end
if awaken and args['技能'] ~= args['觉醒技能'] and args['觉醒技能'] ~= nil then skillawaken = true else skillawaken = false end
if args['第二技能'] then skillsec = true else skillsec = false end
if args['所属曲包'] then
belongs = '所属曲包'
elseif args['所属单曲'] then
belongs = '所属单曲'
else
belongs = '所属单曲/曲包'
end
local imageA = getImage(args['图片'], args['觉醒图片'], args['画师'], args['觉醒画师'], awaken, 'a')
local imageB = getImage(args['图片'], args['觉醒图片'], args['画师'], args['觉醒画师'], awaken, 'b')
local infoList = {
[1] = {title(args['名称'], args['第二名称']), {id = 'title'}},
[2] = {imageA, {id = 'top-image'}},
[3] = {imageB, {id = 'right-image'}},
[4] = {'搭档信息', {class = 'header'}},
[5] = {'类型', {class = 'label'}},
[6] = {args['类型'], {class = 'data'}},
[7] = {belongs, {class = 'label'}},
[8] = {args[belongs] or '-', {class = 'data'}},
[9] = {'种类', {class = 'label'}},
[10] = {args['种类'] or '-', {class = 'data'}},
[11] = {'觉醒形态', {class = 'label'}},
[12] = {args['觉醒形态'] or '无', {class = 'data'}},
[13] = {'搭档数据', {class = 'header', id = 'all-play-header'}},
[14] = {'搭档数据 (移动版)', {class = 'header', id = 'mobile-play-header'}},
[15] = {'等级', {class = 'label'}},
[16] = {'Lv1', {class = 'level-data'}},
[17] = {'Lv20', {class = 'level-data'}},
[18] = {'Lv30', {class = 'awaken-data'}},
[19] = {'Frag', {class = 'label'}},
[20] = {args['Frag1'], {class = 'level-data'}},
[21] = {args['Frag20'], {class = 'level-data'}},
[22] = {args['Frag30'], {class = 'awaken-data'}},
[23] = {'Step', {class = 'label'}},
[24] = {args['Step1'], {class = 'level-data'}},
[25] = {args['Step20'], {class = 'level-data'}},
[26] = {args['Step30'], {class = 'awaken-data'}},
[27] = {'Over', {class = 'label over'}},
[28] = {args['Over1'], {class = 'level-data over'}},
[29] = {args['Over20'], {class = 'level-data over'}},
[30] = {args['Over30'], {class = 'awaken-data over'}},
[31] = {'搭档数据 (Nintendo Switch版)', {class = 'header ns', id = 'ns-play-header'}},
[32] = {'等级', {class = 'label ns'}},
[33] = {'Lv1', {class = 'level-data ns'}},
[34] = {'Lv20', {class = 'level-data ns'}},
[35] = {'Lv30', {class = 'awaken-data ns'}},
[36] = {'Frag', {class = 'label ns'}},
[37] = {args['Frag1NS'], {class = 'level-data ns'}},
[38] = {args['Frag20NS'], {class = 'level-data ns'}},
[39] = {args['Frag30NS'], {class = 'awaken-data ns'}},
[40] = {'Step', {class = 'label ns'}},
[41] = {args['Step1NS'], {class = 'level-data ns'}},
[42] = {args['Step20NS'], {class = 'level-data ns'}},
[43] = {args['Step30NS'], {class = 'awaken-data ns'}},
[44] = {'技能', {class = 'label', id = 'skill-label'}},
[45] = {skill(args['技能'] or '-', skillawaken, '普通形态'), {class = 'data', id = 'skill-normal'}},
[46] = {skill(args['觉醒技能'] or args['技能'], skillawaken, '觉醒形态'), {class = 'data', id = 'skill-awaken'}},
[47] = {skill(args['技能'], skillsec, args['第一技能说明'] or '第一技能'), {class = 'data', id = 'skill-first'}},
[48] = {skill(args['第二技能'], skillsec, args['第二技能说明'] or '第二技能'), {class = 'data', id = 'skill-first'}},
[49] = {'更新时间', {id = 'update-data-label', class = 'label'}},
[50] = {update(args['更新时间'] or '无', 'mobile', awaken, args['觉醒更新时间'] or args['更新时间']), {id = 'mobile-date-normal', class = 'data'}},
[51] = {update(args['更新时间NS'] or '无', 'ns', awaken, args['觉醒更新时间NS'] or args['更新时间NS']), {id = 'ns-date-normal', class = 'data'}}
}


--     toPrint = toPrint .. string.rep(" ", indent + 2) .. "[" .. keyString .. "] = " .. valueString .. ",\n"
local box = mw.html.create 'div'
--   end


--    toPrint = toPrint .. string.rep(" ", indent) .. "}"
-- 样式控制
--    return toPrint
box:addClass 'partnerbox arcaeabox'
-- end
if awaken then box:addClass 'awaken' end
-- if args['名称'] == '' then box:addClass( "ns-only" ) end
if skillawaken then box:addClass 'skill-awaken' end
if skillsec then box:addClass 'skill-second' end
if args['类型'] == '支援型' then
box:addClass 'support'
elseif args['类型'] == '挑战型' then
box:addClass 'challenge'
else
box:addClass 'balance'
end


local function songTitle(id,byd)
if args[' 更新时间NS'] then
local display
box:addClass 'ns-box'
local title = queryMO(id, 'title') or queryNS(id, 'title')
if byd then
display = queryMO(id, 'bydSongName')
-- 如果有新的ns独占byd曲目再使用
-- display = queryMO(id, 'bydSongName') or queryNS(id, 'bydSongName') or 'cant find BYD'
if not display then
return nil
end
else
display = title
end
end
local res = trans.songNameToDisplayName[title]
if res then return res..'|'..display end
res = trans.sameName[title]
if res then return res[id]..'|'..display end
if title then return title..'|'..display
else return nil end
end


local function songPack(id)
--表格生成
local packid,plat,isNS
local mwHtmlMeta = getmetatable(box)
-- if queryNS(id, 'set') then
for _, v in ipairs(infoList) do
-- packid = queryNS(id, 'set')
local cell = box:tag 'div':attr(v[2]):cssText(v[3])
-- plat = 'ns'
if getmetatable(v[1]) == mwHtmlMeta then cell:node(v[1]) else cell:wikitext(tostring(v[1])) end
-- isNS = 1
if queryMO(id, 'set') then
packid = queryMO(id, 'set')
else
return nil
end
end
local packName = trans.packName[packid] or mad.packQueryWrap(packid, plat).name
local packLink = CL.packLink(packName,1,isNS)
return packLink
end


local head = '{| class="wikitable" border="1" cellspacing="1" cellpadding="5" style="text-align:center" width="100%"\n'
-- 分类添加
head = head .. '! width="20%" style="position:-webkit-sticky;position:sticky;top:0px;" |曲名 \n'
local category = mw.html.create()
head = head .. '! width="20%" style="position:-webkit-sticky;position:sticky;top:0px;" |所属曲包 \n'
head = head .. '! colspan="2" width="40%" style="position:-webkit-sticky;position:sticky;top:0px;" |谱师名义 \n'
head = head .. '! width="20%" style="position:-webkit-sticky;position:sticky;top:0px;" |备注 \n'


local ratingSortMemory ={}
--平台
local function ratingSort(rating)
local plat
local findInMemory = ratingSortMemory[rating]
if args['更新时间NS'] then
if findInMemory then return findInMemory end
if args['更新时间'] then
local num
plat = ' 双平台'
if string.find(rating, '+') then
else
num = tonumber(string.match(rating,'%d+'))*2 +1
plat = 'NS版'
end
else
else
num = tonumber(rating)*2
plat = '移动版'
end
end
ratingSortMemory[rating] = num
category:wikitext('[[分类:', plat, '搭档]]')
return num
 
end
--觉醒
category:wikitext('[[分类:', awaken and '有' or '没有', '觉醒形态的', '搭档]]')


--类型
local type = args['类型'] or '平衡型'
local typeSet = {['支援型'] = true, ['平衡型'] = true, ['挑战型'] = true,}
category:wikitext('[[分类:', typeSet[type] and type or '特殊类型', '搭档]]')
-- ???/创世型; ???/探索者; ???


function p.main(frame)
--种类
local cMap = {[' 限时'] = ' 限时活动', [' 特殊'] = ' 获取方式特殊的', [' 专辑'] = 'Arcaea原声专辑特典',}
local parentArgs = frame:getParent().args
for c in mw.text.gsplit(args['种类'], '/', true) do
local Args = frame.args
if c ~= ' 原创' then
category:wikitext('[[分类:', cMap[c] or c, ' 搭档]]')
local function getOrder(name)
local orderArg = Args[name]
if orderArg then return mw.text.split(orderArg,'\n') end
end
local function getDescription(title)
return parentArgs[title .. '.description'] and parentArgs[title .. '.description']..'\n' or ''
end
local function getText(dasigner, songid)
local argName = dasigner..'.'..songid .. '.text'
return parentArgs[argName] or '<span title="'.. argName .. '">-</span>'
end
local function color(diff,theText)
theText = theText or (diffNameList[diff] or '?')
return frame:expandTemplate{ title = "color", args = {diff, theText} }
end
local append = Args['appendList']
local appendList = {}
if append then
local list = mw.text.split(append,'\n')
for _,id in pairs(list) do
appendList[id] = {}
local designerList = {}
for i=0,4 do
local diffDesigner = Args[id .. '.'.. i ..'.designer']
if diffDesigner then
table.insert(designerList,{ratingClass = i, chartDesigner = diffDesigner})
-- chartDesigner ratingClass
end
end
-- appendList[id].pack = Args[id .. '.pack']
appendList[id] = designerList
end
end
end
end
local pickList = readList(appendList)
local singleList = genList(pickList)


local function songUnit(songid,text)
--版本
if not songDiffDesigner[songid] then return '' end
if args[' 更新时间'] then
   local data = songDiffDesigner[songid]
category:wikitext('[[ 分类:', lang:ucfirst(version(args[' 更新时间'])), ' 添加的', ' 搭档]]')
   local name =  songTitle(songid) or Args[songid .. '.title'] or '???'
end
   local nameBYD = {songTitle(songid,true)}
if awaken then
   local hasBydAppend = bydAppendInfo[songid] and songTitle(bydAppendInfo[songid].id)
category:wikitext('[[ 分类:', lang:ucfirst(version(args[' 觉醒更新时间'] or args[' 更新时间'])), ' 添加觉醒形态的', ' 搭档]]')
   table.insert(nameBYD, hasBydAppend)
   local pack = songPack(songid) or Args[songid .. '.pack'] or '/'
   if data[1][3] and data[1][3]==#data then
   local allDifficultiesText= '全难度'
   local style = '|style="height: 35px"'
if hasBydAppend then
return '|-\n'.. style ..'|[['..name..']]\n|rowspan=3|'..pack..'\n|rowspan=3|'..allDifficultiesText..'\n|rowspan=3|'..data[1][2]..'\n|rowspan=3|'..text..'\n|-\n|[['..nameBYD[1]..']]\n|-\n|[['..songTitle(bydAppendInfo[songid].id)..']]\n|-\n'
else
   return '|-\n'.. style ..'|[['..name..']]||'..pack..'||'..allDifficultiesText..'||'..data[1][2]..'\n|'..text..'\n|-\n'
end
   end
   local row = #data
   local wikiText = ''
   local rowspanSong = nameBYD and ('|rowspan='.. row-#nameBYD ..'|') or ('|rowspan='.. #data ..'|')
   local rowspan ='|rowspan='.. row ..'|'
   wikiText = wikiText .. '|-\n'..rowspanSong ..'[['..name..']]'..'\n'
   wikiText = wikiText .. rowspan ..pack ..'\n'
   local style='|style="height: 15px" width="10%"'
   for num, i in ipairs(data) do
   wikiText = wikiText ..style
   local diffFormat = '| '..(i[1] and color(i[1]) or '')
   local designerFormat = i[3] and '||rowspan='.. i[3] ..'|' ..i[2] or (i[2] and '||'..i[2] or '')
   if nameBYD[1] and i[1] == 'BYD' then
wikiText = wikiText ..'|'..'[['..(nameBYD[1] or '')..']]'..'\n'
wikiText = wikiText .. diffFormat ..designerFormat..'\n'
   wikiText = wikiText .. (num == 1 and rowspan .. (text or '')..'\n' or '')
   wikiText = wikiText ..'\n|-\n'
if hasBydAppend then
wikiText = wikiText .. '|' ..'[['..songTitle(bydAppendInfo[songid].id)..']]'..'\n'
wikiText = wikiText .. diffFormat ..designerFormat..'\n'
   wikiText = wikiText .. (num == 1 and rowspan .. (text or '')..'\n' or '')
wikiText = wikiText .. '\n|-\n'
return wikiText
end
else
   wikiText = wikiText .. diffFormat ..designerFormat..'\n'
   wikiText = wikiText .. (num == 1 and rowspan .. (text or '')..'\n' or '')
   wikiText = wikiText ..'\n|-\n'
   end
   end
   return wikiText
end
end
if args[' 更新时间NS'] then
local function cateText(cate, titelStr, formatJa)
category:wikitext('[[ 分类:', 'NS ', lang:ucfirst(version(args[' 更新时间NS'])), ' 添加的', '搭档]]')
local theText = ''
local sectionCode = {unknown = 100, free = 1, archive = 2, mainstory = 3, sidestory = 4, collab = 5, single = 6}
function sort_fun(a, b)
a, b = a.sort, b.sort
for i = 1, 3 do
local d = a[i] - b[i]
if d ~= 0 then return d < 0 end
end
return a[4]<b[4]
end
local function getSongSort(songs)
local songSort = {}
for songid, diff in pairs(songs) do
local packItem = mad.packQueryWrap(queryMO(songid, 'set'), 'mobile')
local sortLevel = ratingSort(queryMO(songid, 'ftrRating') or 0)
table.insert(songSort, {
id=songid,
sort={
sectionCode[packItem['section']]
packItem['numero'] or Args[songid..'.sortNum'] or 0
sortLevel,
songid
}})
end
table.sort(songSort, sort_fun)
return songSort
end
local function writeText(designer, songs)
local songSort = getSongSort(songs)
local designerTitle = designer
if formatJa and mw.ustring.match(designer,'[ 一-龠ぁ-ゔァ-ヴー々〆〤ヶ]+') then
designerTitle = '<span lang="ja">' .. designer .. '</span>'
end
theText = theText ..titelStr.. designerTitle ..titelStr.."\n"
theText = theText .. getDescription(designer)
theText = theText .. head
for _,data in ipairs(songSort) do
local songid = data.id
local text = getText(designer, songid)
theText = theText .. songUnit(songid,text)
end
theText = theText .. '|}\n'
end
if cate then
for _,designer in ipairs(cate) do
local songs = singleList[designer] or {}
writeText(designer, songs)
singleList[designer]=nil
end
else
for designer,songs in pairs(singleList) do
writeText(designer, songs)
singleList[designer]=nil
end
end
return theText
end
end


local common = getOrder("common")
--手动
local commonText = cateText(common, '==')
if args['nocat'] then category = '' end
local rare = getOrder("rare")
local rareTitle = '非常驻谱师'
local rareSpanid = '\n<span id="已确认的其他谱师名义及相 曲目名单" />'
local rareText = rareSpanid.. '\n=='.. rareTitle .. '==\n' .. getDescription(rareTitle)
rareText = rareText .. cateText(rare, '===')
local uncommonTitle = '未确认谱师'
local uncommonSpanid = '\n<span id="未采用常驻谱师名义的曲目名单及所用名义" />'
local uncommonText = uncommonSpanid..'\n=='.. uncommonTitle .. '==\n' .. getDescription(uncommonTitle)
local headText = cateText(getOrder("uncommon_head"), '===', true)
local endText = cateText(getOrder("uncommon_end"), '===')
uncommonText = uncommonText..headText..cateText(nil, '===')..endText


return commonText..rareText..uncommonText
return tostring(box) .. tostring(category)
-- return tableToString(appendList) ..'\n'..commonText..rareText..uncommonText
end
end


return p
return p

2025年3月11日 (二) 18:47的版本

可在Module:沙盒/在咕咕咕的咕子/Sandbox1/doc创建此模块的帮助文档

local getArgs = require 'Module:Arguments'.getArgs
local lang = mw.getContentLanguage()
local p = {}

function labelText(text)
	return mw.html.create 'span':addClass 'label-text':wikitext(text)
end

function updateReplace(version)
	-- local result = string.gsub(version, 'V(%d+%.%d+)', 'v%1')
	-- local result = string.gsub(version, '(%d+c?)%(', '%1<br>(')
	-- local result = string.gsub(version, '[^]%f[(]', '<br>(')
	local result = string.gsub(version, '(%d+c?)%(', '%1<br>(')
	return result
end

function update(version, device, awakenyes, version2) --更新时间
	local deviceEpitaxy = (device == 'ns') and 'NS版' or '移动版'
	local versionEpitaxy = (awakenyes and version ~= version2 and version2)
		and {'搭档:', updateReplace(version), '<br>觉醒形态:', updateReplace(version2)}
		or {updateReplace(version)}
	local dataBox = mw.html.create 'div':addClass 'date-box'
	dataBox:tag 'div':node(labelText(deviceEpitaxy)):done()
		:tag 'div':wikitext(unpack(versionEpitaxy)):done()
	return dataBox
end

function skill(text, skilldiff, label)
	local result = mw.html.create()
	if skilldiff then result:tag 'div':node(labelText(label)) end
	result:wikitext(text)
	return result
end

function title(...)
	return mw.text.listToText({...}, '<br>', '<br>')
end

function version(time)
	return ({string.find(time, '([vV]%d+%.%d+%.%d+c?)')})[3] or 'unknown'
end

function getImage(normal, awaken, normalJacket, awakenJacket, awakenyes, type)
	local container = mw.html.create 'div':addClass 'container'
	local JacketNormal = normalJacket
	if awaken then
		local JacketAwaken = awakenJacket or normalJacket
		container -- tab
			:tag 'div':addClass 'img-tab':attr('id', 'tab-' .. type)
			:tag 'div':wikitext 'Normal':addClass 'img-tab-part normal active':done()
			:tag 'div':wikitext 'Awaken':addClass 'img-tab-part awaken':done()
		container -- part
			:tag 'div':wikitext('[[文件:', normal, '|300px|none]]'):node(labelText '画师'):wikitext(tostring(JacketNormal)):addClass('active tab-text-' .. type):done()
			:tag 'div':wikitext('[[文件:', awaken, '|300px|none]]'):node(labelText '画师'):wikitext(tostring(JacketAwaken)):addClass('tab-text-' .. type):done()
	else
		container
			:tag 'div':wikitext('[[文件:', normal, '|300px]]'):done()
			:tag 'div':node(labelText '画师'):wikitext(JacketNormal):done()
	end
	return container
end

function p.main(frame)
	local args = getArgs(frame)
	return p._main(args)
end

function p._main(args)
	local awaken   --觉醒判定
	local size     --图片大小
	local belongs  --所属单位
	local skillawaken --觉醒技能
	local skillsec --第二技能
	if args['觉醒形态'] == '有' then awaken = true else awaken = false end
	if awaken and args['技能'] ~= args['觉醒技能'] and args['觉醒技能'] ~= nil then skillawaken = true else skillawaken = false end
	if args['第二技能'] then skillsec = true else skillsec = false end
	if args['所属曲包'] then
		belongs = '所属曲包'
	elseif args['所属单曲'] then
		belongs = '所属单曲'
	else
		belongs = '所属单曲/曲包'
	end
	local imageA = getImage(args['图片'], args['觉醒图片'], args['画师'], args['觉醒画师'], awaken, 'a')
	local imageB = getImage(args['图片'], args['觉醒图片'], args['画师'], args['觉醒画师'], awaken, 'b')
	local infoList = {
		[1] = {title(args['名称'], args['第二名称']), {id = 'title'}},
		[2] = {imageA, {id = 'top-image'}},
		[3] = {imageB, {id = 'right-image'}},
		[4] = {'搭档信息', {class = 'header'}},
		[5] = {'类型', {class = 'label'}},
		[6] = {args['类型'], {class = 'data'}},
		[7] = {belongs, {class = 'label'}},
		[8] = {args[belongs] or '-', {class = 'data'}},
		[9] = {'种类', {class = 'label'}},
		[10] = {args['种类'] or '-', {class = 'data'}},
		[11] = {'觉醒形态', {class = 'label'}},
		[12] = {args['觉醒形态'] or '无', {class = 'data'}},
		[13] = {'搭档数据', {class = 'header', id = 'all-play-header'}},
		[14] = {'搭档数据 (移动版)', {class = 'header', id = 'mobile-play-header'}},
		[15] = {'等级', {class = 'label'}},
		[16] = {'Lv1', {class = 'level-data'}},
		[17] = {'Lv20', {class = 'level-data'}},
		[18] = {'Lv30', {class = 'awaken-data'}},
		[19] = {'Frag', {class = 'label'}},
		[20] = {args['Frag1'], {class = 'level-data'}},
		[21] = {args['Frag20'], {class = 'level-data'}},
		[22] = {args['Frag30'], {class = 'awaken-data'}},
		[23] = {'Step', {class = 'label'}},
		[24] = {args['Step1'], {class = 'level-data'}},
		[25] = {args['Step20'], {class = 'level-data'}},
		[26] = {args['Step30'], {class = 'awaken-data'}},
		[27] = {'Over', {class = 'label over'}},
		[28] = {args['Over1'], {class = 'level-data over'}},
		[29] = {args['Over20'], {class = 'level-data over'}},
		[30] = {args['Over30'], {class = 'awaken-data over'}},
		[31] = {'搭档数据 (Nintendo Switch版)', {class = 'header ns', id = 'ns-play-header'}},
		[32] = {'等级', {class = 'label ns'}},
		[33] = {'Lv1', {class = 'level-data ns'}},
		[34] = {'Lv20', {class = 'level-data ns'}},
		[35] = {'Lv30', {class = 'awaken-data ns'}},
		[36] = {'Frag', {class = 'label ns'}},
		[37] = {args['Frag1NS'], {class = 'level-data ns'}},
		[38] = {args['Frag20NS'], {class = 'level-data ns'}},
		[39] = {args['Frag30NS'], {class = 'awaken-data ns'}},
		[40] = {'Step', {class = 'label ns'}},
		[41] = {args['Step1NS'], {class = 'level-data ns'}},
		[42] = {args['Step20NS'], {class = 'level-data ns'}},
		[43] = {args['Step30NS'], {class = 'awaken-data ns'}},
		[44] = {'技能', {class = 'label', id = 'skill-label'}},
		[45] = {skill(args['技能'] or '-', skillawaken, '普通形态'), {class = 'data', id = 'skill-normal'}},
		[46] = {skill(args['觉醒技能'] or args['技能'], skillawaken, '觉醒形态'), {class = 'data', id = 'skill-awaken'}},
		[47] = {skill(args['技能'], skillsec, args['第一技能说明'] or '第一技能'), {class = 'data', id = 'skill-first'}},
		[48] = {skill(args['第二技能'], skillsec, args['第二技能说明'] or '第二技能'), {class = 'data', id = 'skill-first'}},
		[49] = {'更新时间', {id = 'update-data-label', class = 'label'}},
		[50] = {update(args['更新时间'] or '无', 'mobile', awaken, args['觉醒更新时间'] or args['更新时间']), {id = 'mobile-date-normal', class = 'data'}},
		[51] = {update(args['更新时间NS'] or '无', 'ns', awaken, args['觉醒更新时间NS'] or args['更新时间NS']), {id = 'ns-date-normal', class = 'data'}}
	}

	local box = mw.html.create 'div'

	--样式控制
	box:addClass 'partnerbox arcaeabox'
	if awaken then box:addClass 'awaken' end
	-- if args['名称'] == '' then box:addClass( "ns-only" ) end
	if skillawaken then box:addClass 'skill-awaken' end
	if skillsec then box:addClass 'skill-second' end
	if args['类型'] == '支援型' then
		box:addClass 'support'
	elseif args['类型'] == '挑战型' then
		box:addClass 'challenge'
	else
		box:addClass 'balance'
	end

	if args['更新时间NS'] then
		box:addClass 'ns-box'
	end

	--表格生成
	local mwHtmlMeta = getmetatable(box)
	for _, v in ipairs(infoList) do
		local cell = box:tag 'div':attr(v[2]):cssText(v[3])
		if getmetatable(v[1]) == mwHtmlMeta then cell:node(v[1]) else cell:wikitext(tostring(v[1])) end
	end

	--分类添加
	local category = mw.html.create()

	--平台
	local plat
	if args['更新时间NS'] then
		if args['更新时间'] then
			plat = '双平台'
		else
			plat = 'NS版'
		end
	else
		plat = '移动版'
	end
	category:wikitext('[[分类:', plat, '搭档]]')

	--觉醒
	category:wikitext('[[分类:', awaken and '有' or '没有', '觉醒形态的', '搭档]]')

	--类型
	local type = args['类型'] or '平衡型'
	local typeSet = {['支援型'] = true, ['平衡型'] = true, ['挑战型'] = true,}
	category:wikitext('[[分类:', typeSet[type] and type or '特殊类型', '搭档]]')
	-- ???/创世型; ???/探索者; ???

	--种类
	local cMap = {['限时'] = '限时活动', ['特殊'] = '获取方式特殊的', ['专辑'] = 'Arcaea原声专辑特典',}
	for c in mw.text.gsplit(args['种类'], '/', true) do
		if c ~= '原创' then
			category:wikitext('[[分类:', cMap[c] or c, '搭档]]')
		end
	end

	--版本
	if args['更新时间'] then
		category:wikitext('[[分类:', lang:ucfirst(version(args['更新时间'])), '添加的', '搭档]]')
	end
	if awaken then
		category:wikitext('[[分类:', lang:ucfirst(version(args['觉醒更新时间'] or args['更新时间'])), '添加觉醒形态的', '搭档]]')
	end
	if args['更新时间NS'] then
		category:wikitext('[[分类:', 'NS ', lang:ucfirst(version(args['更新时间NS'])), '添加的', '搭档]]')
	end

	--手动关闭
	if args['nocat'] then category = '' end

	return tostring(box) .. tostring(category)
end

return p