Modul:place/data

Üdvözlöm, Ön a Modul:place/data szó jelentését keresi. A DICTIOUS-ban nem csak a Modul:place/data szó összes szótári jelentését megtalálod, hanem megismerheted az etimológiáját, a jellemzőit és azt is, hogyan kell a Modul:place/data szót egyes és többes számban mondani. Minden, amit a Modul:place/data szóról tudni kell, itt található. A Modul:place/data szó meghatározása segít abban, hogy pontosabban és helyesebben fogalmazz, amikor beszélsz vagy írsz. AModul:place/data és más szavak definíciójának ismerete gazdagítja a szókincsedet, és több és jobb nyelvi forráshoz juttat.

A modult a Modul:place/data/doc lapon tudod dokumentálni

local export = {}

local m_shared = require("Module:place/shared-data")
local m_links = require("Module:links")
local m_strutils = require("Module:string utilities")

local function ucfirst(label)
	return mw.getContentLanguage():ucfirst(label)
end

local function lc(label)
	return mw.getContentLanguage():lc(label)
end


-- This is a map from aliases to their canonical forms. Any placetypes appearing
-- as keys here will be mapped to their canonical forms in all respects, including
-- the display form. Contrast 'placetype_equivs', which apply to categorization and
-- other processes but not to display.
export.placetype_aliases = {
	 = "country",
	 = "constituent country",
	 = "province",
	 = "autonomous province",
	 = "region",
	 = "autonomous region",
	 = "administrative region",
	 = "special administrative region",
	 = "state",
	 = "archipelago",
	 = "borough",
	 = "canton",
	 = "council area",
	 = "community development block",
	 = "Crown dependency",
	 = "census-designated place",
	 = "census-designated place",
	 = "county",
	 = "county borough",
	 = "county-level city",
	 = "collectivity",
	 = "community",
	 = "autonomous community",
	 = "continent",
	 = "civil parish",
	 = "dependency",
	 = "department",
	 = "district",
	 = "district municipality",
	 = "division",
	 = "governorate",
	 = "governorate",
	 = "Indian reservation",
	 = "island",
	 = "London borough",
	 = "local government area",
	 = "local government district",
	 = "metropolitan borough",
	 = "metropolitan city",
	 = "mountain",
	 = "municipality",
	 = "municipal district",
	 = "oblast",
	 = "autonomous oblast",
	 = "okrug",
	 = "autonomous okrug",
	 = "parish",
	 = "parish municipality",
	 = "peninsula",
	 = "prefecture",
	 = "prefecture-level city",
	 = "autonomous prefecture",
	 = "republic",
	 = "autonomous republic",
	 = "river",
	 = "regional county municipality",
	 = "regional district",
	 = "regional municipality",
	 = "royal borough",
	 = "regional unit",
	 = "rural municipality",
	 = "territorial authority",
	 = "territory",
	 = "autonomous territory",
	 = "union territory",
	 = "tribal jurisdictional area",
	 = "township",
	 = "township municipality",
	 = "united township municipality",
	 = "valley",
	 = "voivodeship",
	 = "mountain range",
	 = "department capital",
	 = "home rule city",
	 = "home rule municipality",
	 = "subprovincial city",
	 = "sub-prefectural city",
	 = "non-metropolitan county",
	 = "inner city area",
}


-- These qualifiers can be prepended onto any placetype and will be handled correctly.
-- For example, the placetype "large city" will be displayed as such but otherwise
-- treated exactly as if "city" were specified. Links will be added to the remainder
-- of the placetype as appropriate, e.g. "small voivodeship" will display as
-- "small ]" because "voivoideship" has an entry in placetype_links.
-- If the value is a string, the qualifier will display according to the string.
-- Note that these qualifiers do not override placetypes with entries elsewhere that
-- contain those same qualifiers. For example, the entry for "former colony" in
-- placetype_equivs will apply in preference to treating "former colony" as equivalent
-- to "colony". Also note that if an entry like "former colony" appears in either
-- placetype_equivs or cat_data, the non-qualifier portion won't automatically be
-- linked, so it needs to be specifically included in placetype_links if linking is
-- desired.
export.placetype_qualifiers = {
	-- generic qualifiers
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true, -- left tributary
	 = true, -- right tributary
	 = true, -- for use in opposition to "ancient" in another definition
	-- "former" qualifiers
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = "historical",
	 = true,
	 = true,
	 = true,
	 = true,
	-- sea qualifiers
	 = true,
	 = true,
	 = true,
	 = "]",
	 = "coastal",
	 = "]",
	 = "]",
	 = true,
	-- political status qualifiers
	 = "]",
	 = "]",
	 = "]",
	 = "]",
	-- monetary status/etc. qualifiers
	 = true,
	 = true,
	 = "]",
	 = "]",
	-- city vs. rural qualifiers
	 = true,
	 = "]",
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	-- land use qualifiers
	 = "]",
	 = "]",
	 = true,
	 = "]",
	 = "]",
	-- business use qualifiers
	 = "]",
	 = "]",
	 = "]",
	 = "]",
	 = "]",
	 = "]",
	 = "]",
	-- religious qualifiers
	 = true,
	 = true,
	 = true,
	 = true,
	-- qualifiers for nonexistent places
	 = true,
	 = true,
	-- directional qualifiers
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	-- misc. qualifiers
	 = true,
	 = true,
	 = true,
}


-- If there's an entry here, the corresponding placetype will use the text of the
-- value, which should be used to add links. If the value is true, a simple link
-- will be added around the whole placetype. If the value is "w", a link to
-- Wikipedia will be added around the whole placetype.
export.placetype_links = {
	 = "w",
	 = "w",
	 = "w",
	 = "w",
	 = "w",
	 = "] ]",
	 = true,
	 = "w",
	 = "w",
	 = true,
	 = "] ]",
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = "w",
	 = "w",
	 = "w",
	 = "w",
	 = true,
	 = true, -- Philippines
	 = true, -- Spanish-speaking countries; Philippines
	 = true,
	 = "w",
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = "] and largest city",
	 = true,
	 = true,
	 = true, -- Australia
	 = true,
	 = true, -- United States
	 = true,
	 = true,
	 = true,
	 = "w", -- Northwest Territories, Canada
	 = true,
	 = true,
	 = "w",
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = "w", -- India
	 = true,
	 = "] region",
	 = true,
	 = "w", -- Taiwan
	 = "w", -- Taiwan
	 = "w", -- China
	 = true,
	 = true,
	 = true,
	 = "w",
	 = "w",
	 = true,
	 = "] ]",
	 = true,
	 = "w",
	 = "w",
	 = "w",
	 = "]",
	 = "w",
	 = true,
	 = true,
	 = "] ]",
	 = "] ]",
	 = "w",
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = "] ]",
	 = "w",
	 = "w",
	 = "w",
	 = "] ]", -- Canada
	 = true,
	 = "former ]",
	 = "former ]",
	 = "former ]",
	 = "former ]",
	 = "former ] ]",
	 = "w",
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = "] ]",
	 = "] ]",
	 = "] ]",
	 = "] ]",
	 = true,
	 = "w",
	 = true,
	 = "w",
	 = "w",
	 = "w",
	 = "w",
	 = "w",
	 = true,
	 = true,
	 = "]",
	 = "w", -- United States
	 = "w", -- Canada
	 = "] ]",
	 = "] area",
	 = "w",
	 = "w",
	 = "w",
	 = "w",
	 = true,
	 = true,
	 = "] ]",
	 = "w",
	 = "w",
	 = "w",
	 = "w",
	 = "] with ]",
	 = "w",
	 = "]",
	 = "w",
	 = true,
	 = true,
	 = "]",
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = "] town", -- England
	 = true,
	 = true,
	 = "]", -- Taiwan
	 = "]", -- Taiwan
	 = true,
	 = true,
	 = "] ]",
	 = "w",
	 = true,
	 = "] with ]",
	 = "w",
	 = true,
	 = "]",
	 = "w",
	 = "w",
	 = true,
	 = "w",
	 = "w",
	 = "w",
	 = true,
	 = "]",
	 = true,
	 = "]",
	 = true,
	 = true,
	 = "]",
	 = true,
	 = true,
	 = "w",
	 = true,
	 = "w",
	 = true,
	 = true,
	 = true,
	 = true,
	 = "] ]",
	 = "w",
	 = "w",
	 = "w",
	 = "w",
	 = true,
	 = "] ]",
	 = "] area",
	 = "w",
	 = "w",
	 = "w",
	 = true,
	 = "w",
	 = "w",
	 = "w",
	 = "]", -- Taiwan
	 = true,
	 = true,
	 = true,
	 = true, -- Isle of Man
	 = true, -- Australia
	 = true,
	 = "w",
	 = true,
	 = "] town",
	 = "]",
	 = "w",
	 = "w", -- China; North Korea; Indonesia; East Timor
	 = "w",
	 = true,
	 = true,
	 = true,
	 = true,
	 = "w",
	 = "w",
	 = true,
	 = true,
	 = true,
	 = "] ]",
	 = true,
	 = true,
	 = "w",
	 = "w",
	 = true,
	 = true,
	 = "w",
	 = true,
	 = true,
	 = "w",
	 = true,
	 = "]",
	-- can't use templates in this code
	 = "] with ]",
	 = true,
	 = "w",
	 = "w",
	 = "w",
	 = true,
	 = "w",
	 = "w",
	 = true,
	 = "w",
	 = "]",
	 = "w",
	 = "w",
	 = "] area",
	 = "w",
	 = "w",
	 = "]",
	 = true, -- Poland
	 = true,
	 = true,
	 = true,
}


-- In this table, the key qualifiers should be treated the same as the value qualifiers for
-- categorization purposes. This is overridden by cat_data, placetype_equivs and
-- qualifier_to_placetype_equivs.
export.qualifier_equivs = {
	 = "historical",
	 = "historical",
	 = "historical",
	 = "historical",
	 = "historical",
	-- This needs to be here. If we take it out, 'historic province' won't properly
	-- map to 'historical political subdivision'.
	 = "historical",
	 = "historical",
	 = "historical",
	 = "historical",
}

-- In this table, any placetypes containing these qualifiers that do not occur in placetype_equivs
-- or cat_data should be mapped to the specified placetypes for categorization purposes. Entries here
-- are overridden by cat_data and placetype_equivs.
export.qualifier_to_placetype_equivs = {
	 = "fictional location",
	 = "mythological location",
}

-- In this table, the key placetypes should be treated the same as the value placetypes for
-- categorization purposes. Entries here are overridden by cat_data.
-- NOTE: 'coal town', 'county town', 'ghost town', 'resort town', 'ski resort town',
-- 'spa town', etc. aren't mapped to 'town' because they aren't necessarily towns.
export.placetype_equivs = {
	 = "főváros",
	 = "administrative centre",
	 = "administrative centre",
	 = "administrative centre",
	 = "ancient settlement",
	 = "ancient settlement",
	 = "ancient settlement",
	 = "ancient settlement",
	 = "island",
	 = "province",
	 = "dependent territory",
	 = "polity",
	 = "neighborhood", -- not completely correct, barangays are formal administrative divisions of a city
	 = "neighborhood", -- not completely correct, in some countries barrios are formal administrative divisions of a city
	 = "polity",
	 = "area",
	 = "borough",
	 = "peninsula",
	 = "főváros",
	 = "főváros",
	 = "főváros",
	 = "city", -- should be 'former city' if we distinguish that
	 = "city",
	 = "neighborhood",
	 = "county",
	 = "island",
	 = "village",
	 = "historical political subdivision",
	 = "village",
	 = "country",
	 = "region",
	 = "county-administered city",
	 = "prefecture-level city",
	 = "dependency",
	 = "dependency",
	 = "főváros",
	 = "ancient settlement",
	 = "ancient settlement",
	 = "municipality",
	 = "municipality",
	 = "river",
	 = "főváros",
	 = "administrative centre",
	 = "volcano",
	 = "polity",
	 = "polity",
	 = "dependent territory",
	 = "territory",
	 = "Indian reserve",
	 = "region",
	 = "valley",
	 = "island",
	 = "village",
	 = "city",
	 = "city",
	 = "town",
	 = "town",
	 = "administrative centre",
	 = "moor",
	 = "town",
	 = "town",
	-- We try to list all top-level polities and political subdivisions here and classify them
	-- accordingly. (Note that the following entries also apply to anything preceded by "former",
	-- "ancient", "historic", "medieval", etc., according to qualifier_equivs.) Anything we don't
	-- list will be categorized as if the qualifier were absent, e.g. "ancient city" will be
	-- categorized as a city and "former sea" as a sea.
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical polity",
	 = "historical political subdivision",
	 = "historical polity",
	 = "historical settlement",
	 = "historical polity",
	 = "historical polity",
	 = "historical political subdivision",
	 = "historical polity",
	 = "historical political subdivision",
	 = "historical polity",
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical polity",
	 = "historical polity",
	 = "historical political subdivision",
	 = "historical polity",
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical polity",
	 = "historical polity",
	 = "historical political subdivision",
	 = "historical settlement",
	 = "historical polity",
	 = "historical political subdivision",
	 = "historical polity",
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical polity",
	 = "historical polity",
	 = "historical polity",
	-- The following could refer either to a state of a country (a subdivision)
	-- or a state = sovereign entity. The latter appears more common (e.g. in
	-- various "ancient states" of East Asia).
	 = "historical polity",
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical political subdivision",
	 = "historical settlement",
	 = "historical settlement",
	 = "historical political subdivision",
	 = "city",
	 = "municipality",
	 = "volcano",
	 = "city",
	 = "town",
	 = "neighborhood",
	 = "country",
	 = "municipality",
	 = "főváros",
	 = "polity",
	 = "főváros",
	 = "local government district",
	 = "local government district",
	 = "unincorporated community",
	 = "village", -- not necessarily true, but usually is the case
	 = "city",
	 = "town",
	 = "ancient capital",
	 = "ancient capital",
	 = "ancient settlement",
	 = "ancient settlement",
	 = "ancient settlement",
	 = "ancient settlement",
	 = "ancient settlement",
	 = "ancient settlement",
	 = "ancient settlement",
	 = "ancient settlement",
	 = "city",
	 = "county",
	 = "country",
	 = "town",
	 = "moor",
	 = "district",
	 = "township",
	 = "mountain",
	 = "region",
	 = "municipality",
	 = "főváros",
	 = "park",
	 = "neighborhood",
	 = "town",
	 = "county",
	 = "local government district",
	 = "collectivity",
	 = "department",
	 = "territory",
	 = "mountain pass",
	 = "village", -- not necessarily true, but usually is the case
	 = "city",
	 = "town",
	 = "főváros",
	 = "főváros",
	 = "municipality",
	 = "city",
	 = "borough",
	 = "főváros",
	 = "village", -- not necessarily true, but usually is the case
	 = "district",
	 = "county",
	 = "county",
	 = "county seat",
	 = "city",
	 = "peninsula",
	 = "főváros",
	 = "park",
	 = "city",
	 = "town",
	 = "river",
	 = "ghost town",
	 = "subprovincial city",
	 = "suburb",
	 = "metro station",
	 = "continent",
	 = "county",
	 = "city", -- should be 'former city' if we distinguish that
	 = "district",
	 = "metro station",
	 = "territory",
	 = "local government district",
	 = "local government district",
	 = "township municipality",
	 = "unrecognized country",
	 = "neighborhood",
	 = "township",
	 = "town",
	 = "town",
	 = "river",
	 = "neighborhood", -- not completely correct, wards are formal administrative divisions of a city
}


-- These contain transformations applied to certain placenames to convert them
-- into displayed form. For example, if any of "country/US", "country/USA" or
-- "country/United States of America" (or "c/US", etc.) are given, the result
-- will be displayed as "United States".
export.placename_display_aliases = {
	 = {
		 = "Valencia",
	},
	 = {
		 = "New York City",
		 = "Washington, D.C.",
		 = "Washington, D.C.",
		 = "Washington, D.C.",
	},
	 = {
		 = "United States",
		 = "United States",
		 = "United States",
		 = "United States",
		 = "United States",
		 = "United Kingdom",
		 = "United Arab Emirates",
		 = "North Macedonia",
		 = "North Macedonia",
		 = "North Macedonia",
		 = "Ireland",
		 = "Armenia",
		 = "Ivory Coast",
		 = "Czech Republic",
		 = "Vatican City",
		 = "Bosnia and Herzegovina",
	},
	 = {
		 = "North Ostrobothnia",
		 = "South Ostrobothnia",
		 = "Northern Savonia",
		 = "Southern Savonia",
		 = "Päijänne Tavastia",
		 = "Tavastia Proper",
		 = "Åland Islands",
	},
	 = {
		 = "Kabardino-Balkar Republic",
		 = "Tuva Republic",
	},
	 = {
		 = "Mecklenburg-Vorpommern",
		 = "State of Mexico",
	},
	 = {
		 = "United States Virgin Islands",
		 = "United States Virgin Islands",
	},
}


-- These contain transformations applied to the displayed form of certain
-- placenames to convert them into the form they will appear in categories.
-- For example, either of "country/Myanmar" and "country/Burma" will be
-- categorized into categories with "Burma" in them (but the displayed form
-- will respect the form as input). (NOTE, the choice of names here should not
-- be taken to imply any political position; it is just this way because it has
-- always been this way.)
export.placename_cat_aliases = {
	 = {
		 = "Nenets Autonomous Okrug",
		 = "Khanty-Mansi Autonomous Okrug",
		 = "Khanty-Mansi Autonomous Okrug",
	},
	 = {
		 = "City of Glasgow",
		 = "City of Edinburgh",
		 = "City of Aberdeen",
		 = "City of Dundee",
		 = "Na h-Eileanan Siar",
	},
	 = {
		-- will categorize into e.g. "Cities in Burma".
		 = "Burma",
		 = "Artsakh",
		 = "China",
		 = "Taiwan",
		 = "Bosnia and Herzegovina",
		 = "Democratic Republic of the Congo",
		 = "Republic of the Congo",
	},
	 = {
		 = "Isle of Anglesey",
	},
	 = {
		-- Only needs to include cases that aren't just shortened versions of the
		-- full federal subject name (i.e. where words like "Republic" and "Oblast"
		-- are omitted but the name is not otherwise modified). Note that a couple
		-- of minor variants are recognized as display aliases, meaning that they
		-- will be canonicalized for display as well as categorization.
		 = "Republic of Bashkortostan",
		 = "Chechen Republic",
		 = "Chuvash Republic",
		 = "Kabardino-Balkar Republic",
		 = "Kabardino-Balkar Republic",
		 = "Karachay-Cherkess Republic",
		 = "Republic of North Ossetia-Alania",
		 = "Republic of North Ossetia-Alania",
		 = "Sakha Republic",
		 = "Sakha Republic",
		 = "Sakha Republic",
		 = "Tuva Republic",
		 = "Udmurt Republic",
	},
}


-- This contains placenames that should be preceded by an article (almost always "the").
-- NOTE: There are multiple ways that placenames can come to be preceded by "the":
-- 1. Listed here.
-- 2. Given in ] with an initial "the". All such placenames
--    are added to this map by the code just below the map.
-- 3. The placetype of the placename has holonym_article = "the" in its cat_data.
-- 4. A regex in placename_the_re matches the placename.
-- Note that "the" is added only before the first holonym in a place spec.
export.placename_article = {
	-- This should only contain info that can't be inferred from ].
	 = {
		 = "the",
		 = "the",
	},
	 = {
		 = "the",
	},
	 = {
		 = "the",
	},
	 = {
		 = "the",
		 = "the",
	},
	 = {
		 = "the",
		 = "the",
		 = "the",
		 = "the",
		 = "the",
		 = "the",
		 = "the",
	},
	 = {
		 = "the",
	},
}

-- Regular expressions to apply to determine whether we need to put 'the' before
-- a holonym. The key "*" applies to all holonyms, otherwise only the regexes
-- for the holonym's placetype apply.
export.placename_the_re = {
	-- We don't need entries for peninsulas, seas, oceans, gulfs or rivers
	-- because they have holonym_article = "the".
	 = {"^Isle of ", " Islands$", " Mountains$", " Empire$", " Country$", " Region$", " District$", "^City of "},
	 = {"^Bay of "},
	 = {"^Lake of "},
	 = {"^Republic of ", " Republic$"},
	 = {"^Republic of ", " Republic$"},
	 = {" egion$"},
	 = {" River$"},
	 = {"^Shire of "},
	 = {"^Shire of "},
	 = {" Reservation", " Nation"},
	 = {" Reservation", " Nation"},
}

-- Now extract from the shared place data all the other places that need "the"
-- prefixed.
for _, group in ipairs(m_shared.polities) do
	for key, value in pairs(group.data) do
		key = key:gsub(", .*$", "") -- Chop off ", England" and such from the end
		local base = key:match("^the (.*)$")
		if base then
			local divtype = value.divtype or group.default_divtype
			if not divtype then
				error("Group in ] is missing a default_divtype key")
			end
			if type(divtype) ~= "table" then
				divtype = {divtype}
			end
			for _, dt in ipairs(divtype) do
				if not export.placename_article then
					export.placename_article = {}
				end
				export.placename_article = "the"
			end
		end
	end
end


-- If any of the following holonyms are present, the associated holonyms are automatically added
-- to the end of the list of holonyms for display and categorization purposes.
-- FIXME: There are none here currently and the mechanism is broken in that it doesn't properly
-- check for the presence of the holonym already. Don't add any without fixing this, or we'll
-- get redundantly-displayed holonyms in the common case where e.g. "Alabama, USA" is specified.
-- See below under cat_implications.
-- FIXME: Consider implementing a handler to automatically add implications for all political
-- subdivisions listed in the groups in ], with the containing polity
-- as the implicand. That way, if someone writes e.g. {{place|en|village|s/Thuringia}}, it will
-- automatically display as if written {{place|en|village|s/Thuringia|c/Germany}}.
export.implications = {
}


-- If any of the following holonyms are present, the associated holonyms are automatically added
-- to the end of the list of holonyms for categorization (but not display) purposes.
-- FIXME: We should implement an implication handler to add cat_implications for all political
-- subdivisions listed in the groups in ], with the containing polity
-- as the implicand. (This should be a handler not a preprocessing step to save memory.) Before
-- doing that, we should fix the implication mechanism to not add a holonym if the holonym
-- already exists or a conflicting holonym exists, where "conflicting" means a different holonym
-- of the same placetype as the holonym being added. Hence, if e.g. two countries have a province of
-- the same name, and we have an entry for one of the provinces, we won't add that province's country
-- if the other country is already specified.
export.cat_implications = {
	 = {
		 = {"continent/Europe"},
		 = {"continent/Europe"},
		 = {"continent/Europe"},
		 = {"continent/Europe"},
		 = {"continent/Europe"},
		 = {"continent/Europe"},
		 = {"continent/Europe"},
		 = {"continent/Asia"},
		 = {"continent/Asia"},
		 = {"continent/Asia"},
		 = {"continent/Asia"},
		 = {"continent/Asia"},
		 = {"continent/Asia"},
		 = {"continent/Asia"},
		 = {"continent/Africa"},
		 = {"continent/Africa"},
		 = {"continent/Africa"},
		 = {"continent/Africa"},
		 = {"continent/Africa"},
		 = {"continent/North America"},
		 = {"continent/North America"},
		 = {"continent/Oceania"},
		 = {"continent/Oceania"},
		 = {"continent/Oceania"},
		 = {"country/Russia", "continent/Asia"},
		 = {"country/Russia", "continent/Asia"},
		 = {"constituent country/Wales", "continent/Europe"},
		 = {"continent/Europe"},
		 = {"country/Palestine", "continent/Asia"},
	}
}


export.cat_implication_handlers = {}

table.insert(export.cat_implication_handlers,
	function(placetype, holonym_placetype, holonym_placename)
		for _, group in ipairs(m_shared.polities) do
			-- Find the appropriate key format for the holonym (e.g. "pref/Osaka" -> "Osaka Prefecture").
			local key = group.place_cat_handler(group, placetype, holonym_placetype, holonym_placename)
			if key then
				local value = group.data
				if value and value.containing_polity and value.containing_polity_type then
					local bare_containing_polity, linked_containing_polity =
						m_shared.construct_bare_and_linked_version(value.containing_polity)
					return {value.containing_polity_type, bare_containing_polity}
				end
			end
		end
	end
)

----------- Basic utilities -----------


function export.remove_links_and_html(text)
	text = m_links.remove_links(text)
	return text:gsub("<.->", "")
end


-- Return the singular version of a maybe-plural placetype, or nil if not plural.
function export.maybe_singularize(placetype)
	if not placetype then
		return nil
	end
	local retval = m_strutils.singularize(placetype)
	if retval == placetype then
		return nil
	end
	return retval
end


-- Look up and resolve any category aliases that need to be applied to a holonym. For example,
-- "country/Republic of China" maps to "Taiwan" for use in categories like "Counties in Taiwan".
-- This also removes any links.
function export.resolve_cat_aliases(holonym_placetype, holonym_placename)
	local retval
	local cat_aliases = export.get_equiv_placetype_prop(holonym_placetype, function(pt) return export.placename_cat_aliases end)
	holonym_placename = export.remove_links_and_html(holonym_placename)
	if cat_aliases then
		retval = cat_aliases
	end
	return retval or holonym_placename
end


-- Given a placetype, split the placetype into one or more potential "splits", each consisting of
-- a three-element list {PREV_QUALIFIERS, THIS_QUALIFIER, BARE_PLACETYPE}, i.e.
-- (a) the concatenation of zero or more previously-recognized qualifiers on the left, normally
--     canonicalized (if there are zero such qualifiers, the value will be nil);
-- (b) a single recognized qualifier, normally canonicalized;
-- (c) the "bare placetype" on the right.
-- Splitting between the qualifier in (b) and the bare placetype in (c) happens at each space
-- character, proceeding from left to right, and stops if a qualifier isn't recognized. (No checks
-- are made as to whether to bare placetype is recognized, and it is not canonicalized in any way.)
-- Canonicalization of qualifiers does not happen if NO_CANON_QUALIFIERS is specified.
-- For example, given the placetype "small beachside unincorporated community", the return value will be
-- {
--   {nil, "small", "beachside unincorporated community"},
--   {"small", "]", "unincorporated community"},
--   {"small ]", "]", "community"},
-- }
-- Here, "beachside" is canonicalized to "]" and "unincorporated" is canonicalized
-- to "]", in both cases according to the entry in placetype_qualifiers.
-- On the other hand, if given "small former haunted community", the return value will be
-- {
--   {nil, "small", "former haunted community"},
--   {"small", "former", "haunted community"},
-- }
-- because "small" and "former" but not "haunted" are recognized as qualifiers.
function export.split_qualifiers_from_placetype(placetype, no_canon_qualifiers)
	local splits = {}
	local prev_qualifier = nil
	while true do
		local qualifier, bare_placetype = placetype:match("^(.-) (.*)$")
		if qualifier then
			local canon = export.placetype_qualifiers
			if not canon then
				break
			end
			local new_qualifier = qualifier
			if not no_canon_qualifiers and canon ~= true then
				new_qualifier = canon
			end
			table.insert(splits, {prev_qualifier, new_qualifier, bare_placetype})
			prev_qualifier = prev_qualifier and prev_qualifier .. " " .. new_qualifier or new_qualifier
			placetype = bare_placetype
		else
			break
		end
	end
	return splits
end


-- Given a placetype, return an ordered list of equivalent placetypes to look under
-- to find the placetype's properties (actually, an ordered list of objects of the
-- form {qualifier=QUALIFIER, placetype=PLACETYPE} where QUALIFIER is a descriptive
-- qualifier to prepend, or nil). The placetype itself always forms the first entry.
function export.get_placetype_equivs(placetype)
	local equivs = {}

	local function do_placetype(qualifier, placetype)
		-- FIXME! The qualifier (first arg) is inserted into the table, but isn't
		-- currently used anywhere.

		-- First do the placetype itself.
		table.insert(equivs, {qualifier=qualifier, placetype=placetype})
		-- Then check for a singularized equivalent.
		local sg_placetype = export.maybe_singularize(placetype)
		if sg_placetype then
			table.insert(equivs, {qualifier=qualifier, placetype=sg_placetype})
		end
		-- Then check for a mapping in placetype_equivs; add if present.
		if export.placetype_equivs then
			table.insert(equivs, {qualifier=qualifier, placetype=export.placetype_equivs})
		end
		-- Then check for a mapping in placetype_equivs for the singularized equivalent.
		if sg_placetype and export.placetype_equivs then
			table.insert(equivs, {qualifier=qualifier, placetype=export.placetype_equivs})
		end
	end

	do_placetype(nil, placetype)

	-- Then successively split off recognized qualifiers and loop over successively greater sets of
	-- qualifiers from the left.
	local splits = export.split_qualifiers_from_placetype(placetype)
	for _, split in ipairs(splits) do
		local prev_qualifier, this_qualifier, bare_placetype = split, split, split
		-- First see if the rightmost split-off qualifier is in qualifier_to_placetype_equivs
		-- (e.g. 'fictional *' -> 'fictional location'). If so, add the mapping.
		if export.qualifier_to_placetype_equivs then
			table.insert(equivs, {qualifier=prev_qualifier, placetype=export.qualifier_to_placetype_equivs})
		end
		-- Then see if the rightmost split-off qualifier is in qualifier_equivs (e.g. 'former' -> 'historical').
		-- If so, create a placetype from the qualifier mapping + the following bare_placetype; then, add
		-- that placetype, and any mapping for the placetype in placetype_equivs.
		if export.qualifier_equivs then
			do_placetype(prev_qualifier, export.qualifier_equivs .. " " .. bare_placetype)
		end
		-- Finally, join the rightmost split-off qualifier to the previously split-off qualifiers to form a
		-- combined qualifier, and add it along with bare_placetype and any mapping in placetype_equivs for
		-- bare_placetype.
		local qualifier = prev_qualifier and prev_qualifier .. " " .. this_qualifier or this_qualifier
		do_placetype(qualifier, bare_placetype)
	end
	return equivs
end


function export.get_equiv_placetype_prop(placetype, fun)
	if not placetype then
		return fun(nil), nil
	end
	local equivs = export.get_placetype_equivs(placetype)
	for _, equiv in ipairs(equivs) do
		local retval = fun(equiv.placetype)
		if retval then
			return retval, equiv
		end
	end
	return nil, nil
end

------------------------------------------------------

local function city_type_cat_handler(placetype, holonym_placetype, holonym_placename, ignore_nocities, no_containing_polity,
		extracats)
	local plural_placetype = m_strutils.pluralize(placetype)
	if m_shared.generic_place_types then
		for _, group in ipairs(m_shared.polities) do
			-- Find the appropriate key format for the holonym (e.g. "pref/Osaka" -> "Osaka Prefecture").
			local key = group.place_cat_handler(group, placetype, holonym_placetype, holonym_placename)
			if key then
				local value = group.data
				if value then
					-- Use the group's value_transformer to ensure that 'nocities', 'containing_polity'
					-- and 'british_spelling' keys are present if they should be.
					value = group.value_transformer(group, key, value)
					if ignore_nocities or not value.nocities then
						-- Categorize both in key, and in the larger polity that the key is part of,
						-- e.g. ] goes in both "Cities in Osaka Prefecture" and
						-- "Cities in Japan". (But don't do the latter if no_containing_polity_cat is set.)
						if plural_placetype == "neighborhoods" and value.british_spelling then
							plural_placetype = "neighbourhoods"
						end
						local retcats = {ucfirst(plural_placetype) .. " in " .. key}
						if value.containing_polity and not value.no_containing_polity_cat and not no_containing_polity then
							table.insert(retcats, ucfirst(plural_placetype) .. " in " .. value.containing_polity)
						end
						if extracats then
							for _, cat in ipairs(extracats) do
								table.insert(retcats, cat)
							end
						end
						return {
							 = retcats
						}
					end
				end
			end
		end
	end
end


local function capital_city_cat_handler(holonym_placetype, holonym_placename, place_spec, non_city)
	-- The first time we're called we want to return something; otherwise we will be called
	-- for later-mentioned holonyms, which can result in wrongly classifying into e.g.
	-- 'National capitals'.
	if holonym_placetype then
		-- Simulate the loop in find_cat_specs() over holonyms so we get the proper
		-- 'Cities in ...' categories as well as the capital category/categories we add below.
		local c = 3
		local inner_data
		if not non_city then
			while place_spec do
				local h_placetype, h_placename = place_spec, place_spec
				h_placename = export.resolve_cat_aliases(h_placetype, h_placename)
				inner_data = export.get_equiv_placetype_prop(h_placetype,
					function(pt) return city_type_cat_handler("city", pt, h_placename) end)
				if inner_data then
					break
				end
				c = c + 1
			end
		end
		if not inner_data then
			inner_data = {
				 = {}
			}
		end
		-- Now find the appropriate capital-type category for the placetype of the holonym,
		-- e.g. 'State capitals'. If we recognize the holonym among the known holonyms in
		-- ], also add a category like 'State capitals of the United States'.
		-- Truncate e.g. 'autonomous region' to 'region', 'union territory' to 'territory' when looking
		-- up the type of capital category, if we can't find an entry for the holonym placetype itself
		-- (there's an entry for 'autonomous community').
		local capital_cat = m_shared.placetype_to_capital_cat
		if not capital_cat then
			capital_cat = m_shared.placetype_to_capital_cat
		end
		if capital_cat then
			capital_cat = ucfirst(capital_cat)
			local inserted_specific_variant_cat = false
			for _, group in ipairs(m_shared.polities) do
				-- Find the appropriate key format for the holonym (e.g. "pref/Osaka" -> "Osaka Prefecture").
				local key = group.place_cat_handler(group, "főváros", holonym_placetype, holonym_placename)
				if key then
					local value = group.data
					if value then
						-- Use the group's value_transformer to ensure that 'containing_polity'
						-- is present if it should be.
						value = group.value_transformer(group, key, value)
						if value.containing_polity and not value.no_containing_polity_cat then
							table.insert(inner_data, capital_cat .. " of " .. value.containing_polity)
							inserted_specific_variant_cat = true
							break
						end
					end
				end
			end
			if not inserted_specific_variant_cat then
				table.insert(inner_data, capital_cat)
			end
		else
			-- We didn't recognize the holonym placetype; just put in 'Capital cities'.
			table.insert(inner_data, "Capital cities")
		end
		return inner_data
	end
end

-- This is used to add pages to base holonym categories like 'en:Places in Merseyside, England'
-- (and 'en:Places in England') for any pages that have 'co/Merseyside' as their holonym.
-- It also handles cities (e.g. 'en:Places in Boston', along with 'en:Places in Massachusetts, USA'
-- and 'en:Places in the United States') for any pages that have 'city/Boston' as their holonym.
local function generic_cat_handler(holonym_placetype, holonym_placename, place_spec)
	for _, group in ipairs(m_shared.polities) do
		-- Find the appropriate key format for the holonym (e.g. "pref/Osaka" -> "Osaka Prefecture").
		local key = group.place_cat_handler(group, "*", holonym_placetype, holonym_placename)
		if key then
			local value = group.data
			if value then
				-- Use the group's value_transformer to ensure that 'nocities' and 'containing_polity'
				-- keys are present if they should be.
				value = group.value_transformer(group, key, value)
				-- Categorize both in key, and in the larger polity that the key is part of,
				-- e.g. ] goes in both "Places in Osaka Prefecture" and "Places in Japan".
				local retcats = {"Places in " .. key}
				if value.containing_polity and not value.no_containing_polity_cat then
					table.insert(retcats, "Places in " .. value.containing_polity)
				end
				return {
					 = retcats
				}
			end
		end
	end
	-- Check for cities mentioned as holonyms.
	if holonym_placetype == "city" then
		for _, city_group in ipairs(m_shared.cities) do
			local value = city_group.data
			if value and value.alias_of then
				local new_value = city_group.data
				if not new_value then
					error("City '" .. holonym_placename .. "' has an entry with non-existent alias_of='" .. value.alias_of .. "'")
				end
				holonym_placename = value.alias_of
				value = new_value
			end
			if value then
				-- Check if any of the city's containing polities are explicitly mentioned. If not, make sure
				-- that no other polities of the same sort are mentioned.
				local containing_polities = m_shared.get_city_containing_polities(city_group, holonym_placename, value)
				local containing_polities_match = false
				local containing_polities_mismatch = false
				for _, polity in ipairs(containing_polities) do
					local bare_polity, linked_polity = m_shared.construct_bare_and_linked_version(polity)
					local divtype = polity.divtype or city_group.default_divtype
					local function holonym_matches_polity(placetype)
						if not place_spec then
							return false
						end
						for _, holonym in ipairs(place_spec) do
							if holonym == bare_polity then
								return true
							end
						end
						return false
					end
					containing_polities_match = export.get_equiv_placetype_prop(divtype, holonym_matches_polity)
					if containing_polities_match then
						break
					end
					containing_polities_mismatch = export.get_equiv_placetype_prop(divtype, function(pt) return not not place_spec end)
					if containing_polities_mismatch then
						break
					end
				end
				-- No mismatching containing polities, so add categories for the city and
				-- its containing polities.
				if not containing_polities_mismatch then
					local retcats = {"Places in " .. holonym_placename}
					for _, polity in ipairs(containing_polities) do
						local divtype = polity.divtype or city_group.default_divtype
						local drop_dead_now = false
						-- Find the group and key corresponding to the polity.
						for _, polity_group in ipairs(m_shared.polities) do
							local key = polity
							if polity_group.placename_to_key then
								key = polity_group.placename_to_key(key)
							end
							local value = polity_group.data
							if value then
								value = polity_group.value_transformer(polity_group, key, value)
								local key_divtype = value.divtype or polity_group.default_divtype
								if key_divtype == divtype or type(key_divtype) == "table" and key_divtype == divtype then
									table.insert(retcats, "Places in " .. key)
									if value.no_containing_polity_cat then
										-- Stop adding containing polities if no_containing_polity_cat
										-- is found. (Used for 'United Kingdom'.)
										drop_dead_now = true
									end
									break
								end
							end
						end
						if drop_dead_now then
							break
						end
					end
					return {
						 = retcats
					}
				end
			end
		end
	end
end


-- Inner data returned by cat handler for districts, neighborhoods, etc.
local function district_inner_data(value, itself_dest)
	local retval = {
		 = value,
		 = value,
		 = value,
		 = value,
		 = value,
		 = value,
		 = value,
		 = value,
	}
	if itself_dest then
		retval = itself_dest
	end
	return retval
end


-- Cat handler for districts and areas. Districts are tricky because they can
-- either be political subdivisions or city neighborhoods. We handle this as follows:
-- (1) For countries etc. where they can be political subdivisions, an entry under
-- "district" will be inserted for the country with something similar to the following:
--
-- {
--		 = {"Districts of Foo"},
--		 = {"Neighborhoods in Foo"},
--		 = {"Neighborhoods in Foo"},
--		 = {"Neighborhoods in Foo"},
--		...
-- }
--
-- This way, a district in a city will categorize under "Neighborhoods in Foo"
-- while some other district will categorize under "Districts of Foo".
-- (2) For the remaining countries, we have a cat_handler that returns the following
-- for all known countries and primary subdivisions:
--
-- {
--		 = {"Neighborhoods in Foo"},
--		 = {"Neighborhoods in Foo"},
--		 = {"Neighborhoods in Foo"},
--		...
-- }
--
-- This way, a district under a city will still categorize under "Neighborhoods in Foo"
-- while other districts won't categorize.
local function district_cat_handler(placetype, holonym_placetype, holonym_placename)
	for _, group in ipairs(m_shared.polities) do
		-- Find the appropriate key format for the holonym (e.g. "pref/Osaka" -> "Osaka Prefecture").
		local key = group.place_cat_handler(group, placetype, holonym_placetype, holonym_placename)
		if key then
			local value = group.data
			if value then
				value = group.value_transformer(group, key, value)
				if value.british_spelling then
					return district_inner_data({"Neighbourhoods in " .. key})
				else
					return district_inner_data({"Neighborhoods in " .. key})
				end
			end
		end
	end
end


local function chinese_subcity_cat_handler(holonym_placetype, holonym_placename, place_spec)
	local spec = m_shared.chinese_provinces_and_autonomous_regions
	if spec and holonym_placetype == (spec.divtype or "province") then
		return {
			 = {"Cities in " .. holonym_placename}
		}
	end
end


function export.check_already_seen_string(holonym_placename, already_seen_strings)
	local canon_placename = lc(m_links.remove_links(holonym_placename))
	if type(already_seen_strings) ~= "table" then
		already_seen_strings = {already_seen_strings}
	end
	for _, already_seen_string in ipairs(already_seen_strings) do
		if canon_placename:find(already_seen_string) then
			return true
		end
	end
	return false
end


-- Prefix display handler that adds a prefix such as "Metropolitan Borough of " to the display
-- form of holonyms. We make sure the holonym doesn't contain the prefix or some variant already.
-- We do this by checking if any of the strings in ALREADY_SEEN_STRINGS, either a single string or
-- a list of strings, or the prefix if ALREADY_SEEN_STRINGS is omitted, are found in the holonym
-- placename, ignoring case and links. If the prefix isn't already present, we create a link that
-- uses the raw form as the link destination but the prefixed form as the display form, unless the
-- holonym already has a link in it, in which case we just add the prefix.
local function prefix_display_handler(prefix, holonym_placename, already_seen_strings)
	if export.check_already_seen_string(holonym_placename, already_seen_strings or lc(prefix)) then
		return holonym_placename
	end
	if holonym_placename:find("%[%[") then
		return prefix .. " " .. holonym_placename
	end
	return prefix .. " ]"
end


-- Suffix display handler that adds a suffix such as " parish" to the display form of holonyms.
-- Works identically to prefix_display_handler but for suffixes instead of prefixes.
local function suffix_display_handler(suffix, holonym_placename, already_seen_strings)
	if export.check_already_seen_string(holonym_placename, already_seen_strings or lc(suffix)) then
		return holonym_placename
	end
	if holonym_placename:find("%[%[") then
		return holonym_placename .. " " .. suffix
	end
	return "] " .. suffix
end


-- Display handler for counties. Irish counties are displayed as e.g. "County ]".
-- Others are displayed as-is.
local function county_display_handler(holonym_placetype, holonym_placename)
	local unlinked_placename = m_links.remove_links(holonym_placename)
	if m_shared.irish_counties or
		m_shared.northern_irish_counties then
		return prefix_display_handler("County", holonym_placename)
	end
	return holonym_placename
end


-- Display handler for boroughs. New York City boroughs are display as-is. Others are suffixed
-- with "borough".
local function borough_display_handler(holonym_placetype, holonym_placename)
	local unlinked_placename = m_links.remove_links(holonym_placename)
	if m_shared.new_york_boroughs then
		-- Hack: don't display "borough" after the names of NYC boroughs
		return holonym_placename
	end
	return suffix_display_handler("borough", holonym_placename)
end


-- Display handler for prefectures. Japanese prefectures are displayed as e.g. "] Prefecture".
-- Others are displayed as e.g. "] prefecture".
local function prefecture_display_handler(holonym_placetype, holonym_placename)
	local unlinked_placename = m_links.remove_links(holonym_placename)
	local suffix = m_shared.japanese_prefectures and "Prefecture" or "prefecture"
	return suffix_display_handler(suffix, holonym_placename)
end


export.cat_data = {
	 = {
		preposition = "of",

		 = {
			 = {true},
		},
	},

	 = {
		article = "the",
		preposition = "of",
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		article = "the",
		preposition = "of",
		 = {
			 = {"Ancient settlements", "Historical capitals"},
		},
	},

	 = {
		 = {
			 = {"Ancient settlements"},
		},
	},

	 = {
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			return district_cat_handler("area", holonym_placetype, holonym_placename)
		end,
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",
		affix_type = "Suf",
		no_affix_strings = "oblast",
	},

	 = {
		preposition = "of",
		affix_type = "Suf",
		no_affix_strings = "okrug",
	},

	 = {
		preposition = "of",

		 = {
			 = {"Districts and autonomous regions of +++"},
		},

		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {true},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",
		display_handler = borough_display_handler,
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			if holonym_placetype == "county" then
				local cat_form = holonym_placename .. ", England"
				if not m_shared.english_counties then
					cat_form = "the " .. cat_form
					if not m_shared.english_counties then
						cat_form = nil
					end
				end
				if cat_form then
					return {
						 = {"Districts of " .. cat_form, "Districts of England"}
					}
				end
			end
			if (holonym_placetype == "country" or holonym_placetype == "constituent country") and
				holonym_placename == "England" then
					return {
						 = {"Districts of +++"},
					}
			end
		end,

		 = {
			 = {"Boroughs of +++, USA"},
		},

		 = {
			 = {"Boroughs in +++"},
		},

		 = {
			 = {"Boroughs in +++, USA"},
		},

		 = {
			 = {"Boroughs in +++, USA"},
		},
	},

	 = {
		article = "the",
		preposition = "of",

		 = {
			 = {"Borough seats of +++, USA"},
		},
	},

	 = {
		preposition = "of",
		affix_type = "suf",

		 = {
			 = {true},
		},
	},

	 = {
		article = "",
		preposition = "",
		cat_handler = capital_city_cat_handler,

		 = {
			 = {true},
		},
	},

	 = {
		affix_type = "Suf",
	},

	 = {
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			if holonym_placetype == "state" then
				return city_type_cat_handler("census-designated place", holonym_placetype, holonym_placename)
			end
		end,

		 = {
			 = {true},
		},
	},

	 = {
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			return city_type_cat_handler("city", holonym_placetype, holonym_placename)
		end,

		 = {
			 = {true},
			 = {true},
		},
	},

	 = {
		 = {
			 = {"City-states", "Cities", "Countries", "Countries in +++", "National capitals"},
			 = {"City-states", "Cities", "Countries", "National capitals"},
		},
	},

	 = {
		preposition = "of",
		affix_type = "suf",

		 = {
			 = {"Civil parishes of +++"},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {"Polities"},
			 = {true},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {"Polities"},
		},
	},

	 = {
		preposition = "of",
	},

	 = {
		affix_type = "suf",
		no_affix_strings = "block",
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",
		affix_type = "suf",

		 = {
			 = {true},
			 = {true},
		},
	},

	 = {
		synergy = {
			 = {
				before = "in the",
				between = "of",
			}
		},

		 = {
			 = {true, "Countries"},
			 = {true},
		},
	},

	 = {
		preposition = "of",
		-- UNITED STATES
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			local spec = m_shared.us_states
			if spec and holonym_placetype == "state" and not spec.county_type then
				return {
					 = {"Counties of " .. holonym_placename .. ", USA"}
				}
			end
		end,
		display_handler = county_display_handler,

		 = {
		},

		 = {
			 = {"Traditional counties of +++"},
		},

		 = {
			 = {"Traditional counties of +++"},
		},

		 = {
			 = {"Polities"},
			 = {true},
		},
	},

	 = {
		 = {
			 = {"Cities in +++"},
		},
	},

	 = {
		preposition = "of",
		affix_type = "suf",
		fallback = "borough",
	},

	 = {
		article = "the",
		preposition = "of",
		-- UNITED STATES
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			local spec = m_shared.us_states
			if spec and holonym_placetype == "state" and not spec.county_type then
				return {
					 = {"County seats of " .. holonym_placename .. ", USA"}
				}
			end
		end,
	},

	 = {
		article = "the",
		preposition = "of",
	},

	 = {
		preposition = "of",
		affix_type = "suf",

		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {true},
			 = {"Dependencies of +++"},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {"Dependencies"},
			 = {"Territories of +++"},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",
		affix_type = "suf",
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			return district_cat_handler("district", holonym_placetype, holonym_placename)
		end,

		 = {
			 = {"Districts and autonomous regions of +++"},
		},

		-- No default. Countries for which districts are political subdivisions will get entries.
	},

	 = {
		preposition = "of",
		affix_type = "suf",
		no_affix_strings = {"district", "municipality"},
		fallback = "municipality",
	},

	 = {
		preposition = "of",

		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",
	},

	 = {
		preposition = "of",
	},

	 = {
		preposition = "of",

		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {true},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			local function check_for_recognized(divlist, default_divtype, placename_to_key)
				local key = placename_to_key and placename_to_key(holonym_placename) or holonym_placename
				local spec = divlist
				if not spec then
					key = "the " .. key
					spec = divlist
				end
				if spec and holonym_placetype == (spec.divtype or default_divtype) then
					return {
						 = {"Ghost towns in " .. key}
					}
				end
			end
			return (
				check_for_recognized(m_shared.us_states, "state", function(placename) return placename .. ", USA" end) or
				check_for_recognized(m_shared.canadian_provinces_and_territories, "province") or
				check_for_recognized(m_shared.australian_states_and_territories, "state")
			)
		end,

		 = {
			 = {true},
			 = {true},
		},
	},

	 = {
		preposition = "of",
		affix_type = "suf",
	},

	 = {
		preposition = "of",
		holonym_article = "the",

		 = {
			 = {true},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		article = "the",
		preposition = "of",
		 = {
			 = {"Historical settlements", "Historical capitals"},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {"Traditional counties of +++"},
		},

		 = {
			 = {"Traditional counties of +++"},
		},

		 = {
			 = {"Historical political subdivisions"},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {true},
		},
	},

	 = {
		 = {
			 = {"Historical and traditional regions"},
		},
	},

	 = {
		 = {
			 = {"Historical settlements"},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		plural = "kibbutzim",

		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",
		affix_type = "Suf",

		 = {
			 = {true},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		article = "the",
		fallback = "city",
	},

	 = {
		preposition = "of",
		affix_type = "suf",
		affix = "district",
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			if holonym_placetype == "county" then
				local cat_form = holonym_placename .. ", England"
				if not m_shared.english_counties then
					cat_form = "the " .. cat_form
					if not m_shared.english_counties then
						cat_form = nil
					end
				end
				if cat_form then
					return {
						 = {"Districts of " .. cat_form, "Districts of England"}
					}
				end
			end
			if (holonym_placetype == "country" or holonym_placetype == "constituent country") and
				holonym_placename == "England" then
					return {
						 = {"Districts of +++"},
					}
			end
		end,
	},

	 = {
		preposition = "of",
		affix_type = "suf",
		affix = "borough",
		fallback = "local government district",
	},

	 = {
		preposition = "of",

		 = {
			 = {"Regions of +++"},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {"Seas"},
		},
	},

	 = {
		preposition = "of",
		affix_type = "Pref",
		no_affix_strings = {"borough", "city"},
		fallback = "local government district",
	},

	 = {
		preposition = "of",
		affix_type = "Pref",
		no_affix_strings = {"metropolitan", "city"},
		fallback = "city",

		 = {
			 = {"Metropolitan cities of Italy"},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",
		affix_type = "Pref",
		no_affix_strings = "district",
		fallback = "municipality",
	},

	 = {
		preposition = "of",

		 = {
			 = {true, "Municipalities of Austria"},
			 = {true},
		},

		 = {
			 = {"Municipalities of +++, Brazil", "Municipalities of Brazil"},
			 = {true},
		},

		 = {
			 = {"Municipalities of +++, Finland", "Municipalities of Finland"},
			 = {true},
		},

		 = {
			 = {"Municipalities of +++, Philippines", "Municipalities of the Philippines"},
			 = {true},
		},

		 = {
			 = {true},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			return city_type_cat_handler("neighborhood", holonym_placetype, holonym_placename,
				"ignore nocities", "no containing polity")
		end,
	},

	 = {
		article = "the",
		preposition = "of",
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			return capital_city_cat_handler(holonym_placetype, holonym_placename, place_spec, "non-city")
		end,

		 = {
			 = {"Capital cities"},
		},
	},

	 = {
		preposition = "of",
		affix_type = "Suf",
	},

	 = {
		holonym_article = "the",

		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",
		affix_type = "Suf",
	},

	 = {
		preposition = "of",
		affix_type = "suf",

		 = {
			 = {"Parishes of +++, USA"},
		},

	},

	 = {
		preposition = "of",
		fallback = "municipality",

		 = {
			 = {"Parishes of +++", "Municipalities of Canada"},
		},
	},

	 = {
		article = "the",
		preposition = "of",

		 = {
			 = {"Parish seats of +++, USA"},
		},

	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {"Regions of +++"},
		},
	},

	 = {
		-- Include this empty so we don't categorize 'planned community' into
		-- villages, as 'community' does.
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",
		display_handler = prefecture_display_handler,

		 = {
			 = {true},
		},
	},

	 = {
		-- CHINA
		cat_handler = chinese_subcity_cat_handler,

		 = {
			 = {"Cities in +++"},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {true},
			 = {true},
		},
	},

	 = {
		preposition = "of",
		affix_type = "Suf",
	},

	 = {
		preposition = "of",

		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {true},
		},

		 = {
			 = {true},
		},

		 = {
			 = {"Counties and regions of +++"},
		},

		 = {
			 = {true},
		},

		 = {
			 = {true},
		},

		 = {
			 = {true},
		},

		 = {
			 = {true},
		},

		 = {
			 = {true},
		},

		 = {
			 = {true},
		},

		 = {
			 = {true},
		},

		 = {
			 = {true},
		},

		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",
		affix_type = "Pref",
		no_affix_strings = "district",
		fallback = "district",

		 = {
			 = {"Regional districts of +++"},
		},
	},

	 = {
		preposition = "of",
		affix_type = "Suf",
		no_affix_strings = {"municipality", "county"},
		fallback = "municipality",
	},

	 = {
		preposition = "of",
		affix_type = "Pref",
		no_affix_strings = "municipality",
		fallback = "municipality",
	},

	 = {
		preposition = "of",
	},

	 = {
		preposition = "of",

		 = {
			 = {true},
		},
	},

	 = {
		holonym_article = "the",
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			return city_type_cat_handler("river", holonym_placetype, holonym_placename)
		end,

		 = {
			 = {true},
			 = {true},
		},
	},

	 = {
		preposition = "of",
		affix_type = "Pref",
		no_affix_strings = {"royal", "borough"},
		fallback = "local government district",
	},

	 = {
		preposition = "of",
		affix_type = "Pref",
		no_affix_strings = "municipality",
		fallback = "municipality",
	},

	 = {
		preposition = "of",
	},

	 = {
		holonym_article = "the",

		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {true},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {true},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {true},
		},

		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",
		affix_type = "suf",
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			return district_cat_handler("subdivision", holonym_placetype, holonym_placename)
		end,
	},

	 = {
		preposition = "of",
	},

	 = {
		preposition = "of",
	},

	 = {
		-- CHINA
		cat_handler = chinese_subcity_cat_handler,

		 = {
			 = {"Cities in +++"},
		},
	},

	 = {
		preposition = "of",
	},

	 = {
		preposition = "of",
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			return city_type_cat_handler("suburb", holonym_placetype, holonym_placename,
				"ignore nocities", "no containing polity")
		end,
	},

	 = {
		affix_type = "suf",
		no_affix_strings = {"tehsil", "tahsil"},
	},

	 = {
		preposition = "of",

		 = {
			 = {"Polities"},
			 = {true},
		},
	},

	 = {
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			return city_type_cat_handler("town", holonym_placetype, holonym_placename)
		end,

		 = {
			 = {true},
			 = {true},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",
		fallback = "municipality",

		 = {
			 = {"Townships in +++", "Townships in Canada", "Municipalities of Canada"},
		},
	},

	 = {
		 = {
			 = {"Historical and traditional regions"},
		},
	},

	 = {
		preposition = "of",
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			return city_type_cat_handler("river", holonym_placetype, holonym_placename)
		end,

		 = {
			 = {"Rivers"},
			 = {"Rivers in +++"},
		},
	},

	 = {
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			if holonym_placetype == "state" then
				return city_type_cat_handler("unincorporated community", holonym_placetype, holonym_placename)
			end
		end,

		 = {
			 = {true},
		},
	},

	 = {
		preposition = "of",
		article = "a",
	},

	 = {
		 = {
			 = {"Countries"},
		},
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		cat_handler = function(holonym_placetype, holonym_placename, place_spec)
			return city_type_cat_handler("village", holonym_placetype, holonym_placename)
		end,

		 = {
			 = {true},
			 = {true},
		},
	},

	 = {
		preposition = "of",

		 = {
			 = {"Villages in +++", "Villages in Canada", "Municipalities of Canada"},
		},
	},

	 = {
		preposition = "of",
		holonym_article = "the",
	},

	 = {
		 = {
			 = {true},
		},
	},

	 = {
		cat_handler = generic_cat_handler,
	},
}


-- Now augment the category data with political subdivisions extracted from the
-- shared data. We don't need to do this if there's already an entry under "default"
-- for the divtype of the containing polity.
for _, group in ipairs(m_shared.polities) do
	for key, value in pairs(group.data) do
		value = group.value_transformer(group, key, value)
		if value.poldiv or value.miscdiv then
			local bare_key, linked_key = m_shared.construct_bare_and_linked_version(key)
			local divtype = value.divtype or group.default_divtype
			if type(divtype) ~= "table" then
				divtype = {divtype}
			end
			for pass=1,2 do
				local list
				if pass == 1 then
					list = value.poldiv
				else
					list = value.miscdiv
				end
				if list then
					for _, div in ipairs(list) do
						if type(div) == "string" then
							div = {div}
						end
						local sgdiv = m_strutils.singularize(div)
						for _, dt in ipairs(divtype) do
							if not export.cat_data then
								-- If there is an entry in placetype_equivs, it will be ignored once
								-- we insert an entry in cat_data. For example, "traditional county" is
								-- listed as a miscdiv of Scotland and Northern Ireland but it's also
								-- an entry in placetype_equivs. Once we insert an entry here for
								-- "traditional county", it will override placetype_equivs. To get
								-- around that, simulate the effect of placetype_equivs using a
								-- fallback = "..." entry.
								if export.placetype_equivs then
									export.cat_data = {
										preposition = "of",
										fallback = export.placetype_equivs,
									}
								else
									export.cat_data = {
										preposition = "of",

										 = {
										},
									}
								end
							end
							if not export.cat_data or not export.cat_data then
								local itself_dest = bare_key == key and {true} or {ucfirst(div) .. " of " .. key}
								if sgdiv == "district" then
									-- see comment above under district_cat_handler().
									local neighborhoods_in = value.british_spelling and "Neighbourhoods in " .. key or "Neighborhoods in " .. key
									local inner_data = district_inner_data({neighborhoods_in}, itself_dest)
									export.cat_data = inner_data
								else
									export.cat_data = {
										 = itself_dest,
									}
								end
							end
						end
					end
				end
			end
		end
	end
end


return export