Module:Build bracket/Params/sandbox
Tools
Actions
General
Print/export
In other projects
| This is themodule sandbox page forModule:Build bracket/Params (diff). |
localParams={}-- =========================-- 1) MODULE BINDINGS-- =========================-- Upvalues bound per calllocalstate,config,Helpers,StateChecks-- Stdlib aliaseslocalstr_format=string.formatlocalt_insert=table.insertlocalt_sort=table.sort-- Locals filled on bind (with safe fallbacks)localisempty,notempty,bargs,getPArg,getFArg,toChar,splitlocalfunction_toCharFallback(n)n=tonumber(nor0)or0ifn>=1andn<=26thenreturnstring.char(96+n)-- 'a'..'z'endreturntostring(n)endlocalfunctionbind(_state,_config,_Helpers,_StateChecks)state,config,Helpers,StateChecks=_state,_config,_Helpers,_StateChecksisempty=HelpersandHelpers.isemptyorfunction(v)returnv==nilorv==""endnotempty=HelpersandHelpers.notemptyorfunction(v)returnv~=nilandv~=""endbargs=HelpersandHelpers.bargsgetPArg=HelpersandHelpers.getPArggetFArg=HelpersandHelpers.getFArgtoChar=(HelpersandHelpers.toChar)or_toCharFallbacksplit=HelpersandHelpers.splitend-- Try both RDj[a]-X and RDj[A]-X; falls back to "" if not presentlocalfunctionreadPerHeaderArg(j,k,suffix)localch=toChar(k)-- e.g. 'a' with Helpers.toCharlocalkey1="RD"..j..ch..suffixlocalv=bargs(key1)ifv~=nilandv~=""thenreturnvendlocalkey2="RD"..j..string.upper(ch)..suffixv=bargs(key2)ifv~=nilandv~=""thenreturnvendreturn""end-- =========================-- 2) ARG HELPERS-- =========================-- Trim + split a comma list frame arg (returns {} on blank)localfunctionreadCsvArg(name)localraw=(getFArg(name)or""):gsub("%s+","")returnsplit(raw,{","},true)end-- ========================================-- 3) BUILD SKELETON (formerly getCells)-- ========================================localfunctionbuildSkeleton()localDEFAULT_TPM=2localmaxrow=1localcolentry={}localhasNoHeaders=true-- ensure containersstate.entries=state.entriesor{}state.shift=state.shiftor{}state.teamsPerMatch=state.teamsPerMatchor{}state.maxtpm=state.maxtpmor0localCmin,Cmax=config.minc,config.c-- Phase 1: Determine header presence and teamsPerMatchforj=Cmin,Cmaxdoifnotempty(getFArg("col"..j.."-headers"))thenhasNoHeaders=falseendlocaltpm=tonumber(getFArg("RD"..j.."-teams-per-match"))ortonumber(getFArg("col"..j.."-teams-per-match"))ortonumber(getFArg("teams-per-match"))orDEFAULT_TPMstate.teamsPerMatch[j]=tpmiftpm>state.maxtpmthenstate.maxtpm=tpmendend-- Phase 2: Build colentry for each columnforj=Cmin,Cmaxdostate.entries[j]={}state.shift[j]=tonumber(bargs("RD"..j.."-shift"))ortonumber(bargs("shift"))or0colentry[j]={readCsvArg("col"..j.."-headers"),readCsvArg("col"..j.."-matches"),readCsvArg("col"..j.."-lines"),readCsvArg("col"..j.."-text"),readCsvArg("col"..j.."-groups")-- reserved for user-specified groups}-- inject a default header if none were specified anywhere (unless noheaders=y/yes)localnoheaders=(getFArg("noheaders")or""):lower()ifhasNoHeadersand(noheaders~="y"andnoheaders~="yes")thent_insert(colentry[j][1],1)endend-- Ctype mapping for colentry positionslocalCTYPE_MAP={"header","team","line","text","group"}-- Helpers to populate entries (preserve legacy shapes)localfunctionpopulateTeam(j,rowIndex,n)localTPM=state.teamsPerMatch[j]-- scaffold a text row above when needed (legacy behavior)ifstate.entries[j][rowIndex-1]==nilandstate.entries[j][rowIndex-2]==nilthenstate.entries[j][rowIndex-2]={ctype="text",index=n}state.entries[j][rowIndex-1]={ctype="blank"}end-- first team (top)state.entries[j][rowIndex]={ctype="team",index=TPM*n-(TPM-1),position="top"}state.entries[j][rowIndex+1]={ctype="blank"}-- remaining teams in the match (every 2 rows)form=2,TPMdolocalidx=TPM*n-(TPM-m)localr=rowIndex+2*(m-1)state.entries[j][r]={ctype="team",index=idx}state.entries[j][r+1]={ctype="blank"}endendlocalfunctionpopulateText(j,rowIndex,index)state.entries[j][rowIndex]={ctype="text",index=index}state.entries[j][rowIndex+1]={ctype="blank"}endlocalfunctionpopulateLine(j,rowIndex)-- first segment draws its bottom edgestate.entries[j][rowIndex]={ctype="line",border="bottom"}state.entries[j][rowIndex+1]={ctype="blank"}-- second segment draws its top edgestate.entries[j][rowIndex+2]={ctype="line",border="top"}state.entries[j][rowIndex+3]={ctype="blank"}endlocalfunctionpopulateGroup(j,rowIndex,n)state.entries[j][rowIndex]={ctype="group",index=n}state.entries[j][rowIndex+1]={ctype="blank"}endlocalfunctionpopulateDefault(j,rowIndex,n)state.entries[j][rowIndex]={ctype="header",index=n,position="top"}state.entries[j][rowIndex+1]={ctype="blank"}end-- Phase 3: Populate entries for each columnforj=Cmin,Cmaxdolocaltextindex=0localTPM=state.teamsPerMatch[j]localshiftJ=state.shift[j]fork,positionsinipairs(colentry[j])dot_sort(positions)localctype=CTYPE_MAP[k]forn=1,#positionsdoifshiftJ~=0andpositions[n]>1thenpositions[n]=positions[n]+shiftJendlocalrowIndex=2*positions[n]-1locallastRow=rowIndex+2*TPM-1iflastRow>maxrowthenmaxrow=lastRowendifctype=="team"thenpopulateTeam(j,rowIndex,n)textindex=nelseifctype=="text"thenpopulateText(j,rowIndex,textindex+n)elseifctype=="line"thenpopulateLine(j,rowIndex)elseifctype=="group"thenpopulateGroup(j,rowIndex,n)elsepopulateDefault(j,rowIndex,n)endendendendifisempty(config.r)thenconfig.r=maxrowendend-- ========================================-- 4) NAME RESOLUTION HELPERS-- ========================================localfunctionparamNames(cname,j,i,l)localfunctiongetArg(key)returnbargs(key)or""endlocalfunctiongetP(key)returngetPArg(key)or""endlocale=state.entries[j][i]localRD="RD"..jlocalhidx=e.headerindexlocalhchar=toChar(hidx)localRDh=RD..hcharlocalSYNONYMS={legs={"legs","sets"}}-- Try a list of names against base+index(+suffix); returns first non-emptylocalfunctiontryAny(base,names,idx,suffix)suffix=suffixor""for_,nminipairs(names)dolocala=bargs(base.."-"..nm..idx..suffix)or""ifisempty(a)thena=bargs(base.."-"..nm..string.format("%02d",idx)..suffix)or""endifnotempty(a)thenreturnaendendreturn""endlocalfunctiontryBoth(base,name,idx,suffix)suffix=suffixor""locala=getArg(base.."-"..name..idx..suffix)ifisempty(a)thena=getArg(base.."-"..name..str_format("%02d",idx)..suffix)endreturnaend-- Round names (prefer altname when present)localRDlabel=getArg(RD.."-altname")orRDlocalRDhlabel=getArg(RDh.."-altname")orRDhlocalrname={{RD,RDlabel},{RDh,RDhlabel}}localname={cname,getArg(cname.."-altname")orcname}localnameKeys=SYNONYMS[cname]or{name[1]}localindex={e.index,e.altindex}localresult={}ifcname=="header"thenifhidx==1thenfor_,baseinipairs({rname[1],rname[2]})dofork=2,1,-1doresult[#result+1]=getArg(base[k])endendelsefork=2,1,-1doresult[#result+1]=getArg(rname[2][k])endendelseifcname=="pheader"thenifhidx==1thenfor_,baseinipairs({rname[1],rname[2]})dofork=2,1,-1doresult[#result+1]=getP(base[k])endendelsefork=2,1,-1doresult[#result+1]=getP(rname[2][k])endendelseifcname=="score"thenlocalbases={rname[2][2],rname[2][1],rname[1][2],rname[1][1]}localidxs={index[2],index[2],index[1],index[1]}forn=1,4doifl==1thenresult[#result+1]=tryAny(bases[n],nameKeys,idxs[n])endresult[#result+1]=tryAny(bases[n],nameKeys,idxs[n],"-"..l)endelseifcname=="shade"thenfork=2,1,-1dolocalbase=(hidx==1)andrname[1][k]orrname[2][k]result[#result+1]=getArg(base.."-"..name[1])endresult[#result+1]=getArg("RD-shade")result[#result+1]=(config.COLORSandconfig.COLORS.cell_bg_dark)or"#eaecf0"elseifcname=="text"thenlocalbases={rname[2][2],rname[2][1],rname[1][2],rname[1][1]}localidxs={index[2],index[2],index[1],index[1]}localnames={name[2],name[1]}forni=1,2doforn=1,4doresult[#result+1]=tryBoth(bases[n],names[ni],idxs[n])endendelselocalbases={rname[2][2],rname[2][1],rname[1][2],rname[1][1]}localidxs={index[2],index[2],index[1],index[1]}forn=1,4doresult[#result+1]=tryAny(bases[n],nameKeys,idxs[n])endendfor_,valinipairs(result)doifnotempty(val)thenreturnvalendendreturn""end-- ========================================-- 5) NUMBERED PARAM MODE-- ========================================localmasterindex=1localfunctionnumberedParams(j)localrow=state.entries[j]ifnotrowthenreturnendlocalfunctionnextArg()localv=bargs(tostring(masterindex))or""masterindex=masterindex+1returnvendlocalR=config.rfori=1,Rdolocale=row[i]ifethenlocalct=e.ctypeifct=="team"thenlocallegs=state.rlegs[j]ifconfig.forceseedsthene.seed=nextArg()ende.team=nextArg()e.legs=paramNames("legs",j,i)e.score={weight={}}e.weight="normal"ifnotempty(e.legs)thenlegs=tonumber(e.legs)orlegsendforl=1,legsdoe.score[l]=nextArg()e.score.weight[l]="normal"endifconfig.aggregateandlegs>1thene.score.agg=nextArg()e.score.weight.agg="normal"endelseifct=="header"thene.header=paramNames("header",j,i)e.pheader=paramNames("pheader",j,i)e.shade=paramNames("shade",j,i)elseifct=="text"thene.text=nextArg()elseifct=="group"thene.group=nextArg()elseifct=="line"ande.hastext==truethene.text=nextArg()endendendend-- ========================================-- 6) NAMED MODE ASSIGNERS (per-ctype)-- ========================================localfunctioncellHasMeaningfulContent(e)ifnotethenreturnfalseendife.ctype=="team"thenreturnnotempty(e.team)endife.ctype=="text"thenreturnnotempty(e.text)endife.ctype=="group"thenreturnnotempty(e.group)endife.ctype=="line"ande.hastext==truethenreturnnotempty(e.text)endreturnfalseendlocalfunctionenforceContentUnhide(j)ifnot(state.hideandstate.hide[j])thenreturnendlocalexplicit=(state._hideExplicitandstate._hideExplicit[j])or{}localR=config.r-- If master hid a header, but we later discover content in that header,-- flip it visible unless there was an EXPLICIT per-header hide.fori=1,Rdolocale=state.entries[j][i]ifeande.headerindexthenlocalh=e.headerindexifstate.hide[j][h]andcellHasMeaningfulContent(e)thenstate.hide[j][h]=falseendendendendlocalfunctionassignTeamParams(j,i)locallegs=state.rlegs[j]locale=state.entries[j][i]e.seed=paramNames("seed",j,i)e.team=paramNames("team",j,i)e.legs=paramNames("legs",j,i)e.score={weight={}}e.weight="normal"ifnotempty(e.legs)thenlegs=tonumber(e.legs)orlegsendifconfig.autolegsthenlocall=1repeate.score[l]=paramNames("score",j,i,l)e.score.weight[l]="normal"l=l+1untilisempty(paramNames("score",j,i,l))legs=l-1elseforl=1,legsdoe.score[l]=paramNames("score",j,i,l)e.score.weight[l]="normal"endendifconfig.aggregateandlegs>1thene.score.agg=paramNames("score",j,i,"agg")e.score.weight.agg="normal"endendlocalfunctionassignHeaderParams(j,i)locale=state.entries[j][i]e.header=paramNames("header",j,i)e.pheader=paramNames("pheader",j,i)e.shade=paramNames("shade",j,i)-- Did shade originate from an RD*-shade param?localhchar=toChar(e.headerindex)localrdNames={"RD"..j.."-shade","RD"..j..hchar.."-shade","RD-shade"}e.shade_is_rd=falsefor_,pnameinipairs(rdNames)dolocalv=bargs(pname)ifnotempty(v)ande.shade==vthene.shade_is_rd=truebreakendendendlocalfunctionassignTextParams(j,i)state.entries[j][i].text=paramNames("text",j,i)endlocalfunctionassignGroupParams(j,i)state.entries[j][i].group=paramNames("group",j,i)endlocalfunctionassignLineTextParams(j,i)state.entries[j][i].text=paramNames("text",j,i)end-- ========================================-- 7) TABLE-WIDE ASSIGNMENT PASS-- ========================================localfunctiongetScalarRoundParam(j,bases)-- e.g. {"legs","sets"}-- prefer per-round keys, then globalfor_,baseinipairs(bases)dolocalv=bargs("RD"..j.."-"..base)ifnotempty(v)thenreturnvendendfor_,baseinipairs(bases)dolocalv=bargs(base)ifnotempty(v)thenreturnvendendreturn""endlocalfunctionassignParams()masterindex=1localmaxcol=1localCmin,Cmax,R=config.minc,config.c,config.rforj=Cmin,Cmaxdo-- prepare per-round containersstate.hide[j]=state.hide[j]or{}state.byes[j]=state.byes[j]or{}-- Set legs for this columnlocalvlegs=getScalarRoundParam(j,{"legs","sets"})state.rlegs[j]=tonumber(vlegs)or1ifnotempty(vlegs)thenconfig.autolegs=falseend-- assign paramsifconfig.paramstyle=="numbered"thennumberedParams(j)elselocalcol=state.entries[j]fori=1,Rdolocalcell=col[i]ifcell~=nilthenlocalct=cell.ctypeifct=="team"thenassignTeamParams(j,i)elseifct=="header"thenassignHeaderParams(j,i)elseifct=="text"thenassignTextParams(j,i)elseifct=="group"thenassignGroupParams(j,i)elseifct=="line"andcell.hastext==truethenassignLineTextParams(j,i)endendifconfig.autocolandnotStateChecks.isBlankEntry(j,i)andj>maxcolthenmaxcol=jendendendenforceContentUnhide(j)-- parent header text forces visiblefori=1,Rdolocale=state.entries[j][i]ifeande.ctype=="header"thenlocalhidx=e.headerindexif(Helpers.notemptyandHelpers.notempty(e.pheader))thenstate.hide[j][hidx]=falseendendendendifconfig.autocolthenconfig.c=maxcolendend-- ========================================-- 8) STRUCTURE DISCOVERY (hide/byes/indices)-- ========================================localfunctiongetHide(j)state.hide[j]={}state._hideExplicit=state._hideExplicitor{}state._hideExplicit[j]={}-- master round-level hide flag: RD{j}-hidelocalmasterRaw=bargs("RD"..j.."-hide")or""localmasterOn=(HelpersandHelpers.yesandHelpers.yes(masterRaw))orfalsefork=1,state.headerindex[j]dostate.hide[j][k]=masterOn-- per-header overridelocalrh=readPerHeaderArg(j,k,"-hide")ifrh~=""thenifHelpersandHelpers.yesandHelpers.yes(rh)thenstate.hide[j][k]=truestate._hideExplicit[j][k]=trueelseifHelpersandHelpers.noandHelpers.no(rh)thenstate.hide[j][k]=falsestate._hideExplicit[j][k]=trueendendendendlocalfunctiongetByes(j)state.byes[j]={}fork=1,state.headerindex[j]do-- global byeslocalbyes=(bargs("byes")or""):lower()if(Helpers.yesandHelpers.yes(byes))thenstate.byes[j][k]=trueelseiftonumber(byes)thenstate.byes[j][k]=(j<=tonumber(byes))elsestate.byes[j][k]=falseend-- per-round byeslocalr=(bargs("RD"..j.."-byes")or""):lower()if(Helpers.yesandHelpers.yes(r))thenstate.byes[j][k]=trueelseifr=="no"orr=="n"thenstate.byes[j][k]=falseend-- per-header byeslocalrh=(readPerHeaderArg(j,k,"-byes")or""):lower()if(Helpers.yesandHelpers.yes(rh))thenstate.byes[j][k]=trueelseifrh=="no"orrh=="n"thenstate.byes[j][k]=falseendendendlocalfunctiongetAltIndices()localCmin,Cmax,R=config.minc,config.c,config.rforj=Cmin,Cmaxdostate.headerindex[j]=0-- per-round counterslocalteamindex,textindex,groupindex=1,1,1localrow=state.entries[j]-- if the very first cell is nil, bump headerindex once (legacy quirk)ifrowandrow[1]==nilthenstate.headerindex[j]=state.headerindex[j]+1end-- walk rows in the roundfori=1,Rdolocale=rowandrow[i]ornilifethenlocalct=e.ctypeifct=="header"thene.altindex=state.headerindex[j]teamindex,textindex=1,1state.headerindex[j]=state.headerindex[j]+1elseifct=="team"thene.altindex=teamindexteamindex=teamindex+1elseifct=="text"or(ct=="line"ande.hastext==true)thene.altindex=textindextextindex=textindex+1elseifct=="group"thene.altindex=groupindexgroupindex=groupindex+1ende.headerindex=state.headerindex[j]endendgetByes(j)getHide(j)endend-- ========================================-- 9) PUBLIC API-- ========================================functionParams.buildSkeleton(_state,_config,_Helpers,_StateChecks)bind(_state,_config,_Helpers,_StateChecks)buildSkeleton()endfunctionParams.scanStructure(_state,_config,_Helpers,_StateChecks)bind(_state,_config,_Helpers,_StateChecks)getAltIndices()endfunctionParams.assign(_state,_config,_Helpers,_StateChecks)bind(_state,_config,_Helpers,_StateChecks)assignParams()end-- ========================================-- 10) SLICING FOR MIN ROUND (base offset)-- ========================================localfunctionshiftCols(tbl,base,c)ifnottblthenreturn{}endlocalout={}forj=base+1,cdoout[j-base]=tbl[j]endreturnoutendfunctionParams.sliceForMinround(_state,_config)localbase=_config.baseor0ifbase<=0thenreturnendlocaloldC=_config.clocalnewC=oldC-baseifnewC<1thennewC=1end-- Shift all column-indexed tables_state.entries=shiftCols(_state.entries,base,oldC)_state.headerindex=shiftCols(_state.headerindex,base,oldC)_state.rlegs=shiftCols(_state.rlegs,base,oldC)_state.maxlegs={}-- recompute later_state.hascross={}-- rebuild later_state.crossCell={}-- rebuild later_state.pathCell={}-- rebuild later_state.skipPath={}-- rebuild later_state.hide=shiftCols(_state.hide,base,oldC)_state.byes=shiftCols(_state.byes,base,oldC)_state.teamsPerMatch=shiftCols(_state.teamsPerMatch,base,oldC)_state.matchgroup={}-- recompute-- Update view range: now we render 1..newC_config.c=newC_config.minc=1endreturnParams