Модуль:Wikidata/Places

Материал из Тептар — свободной энциклопедии
< Модуль:Wikidata
Версия от 11:54, 7 февраля 2022; Adam (обсуждение | вклад) (Новая страница: «local categorizeByPlace = true; local WDS = require( 'Module:WikidataSelectors' ); local Flags = require( 'Module:Wikidata/Flags' ); local p = { config = { hideSameLabels = false, hidePartOfLabels = false, hideUnitsForCapitals = true, reverseOrder = false, catAmbiguousGeoChains = 'Категория:Тептар:Страницы с неоднозначными геоцепочками', catLoopInGeoChains = '[[Категория:Тепта...»)
(разн.) ← Предыдущая версия | Текущая версия (разн.) | Следующая версия → (разн.)
Перейти к навигации Перейти к поиску

Содержит функции форматирования для свойств (claims) Тептар данных, представляющих собой ссылки на географические элементы (обычно — административные единицы или страны).

Вызов всех функций данного шаблона осуществляется из шаблона {{wikidata}}}. Функции модуля нельзя вызывать напрямую — они передаются в виде аргументов из соответствующих связанных шаблонов (и только из них, в другие шаблоны их также вставлять не нужно).

formatCountryClaimWithFlag[править код]

Отличием от обычной функции форматирования элемента являются:

  • дополнение каждой страны флагом
  • оборачивание значений в <span class="country-name">…</span>

Для вывода флага модуль сначала вычисляет «актуальную дату»:

  1. сначала пытается взять квалификатор у значения страны
  2. если нет, то берёт первое нормальное значение у одного из следующих свойств у текущего объекта:
  3. если всё ещё нет, берётся текущая дата

Далее модуль идёт в по флагам, перечисленным в свойстве и берёт там последний из флагов указанной страны, для которого дата введения меньше вычисленной актуальной даты (флаги отсортированы по дате введения).

Таким образом, если шаблон {{wikidata|p27}} не отображает флаг в карточке, проверьте, что у страны на Тептар данных заполнено свойство , а у флага указана корректная дата введения (ранг игнорируется)

Если отображается ненужный флаг (то есть флага не может быть по историческим причинам), либо флаг должен быть другой, то проверьте:

  • наличие даты окончания принадлежности к стране (квалификатор ) у значения свойства текущего элемента, либо корректной даты смерти (или другого соответствующего свойства)
  • корректность значения свойства у соответствующего элемента страны, в том числе наличие корректного значения квалификатора у каждого значения флага

formatPlaceWithQualifiers[править код]


TODO[править код]

Сейчас не решена проблема в случаях, когда есть неоднозначность в построении цепочки. Для некоторых стран (например, Франции) подобная неоднозначность в обозримом будущем не будет разрешена.

Квалификатор «указано для части»[править код]

У Адамс, Келли в месте рождения указано Линкольн, Линкольншир и никакой тебе Великобритании. Проблема в том что часть графства одновременно относится к Восточному Мидленду, а часть к — Йоркшир и Хамбер. В результате система просто не может сделать между ними выбор, но в самом элементе Линкольншир указано что к чему относится с помощью квалификатора указано для части. Есть ли возможность учитывать этот квалификатор при построении геоцепочек в подобных случаях? Например, у людей родившихся в Линкольне после 1994 года полное место рождения: Линкольн (город), Линкольн (боро), Линкольншир (неметропольное графство), Линкольншир (церемониальное графство), Восточный Мидленд, Англия, Великобритания. С учётом столичных элементов должно быть: Линкольн, Восточный Мидленд, Англия, Великобритания. Проверить можно на Джордан, Пэт он умер уже после образования Восточного Мидленда (если режиме предварительного простора убрать то, что введено вручную, на подгрузку из Тептар данных). Коллеги, в том числе Putnik, как участник, занимающийся АТЕ и геоцепочками, посмотрите, пожалуйста, реализуемо ли это предложение технически и может ли от него быть польза? --Ksc~ruwiki (обс.) 19:48, 23 мая 2018 (UTC)


local categorizeByPlace = true;

local WDS = require( 'Module:WikidataSelectors' );
local Flags = require( 'Module:Wikidata/Flags' );
local p = {
	config = {
		hideSameLabels = false,
		hidePartOfLabels = false,
		hideUnitsForCapitals = true,
		reverseOrder = false,
		catAmbiguousGeoChains = '[[Категория:Тептар:Страницы с неоднозначными геоцепочками]]',
		catLoopInGeoChains = '[[Категория:Тептар:Страницы с зацикливающимися геоцепочками]]',
		catWikibaseError = '[[Категория:Тептар:Страницы с ошибками скриптов, использующих Тептар данные]]'
	}
};

local function min( prev, next )
	if prev == nil then
		return next;
	elseif prev > next then
		return next;
	else
		return prev;
	end
end

local function max( prev, next )
	if prev == nil then
		return next;
	elseif prev < next then
		return next;
	else
		return prev;
	end
end

local function getTimeBoundariesFromProperty( context, propertyId )
	local dateClaims = WDS.filter( context.entity.claims, propertyId );
	if not dateClaims or #dateClaims == 0 then
		return nil;
	end

	-- only support exact date so far, but need improvment
	local left = nil;
	local right = nil;
	for _, claim in pairs( dateClaims ) do
		if not claim.mainsnak then return nil; end
		local boundaries = context.parseTimeBoundariesFromSnak( claim.mainsnak );
		if not boundaries then return nil; end
		left = min( left, boundaries[ 1 ] );
		right = max( right, boundaries[ 2 ] );
	end

	if not left or not right then return nil; end

	return { left, right };
end

local function getTimeBoundariesFromProperties( context, propertyIds )
	for _, propertyId in ipairs( propertyIds ) do
		local result = getTimeBoundariesFromProperty( context, propertyId );
		if result then
			return result;
		end
	end

	return nil;
end

local function getTimeBoundariesFromQualifiers( context, statement, qualifierId )
	-- only support exact date so far, but need improvment
	local left = nil;
	local right = nil;
	if statement.qualifiers and statement.qualifiers[qualifierId] then
		for _, qualifier in pairs( statement.qualifiers[qualifierId] ) do
			local boundaries = context.parseTimeBoundariesFromSnak( qualifier );
			if not boundaries then return nil; end
			left = min( left, boundaries[1] );
			right = max( right, boundaries[2] );
		end
	end

	if not left or not right then
		return nil;
	end

	return { left, right };
end

local function getParentsInBoundariesSnakImpl( context, entityId, boundaries, propertyIds, selectors )
	local results = {};

	if not propertyIds or #propertyIds == 0 then
		return results;
	end
	
	for _, propertyId in ipairs( propertyIds ) do
		if (not string.match( propertyId, '^P%d+$' )) then error('Incorrect propertyId: ' + propertyId); end
		local selector;
		if (selectors ~= nil) then
			selector = selectors[propertyId] or propertyId;
		else
			selector = propertyId;
		end

		local entityClaims = {};
		entityClaims[propertyId] = mw.wikibase.getAllStatements( entityId, propertyId );

		local filteredClaims = WDS.filter( entityClaims, selector .. '[rank:preferred, rank:normal]' );
		if filteredClaims then
			for _, claim in pairs( filteredClaims ) do
				if not boundaries or not propertyIds or #propertyIds == 0 then
					table.insert( results, claim.mainsnak );
				else
					local startBoundaries = getTimeBoundariesFromQualifiers( context, claim, 'P580' );
					local endBoundaries = getTimeBoundariesFromQualifiers( context, claim, 'P582' );
		
					if ( startBoundaries == nil or startBoundaries[2] <= boundaries[1] ) and
						( endBoundaries == nil or endBoundaries[1] >= boundaries[2] )
					then
						table.insert( results, claim.mainsnak );
					end 
				end
			end
		end

		if #results > 0 then
			break;
		end
	end

	return results;
end

local function getParentsInBoundariesSnak( context, entityId, boundaries )
	if not entityId then error('entityId must be specified'); end
	if type(entityId) ~= 'string' then error('entityId must be string'); end
	if not boundaries then error('boundaries must be specified'); end
	if type(boundaries) ~= 'table' then error('boundaries must be table'); end

	local results = getParentsInBoundariesSnakImpl( context, entityId, boundaries, {'P131'} ) -- located in
	if not results or #results == 0 then
		results = getParentsInBoundariesSnakImpl( context, entityId, boundaries, {'P17'} ) -- country
	end

	for r, result in pairs( results ) do
		if result.snaktype ~= 'value' then
			return nil;
		end
		local resultId = result.datavalue.value.id;
		if resultId == entityId then
			return nil;
		end
	end
	return results;
end

local unions = { 
	Q1140229 = true, -- political union
	Q3623811 = true, -- Экономический союз
	Q4120211 = true -- региональная организация
}

local countries = {
	Q6256 = true, -- страна
	Q7275 = true, -- государство
	Q3024240 = true, -- историческое государство
	Q3624078 = true -- суверенное государство
}

local function isSkipTopLevel( entity )
	local isCountry = false;
	local isUnion = false;
	if entity and
		entity.claims and
		entity.claims.P31
	then
		for c, claim in pairs( entity.claims.P31 ) do
			if claim and
				claim.mainsnak and
				claim.mainsnak.datavalue and
				claim.mainsnak.datavalue.value and
				claim.mainsnak.datavalue.value.id
			then
				local typeId = claim.mainsnak.datavalue.value.id;
				isCountry = isCountry or countries[ typeId ];
				isUnion = isUnion or unions[ typeId ];
			end
		end
	end
	return isUnion and not isCountry;
end

local function isPartOfNext( prevLabel, nextLabel )
	return ( mw.ustring.len( prevLabel ) > mw.ustring.len( nextLabel ) )
		and ( mw.ustring.sub( prevLabel, mw.ustring.len( prevLabel ) - mw.ustring.len( nextLabel ) + 1 ) == nextLabel );
end

--Property:P19, Property:P20, Property:P119
function p.formatPlaceWithQualifiers( context, options, statement )
	local property = mw.ustring.upper( options.property );

	local actualDateBoundariesProperties = nil;
	if property == 'P19' then actualDateBoundariesProperties = {'P569','P570'}; end
	if property == 'P20' then actualDateBoundariesProperties = {'P570','P569'}; end
	if property == 'P119' then actualDateBoundariesProperties = {'P570','P569'}; end
	if property == 'P159' then actualDateBoundariesProperties = {'P576'}; end

	local boundaries = nil;
	if actualDateBoundariesProperties ~= nil then
		boundaries = getTimeBoundariesFromProperties( context, actualDateBoundariesProperties );
		if (boundaries == nil) and (property == 'P159') then
			boundaries = {os.time() * 1000, os.time() * 1000};
		end
	end

	local entriesToLookupCategory = {};

	local circumstances = context.getSourcingCircumstances( statement );
	local result = '';
	local baseResult = context.formatSnak( options, statement.mainsnak, circumstances );
	if not baseResult then
		return nil;
	end
	
	insertFromSnak( statement.mainsnak, entriesToLookupCategory )

	local hasAdditionalQualifiers = false;
	if statement.qualifiers then
		--parent divisions
		if statement.qualifiers.P131 then
			for i, qualifier in ipairs( statement.qualifiers.P131 ) do
				if qualifier.datavalue then
					local parentOptions = context.cloneOptions( options );
					local qualifierEntityId = qualifier.datavalue.value.id;
					parentOptions['text'] = getLabel( context, qualifierEntityId, boundaries );
					local link = context.formatSnak( parentOptions, qualifier );
	
					if p.config.reverseOrder then
						result = link .. ', ' .. result;
					else
						result = result .. ', ' .. link;
					end
					insertFromSnak( qualifier, entriesToLookupCategory )
					hasAdditionalQualifiers = true;
				end
			end
		end

		--country
		if statement.qualifiers.P17 then
			for i, qualifier in ipairs( statement.qualifiers.P17 ) do
				if qualifier.datavalue then
					local parentOptions = context.cloneOptions( options );
					local qualifierEntityId = qualifier.datavalue.value.id;
					parentOptions[ 'text' ] = getLabel( context, qualifierEntityId, boundaries );
					local link = context.formatSnak( parentOptions, qualifier );
	
					if p.config.reverseOrder then
						result = link .. ', ' .. result;
					else
						result = result .. ', ' .. link;
					end
					insertFromSnak( qualifier, entriesToLookupCategory )
					hasAdditionalQualifiers = true;
				end
			end
		end
	end

	if statement.mainsnak and
		statement.mainsnak.datavalue and
		statement.mainsnak.datavalue.value and
		statement.mainsnak.datavalue.value.id
	then
		local entityId = statement.mainsnak.datavalue.value.id;
		local parentSnaks = { statement.mainsnak };
		local parentEntityIds = { entityId };

		if actualDateBoundariesProperties ~= nil then
			local filterCapitalOf = {
				[ entityId ] = getParentsInBoundariesSnakImpl( context, entityId, boundaries, {'P1376'} )
			};
			if boundaries then
				local entityOptions = context.cloneOptions( options );
				entityOptions['text'] = getLabel( context, entityId, boundaries );
				baseResult = context.formatSnak( entityOptions, statement.mainsnak, circumstances );

				local parentId = entityId;
				while parentId ~= nil do
					-- get parent
					local newParentSnaks = getParentsInBoundariesSnak( context, parentId, boundaries );
					if not newParentSnaks or #newParentSnaks == 0 then
						parentId = nil;
					elseif #newParentSnaks == 1 then
						local parentSnak = newParentSnaks[ 1 ];
						parentId = parentSnak.datavalue.value.id;
						
						local hasLoop = false
						for _, parentEntityId in pairs(parentEntityIds) do
							if parentEntityId == parentId then
								hasLoop = true
							end
						end
						
						if hasLoop then
							if p.config and p.config.catLoopInGeoChains then
								result = result .. p.config.catLoopInGeoChains;
							end
							break -- while parentId ~= nil do
						end
								
						table.insert( parentSnaks, parentSnak );
						table.insert( parentEntityIds, parentId );
						filterCapitalOf[ parentId ] = getParentsInBoundariesSnakImpl( context, parentId, boundaries, { 'P1376' } );
					else
						parentId = nil;
						if p.config and p.config.catAmbiguousGeoChains then
							result = result .. p.config.catAmbiguousGeoChains;
						end
					end
				end

				if not hasAdditionalQualifiers then
					for i = 2, #parentSnaks, 1 do
						local parentSnak = parentSnaks[ i ];
						insertFromSnak( parentSnak, entriesToLookupCategory )
					end
				end

				-- do not output similar countries like "Denmark, the Kingdom of Denmark"
				local simularCountries = {
					['Q41304'] = 'Q1206012', -- Weimar Republic / German Reich
					['Q7318'] = 'Q1206012', -- Weimar Republic / Nazi Germany
					['Q35'] = 'Q756617', -- Denmark / Danish Realm
					['Q55'] = 'Q29999', -- Netherlands / Kingdom of the Netherlands
					['Q32081'] = 'Q865', -- Taiwan Province / Taiwan
				}
				if (#parentSnaks > 1) then
					for smallerCountryId, largerCountryId in pairs( simularCountries ) do
						if parentSnaks[ #parentSnaks ].datavalue.value.id == largerCountryId
							and parentSnaks[ #parentSnaks - 1 ].datavalue.value.id == smallerCountryId
						then
							table.remove( parentSnaks, #parentSnaks );
							table.remove( parentEntityIds, #parentEntityIds );
						end
					end
				end

				-- optimization for capital regions
				if (#parentSnaks > 3) then
					if parentSnaks[ #parentSnaks - 2 ].datavalue.value.id == 'Q23939248' --Greater London, Greater London
						and parentSnaks[ #parentSnaks - 3 ].datavalue.value.id == 'Q23306'
					then
						table.remove( parentSnaks, #parentSnaks - 2 );
						table.remove( parentEntityIds, #parentEntityIds - 2 );
					end
				end
				if (#parentSnaks > 2) then
					if parentSnaks[ #parentSnaks - 1 ].datavalue.value.id == 'Q240' --Brussels-Capital, Brussels
						and parentSnaks[ #parentSnaks - 2 ].datavalue.value.id == 'Q90870'
					then
						table.remove( parentSnaks, #parentSnaks - 2 );
						table.remove( parentEntityIds, #parentEntityIds - 2 );
					end
				end

				-- do not output (maternity) hospitals, houses and streets but do it for manor and English country houses
				local unignoredTypes = {
					'Q879050', -- manor house
					'Q1343246', -- English country house
				}
				local ignoredTypes = {
					'Q3947', -- house
					'Q16917', -- hospital
					'Q34442', -- road
					'Q79007', -- street
					'Q174782', -- square
					'Q958822', -- maternity hospital
					'Q2087181', -- historic house museum
				}
				if (#parentSnaks > 1) then
					local p31 = mw.wikibase.getAllStatements( parentEntityIds[ 1 ], 'P31' );
					local doignore = true;
					for _, iOf in ipairs( p31 ) do
						for _, unignoredTypeId in ipairs( unignoredTypes ) do
							if ( iOf.mainsnak.datavalue.value.id == unignoredTypeId ) then
								doignore = false;
								unignoredTypes = {};
								ignoredTypes = {};
								break;
							end
						end
					end
					
					if (doignore) then
						for _, iOf in ipairs( p31 ) do
							for _, ignoredTypeId in ipairs( ignoredTypes ) do
								if ( iOf.mainsnak.datavalue.value.id == ignoredTypeId ) then
									baseResult = '';
									unignoredTypes = {};
									ignoredTypes = {};
									break;
								end
							end
						end
					end
				end

				do
					local capofstate = false;
					local i = #parentSnaks;
					while i > 1 do
						local prevEntityId = parentEntityIds[ i - 1 ];
						-- TODO: use English labels, if there is no current language labels
						local prevLabel = getLabel( context, prevEntityId, boundaries ) or '';
						local nextEntityId = parentEntityIds[ i ];
						local nextLabel = getLabel( context, nextEntityId, boundaries ) or '';
						if p.config and p.config.hideSameLabels == true and prevLabel == nextLabel then
							-- do not output same label twice (NY, NY, USA)
							table.remove( parentSnaks, i );
							table.remove( parentEntityIds, i );
						elseif p.config and p.config.hidePartOfLabels == true and isPartOfNext( prevLabel, ' ' .. nextLabel ) then
							-- do not output same label if it's part of previos
							table.remove( parentSnaks, i - 1 );
							table.remove( parentEntityIds, i - 1 );
						elseif p.config and p.config.hideUnitsForCapitals == true then
							-- do not ouput items whose capital is the first item
							local capitalId = nil;
							for _capitalId, capitalSnaks in pairs( filterCapitalOf ) do
								if #capitalSnaks > 0 then
									for __, capitalSnak in pairs( capitalSnaks ) do
										if	capitalSnak.datavalue and 
											parentSnaks[ i ].datavalue.value.id == capitalSnak.datavalue.value.id then
											capitalId = _capitalId;
											if (i == #parentSnaks) then
												capofstate = true;
											end
											break;
										end
									end
								end
							end
							if capitalId ~= nil then
								if i == #parentSnaks then
									i = i - 1;
								end
								-- always ouput constituent countries like England or Russian SFSR
								if (i == (#parentSnaks-1)) and (capofstate == false) then
									local p31 = mw.wikibase.getAllStatements(parentEntityIds[ i ], 'P31');
										for _, iOf in pairs (p31) do
											if (iOf.mainsnak.datavalue.value['numeric-id'] == 236036) or (iOf.mainsnak.datavalue.value['numeric-id'] == 3336843) or (iOf.mainsnak.datavalue.value['numeric-id'] == 12959600) or (iOf.mainsnak.datavalue.value['numeric-id'] == 56219758) or (iOf.mainsnak.datavalue.value['numeric-id'] == 15304003) or (iOf.mainsnak.datavalue.value['numeric-id'] == 66724388) then
												i = i - 1;
										end
									end
								end
								while i > 1 and parentEntityIds[ i ] ~= capitalId do
									table.remove( parentSnaks, i );
									table.remove( parentEntityIds, i );
									i = i - 1;
								end
							end
						end
						i = i - 1;
					end
				end

				if isSkipTopLevel( parentEntityIds[ #parentEntityIds ] ) then
					table.remove( parentSnaks, #parentEntityIds );
					table.remove( parentEntityIds, #parentEntityIds );
				end

				if not hasAdditionalQualifiers then
					for i = 2, #parentSnaks, 1 do
						local parentSnak = parentSnaks[ i ];

						local parentOptions = context.cloneOptions( options );
						parentOptions['text'] = getLabel( context, parentEntityIds[ i ], boundaries );

						local comma;
						if ((baseResult == '') and (i == 2)) then
							comma = '';
						else
							comma = ', ';
						end

						if p.config.reverseOrder then
							result = context.formatSnak( parentOptions, parentSnak ) .. comma .. result;
						else
							result = result .. comma .. context.formatSnak( parentOptions, parentSnak );
						end
					end
				end
			end
		end
	end

	if options[ 'thisLocationOnly' ] then
		result = baseResult;
	elseif p.config.reverseOrder then
		result = result .. baseResult;
	else
		result = baseResult .. result;
	end
	if options.references then
		result = result .. context.formatRefs( options, statement );
	end

	if categorizeByPlace then
		if property == 'P19' then result = result .. getCategory( 'P1464', entriesToLookupCategory ); end
		if property == 'P20' then result = result .. getCategory( 'P1465', entriesToLookupCategory ); end
		if property == 'P119' then result = result .. getCategory( 'P1791', entriesToLookupCategory ); end
	end

	return result;
end

-- append entity id from snak to result
function insertFromSnak( snak, result )
	if not categorizeByPlace then
		return;
	end
	if snak and
		snak.datavalue and
		snak.datavalue.type == 'wikibase-entityid' and
		snak.datavalue.value and
		snak.datavalue.value[ 'entity-type' ] == 'item'
	then
		table.insert( result, snak.datavalue.value.id );
	end
end

function getCategory( propertyId, entriesToLookupCategoryFor )
	if mw.title.getCurrentTitle().namespace == 0 then
		for _, placeId in pairs( entriesToLookupCategoryFor ) do
			local claims = mw.wikibase.getBestStatements(placeId, propertyId);
	
			if claims then
				for _, claim in pairs( claims ) do
					if claim.mainsnak and
						claim.mainsnak and
						claim.mainsnak.datavalue and
						claim.mainsnak.datavalue.type == 'wikibase-entityid'
					then
						local catEntityId = claim.mainsnak.datavalue.value.id;
						local catSitelink = mw.wikibase.getSitelink(catEntityId);
						if (catSitelink) then
							return '[[' .. catSitelink .. ']]';
						end
					end
				end
			end
		end
	end
	return '';
end


local historicNamesProperties = { 'P1813', 'P1448', 'P1705' };

local langCode = mw.language.getContentLanguage():getCode();
local historicNamesPropertySelectors = {
		P1813 = 'P1813[language:' .. langCode .. '][!P3831,P3831:Q105690470]',
		P1448 = 'P1448[language:' .. langCode .. '][!P3831,P3831:Q105690470]',
		P1705 = 'P1705[language:' .. langCode .. '][!P3831,P3831:Q105690470]'
};

-- get current of historic name of place
function getLabel( context, entityId, boundaries )
	if not entityId then
		return nil;
	end
	if (type(entityId) ~= 'string') then error('incorrect type of entityId argument'); end;

    local label = nil;

	-- name from properties
	local results = getParentsInBoundariesSnakImpl( context, entityId, boundaries,
		historicNamesProperties, historicNamesPropertySelectors);

	for r, result in pairs( results ) do
		if result.datavalue and
			result.datavalue.value and
			result.datavalue.value.text
		then
			label = result.datavalue.value.text;
			break;
		end
	end

    -- name from label
    if label == nil then
		label = mw.wikibase.getLabel( entityId );
    end

    return label;
end

p.getLabel = getLabel;

local function calculateEndDateTimestamp( context, options, statement )
	if not context then error( 'context not specified' ) end;
	if not options then error( 'options not specified' ) end;
	if not options.entity then error( 'options.entity missing' ) end;
	if not statement then error( 'statement not specified' ) end;

	if statement.qualifiers and statement.qualifiers.P582 then
		for i, qualifier in ipairs( statement.qualifiers.P582 ) do
			local parsedTime = context.parseTimeFromSnak( qualifier );
			if parsedTime then
				return parsedTime;
			end
		end
	end

	-- check death day... do we have it at all?
	for h, propertyId in pairs( { "P570", "P577", "P576" } ) do
		local dateClaims = context.selectClaims( options, propertyId );
		if dateClaims then
			for i, statement in ipairs( dateClaims ) do
				local parsedTime = context.parseTimeFromSnak( statement.mainsnak );
				if parsedTime then
					return parsedTime;
				end
			end
		end
	end

	-- TODO: check other "end" properties

	-- no death day
	return os.time() * 1000;
end

local function deleteTwinAncestors( countryEntityId, propertyId, entityId ) --do not display countries which have twin ancestors
	local badTwins
	if ( countryEntityId == 'Q174193' ) then				--Great Britain and Ireland
		badTwins = {'Q145'}									--Great Brirani & NI
    elseif ( countryEntityId == 'Q161885' ) then			--Great Britain
		badTwins = {'Q174193'}								--Great Britain and Ireland
	elseif ( countryEntityId == 'Q43287' ) then				--German Impire
		badTwins = {'Q41304', 'Q7318', 'Q2415901', 'Q183'}	--Weimar Republic or Nazi Germany or Allied-occupied Germany or Germany
	elseif ( countryEntityId == 'Q41304' ) then				--Weimar Republic
		badTwins = {'Q7318', 'Q2415901', 'Q183'}			--Nazi Germany or Allied-occupied Germany or Germany
	elseif ( countryEntityId == 'Q7318' ) then				--Nazi Germany
		badTwins = {'Q2415901', 'Q183'}						--Allied-occupied Germany or Germany
    elseif ( countryEntityId == 'Q2415901' ) then			--Allied-occupied Germany
		badTwins = {'Q183'}									--Germany
	elseif ( countryEntityId == 'Q696908' ) then			--Kingdom of Poland
		badTwins = {'Q207272', 'Q211274', 'Q36'}			--Second Polish Republic or Polish People's Republic or Poland
	elseif ( countryEntityId == 'Q207272' ) then			--Second Polish Republic
		badTwins = {'Q211274', 'Q36'}						--Polish People's Republic or Poland
	elseif ( countryEntityId == 'Q211274' ) then			--Polish People's Republic
		badTwins = {'Q36'}									--Poland
	elseif ( countryEntityId == 'Q203493' ) then			--Kingdom of Romania
		badTwins = {'Q842794', 'Q218'}						--Socialist Republic of Romania or Romania
	elseif ( countryEntityId == 'Q842794' ) then			--Socialist Republic of Romania
		badTwins = {'Q218'}									--Romania
	elseif ( countryEntityId == 'Q838261' ) then			--FR of Yugoslavia
		badTwins = {'Q37024'}								--Serbia & Montenegro
	else
		return true;
	end

	local listforcheck
	if propertyId == 'P1532' then
		listforcheck = mw.wikibase.getAllStatements( entityId, propertyId );
	else
		listforcheck = mw.wikibase.getBestStatements( entityId, propertyId );
	end

	for _, claim in pairs( listforcheck ) do
		if ( claim and claim.mainsnak
			and claim.mainsnak.datavalue
			and claim.mainsnak.datavalue.value
			and claim.mainsnak.datavalue.value.id ) then
			local actualId = claim.mainsnak.datavalue.value.id;
			for index, value in ipairs(badTwins) do
				if ( value == actualId ) then
            		return false;
        		end
			end
		end
	end
	return true; 
end

function p.formatCountryClaimWithFlag( context, options, statement )
	if not context then error('context not specified') end;
	if not options then error('options not specified') end;
	if not options.entity then error('options.entity is missing') end;
	if not statement then error('statement not specified') end;

	if not statement.mainsnak or
		not statement.mainsnak.datavalue or
		not statement.mainsnak.datavalue.value or
		not statement.mainsnak.datavalue.value.id
	then
		local result = context.formatStatementDefault( context, options, statement );
		if not result then
			return '';
		end
		return '<span class="country-name">' .. result .. '</span>';
	end
	
	local countryEntityId = statement.mainsnak.datavalue.value.id;
	local endDateTimestamp = calculateEndDateTimestamp( context, options, statement );
	local boundaries = getTimeBoundariesFromProperties( context, {'P570', 'P577', 'P571'} );

	if deleteTwinAncestors( countryEntityId, string.upper(options.property), options.entity.id ) then

		local countryOptions = context.cloneOptions( options );
		if not countryOptions['text'] or countryOptions['text'] == '' then
			countryOptions['text'] = getLabel( context, countryEntityId, boundaries );
		end

		local flag = Flags.getFlag( context, countryEntityId, endDateTimestamp );	
		if flag then
			return flag .. '&nbsp;<span class="country-name">' ..
				context.formatStatementDefault( context, countryOptions, statement ) ..
				'</span>';
		end

		return '<span class="country-name">' ..
			context.formatStatementDefault( context, countryOptions, statement ) ..
			'</span>';
	else
		return nil;
	end
end

return p;