十二生肖本领强是什么生肖| 小便憋不住尿裤子是什么情况| aqi是什么意思| 什么的玉米| ct检查是什么意思| 12月10号是什么星座| 1月2日是什么星座| 煮中药用什么锅| 雄起是什么意思| 离心是什么意思| 眼角下面长斑是什么原因引起的| 什么是葡萄糖| 属狗什么命| 清真不吃什么肉| 形态是什么意思| 四点半是什么时辰| 南字五行属什么| 致意是什么意思| 25羟维生素d测定是什么| 其实不然是什么意思| 离心是什么意思| 为什么脚底板发黄| 什么病不能吃芒果| 兽中之王是什么动物| 四维彩超什么时候做| 小孩口腔溃疡是什么原因| 嘎哈是什么意思| 岔气吃什么药| 淤青用什么药| 软开是什么| 刺身是什么| 神经外科主要看什么病| 梦见蛇追我是什么预兆| 物理压榨油是什么意思| 为什么发烧会觉得冷| 舌头有裂纹是什么原因| 二甲双胍什么时候吃| 长痘不能吃什么| cross是什么牌子| 什么饮料好喝| 血府逐瘀丸治什么病| 手癣用什么药膏效果好| 什么是gmp| 孕早期吃什么有利于胎心胎芽发育| 孕妇前三个月吃什么对胎儿好| 什么是心脏病| 子宫内膜薄是什么原因造成的| 子宫附件包括什么| 肺气泡吃什么药| mbi是什么意思| 喝雄黄酒是什么节日| 第一次查怀孕挂什么科| 小厮是什么意思| 什么因什么果| 锑对人体有什么危害| 吃什么提神醒脑抗疲劳| 脚底板发红是什么原因| 小满是什么季节| 晚上口渴是什么原因引起的| 延时吃什么药| 萧敬腾为什么叫雨神| 食管憩室是什么病| 内蒙古简称什么| 化妆水是什么| 阑尾炎手术后可以吃什么水果| 活菩萨是什么意思| 吃红薯有什么好处和坏处| 6541是什么药| 英红九号红茶什么档次| 骨质疏松吃什么药| modern是什么牌子| 月经快来了有什么征兆| 唐氏综合征是什么原因造成的| 境字五行属什么| 地中海贫血是什么病| tba是什么意思| 凝胶是什么东西| 四个月念什么| 心跳的快是什么原因| 什么叫飘窗| 卫生巾有什么用| 更年期挂什么科| 明星每天都吃什么| 白细胞一个加号什么意思| 什么的母鸡| 梦见恐龙是什么预兆| 胸为什么会下垂| 燃脂是什么意思| 炭疽病用什么农药最好| 变白吃什么| 什么叫脘腹胀痛| 念珠菌性阴道炎用什么药| 易栓症是什么病| 全身无力是什么原因| 二氧化碳低是什么原因| 男生喜欢女生有什么表现| 618是什么| 口犬读什么| 乳酸杆菌阳性什么意思| 小猫什么时候打疫苗| 脾湿热吃什么中成药| 04年属什么| 丑时五行属什么| 情感什么意思| 来月经吃什么排得最干净| 高铁特等座有什么待遇| 国家电网需要什么专业| 但爱鲈鱼美的但是什么意思| 什么叫血沉| 输卵管堵塞有什么症状| 什么的花瓣| 弯弯是什么意思| 阴道炎用什么药好| 悠悠岁月什么意思| 来大姨妈量少是什么原因| 同工同酬是什么意思| 孕妇牙痛有什么办法| 梦到狐狸是什么意思| 夏天吃什么菜| 前世是什么意思| 梦见洗车是什么意思| 细软是什么意思| 肠道长息肉是什么原因造成的| 赵云的坐骑是什么马| 梦见苍蝇很多是什么意思| 吃什么养肝护肝| 什么是碧玺| 绮字五行属什么| 受凉肚子疼吃什么药| 郁闷是什么意思| advil是什么药| 什么是贸易顺差| 眼底筛查是检查什么| 恐龙是什么时代| 空调制冷效果差是什么原因| 老生常谈是什么意思| 91年的属什么生肖| 高碱性食物都有什么| 松花粉对肝有什么好处| 楚怀王和芈月什么关系| 营养不良会导致身体出现什么症状| o血型的人有什么特点| 免疫力是什么| 车工是做什么的| 女生适合什么工作| 专升本有什么专业| 道德绑架是什么意思| amo是什么意思| 1943年属什么生肖| 体温偏低是什么原因| 今天什么生肖最旺| 10月10日是什么星座| 巨蟹座喜欢什么星座| 屁股生疮是什么原因| 开封有什么好玩的地方| 金玉满堂是什么菜| 肉刺用什么药膏能治好| 杀马特是什么| 棒打鸳鸯什么意思| 药店为什么不让卖高锰酸钾| 师范类是什么意思| 胎儿为什么会喜欢臀位| 华是什么意思| rock是什么意思| 魏丑夫和芈月什么关系| 爱马仕是什么| 梦见下雪是什么意思| 全身骨头疼是什么原因| 白带变绿用什么药| 我能做什么| 为什么一同房就出血| 胆固醇高不可以吃什么| 阴囊潮湿是什么原因| soie是什么面料| 昱念什么| 皮肤过敏用什么药最好| 电解液是什么| 过奖了是什么意思| 月经量突然减少是什么原因| 菠萝与凤梨有什么区别| 滴虫性阴炎有什么症状表现| 嗓子发炎是什么原因引起的| 血虚肝旺有什么症状有哪些| 58岁属什么生肖| 下巴长闭口是什么原因| 梦见自己假牙掉了是什么意思| 内分泌失调是什么原因引起的| 聚字五行属什么| 孩子不长个子是什么原因| 低分化腺癌是什么意思| 无咎是什么意思| 势利是什么意思| 心病有什么症状| 梦见自己儿子死了是什么意思| 梅菜在北方叫什么菜| 生理期为什么会肚子疼| 防冻液红色和绿色有什么区别| 祖马龙是什么档次| 脸上长红色的痘痘是什么原因| 吃什么可以流产| 多囊吃什么药| 黄疸高是什么原因引起的| 褶皱是什么意思| 水怡是什么| 打乒乓球有什么好处| 老年人便秘吃什么好| 什么属相不能养龙鱼| 葫芦是什么意思| 梦见生了个儿子是什么意思| girls是什么意思| 哺乳期可以喝什么饮料| 五谷丰登是什么生肖| 退烧药吃多了有什么副作用| 肺阴虚吃什么药| 游离前列腺特异性抗原是什么意思| 晕车的人是什么体质| 核桃壳有什么用| 妊娠期是指什么时候| 打狂犬疫苗后注意什么| 人丁兴旺是什么意思| 河汉是什么意思| 有什么好听的歌曲| 辅酶q10什么价格| 白羊座男和什么星座最配| 嬴政和芈月是什么关系| 三七花泡水喝有什么功效| 耳鸣用什么药| 小猫的尾巴有什么用处| 盥洗是什么意思| 母乳是什么颜色| 手气是什么原因引起的| 坐支是什么意思| 什么龙什么虎| 凉皮是用什么做的| 制片人是什么意思| 什么是阴虚什么是阳虚| 为什么叫拉丁美洲| 神经炎用什么药| 晕3d是什么原因| 物色是什么意思| 沄字五行属什么| 五步蛇为什么叫五步蛇| 阑尾炎挂什么科室| 吃什么下奶快| qs排名是什么意思| 头孢吃多了有什么副作用| 尿酸高是什么造成的| 什么叫轻食| 乳腺炎吃什么消炎药| 签注是什么| 为什么会高反| ups是什么快递| 心肌炎是什么病严重吗| 眼干是什么原因| 黄铜刮痧板有什么好处| cea是什么检查项目| 消肿吃什么食物好| 当医生学什么专业| 牡丹鹦鹉吃什么| 狐臭手术挂什么科室| 一什么凤冠| 基诺浦鞋属于什么档次| 一什么树林| 老人头发由白变黑是什么原因| 百度Jump to content

沧州破获一起聚众扰乱社会秩序案件

Permanently protected module
From Wikipedia, the free encyclopedia

-- This module implements {{pp-meta}} and its daughter templates such as
-- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}.

-- Initialise necessary modules.
require('strict')
local makeFileLink = require('Module:File link')._main
local effectiveProtectionLevel = require('Module:Effective protection level')._main
local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main
local yesno = require('Module:Yesno')

-- Lazily initialise modules and objects we don't always need.
local getArgs, makeMessageBox, lang

-- Set constants.
local CONFIG_MODULE = 'Module:Protection banner/config'

--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------

local function makeCategoryLink(cat, sort)
	if cat then
		return string.format(
			'[[%s:%s|%s]]',
			mw.site.namespaces[14].name,
			cat,
			sort
		)
	end
end

-- Validation function for the expiry and the protection date
local function validateDate(dateString, dateType)
	if not lang then
		lang = mw.language.getContentLanguage()
	end
	local success, result = pcall(lang.formatDate, lang, 'U', dateString)
	if success then
		result = tonumber(result)
		if result then
			return result
		end
	end
	error(string.format(
		'invalid %s: %s',
		dateType,
		tostring(dateString)
	), 4)
end

local function makeFullUrl(page, query, display)
	return string.format(
		'[%s %s]',
		tostring(mw.uri.fullUrl(page, query)),
		display
	)
end

-- Given a directed graph formatted as node -> table of direct successors,
-- get a table of all nodes reachable from a given node (though always
-- including the given node).
local function getReachableNodes(graph, start)
	local toWalk, retval = {[start] = true}, {}
	while true do
		-- Can't use pairs() since we're adding and removing things as we're iterating
		local k = next(toWalk) -- This always gets the "first" key
		if k == nil then
			return retval
		end
		toWalk[k] = nil
		retval[k] = true
		for _,v in ipairs(graph[k]) do
			if not retval[v] then
				toWalk[v] = true
			end
		end
	end
end

--------------------------------------------------------------------------------
-- Protection class
--------------------------------------------------------------------------------

local Protection = {}
Protection.__index = Protection

Protection.supportedActions = {
	edit = true,
	move = true,
	autoreview = true,
	upload = true
}

Protection.bannerConfigFields = {
	'text',
	'explanation',
	'tooltip',
	'alt',
	'link',
	'image'
}

function Protection.new(args, cfg, title)
	local obj = {}
	obj._cfg = cfg
	obj.title = title or mw.title.getCurrentTitle()

	-- Set action
	if not args.action then
		obj.action = 'edit'
	elseif Protection.supportedActions[args.action] then
		obj.action = args.action
	else
		error(string.format(
			'invalid action: %s',
			tostring(args.action)
		), 3)
	end

	-- Set level
	obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title)
	if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then
		-- Users need to be autoconfirmed to move pages anyway, so treat
		-- semi-move-protected pages as unprotected.
		obj.level = '*'
	end

	-- Set expiry
	local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title)
	if effectiveExpiry == 'infinity' then
		obj.expiry = 'indef'
	elseif effectiveExpiry ~= 'unknown' then
		obj.expiry = validateDate(effectiveExpiry, 'expiry date')
	end

	-- Set reason
	if args[1] then
		obj.reason = mw.ustring.lower(args[1])
		if obj.reason:find('|') then
			error('reasons cannot contain the pipe character ("|")', 3)
		end
	end

	-- Set protection date
	if args.date then
		obj.protectionDate = validateDate(args.date, 'protection date')
	end
	
	-- Set banner config
	do
		obj.bannerConfig = {}
		local configTables = {}
		if cfg.banners[obj.action] then
			configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason]
		end
		if cfg.defaultBanners[obj.action] then
			configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level]
			configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default
		end
		configTables[#configTables + 1] = cfg.masterBanner
		for i, field in ipairs(Protection.bannerConfigFields) do
			for j, t in ipairs(configTables) do
				if t[field] then
					obj.bannerConfig[field] = t[field]
					break
				end
			end
		end
	end
	return setmetatable(obj, Protection)
end

function Protection:isUserScript()
	-- Whether the page is a user JavaScript or CSS page.
	local title = self.title
	return title.namespace == 2 and (
		title.contentModel == 'javascript' or title.contentModel == 'css'
	)
end

function Protection:isProtected()
	return self.level ~= '*'
end

function Protection:shouldShowLock()
	-- Whether we should output a banner/padlock
	return self:isProtected() and not self:isUserScript()
end

-- Whether this page needs a protection category.
Protection.shouldHaveProtectionCategory = Protection.shouldShowLock

function Protection:isTemporary()
	return type(self.expiry) == 'number'
end

function Protection:makeProtectionCategory()
	if not self:shouldHaveProtectionCategory() then
		return ''
	end

	local cfg = self._cfg
	local title = self.title
	
	-- Get the expiry key fragment.
	local expiryFragment
	if self.expiry == 'indef' then
		expiryFragment = self.expiry
	elseif type(self.expiry) == 'number' then
		expiryFragment = 'temp'
	end

	-- Get the namespace key fragment.
	local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace]
	if not namespaceFragment and title.namespace % 2 == 1 then
			namespaceFragment = 'talk'
	end

	-- Define the order that key fragments are tested in. This is done with an
	-- array of tables containing the value to be tested, along with its
	-- position in the cfg.protectionCategories table.
	local order = {
		{val = expiryFragment,    keypos = 1},
		{val = namespaceFragment, keypos = 2},
		{val = self.reason,       keypos = 3},
		{val = self.level,        keypos = 4},
		{val = self.action,       keypos = 5}
	}

	--[[
	-- The old protection templates used an ad-hoc protection category system,
	-- with some templates prioritising namespaces in their categories, and
	-- others prioritising the protection reason. To emulate this in this module
	-- we use the config table cfg.reasonsWithNamespacePriority to set the
	-- reasons for which namespaces have priority over protection reason.
	-- If we are dealing with one of those reasons, move the namespace table to
	-- the end of the order table, i.e. give it highest priority. If not, the
	-- reason should have highest priority, so move that to the end of the table
	-- instead.
	--]]
	table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3))
 
	--[[
	-- Define the attempt order. Inactive subtables (subtables with nil "value"
	-- fields) are moved to the end, where they will later be given the key
	-- "all". This is to cut down on the number of table lookups in
	-- cfg.protectionCategories, which grows exponentially with the number of
	-- non-nil keys. We keep track of the number of active subtables with the
	-- noActive parameter.
	--]]
	local noActive, attemptOrder
	do
		local active, inactive = {}, {}
		for i, t in ipairs(order) do
			if t.val then
				active[#active + 1] = t
			else
				inactive[#inactive + 1] = t
			end
		end
		noActive = #active
		attemptOrder = active
		for i, t in ipairs(inactive) do
			attemptOrder[#attemptOrder + 1] = t
		end
	end
 
	--[[
	-- Check increasingly generic key combinations until we find a match. If a
	-- specific category exists for the combination of key fragments we are
	-- given, that match will be found first. If not, we keep trying different
	-- key fragment combinations until we match using the key
	-- "all-all-all-all-all".
	--
	-- To generate the keys, we index the key subtables using a binary matrix
	-- with indexes i and j. j is only calculated up to the number of active
	-- subtables. For example, if there were three active subtables, the matrix
	-- would look like this, with 0 corresponding to the key fragment "all", and
	-- 1 corresponding to other key fragments.
	-- 
	--   j 1  2  3
	-- i  
	-- 1   1  1  1
	-- 2   0  1  1
	-- 3   1  0  1
	-- 4   0  0  1
	-- 5   1  1  0
	-- 6   0  1  0
	-- 7   1  0  0
	-- 8   0  0  0
	-- 
	-- Values of j higher than the number of active subtables are set
	-- to the string "all".
	--
	-- A key for cfg.protectionCategories is constructed for each value of i.
	-- The position of the value in the key is determined by the keypos field in
	-- each subtable.
	--]]
	local cats = cfg.protectionCategories
	for i = 1, 2^noActive do
		local key = {}
		for j, t in ipairs(attemptOrder) do
			if j > noActive then
				key[t.keypos] = 'all'
			else
				local quotient = i / 2 ^ (j - 1)
				quotient = math.ceil(quotient)
				if quotient % 2 == 1 then
					key[t.keypos] = t.val
				else
					key[t.keypos] = 'all'
				end
			end
		end
		key = table.concat(key, '|')
		local attempt = cats[key]
		if attempt then
			return makeCategoryLink(attempt, title.text)
		end
	end
	return ''
end

function Protection:isIncorrect()
	local expiry = self.expiry
	return not self:shouldHaveProtectionCategory()
		or type(expiry) == 'number' and expiry < os.time()
end

function Protection:isTemplateProtectedNonTemplate()
	local action, namespace = self.action, self.title.namespace
	return self.level == 'templateeditor'
		and (
			(action ~= 'edit' and action ~= 'move')
			or (namespace ~= 10 and namespace ~= 828)
		)
end

function Protection:makeCategoryLinks()
	local msg = self._cfg.msg
	local ret = {self:makeProtectionCategory()}
	if self:isIncorrect() then
		ret[#ret + 1] = makeCategoryLink(
			msg['tracking-category-incorrect'],
			self.title.text
		)
	end
	if self:isTemplateProtectedNonTemplate() then
		ret[#ret + 1] = makeCategoryLink(
			msg['tracking-category-template'],
			self.title.text
		)
	end
	return table.concat(ret)
end

--------------------------------------------------------------------------------
-- Blurb class
--------------------------------------------------------------------------------

local Blurb = {}
Blurb.__index = Blurb

Blurb.bannerTextFields = {
	text = true,
	explanation = true,
	tooltip = true,
	alt = true,
	link = true
}

function Blurb.new(protectionObj, args, cfg)
	return setmetatable({
		_cfg = cfg,
		_protectionObj = protectionObj,
		_args = args
	}, Blurb)
end

-- Private methods --

function Blurb:_formatDate(num)
	-- Formats a Unix timestamp into dd Month, YYYY format.
	lang = lang or mw.language.getContentLanguage()
	local success, date = pcall(
		lang.formatDate,
		lang,
		self._cfg.msg['expiry-date-format'] or 'j F Y',
		'@' .. tostring(num)
	)
	if success then
		return date
	end
end

function Blurb:_getExpandedMessage(msgKey)
	return self:_substituteParameters(self._cfg.msg[msgKey])
end

function Blurb:_substituteParameters(msg)
	if not self._params then
		local parameterFuncs = {}

		parameterFuncs.CURRENTVERSION     = self._makeCurrentVersionParameter
		parameterFuncs.EDITREQUEST        = self._makeEditRequestParameter
		parameterFuncs.EXPIRY             = self._makeExpiryParameter
		parameterFuncs.EXPLANATIONBLURB   = self._makeExplanationBlurbParameter
		parameterFuncs.IMAGELINK          = self._makeImageLinkParameter
		parameterFuncs.INTROBLURB         = self._makeIntroBlurbParameter
		parameterFuncs.INTROFRAGMENT      = self._makeIntroFragmentParameter
		parameterFuncs.PAGETYPE           = self._makePagetypeParameter
		parameterFuncs.PROTECTIONBLURB    = self._makeProtectionBlurbParameter
		parameterFuncs.PROTECTIONDATE     = self._makeProtectionDateParameter
		parameterFuncs.PROTECTIONLEVEL    = self._makeProtectionLevelParameter
		parameterFuncs.PROTECTIONLOG      = self._makeProtectionLogParameter
		parameterFuncs.TALKPAGE           = self._makeTalkPageParameter
		parameterFuncs.TOOLTIPBLURB       = self._makeTooltipBlurbParameter
		parameterFuncs.TOOLTIPFRAGMENT    = self._makeTooltipFragmentParameter
		parameterFuncs.VANDAL             = self._makeVandalTemplateParameter
		
		self._params = setmetatable({}, {
			__index = function (t, k)
				local param
				if parameterFuncs[k] then
					param = parameterFuncs[k](self)
				end
				param = param or ''
				t[k] = param
				return param
			end
		})
	end
	
	msg = msg:gsub('${(%u+)}', self._params)
	return msg
end

function Blurb:_makeCurrentVersionParameter()
	-- A link to the page history or the move log, depending on the kind of
	-- protection.
	local pagename = self._protectionObj.title.prefixedText
	if self._protectionObj.action == 'move' then
		-- We need the move log link.
		return makeFullUrl(
			'Special:Log',
			{type = 'move', page = pagename},
			self:_getExpandedMessage('current-version-move-display')
		)
	else
		-- We need the history link.
		return makeFullUrl(
			pagename,
			{action = 'history'},
			self:_getExpandedMessage('current-version-edit-display')
		)
	end
end

function Blurb:_makeEditRequestParameter()
	local mEditRequest = require('Module:Submit an edit request')
	local action = self._protectionObj.action
	local level = self._protectionObj.level
	
	-- Get the edit request type.
	local requestType
	if action == 'edit' then
		if level == 'autoconfirmed' then
			requestType = 'semi'
		elseif level == 'extendedconfirmed' then
			requestType = 'extended'
		elseif level == 'templateeditor' then
			requestType = 'template'
		end
	end
	requestType = requestType or 'full'
	
	-- Get the display value.
	local display = self:_getExpandedMessage('edit-request-display')

	return mEditRequest._link{type = requestType, display = display}
end

function Blurb:_makeExpiryParameter()
	local expiry = self._protectionObj.expiry
	if type(expiry) == 'number' then
		return self:_formatDate(expiry)
	else
		return expiry
	end
end

function Blurb:_makeExplanationBlurbParameter()
	-- Cover special cases first.
	if self._protectionObj.title.namespace == 8 then
		-- MediaWiki namespace
		return self:_getExpandedMessage('explanation-blurb-nounprotect')
	end

	-- Get explanation blurb table keys
	local action = self._protectionObj.action
	local level = self._protectionObj.level
	local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject'

	-- Find the message in the explanation blurb table and substitute any
	-- parameters.
	local explanations = self._cfg.explanationBlurbs
	local msg
	if explanations[action][level] and explanations[action][level][talkKey] then
		msg = explanations[action][level][talkKey]
	elseif explanations[action][level] and explanations[action][level].default then
		msg = explanations[action][level].default
	elseif explanations[action].default and explanations[action].default[talkKey] then
		msg = explanations[action].default[talkKey]
	elseif explanations[action].default and explanations[action].default.default then
		msg = explanations[action].default.default
	else
		error(string.format(
			'could not find explanation blurb for action "%s", level "%s" and talk key "%s"',
			action,
			level,
			talkKey
		), 8)
	end
	return self:_substituteParameters(msg)
end

function Blurb:_makeImageLinkParameter()
	local imageLinks = self._cfg.imageLinks
	local action = self._protectionObj.action
	local level = self._protectionObj.level
	local msg
	if imageLinks[action][level] then
		msg = imageLinks[action][level]
	elseif imageLinks[action].default then
		msg = imageLinks[action].default
	else
		msg = imageLinks.edit.default
	end
	return self:_substituteParameters(msg)
end

function Blurb:_makeIntroBlurbParameter()
	if self._protectionObj:isTemporary() then
		return self:_getExpandedMessage('intro-blurb-expiry')
	else
		return self:_getExpandedMessage('intro-blurb-noexpiry')
	end
end

function Blurb:_makeIntroFragmentParameter()
	if self._protectionObj:isTemporary() then
		return self:_getExpandedMessage('intro-fragment-expiry')
	else
		return self:_getExpandedMessage('intro-fragment-noexpiry')
	end
end

function Blurb:_makePagetypeParameter()
	local pagetypes = self._cfg.pagetypes
	return pagetypes[self._protectionObj.title.namespace]
		or pagetypes.default
		or error('no default pagetype defined', 8)
end

function Blurb:_makeProtectionBlurbParameter()
	local protectionBlurbs = self._cfg.protectionBlurbs
	local action = self._protectionObj.action
	local level = self._protectionObj.level
	local msg
	if protectionBlurbs[action][level] then
		msg = protectionBlurbs[action][level]
	elseif protectionBlurbs[action].default then
		msg = protectionBlurbs[action].default
	elseif protectionBlurbs.edit.default then
		msg = protectionBlurbs.edit.default
	else
		error('no protection blurb defined for protectionBlurbs.edit.default', 8)
	end
	return self:_substituteParameters(msg)
end

function Blurb:_makeProtectionDateParameter()
	local protectionDate = self._protectionObj.protectionDate
	if type(protectionDate) == 'number' then
		return self:_formatDate(protectionDate)
	else
		return protectionDate
	end
end

function Blurb:_makeProtectionLevelParameter()
	local protectionLevels = self._cfg.protectionLevels
	local action = self._protectionObj.action
	local level = self._protectionObj.level
	local msg
	if protectionLevels[action][level] then
		msg = protectionLevels[action][level]
	elseif protectionLevels[action].default then
		msg = protectionLevels[action].default
	elseif protectionLevels.edit.default then
		msg = protectionLevels.edit.default
	else
		error('no protection level defined for protectionLevels.edit.default', 8)
	end
	return self:_substituteParameters(msg)
end

function Blurb:_makeProtectionLogParameter()
	local pagename = self._protectionObj.title.prefixedText
	if self._protectionObj.action == 'autoreview' then
		-- We need the pending changes log.
		return makeFullUrl(
			'Special:Log',
			{type = 'stable', page = pagename},
			self:_getExpandedMessage('pc-log-display')
		)
	else
		-- We need the protection log.
		return makeFullUrl(
			'Special:Log',
			{type = 'protect', page = pagename},
			self:_getExpandedMessage('protection-log-display')
		)
	end
end

function Blurb:_makeTalkPageParameter()
	return string.format(
		'[[%s:%s#%s|%s]]',
		mw.site.namespaces[self._protectionObj.title.namespace].talk.name,
		self._protectionObj.title.text,
		self._args.section or 'top',
		self:_getExpandedMessage('talk-page-link-display')
	)
end

function Blurb:_makeTooltipBlurbParameter()
	if self._protectionObj:isTemporary() then
		return self:_getExpandedMessage('tooltip-blurb-expiry')
	else
		return self:_getExpandedMessage('tooltip-blurb-noexpiry')
	end
end

function Blurb:_makeTooltipFragmentParameter()
	if self._protectionObj:isTemporary() then
		return self:_getExpandedMessage('tooltip-fragment-expiry')
	else
		return self:_getExpandedMessage('tooltip-fragment-noexpiry')
	end
end

function Blurb:_makeVandalTemplateParameter()
	return mw.getCurrentFrame():expandTemplate{
		title="vandal-m",
		args={self._args.user or self._protectionObj.title.baseText}
	}
end

-- Public methods --

function Blurb:makeBannerText(key)
	-- Validate input.
	if not key or not Blurb.bannerTextFields[key] then
		error(string.format(
			'"%s" is not a valid banner config field',
			tostring(key)
		), 2)
	end

	-- Generate the text.
	local msg = self._protectionObj.bannerConfig[key]
	if type(msg) == 'string' then
		return self:_substituteParameters(msg)
	elseif type(msg) == 'function' then
		msg = msg(self._protectionObj, self._args)
		if type(msg) ~= 'string' then
			error(string.format(
				'bad output from banner config function with key "%s"'
					.. ' (expected string, got %s)',
				tostring(key),
				type(msg)
			), 4)
		end
		return self:_substituteParameters(msg)
	end
end

--------------------------------------------------------------------------------
-- BannerTemplate class
--------------------------------------------------------------------------------

local BannerTemplate = {}
BannerTemplate.__index = BannerTemplate

function BannerTemplate.new(protectionObj, cfg)
	local obj = {}
	obj._cfg = cfg

	-- Set the image filename.
	local imageFilename = protectionObj.bannerConfig.image
	if imageFilename then
		obj._imageFilename = imageFilename
	else
		-- If an image filename isn't specified explicitly in the banner config,
		-- generate it from the protection status and the namespace.
		local action = protectionObj.action
		local level = protectionObj.level
		local namespace = protectionObj.title.namespace
		local reason = protectionObj.reason
		
		-- Deal with special cases first.
		if (
			namespace == 10
			or namespace == 828
			or reason and obj._cfg.indefImageReasons[reason]
			)
			and action == 'edit'
			and level == 'sysop'
			and not protectionObj:isTemporary()
		then
			-- Fully protected modules and templates get the special red "indef"
			-- padlock.
			obj._imageFilename = obj._cfg.msg['image-filename-indef']
		else
			-- Deal with regular protection types.
			local images = obj._cfg.images
			if images[action] then
				if images[action][level] then
					obj._imageFilename = images[action][level]
				elseif images[action].default then
					obj._imageFilename = images[action].default
				end
			end
		end
	end
	return setmetatable(obj, BannerTemplate)
end

function BannerTemplate:renderImage()
	local filename = self._imageFilename
		or self._cfg.msg['image-filename-default']
		or 'Transparent.gif'
	return makeFileLink{
		file = filename,
		size = (self.imageWidth or 20) .. 'px',
		alt = self._imageAlt,
		link = self._imageLink,
		caption = self.imageCaption
	}
end

--------------------------------------------------------------------------------
-- Banner class
--------------------------------------------------------------------------------

local Banner = setmetatable({}, BannerTemplate)
Banner.__index = Banner

function Banner.new(protectionObj, blurbObj, cfg)
	local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb.
	obj.imageWidth = 40
	obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip.
	obj._reasonText = blurbObj:makeBannerText('text')
	obj._explanationText = blurbObj:makeBannerText('explanation')
	obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing.
	return setmetatable(obj, Banner)
end

function Banner:__tostring()
	-- Renders the banner.
	makeMessageBox = makeMessageBox or require('Module:Message box').main
	local reasonText = self._reasonText or error('no reason text set', 2)
	local explanationText = self._explanationText
	local mbargs = {
		page = self._page,
		type = 'protection',
		image = self:renderImage(),
		text = string.format(
			"'''%s'''%s",
			reasonText,
			explanationText and '<br />' .. explanationText or ''
		)
	}
	return makeMessageBox('mbox', mbargs)
end

--------------------------------------------------------------------------------
-- Padlock class
--------------------------------------------------------------------------------

local Padlock = setmetatable({}, BannerTemplate)
Padlock.__index = Padlock

function Padlock.new(protectionObj, blurbObj, cfg)
	local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb.
	obj.imageWidth = 20
	obj.imageCaption = blurbObj:makeBannerText('tooltip')
	obj._imageAlt = blurbObj:makeBannerText('alt')
	obj._imageLink = blurbObj:makeBannerText('link')
	obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action]
		or cfg.padlockIndicatorNames.default
		or 'pp-default'
	return setmetatable(obj, Padlock)
end

function Padlock:__tostring()
	local frame = mw.getCurrentFrame()
	-- The nowiki tag helps prevent whitespace at the top of articles.
	return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{
		name = 'indicator',
		args = {name = self._indicatorName},
		content = self:renderImage()
	}
end

--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------

local p = {}

function p._exportClasses()
	-- This is used for testing purposes.
	return {
		Protection = Protection,
		Blurb = Blurb,
		BannerTemplate = BannerTemplate,
		Banner = Banner,
		Padlock = Padlock,
	}
end

function p._main(args, cfg, title)
	args = args or {}
	cfg = cfg or require(CONFIG_MODULE)

	local protectionObj = Protection.new(args, cfg, title)

	local ret = {}

	-- If a page's edit protection is equally or more restrictive than its
	-- protection from some other action, then don't bother displaying anything
	-- for the other action (except categories).
	if not yesno(args.catonly) and (protectionObj.action == 'edit' or
		args.demolevel or
		not getReachableNodes(
			cfg.hierarchy,
			protectionObj.level
		)[effectiveProtectionLevel('edit', protectionObj.title)])
	then
		-- Initialise the blurb object
		local blurbObj = Blurb.new(protectionObj, args, cfg)
	
		-- Render the banner
		if protectionObj:shouldShowLock() then
			ret[#ret + 1] = tostring(
				(yesno(args.small) and Padlock or Banner)
				.new(protectionObj, blurbObj, cfg)
			)
		end
	end

	-- Render the categories
	if yesno(args.category) ~= false then
		ret[#ret + 1] = protectionObj:makeCategoryLinks()
	end
	
	-- For arbitration enforcement, flagging [[WP:PIA]] pages to enable [[Special:AbuseFilter/1339]] to flag edits to them
	if protectionObj.level == "extendedconfirmed" then
		if require("Module:TableTools").inArray(protectionObj.title.talkPageTitle.categories, "Wikipedia pages subject to the extended confirmed restriction related to the Arab-Israeli conflict") then
			ret[#ret + 1] = "<p class='PIA-flag' style='display:none; visibility:hidden;' title='This page is subject to the extended confirmed restriction related to the Arab-Israeli conflict.'></p>"
		end
	end
	
	return table.concat(ret)	
end

function p.main(frame, cfg)
	cfg = cfg or require(CONFIG_MODULE)

	-- Find default args, if any.
	local parent = frame.getParent and frame:getParent()
	local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')]

	-- Find user args, and use the parent frame if we are being called from a
	-- wrapper template.
	getArgs = getArgs or require('Module:Arguments').getArgs
	local userArgs = getArgs(frame, {
		parentOnly = defaultArgs,
		frameOnly = not defaultArgs
	})

	-- Build the args table. User-specified args overwrite default args.
	local args = {}
	for k, v in pairs(defaultArgs or {}) do
		args[k] = v
	end
	for k, v in pairs(userArgs) do
		args[k] = v
	end
	return p._main(args, cfg)
end

return p
拉比是什么意思 月经量少发黑是什么原因 化验痰可以检查出什么 11月14日什么星座 怀孕上火吃什么能降火
梦见嫂子是什么意思 绿茶婊什么意思 古井贡酒是什么香型 不可名状的名是什么意思 怀孕要检查什么项目
hrd是什么意思 手麻脚麻是什么原因 小儿肠炎吃什么药最好 cnd是什么意思 女孩子喜欢什么礼物
黄芪不能和什么一起吃 喝什么去火效果最好 柿子不能跟什么一起吃 希特勒为什么杀犹太人 活水是什么意思
吃木耳有什么好处hcv9jop1ns1r.cn 福寿延绵是什么意思hcv7jop5ns2r.cn 种什么药材最快又值钱hcv7jop7ns3r.cn 飞沙走石是什么意思hcv8jop9ns6r.cn 子息克乏是什么意思hcv9jop8ns2r.cn
平身是什么意思hcv9jop3ns0r.cn 什么是免疫组化检查hcv7jop6ns6r.cn 年少轻狂下一句是什么hcv8jop6ns3r.cn 手指头肿胀是什么原因mmeoe.com 南昌有什么好吃的hcv9jop8ns2r.cn
肝昏迷是什么症状hcv9jop0ns8r.cn 急性乳腺炎是什么原因引起的kuyehao.com 背痛挂什么科hcv8jop7ns3r.cn 脱肛吃什么药xianpinbao.com 皮肤黑吃什么会变白hcv8jop4ns5r.cn
鸡蛋与什么食物相克hcv9jop1ns5r.cn 健康查体是什么意思hcv9jop3ns4r.cn 阴茎皮开裂是什么原因hcv9jop2ns2r.cn 登高望远是什么生肖hcv8jop3ns1r.cn 梦见好多动物是什么意思hcv7jop6ns6r.cn
百度