-- This module is a replacement for the RfX report bot.  local convert = require('মডিউল:সংখ্যা রূপান্তরকারী').convert  local rfx = require( 'Module:Rfx' ) local colours = mw.loadData( 'Module:RFX report/colour' )  local p = {}  local function getTableLength(tbl) 	local length = 0 	for _ in pairs(tbl) do 		length = length + 1 	end 	return length end  local function getRfxes()     -- Get the title object for Wikipedia:Requests for adminship.     local noError, rfa = pcall( mw.title.new, 'উইকিপিডিয়া:প্রশাসক হওয়ার আবেদন' )     if not noError or ( noError and not rfa ) then         return nil     end     local rfaText = rfa:getContent()     if not rfaText then         return nil     end          -- Return a table with a list of pages transcluded from     -- Wikipedia:Requests for adminship, minus the exceptions     -- which are always transcluded there.     local t = {}     local exceptions = { 'শীর্ষ', 'বার্তা' }     for rfxPage, rfxSubpage in mw.ustring.gmatch( rfaText, '{{[ _]*(উইকিপিডিয়া:প্রশাসক হওয়ার আবেদন/([^{}]-))[ _]*}}' ) do         local isException = false         for _, v in ipairs( exceptions ) do             if rfxSubpage == v then                 isException = true             end         end         if not isException then             table.insert( t, rfxPage )         end     end     return t end  local function makeRow( rfxObject )     if not ( type( rfxObject ) == 'table' and rfxObject.getTitleObject and rfxObject.getSupportUsers ) then         return nil     end     local status = rfxObject:getStatus()     local page = rfxObject:getTitleObject().prefixedText     local user = rfxObject.user or rfxObject:getTitleObject().subpageText     local supports = convert('bn', tostring(rfxObject.supports))     local opposes = convert('bn', tostring(rfxObject.opposes))     local neutrals = convert('bn', tostring(rfxObject.neutrals))     local percent = convert('bn', tostring(rfxObject.percent))     local colour     if percent then         colour = colours[ rfxObject.type ][ percent ]     end     colour = colour or     local percentStr = mw.ustring.format( '%s', percent or 0 )     if percent == '০' and supports == '০' and opposes == '০' and neutrals == '০' then         percentStr = 'N/A'     elseif percent == 100 and opposes ~= '০'   then     	percentStr = '>99'     end     local votes     if supports and opposes and neutrals and percent then         votes = mw.ustring.format( [==[          | class="rfx-report-number" | %s  | class="rfx-report-number" | %s  | class="rfx-report-number" | %s | class="rfx-report-number rfx-report-percent" style="background: #%s;" | %s%%]==],             page, supports,             page, opposes,             page, neutrals,             colour, percentStr         )     else         votes = '\n| colspan="4" class="rfx-report-error" | ভোট পার্সিংয়ে ত্রুটি'     end     if status then         status = mw.language.getContentLanguage():ucfirst( status )         if status == 'Pending closure' then             status = 'Pending closure...'         end         status = '\n|' .. status     else         status = '\n| class="rfx-report-error" | স্থিতি বেরকরণ ত্রুটি'     end      local endTime = mw.getContentLanguage():formatDate('d M Y, h:m', rfxObject.endTime, true)     local secondsLeft = rfxObject:getSecondsLeft()     local timeLeft = rfxObject:getTimeLeft()     if timeLeft == "০ ঘণ্টা" then      	timeLeft = "সমাপ্ত" else      		timeLeft = timeLeft     		end     local time     if endTime and timeLeft then         time = mw.ustring.format( '\n| %s\n| %s', endTime, timeLeft )     else         time = '\n| colspan="2" class="rfx-report-error" | শেষের সময় পার্সিংয়ে ত্রুটি'     end     local dupes = rfxObject:dupesExist()     if dupes then         dupes = 'হ্যাঁ'     elseif dupes == false then         dupes = 'না'     else         dupes = '--'     end          local pending_class =      if status == 'pending closure' then         pending_class = 'class="rfx-report-pending"'     end     return mw.ustring.format(         '\n|-%s\n| %s%s%s%s \n| class="rfx-report-dupes" | %s',         pending_class, page, user, votes, status, time, dupes     ) end  local function makeHeading( rfxType ) 	local frame = mw.getCurrentFrame()     local rfxCaps     if rfxType == 'rfa' then         rfxCaps = 'RfA'     else         return nil     end     return mw.ustring.format(         '\n|-\n! scope="col" |  প্রার্থী !! scope="col" | স !! scope="col" | বি !! scope="col" | নি !! scope="col" | স %% !! scope="col" | স্থিতি!! scope="col" | শেষ হবে (ইউটিসি) !! scope="col" | সময় বাকি!! scope="col" | সদৃশ? ',         rfxCaps     ) end  local function getRfs() 	local rfxes = getRfxes()     if not rfxes then         return nil     end     -- Get RfX objects and separate RfAs and RfBs.     local rfas = {}     for i, rfxPage in ipairs( rfxes ) do         local rfxObject = rfx.new( rfxPage )         if rfxObject then             if rfxObject.type == 'rfa' then                 table.insert( rfas, rfxObject )             end         end     end               return rfas end  local function makeReportRows() 	local rfas= getRfs()      local ret = {}     if #rfas > 0 then         table.insert( ret, makeHeading( 'rfa' ) )         for i, rfaObject in ipairs( rfas ) do             table.insert( ret, makeRow( rfaObject ) )         end     end     return table.concat( ret ) end  local function makeReport( args )     local purgeLink = mw.title.getCurrentTitle():fullUrl( 'action=purge' )     local header = mw.ustring.format(         '\n|+প্রশাসক হওয়ার আবেদন [%s হালনাগাদ]',         purgeLink     )     local rows = makeReportRows() or     if rows ==  then         rows = '\n|-\n| colspan="10" | বর্তমানে কোনো আবেদন নেই। সাম্প্রতিক প্রশাসক হওয়ার আবেদন'     end          local float = args.float or args.align     if not float or mw.text.trim(float) ==  then     	float = nil     end     local clear = args.clear     if not clear or mw.text.trim(clear) ==  then     	clear = nil     end          local style =     if float or clear then     	style = string.format(     		'style="%s%s"',     		clear and ('clear: ' .. clear .. ';') or ,     		float and ('float: ' .. float .. ';') or ''     	)     end      return mw.getCurrentFrame():extensionTag{ 		name = 'templatestyles', args = { src = 'Module:RFX report/styles.css' } 	} .. mw.ustring.format(     	'\n{| class="wikitable rfx-report" %s%s%s\n|-\n|}',     	style,     	header,     	rows     ) end  function p.countRfas() 	local rfas = getRfs() 	return getTableLength(rfas) end  function p.main( frame )     -- Process the arguments.     local args     if frame == mw.getCurrentFrame() then         args = frame:getParent().args         for k, v in pairs( frame.args ) do             args = frame.args             break         end     else         args = frame     end         return makeReport( args ) end  return p